Chris@102
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
|
Chris@102
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@102
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //
|
Chris@102
|
7 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@102
|
8 //
|
Chris@102
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
10
|
Chris@102
|
11 #ifndef BOOST_INTRUSIVE_POINTER_REBIND_HPP
|
Chris@102
|
12 #define BOOST_INTRUSIVE_POINTER_REBIND_HPP
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
|
Chris@102
|
15 #include <boost/intrusive/detail/workaround.hpp>
|
Chris@102
|
16 #endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
|
Chris@102
|
17
|
Chris@102
|
18 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
19 # include <boost/config.hpp>
|
Chris@102
|
20 #endif
|
Chris@102
|
21
|
Chris@102
|
22 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
23 # pragma once
|
Chris@102
|
24 #endif
|
Chris@102
|
25
|
Chris@102
|
26 namespace boost {
|
Chris@102
|
27 namespace intrusive {
|
Chris@102
|
28
|
Chris@102
|
29 ///////////////////////////
|
Chris@102
|
30 //struct pointer_rebind_mode
|
Chris@102
|
31 ///////////////////////////
|
Chris@102
|
32 template <typename Ptr, typename U>
|
Chris@102
|
33 struct pointer_has_rebind
|
Chris@102
|
34 {
|
Chris@102
|
35 template <typename V> struct any
|
Chris@102
|
36 { any(const V&) { } };
|
Chris@102
|
37
|
Chris@102
|
38 template <typename X>
|
Chris@102
|
39 static char test(int, typename X::template rebind<U>*);
|
Chris@102
|
40
|
Chris@102
|
41 template <typename X>
|
Chris@102
|
42 static int test(any<int>, void*);
|
Chris@102
|
43
|
Chris@102
|
44 static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
|
Chris@102
|
45 };
|
Chris@102
|
46
|
Chris@102
|
47 template <typename Ptr, typename U>
|
Chris@102
|
48 struct pointer_has_rebind_other
|
Chris@102
|
49 {
|
Chris@102
|
50 template <typename V> struct any
|
Chris@102
|
51 { any(const V&) { } };
|
Chris@102
|
52
|
Chris@102
|
53 template <typename X>
|
Chris@102
|
54 static char test(int, typename X::template rebind<U>::other*);
|
Chris@102
|
55
|
Chris@102
|
56 template <typename X>
|
Chris@102
|
57 static int test(any<int>, void*);
|
Chris@102
|
58
|
Chris@102
|
59 static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
|
Chris@102
|
60 };
|
Chris@102
|
61
|
Chris@102
|
62 template <typename Ptr, typename U>
|
Chris@102
|
63 struct pointer_rebind_mode
|
Chris@102
|
64 {
|
Chris@102
|
65 static const unsigned int rebind = (unsigned int)pointer_has_rebind<Ptr, U>::value;
|
Chris@102
|
66 static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other<Ptr, U>::value;
|
Chris@102
|
67 static const unsigned int mode = rebind + rebind*rebind_other;
|
Chris@102
|
68 };
|
Chris@102
|
69
|
Chris@102
|
70 ////////////////////////
|
Chris@102
|
71 //struct pointer_rebinder
|
Chris@102
|
72 ////////////////////////
|
Chris@102
|
73 template <typename Ptr, typename U, unsigned int RebindMode>
|
Chris@102
|
74 struct pointer_rebinder;
|
Chris@102
|
75
|
Chris@102
|
76 // Implementation of pointer_rebinder<U>::type if Ptr has
|
Chris@102
|
77 // its own rebind<U>::other type (C++03)
|
Chris@102
|
78 template <typename Ptr, typename U>
|
Chris@102
|
79 struct pointer_rebinder< Ptr, U, 2u >
|
Chris@102
|
80 {
|
Chris@102
|
81 typedef typename Ptr::template rebind<U>::other type;
|
Chris@102
|
82 };
|
Chris@102
|
83
|
Chris@102
|
84 // Implementation of pointer_rebinder<U>::type if Ptr has
|
Chris@102
|
85 // its own rebind template.
|
Chris@102
|
86 template <typename Ptr, typename U>
|
Chris@102
|
87 struct pointer_rebinder< Ptr, U, 1u >
|
Chris@102
|
88 {
|
Chris@102
|
89 typedef typename Ptr::template rebind<U> type;
|
Chris@102
|
90 };
|
Chris@102
|
91
|
Chris@102
|
92 // Specialization of pointer_rebinder if Ptr does not
|
Chris@102
|
93 // have its own rebind template but has a the form Ptr<A, An...>,
|
Chris@102
|
94 // where An... comprises zero or more type parameters.
|
Chris@102
|
95 // Many types fit this form, hence many pointers will get a
|
Chris@102
|
96 // reasonable default for rebind.
|
Chris@102
|
97 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@102
|
98
|
Chris@102
|
99 template <template <class, class...> class Ptr, typename A, class... An, class U>
|
Chris@102
|
100 struct pointer_rebinder<Ptr<A, An...>, U, 0u >
|
Chris@102
|
101 {
|
Chris@102
|
102 typedef Ptr<U, An...> type;
|
Chris@102
|
103 };
|
Chris@102
|
104
|
Chris@102
|
105 //Needed for non-conforming compilers like GCC 4.3
|
Chris@102
|
106 template <template <class> class Ptr, typename A, class U>
|
Chris@102
|
107 struct pointer_rebinder<Ptr<A>, U, 0u >
|
Chris@102
|
108 {
|
Chris@102
|
109 typedef Ptr<U> type;
|
Chris@102
|
110 };
|
Chris@102
|
111
|
Chris@102
|
112 #else //C++03 compilers
|
Chris@102
|
113
|
Chris@102
|
114 template <template <class> class Ptr //0arg
|
Chris@102
|
115 , typename A
|
Chris@102
|
116 , class U>
|
Chris@102
|
117 struct pointer_rebinder<Ptr<A>, U, 0u>
|
Chris@102
|
118 { typedef Ptr<U> type; };
|
Chris@102
|
119
|
Chris@102
|
120 template <template <class, class> class Ptr //1arg
|
Chris@102
|
121 , typename A, class P0
|
Chris@102
|
122 , class U>
|
Chris@102
|
123 struct pointer_rebinder<Ptr<A, P0>, U, 0u>
|
Chris@102
|
124 { typedef Ptr<U, P0> type; };
|
Chris@102
|
125
|
Chris@102
|
126 template <template <class, class, class> class Ptr //2arg
|
Chris@102
|
127 , typename A, class P0, class P1
|
Chris@102
|
128 , class U>
|
Chris@102
|
129 struct pointer_rebinder<Ptr<A, P0, P1>, U, 0u>
|
Chris@102
|
130 { typedef Ptr<U, P0, P1> type; };
|
Chris@102
|
131
|
Chris@102
|
132 template <template <class, class, class, class> class Ptr //3arg
|
Chris@102
|
133 , typename A, class P0, class P1, class P2
|
Chris@102
|
134 , class U>
|
Chris@102
|
135 struct pointer_rebinder<Ptr<A, P0, P1, P2>, U, 0u>
|
Chris@102
|
136 { typedef Ptr<U, P0, P1, P2> type; };
|
Chris@102
|
137
|
Chris@102
|
138 template <template <class, class, class, class, class> class Ptr //4arg
|
Chris@102
|
139 , typename A, class P0, class P1, class P2, class P3
|
Chris@102
|
140 , class U>
|
Chris@102
|
141 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3>, U, 0u>
|
Chris@102
|
142 { typedef Ptr<U, P0, P1, P2, P3> type; };
|
Chris@102
|
143
|
Chris@102
|
144 template <template <class, class, class, class, class, class> class Ptr //5arg
|
Chris@102
|
145 , typename A, class P0, class P1, class P2, class P3, class P4
|
Chris@102
|
146 , class U>
|
Chris@102
|
147 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4>, U, 0u>
|
Chris@102
|
148 { typedef Ptr<U, P0, P1, P2, P3, P4> type; };
|
Chris@102
|
149
|
Chris@102
|
150 template <template <class, class, class, class, class, class, class> class Ptr //6arg
|
Chris@102
|
151 , typename A, class P0, class P1, class P2, class P3, class P4, class P5
|
Chris@102
|
152 , class U>
|
Chris@102
|
153 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5>, U, 0u>
|
Chris@102
|
154 { typedef Ptr<U, P0, P1, P2, P3, P4, P5> type; };
|
Chris@102
|
155
|
Chris@102
|
156 template <template <class, class, class, class, class, class, class, class> class Ptr //7arg
|
Chris@102
|
157 , typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
|
Chris@102
|
158 , class U>
|
Chris@102
|
159 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6>, U, 0u>
|
Chris@102
|
160 { typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6> type; };
|
Chris@102
|
161
|
Chris@102
|
162 template <template <class, class, class, class, class, class, class, class, class> class Ptr //8arg
|
Chris@102
|
163 , typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
|
Chris@102
|
164 , class U>
|
Chris@102
|
165 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7>, U, 0u>
|
Chris@102
|
166 { typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7> type; };
|
Chris@102
|
167
|
Chris@102
|
168 template <template <class, class, class, class, class, class, class, class, class, class> class Ptr //9arg
|
Chris@102
|
169 , typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
|
Chris@102
|
170 , class U>
|
Chris@102
|
171 struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U, 0u>
|
Chris@102
|
172 { typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; };
|
Chris@102
|
173
|
Chris@102
|
174 #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@102
|
175
|
Chris@102
|
176 template <typename Ptr, typename U>
|
Chris@102
|
177 struct pointer_rebind
|
Chris@102
|
178 : public pointer_rebinder<Ptr, U, pointer_rebind_mode<Ptr, U>::mode>
|
Chris@102
|
179 {};
|
Chris@102
|
180
|
Chris@102
|
181 template <typename T, typename U>
|
Chris@102
|
182 struct pointer_rebind<T*, U>
|
Chris@102
|
183 { typedef U* type; };
|
Chris@102
|
184
|
Chris@102
|
185 } //namespace container {
|
Chris@102
|
186 } //namespace boost {
|
Chris@102
|
187
|
Chris@102
|
188 #endif // defined(BOOST_INTRUSIVE_POINTER_REBIND_HPP)
|