pointer_rebind.hpp 6.4 KB

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