]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/spirit/home/phoenix/stl/container/detail/container.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / spirit / home / 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 PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
9 #define 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<
78                 boost::is_const<C>
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<
90                 boost::is_const<C>
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<
102                 boost::is_const<C>
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 // PHOENIX_STL_CONTAINER_TRAITS_HPP