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