is_subconcept.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2012 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #ifndef BOOST_TYPE_ERASURE_IS_SUBCONCEPT_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_IS_SUBCONCEPT_HPP_INCLUDED
  12. #include <boost/mpl/and.hpp>
  13. #include <boost/mpl/bool.hpp>
  14. #include <boost/mpl/not.hpp>
  15. #include <boost/mpl/if.hpp>
  16. #include <boost/mpl/end.hpp>
  17. #include <boost/mpl/find_if.hpp>
  18. #include <boost/mpl/has_key.hpp>
  19. #include <boost/type_traits/is_same.hpp>
  20. #include <boost/type_erasure/detail/normalize.hpp>
  21. #include <boost/type_erasure/detail/check_map.hpp>
  22. #include <boost/type_erasure/detail/rebind_placeholders.hpp>
  23. #include <boost/type_erasure/static_binding.hpp>
  24. namespace boost {
  25. namespace type_erasure {
  26. namespace detail {
  27. #ifdef BOOST_TYPE_ERASURE_USE_MP11
  28. template<class S, class K>
  29. struct mp_set_has_key : ::boost::mp11::mp_set_contains<S, K> {};
  30. template<class Super, class Bindings>
  31. struct is_subconcept_f
  32. {
  33. template<class T>
  34. using apply = ::boost::mp11::mp_set_contains<Super, ::boost::type_erasure::detail::rebind_placeholders_t<T, Bindings> >;
  35. };
  36. template<class Super>
  37. struct is_subconcept_f<Super, void>
  38. {
  39. template<class T>
  40. using apply = ::boost::mp11::mp_set_contains<Super, T>;
  41. };
  42. #endif
  43. template<class Sub, class Super, class PlaceholderMap>
  44. struct is_subconcept_impl {
  45. #ifndef BOOST_TYPE_ERASURE_USE_MP11
  46. typedef typename ::boost::type_erasure::detail::normalize_concept<
  47. Super>::concept_set super_set;
  48. typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
  49. Super
  50. >::type placeholder_subs_super;
  51. typedef typename ::boost::type_erasure::detail::normalize_concept<
  52. Sub>::type normalized_sub;
  53. typedef typename ::boost::type_erasure::detail::get_placeholder_normalization_map<
  54. Sub
  55. >::type placeholder_subs_sub;
  56. typedef typename ::boost::mpl::eval_if< ::boost::is_same<PlaceholderMap, void>,
  57. boost::mpl::identity<void>,
  58. ::boost::type_erasure::detail::convert_deductions<
  59. PlaceholderMap,
  60. placeholder_subs_sub,
  61. placeholder_subs_super
  62. >
  63. >::type bindings;
  64. typedef typename ::boost::mpl::if_< ::boost::is_same<PlaceholderMap, void>,
  65. ::boost::mpl::_1,
  66. ::boost::type_erasure::detail::rebind_placeholders<
  67. ::boost::mpl::_1,
  68. bindings
  69. >
  70. >::type transform;
  71. typedef typename ::boost::is_same<
  72. typename ::boost::mpl::find_if<normalized_sub,
  73. ::boost::mpl::not_<
  74. ::boost::mpl::has_key<
  75. super_set,
  76. transform
  77. >
  78. >
  79. >::type,
  80. typename ::boost::mpl::end<normalized_sub>::type
  81. >::type type;
  82. #else
  83. typedef ::boost::type_erasure::detail::normalize_concept_t<Super> super_set;
  84. typedef ::boost::type_erasure::detail::get_placeholder_normalization_map_t<
  85. Super
  86. > placeholder_subs_super;
  87. typedef ::boost::type_erasure::detail::normalize_concept_t<Sub> normalized_sub;
  88. typedef ::boost::type_erasure::detail::get_placeholder_normalization_map_t<
  89. Sub
  90. > placeholder_subs_sub;
  91. typedef ::boost::mp11::mp_eval_if_c< ::boost::is_same<PlaceholderMap, void>::value,
  92. void,
  93. ::boost::type_erasure::detail::convert_deductions_t,
  94. PlaceholderMap,
  95. placeholder_subs_sub,
  96. placeholder_subs_super
  97. > bindings;
  98. typedef typename ::boost::mp11::mp_all_of<
  99. normalized_sub,
  100. ::boost::type_erasure::detail::is_subconcept_f<super_set, bindings>::template apply
  101. > type;
  102. #endif
  103. };
  104. }
  105. /**
  106. * @ref is_subconcept is a boolean metafunction that determines whether
  107. * one concept is a sub-concept of another.
  108. *
  109. * \code
  110. * is_subconcept<incrementable<>, incrementable<> > -> true
  111. * is_subconcept<incrementable<>, addable<> > -> false
  112. * is_subconcept<incrementable<_a>, forward_iterator<_iter>,
  113. * mpl::map<mpl::pair<_a, _iter> > > -> true
  114. * \endcode
  115. *
  116. * \tparam Sub The sub concept
  117. * \tparam Super The super concept
  118. * \tparam PlaceholderMap (optional) An MPL map with keys for
  119. * every non-deduced placeholder in Sub. The
  120. * associated value of each key is the corresponding placeholder
  121. * in Super. If @c PlaceholderMap is omitted, @c Super and @c Sub
  122. * are presumed to use the same set of placeholders.
  123. */
  124. template<class Sub, class Super, class PlaceholderMap = void>
  125. struct is_subconcept :
  126. ::boost::mpl::and_<
  127. ::boost::type_erasure::detail::check_map<Sub, PlaceholderMap>,
  128. ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>
  129. >::type
  130. {};
  131. #ifndef BOOST_TYPE_ERASURE_DOXYGEN
  132. template<class Sub, class Super>
  133. struct is_subconcept<Sub, Super, void> :
  134. ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, void>::type
  135. {};
  136. template<class Sub, class Super, class PlaceholderMap>
  137. struct is_subconcept<Sub, Super, static_binding<PlaceholderMap> > :
  138. ::boost::mpl::and_<
  139. ::boost::type_erasure::detail::check_map<Sub, PlaceholderMap>,
  140. ::boost::type_erasure::detail::is_subconcept_impl<Sub, Super, PlaceholderMap>
  141. >::type
  142. {};
  143. #endif
  144. }
  145. }
  146. #endif