]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/phoenix/stl/container/detail/container.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / phoenix / stl / container / detail / container.hpp
1 /*=============================================================================
2 Copyright (c) 2004 Angus Leeming
3 Copyright (c) 2004 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #ifndef BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
9 #define BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
10
11 #include <utility>
12 #include <boost/mpl/eval_if.hpp>
13 #include <boost/type_traits/is_same.hpp>
14 #include <boost/type_traits/is_const.hpp>
15 #include <boost/type_traits/is_convertible.hpp>
16
17 namespace boost { namespace phoenix { namespace stl
18 {
19 ///////////////////////////////////////////////////////////////////////////////
20 //
21 // Metafunctions "value_type_of", "key_type_of" etc.
22 //
23 // These metafunctions define a typedef "type" that returns the nested
24 // type if it exists. If not then the typedef returns void.
25 //
26 // For example, "value_type_of<std::vector<int> >::type" is "int" whilst
27 // "value_type_of<double>::type" is "void".
28 //
29 // I use a macro to define structs "value_type_of" etc simply to cut
30 // down on the amount of code. The macro is #undef-ed immediately after
31 // its final use.
32 //
33 /////////////////////////////////////////////////////////////////c//////////////
34 #define MEMBER_TYPE_OF(MEMBER_TYPE) \
35 template <typename C> \
36 struct BOOST_PP_CAT(MEMBER_TYPE, _of) \
37 { \
38 typedef typename C::MEMBER_TYPE type; \
39 }
40
41 MEMBER_TYPE_OF(allocator_type);
42 MEMBER_TYPE_OF(const_iterator);
43 MEMBER_TYPE_OF(const_reference);
44 MEMBER_TYPE_OF(const_reverse_iterator);
45 MEMBER_TYPE_OF(container_type);
46 MEMBER_TYPE_OF(data_type);
47 MEMBER_TYPE_OF(iterator);
48 MEMBER_TYPE_OF(key_compare);
49 MEMBER_TYPE_OF(key_type);
50 MEMBER_TYPE_OF(reference);
51 MEMBER_TYPE_OF(reverse_iterator);
52 MEMBER_TYPE_OF(size_type);
53 MEMBER_TYPE_OF(value_compare);
54 MEMBER_TYPE_OF(value_type);
55
56 #undef MEMBER_TYPE_OF
57
58 ///////////////////////////////////////////////////////////////////////////////
59 //
60 // Const-Qualified types.
61 //
62 // Many of the stl member functions have const and non-const
63 // overloaded versions that return distinct types. For example:
64 //
65 // iterator begin();
66 // const_iterator begin() const;
67 //
68 // The three class templates defined below,
69 // const_qualified_reference_of, const_qualified_iterator_of
70 // and const_qualified_reverse_iterator_of provide a means to extract
71 // this return type automatically.
72 //
73 ///////////////////////////////////////////////////////////////////////////////
74 template <typename C>
75 struct const_qualified_reference_of
76 {
77 typedef typename
78 boost::mpl::eval_if_c<
79 boost::is_const<C>::value
80 , const_reference_of<C>
81 , reference_of<C>
82 >::type
83 type;
84 };
85
86 template <typename C>
87 struct const_qualified_iterator_of
88 {
89 typedef typename
90 boost::mpl::eval_if_c<
91 boost::is_const<C>::value
92 , const_iterator_of<C>
93 , iterator_of<C>
94 >::type
95 type;
96 };
97
98 template <typename C>
99 struct const_qualified_reverse_iterator_of
100 {
101 typedef typename
102 boost::mpl::eval_if_c<
103 boost::is_const<C>::value
104 , const_reverse_iterator_of<C>
105 , reverse_iterator_of<C>
106 >::type
107 type;
108 };
109
110 ///////////////////////////////////////////////////////////////////////////////
111 //
112 // has_mapped_type<C>
113 //
114 // Given a container C, determine if it is a map, multimap, unordered_map,
115 // or unordered_multimap by checking if it has a member type named "mapped_type".
116 //
117 ///////////////////////////////////////////////////////////////////////////////
118 namespace stl_impl
119 {
120 struct one { char a[1]; };
121 struct two { char a[2]; };
122
123 template <typename C>
124 one has_mapped_type(typename C::mapped_type(*)());
125
126 template <typename C>
127 two has_mapped_type(...);
128 }
129
130 template <typename C>
131 struct has_mapped_type
132 : boost::mpl::bool_<
133 sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one)
134 >
135 {};
136
137 ///////////////////////////////////////////////////////////////////////////////
138 //
139 // has_key_type<C>
140 //
141 // Given a container C, determine if it is a Associative Container
142 // by checking if it has a member type named "key_type".
143 //
144 ///////////////////////////////////////////////////////////////////////////////
145 namespace stl_impl
146 {
147 template <typename C>
148 one has_key_type(typename C::key_type(*)());
149
150 template <typename C>
151 two has_key_type(...);
152 }
153
154 template <typename C>
155 struct has_key_type
156 : boost::mpl::bool_<
157 sizeof(stl_impl::has_key_type<C>(0)) == sizeof(stl_impl::one)
158 >
159 {};
160
161 ///////////////////////////////////////////////////////////////////////////////
162 //
163 // is_key_type_of<C, Arg>
164 //
165 // Lazy evaluation friendly predicate.
166 //
167 ///////////////////////////////////////////////////////////////////////////////
168
169 template <typename C, typename Arg>
170 struct is_key_type_of
171 : boost::is_convertible<Arg, typename key_type_of<C>::type>
172 {};
173
174 ///////////////////////////////////////////////////////////////////////////////
175 //
176 // map_insert_returns_pair<C>
177 //
178 // Distinguish a map from a multimap by checking the return type
179 // of its "insert" member function. A map returns a pair while
180 // a multimap returns an iterator.
181 //
182 ///////////////////////////////////////////////////////////////////////////////
183 namespace stl_impl
184 {
185 // Cool implementation of map_insert_returns_pair by Daniel Wallin.
186 // Thanks Daniel!!! I owe you a Pizza!
187
188 template<class A, class B>
189 one map_insert_returns_pair_check(std::pair<A,B> const&);
190
191 template <typename T>
192 two map_insert_returns_pair_check(T const&);
193
194 template <typename C>
195 struct map_insert_returns_pair
196 {
197 static typename C::value_type const& get;
198 BOOST_STATIC_CONSTANT(int,
199 value = sizeof(
200 map_insert_returns_pair_check(((C*)0)->insert(get))));
201 typedef boost::mpl::bool_<value == sizeof(one)> type;
202 };
203 }
204
205 template <typename C>
206 struct map_insert_returns_pair
207 : stl_impl::map_insert_returns_pair<C>::type {};
208
209 }}} // namespace boost::phoenix::stl
210
211 #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP