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

source code of boost/libs/type_erasure/include/boost/type_erasure/is_subconcept.hpp