]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2006-2014 | |
4 | // (C) Copyright Microsoft Corporation 2014 | |
5 | // | |
6 | // Distributed under the Boost Software License, Version 1.0. | |
7 | // (See accompanying file LICENSE_1_0.txt or copy at | |
8 | // http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | // See http://www.boost.org/libs/intrusive for documentation. | |
11 | // | |
12 | ///////////////////////////////////////////////////////////////////////////// | |
13 | ||
14 | #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP | |
15 | #define BOOST_INTRUSIVE_DETAIL_MPL_HPP | |
16 | ||
17 | #ifndef BOOST_CONFIG_HPP | |
18 | # include <boost/config.hpp> | |
19 | #endif | |
20 | ||
21 | #if defined(BOOST_HAS_PRAGMA_ONCE) | |
22 | # pragma once | |
23 | #endif | |
24 | ||
25 | #include <boost/intrusive/detail/config_begin.hpp> | |
26 | #include <boost/move/detail/type_traits.hpp> | |
27 | #include <cstddef> | |
28 | ||
29 | namespace boost { | |
30 | namespace intrusive { | |
31 | namespace detail { | |
32 | ||
33 | using boost::move_detail::is_same; | |
34 | using boost::move_detail::add_const; | |
35 | using boost::move_detail::remove_const; | |
36 | using boost::move_detail::remove_cv; | |
37 | using boost::move_detail::remove_reference; | |
38 | using boost::move_detail::add_reference; | |
39 | using boost::move_detail::remove_pointer; | |
40 | using boost::move_detail::add_pointer; | |
41 | using boost::move_detail::true_type; | |
42 | using boost::move_detail::false_type; | |
43 | using boost::move_detail::enable_if_c; | |
44 | using boost::move_detail::enable_if; | |
45 | using boost::move_detail::disable_if_c; | |
46 | using boost::move_detail::disable_if; | |
47 | using boost::move_detail::is_convertible; | |
48 | using boost::move_detail::if_c; | |
49 | using boost::move_detail::if_; | |
50 | using boost::move_detail::is_const; | |
51 | using boost::move_detail::identity; | |
52 | using boost::move_detail::alignment_of; | |
53 | using boost::move_detail::is_empty; | |
54 | using boost::move_detail::addressof; | |
55 | using boost::move_detail::integral_constant; | |
56 | using boost::move_detail::enable_if_convertible; | |
57 | using boost::move_detail::disable_if_convertible; | |
58 | using boost::move_detail::bool_; | |
59 | using boost::move_detail::true_; | |
60 | using boost::move_detail::false_; | |
61 | using boost::move_detail::yes_type; | |
62 | using boost::move_detail::no_type; | |
63 | using boost::move_detail::apply; | |
64 | using boost::move_detail::eval_if_c; | |
65 | using boost::move_detail::eval_if; | |
66 | using boost::move_detail::unvoid_ref; | |
67 | using boost::move_detail::add_const_if_c; | |
68 | ||
69 | template<std::size_t S> | |
70 | struct ls_zeros | |
71 | { | |
72 | static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); | |
73 | }; | |
74 | ||
75 | template<> | |
76 | struct ls_zeros<0> | |
77 | { | |
78 | static const std::size_t value = 0; | |
79 | }; | |
80 | ||
81 | template<> | |
82 | struct ls_zeros<1> | |
83 | { | |
84 | static const std::size_t value = 0; | |
85 | }; | |
86 | ||
87 | // Infrastructure for providing a default type for T::TNAME if absent. | |
88 | #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ | |
89 | template <typename T, typename DefaultType> \ | |
90 | struct boost_intrusive_default_type_ ## TNAME \ | |
91 | { \ | |
92 | template <typename X> \ | |
93 | static char test(int, typename X::TNAME*); \ | |
94 | \ | |
95 | template <typename X> \ | |
96 | static int test(...); \ | |
97 | \ | |
98 | struct DefaultWrap { typedef DefaultType TNAME; }; \ | |
99 | \ | |
100 | static const bool value = (1 == sizeof(test<T>(0, 0))); \ | |
101 | \ | |
102 | typedef typename \ | |
103 | ::boost::intrusive::detail::if_c \ | |
104 | <value, T, DefaultWrap>::type::TNAME type; \ | |
105 | }; \ | |
106 | // | |
107 | ||
108 | #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ | |
109 | typename INSTANTIATION_NS_PREFIX \ | |
110 | boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ | |
111 | // | |
112 | ||
113 | #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ | |
114 | template <typename T, typename DefaultType> \ | |
115 | struct boost_intrusive_eval_default_type_ ## TNAME \ | |
116 | { \ | |
117 | template <typename X> \ | |
118 | static char test(int, typename X::TNAME*); \ | |
119 | \ | |
120 | template <typename X> \ | |
121 | static int test(...); \ | |
122 | \ | |
123 | struct DefaultWrap \ | |
124 | { typedef typename DefaultType::type TNAME; }; \ | |
125 | \ | |
126 | static const bool value = (1 == sizeof(test<T>(0, 0))); \ | |
127 | \ | |
128 | typedef typename \ | |
129 | ::boost::intrusive::detail::eval_if_c \ | |
130 | < value \ | |
131 | , ::boost::intrusive::detail::identity<T> \ | |
132 | , ::boost::intrusive::detail::identity<DefaultWrap> \ | |
133 | >::type::TNAME type; \ | |
134 | }; \ | |
135 | // | |
136 | ||
137 | #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ | |
138 | typename INSTANTIATION_NS_PREFIX \ | |
139 | boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ | |
140 | // | |
141 | ||
142 | #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ | |
143 | template <class T>\ | |
144 | struct TRAITS_PREFIX##_bool\ | |
145 | {\ | |
146 | template<bool Add>\ | |
147 | struct two_or_three {yes_type _[2 + Add];};\ | |
148 | template <class U> static yes_type test(...);\ | |
149 | template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\ | |
150 | static const std::size_t value = sizeof(test<T>(0));\ | |
151 | };\ | |
152 | \ | |
153 | template <class T>\ | |
154 | struct TRAITS_PREFIX##_bool_is_true\ | |
155 | {\ | |
156 | static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\ | |
157 | };\ | |
158 | // | |
159 | ||
160 | #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ | |
161 | template <typename U, typename Signature> \ | |
162 | class TRAITS_NAME \ | |
163 | { \ | |
164 | private: \ | |
165 | template<Signature> struct helper;\ | |
166 | template<typename T> \ | |
167 | static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \ | |
168 | template<typename T> static ::boost::intrusive::detail::no_type test(...); \ | |
169 | public: \ | |
170 | static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \ | |
171 | }; \ | |
172 | // | |
173 | ||
174 | #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ | |
175 | template <typename Type> \ | |
176 | struct TRAITS_NAME \ | |
177 | { \ | |
178 | struct BaseMixin \ | |
179 | { \ | |
180 | void FUNC_NAME(); \ | |
181 | }; \ | |
182 | struct Base : public Type, public BaseMixin { Base(); }; \ | |
183 | template <typename T, T t> class Helper{}; \ | |
184 | template <typename U> \ | |
185 | static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \ | |
186 | static ::boost::intrusive::detail::yes_type test(...); \ | |
187 | static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \ | |
188 | };\ | |
189 | // | |
190 | ||
191 | #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ | |
192 | BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ | |
193 | \ | |
194 | template <typename Type, class> \ | |
195 | struct TRAITS_NAME \ | |
196 | : public TRAITS_NAME##_ignore_signature<Type> \ | |
197 | {};\ | |
198 | // | |
199 | ||
200 | } //namespace detail | |
201 | } //namespace intrusive | |
202 | } //namespace boost | |
203 | ||
204 | #include <boost/intrusive/detail/config_end.hpp> | |
205 | ||
206 | #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP |