pointer_rebind.hpp 6.2 KB

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