]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
16 | namespace boost { namespace phoenix { namespace stl | |
17 | { | |
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | // | |
20 | // Metafunctions "value_type_of", "key_type_of" etc. | |
21 | // | |
22 | // These metafunctions define a typedef "type" that returns the nested | |
23 | // type if it exists. If not then the typedef returns void. | |
24 | // | |
25 | // For example, "value_type_of<std::vector<int> >::type" is "int" whilst | |
26 | // "value_type_of<double>::type" is "void". | |
27 | // | |
28 | // I use a macro to define structs "value_type_of" etc simply to cut | |
29 | // down on the amount of code. The macro is #undef-ed immediately after | |
30 | // its final use. | |
31 | // | |
32 | /////////////////////////////////////////////////////////////////c////////////// | |
33 | #define MEMBER_TYPE_OF(MEMBER_TYPE) \ | |
34 | template <typename C> \ | |
35 | struct BOOST_PP_CAT(MEMBER_TYPE, _of) \ | |
36 | { \ | |
37 | typedef typename C::MEMBER_TYPE type; \ | |
38 | } | |
39 | ||
40 | MEMBER_TYPE_OF(allocator_type); | |
41 | MEMBER_TYPE_OF(const_iterator); | |
42 | MEMBER_TYPE_OF(const_reference); | |
43 | MEMBER_TYPE_OF(const_reverse_iterator); | |
44 | MEMBER_TYPE_OF(container_type); | |
45 | MEMBER_TYPE_OF(data_type); | |
46 | MEMBER_TYPE_OF(iterator); | |
47 | MEMBER_TYPE_OF(key_compare); | |
48 | MEMBER_TYPE_OF(key_type); | |
49 | MEMBER_TYPE_OF(reference); | |
50 | MEMBER_TYPE_OF(reverse_iterator); | |
51 | MEMBER_TYPE_OF(size_type); | |
52 | MEMBER_TYPE_OF(value_compare); | |
53 | MEMBER_TYPE_OF(value_type); | |
54 | ||
55 | #undef MEMBER_TYPE_OF | |
56 | ||
57 | /////////////////////////////////////////////////////////////////////////////// | |
58 | // | |
59 | // Const-Qualified types. | |
60 | // | |
61 | // Many of the stl member functions have const and non-const | |
62 | // overloaded versions that return distinct types. For example: | |
63 | // | |
64 | // iterator begin(); | |
65 | // const_iterator begin() const; | |
66 | // | |
67 | // The three class templates defined below, | |
68 | // const_qualified_reference_of, const_qualified_iterator_of | |
69 | // and const_qualified_reverse_iterator_of provide a means to extract | |
70 | // this return type automatically. | |
71 | // | |
72 | /////////////////////////////////////////////////////////////////////////////// | |
73 | template <typename C> | |
74 | struct const_qualified_reference_of | |
75 | { | |
76 | typedef typename | |
77 | boost::mpl::eval_if_c< | |
78 | boost::is_const<C>::value | |
79 | , const_reference_of<C> | |
80 | , reference_of<C> | |
81 | >::type | |
82 | type; | |
83 | }; | |
84 | ||
85 | template <typename C> | |
86 | struct const_qualified_iterator_of | |
87 | { | |
88 | typedef typename | |
89 | boost::mpl::eval_if_c< | |
90 | boost::is_const<C>::value | |
91 | , const_iterator_of<C> | |
92 | , iterator_of<C> | |
93 | >::type | |
94 | type; | |
95 | }; | |
96 | ||
97 | template <typename C> | |
98 | struct const_qualified_reverse_iterator_of | |
99 | { | |
100 | typedef typename | |
101 | boost::mpl::eval_if_c< | |
102 | boost::is_const<C>::value | |
103 | , const_reverse_iterator_of<C> | |
104 | , reverse_iterator_of<C> | |
105 | >::type | |
106 | type; | |
107 | }; | |
108 | ||
109 | /////////////////////////////////////////////////////////////////////////////// | |
110 | // | |
111 | // has_mapped_type<C> | |
112 | // | |
113 | // Given a container C, determine if it is a map or multimap | |
114 | // by checking if it has a member type named "mapped_type". | |
115 | // | |
116 | /////////////////////////////////////////////////////////////////////////////// | |
117 | namespace stl_impl | |
118 | { | |
119 | struct one { char a[1]; }; | |
120 | struct two { char a[2]; }; | |
121 | ||
122 | template <typename C> | |
123 | one has_mapped_type(typename C::mapped_type(*)()); | |
124 | ||
125 | template <typename C> | |
126 | two has_mapped_type(...); | |
127 | } | |
128 | ||
129 | template <typename C> | |
130 | struct has_mapped_type | |
131 | : boost::mpl::bool_< | |
132 | sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one) | |
133 | > | |
134 | {}; | |
135 | ||
136 | /////////////////////////////////////////////////////////////////////////////// | |
137 | // | |
138 | // map_insert_returns_pair<C> | |
139 | // | |
140 | // Distinguish a map from a multimap by checking the return type | |
141 | // of its "insert" member function. A map returns a pair while | |
142 | // a multimap returns an iterator. | |
143 | // | |
144 | /////////////////////////////////////////////////////////////////////////////// | |
145 | namespace stl_impl | |
146 | { | |
147 | // Cool implementation of map_insert_returns_pair by Daniel Wallin. | |
148 | // Thanks Daniel!!! I owe you a Pizza! | |
149 | ||
150 | template<class A, class B> | |
151 | one map_insert_returns_pair_check(std::pair<A,B> const&); | |
152 | ||
153 | template <typename T> | |
154 | two map_insert_returns_pair_check(T const&); | |
155 | ||
156 | template <typename C> | |
157 | struct map_insert_returns_pair | |
158 | { | |
159 | static typename C::value_type const& get; | |
160 | BOOST_STATIC_CONSTANT(int, | |
161 | value = sizeof( | |
162 | map_insert_returns_pair_check(((C*)0)->insert(get)))); | |
163 | typedef boost::mpl::bool_<value == sizeof(one)> type; | |
164 | }; | |
165 | } | |
166 | ||
167 | template <typename C> | |
168 | struct map_insert_returns_pair | |
169 | : stl_impl::map_insert_returns_pair<C>::type {}; | |
170 | ||
171 | }}} // namespace boost::phoenix::stl | |
172 | ||
173 | #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP |