1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2005-2013. |
4 | // |
5 | // Distributed under the Boost Software License, Version 1.0. |
6 | // (See accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | // |
9 | // See http://www.boost.org/libs/container for documentation. |
10 | // |
11 | ////////////////////////////////////////////////////////////////////////////// |
12 | |
13 | #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP |
14 | #define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP |
15 | |
16 | #ifndef BOOST_CONFIG_HPP |
17 | # include <boost/config.hpp> |
18 | #endif |
19 | |
20 | #if defined(BOOST_HAS_PRAGMA_ONCE) |
21 | # pragma once |
22 | #endif |
23 | |
24 | #include <boost/container/detail/config_begin.hpp> |
25 | #include <boost/container/detail/workaround.hpp> |
26 | |
27 | #include <cstddef> |
28 | |
29 | namespace boost { |
30 | namespace container { |
31 | namespace container_detail { |
32 | |
33 | template <class T, T val> |
34 | struct integral_constant |
35 | { |
36 | static const T value = val; |
37 | typedef integral_constant<T,val> type; |
38 | }; |
39 | |
40 | template< bool C_ > |
41 | struct bool_ : integral_constant<bool, C_> |
42 | { |
43 | static const bool value = C_; |
44 | operator bool() const { return bool_::value; } |
45 | }; |
46 | |
47 | template< unsigned V_ > |
48 | struct unsigned_ : integral_constant<unsigned, V_> |
49 | { |
50 | static const unsigned value = V_; |
51 | operator unsigned() const { return unsigned_::value; } |
52 | }; |
53 | |
54 | typedef bool_<true> true_; |
55 | typedef bool_<false> false_; |
56 | |
57 | typedef true_ true_type; |
58 | typedef false_ false_type; |
59 | |
60 | typedef char yes_type; |
61 | struct no_type |
62 | { |
63 | char padding[8]; |
64 | }; |
65 | |
66 | template <bool B, class T = void> |
67 | struct enable_if_c { |
68 | typedef T type; |
69 | }; |
70 | |
71 | template <class T> |
72 | struct enable_if_c<false, T> {}; |
73 | |
74 | template <class Cond, class T = void> |
75 | struct enable_if : public enable_if_c<Cond::value, T> {}; |
76 | |
77 | template <class Cond, class T = void> |
78 | struct disable_if : public enable_if_c<!Cond::value, T> {}; |
79 | |
80 | template <bool B, class T = void> |
81 | struct disable_if_c : public enable_if_c<!B, T> {}; |
82 | |
83 | #if defined(_MSC_VER) && (_MSC_VER >= 1400) |
84 | |
85 | template <class T, class U> |
86 | struct is_convertible |
87 | { |
88 | static const bool value = __is_convertible_to(T, U); |
89 | }; |
90 | |
91 | #else |
92 | |
93 | template <class T, class U> |
94 | class is_convertible |
95 | { |
96 | typedef char true_t; |
97 | class false_t { char dummy[2]; }; |
98 | //use any_conversion as first parameter since in MSVC |
99 | //overaligned types can't go through ellipsis |
100 | static false_t dispatch(...); |
101 | static true_t dispatch(U); |
102 | static T &trigger(); |
103 | public: |
104 | static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); |
105 | }; |
106 | |
107 | #endif |
108 | |
109 | template< |
110 | bool C |
111 | , typename T1 |
112 | , typename T2 |
113 | > |
114 | struct if_c |
115 | { |
116 | typedef T1 type; |
117 | }; |
118 | |
119 | template< |
120 | typename T1 |
121 | , typename T2 |
122 | > |
123 | struct if_c<false,T1,T2> |
124 | { |
125 | typedef T2 type; |
126 | }; |
127 | |
128 | template< |
129 | typename T1 |
130 | , typename T2 |
131 | , typename T3 |
132 | > |
133 | struct if_ |
134 | { |
135 | typedef typename if_c<0 != T1::value, T2, T3>::type type; |
136 | }; |
137 | |
138 | |
139 | template <class Pair> |
140 | struct select1st |
141 | { |
142 | typedef Pair argument_type; |
143 | typedef typename Pair::first_type result_type; |
144 | |
145 | template<class OtherPair> |
146 | const typename Pair::first_type& operator()(const OtherPair& x) const |
147 | { return x.first; } |
148 | |
149 | const typename Pair::first_type& operator()(const typename Pair::first_type& x) const |
150 | { return x; } |
151 | }; |
152 | |
153 | // identity is an extension: it is not part of the standard. |
154 | template <class T> |
155 | struct identity |
156 | { |
157 | typedef T argument_type; |
158 | typedef T result_type; |
159 | |
160 | typedef T type; |
161 | const T& operator()(const T& x) const |
162 | { return x; } |
163 | }; |
164 | |
165 | template<std::size_t S> |
166 | struct ls_zeros |
167 | { |
168 | static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value); |
169 | }; |
170 | |
171 | template<> |
172 | struct ls_zeros<0> |
173 | { |
174 | static const std::size_t value = 0; |
175 | }; |
176 | |
177 | template<> |
178 | struct ls_zeros<1> |
179 | { |
180 | static const std::size_t value = 0; |
181 | }; |
182 | |
183 | template <std::size_t OrigSize, std::size_t RoundTo> |
184 | struct ct_rounded_size |
185 | { |
186 | static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo; |
187 | }; |
188 | |
189 | template <typename T> struct unvoid { typedef T type; }; |
190 | template <> struct unvoid<void> { struct type { }; }; |
191 | template <> struct unvoid<const void> { struct type { }; }; |
192 | |
193 | } //namespace container_detail { |
194 | } //namespace container { |
195 | } //namespace boost { |
196 | |
197 | #include <boost/container/detail/config_end.hpp> |
198 | |
199 | #endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP |
200 | |
201 | |