123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- // Boost.TypeErasure library
- //
- // Copyright 2012 Steven Watanabe
- //
- // Distributed under the Boost Software License Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // $Id$
- #ifndef BOOST_TYPE_ERASURE_IS_SUBCONCEPT_HPP_INCLUDED
- #define BOOST_TYPE_ERASURE_IS_SUBCONCEPT_HPP_INCLUDED
- #include <boost/mpl/and.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/not.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/end.hpp>
- #include <boost/mpl/find_if.hpp>
- #include <boost/mpl/has_key.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_erasure/detail/normalize.hpp>
- #include <boost/type_erasure/detail/check_map.hpp>
- #include <boost/type_erasure/detail/rebind_placeholders.hpp>
- #include <boost/type_erasure/static_binding.hpp>
- namespace boost {
- namespace type_erasure {
- namespace detail {
- #ifdef BOOST_TYPE_ERASURE_USE_MP11
- template<class S, class K>
- struct mp_set_has_key : ::boost::mp11::mp_set_contains<S, K> {};
- template<class Super, class Bindings>
- struct is_subconcept_f
- {
- template<class T>
- using apply = ::boost::mp11::mp_set_contains<Super, ::boost::type_erasure::detail::rebind_placeholders_t<T, Bindings> >;
- };
- template<class Super>
- struct is_subconcept_f<Super, void>
- {
- template<class T>
- using apply = ::boost::mp11::mp_set_contains<Super, T>;
- };
- #endif
- template<class Sub, class Super, class PlaceholderMap>
- struct is_subconcept_impl {
- #ifndef BOOST_TYPE_ERASURE_USE_MP11
- typedef typename ::boost::type_erasure::detail::normalize_concept<
- Super>::concept_set super_set;
- typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
- Super
- >::type placeholder_subs_super;
-
- typedef typename ::boost::type_erasure::detail::normalize_concept<
- Sub>::type normalized_sub;
- typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
- Sub
- >::type placeholder_subs_sub;
- typedef typename ::boost::mpl::eval_if< ::boost::is_same<PlaceholderMap, void>,
- boost::mpl::identity<void>,
- ::boost::type_erasure::detail::convert_deductions<
- PlaceholderMap,
- placeholder_subs_sub,
- placeholder_subs_super
- >
- >::type bindings;
- typedef typename ::boost::mpl::if_< ::boost::is_same<PlaceholderMap, void>,
- ::boost::mpl::_1,
- ::boost::type_erasure::detail::rebind_placeholders<
- ::boost::mpl::_1,
- bindings
- >
- >::type transform;
- typedef typename ::boost::is_same<
- typename ::boost::mpl::find_if<normalized_sub,
- ::boost::mpl::not_<
- ::boost::mpl::has_key<
- super_set,
- transform
- >
- >
- >::type,
- typename ::boost::mpl::end<normalized_sub>::type
- >::type type;
- #else
- typedef ::boost::type_erasure::detail::normalize_concept_t<Super> super_set;
- typedef ::boost::type_erasure::detail::get_placeholder_normalization_map_t<
- Super
- > placeholder_subs_super;
-
- typedef ::boost::type_erasure::detail::normalize_concept_t<Sub> normalized_sub;
- typedef ::boost::type_erasure::detail::get_placeholder_normalization_map_t<
- Sub
- > placeholder_subs_sub;
- typedef ::boost::mp11::mp_eval_if_c< ::boost::is_same<PlaceholderMap, void>::value,
- void,
- ::boost::type_erasure::detail::convert_deductions_t,
- PlaceholderMap,
- placeholder_subs_sub,
- placeholder_subs_super
- > bindings;
- typedef typename ::boost::mp11::mp_all_of<
- normalized_sub,
- ::boost::type_erasure::detail::is_subconcept_f<super_set, bindings>::template apply
- > type;
- #endif
- };
- }
- /**
- * @ref is_subconcept is a boolean metafunction that determines whether
- * one concept is a sub-concept of another.
- *
- * \code
- * is_subconcept<incrementable<>, incrementable<> > -> true
- * is_subconcept<incrementable<>, addable<> > -> false
- * is_subconcept<incrementable<_a>, forward_iterator<_iter>,
- * mpl::map<mpl::pair<_a, _iter> > > -> true
- * \endcode
- *
- * \tparam Sub The sub concept
- * \tparam Super The super concept
- * \tparam PlaceholderMap (optional) An MPL map with keys for
- * every non-deduced placeholder in Sub. The
- * associated value of each key is the corresponding placeholder
- * in Super. If @c PlaceholderMap is omitted, @c Super and @c Sub
- * are presumed to use the same set of placeholders.
- */
- template<class Sub, class Super, class PlaceholderMap = void>
- struct is_subconcept :
- ::boost::mpl::and_<
- ::boost::type_erasure::detail::check_map<Sub, PlaceholderMap>,
- ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>
- >::type
- {};
- #ifndef BOOST_TYPE_ERASURE_DOXYGEN
- template<class Sub, class Super>
- struct is_subconcept<Sub, Super, void> :
- ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, void>::type
- {};
- template<class Sub, class Super, class PlaceholderMap>
- struct is_subconcept<Sub, Super, static_binding<PlaceholderMap> > :
- ::boost::mpl::and_<
- ::boost::type_erasure::detail::check_map<Sub, PlaceholderMap>,
- ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>
- >::type
- {};
- #endif
- }
- }
- #endif
|