pointer_element.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2017. 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/move for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP
  11. #define BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
  19. #include <boost/move/detail/workaround.hpp>
  20. #endif //BOOST_MOVE_DETAIL_WORKAROUND_HPP
  21. namespace boost {
  22. namespace movelib {
  23. namespace detail{
  24. //////////////////////
  25. //struct first_param
  26. //////////////////////
  27. template <typename T> struct first_param
  28. { typedef void type; };
  29. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  30. template <template <typename, typename...> class TemplateClass, typename T, typename... Args>
  31. struct first_param< TemplateClass<T, Args...> >
  32. {
  33. typedef T type;
  34. };
  35. #else //C++03 compilers
  36. template < template //0arg
  37. <class
  38. > class TemplateClass, class T
  39. >
  40. struct first_param
  41. < TemplateClass<T> >
  42. { typedef T type; };
  43. template < template //1arg
  44. <class,class
  45. > class TemplateClass, class T
  46. , class P0>
  47. struct first_param
  48. < TemplateClass<T, P0> >
  49. { typedef T type; };
  50. template < template //2arg
  51. <class,class,class
  52. > class TemplateClass, class T
  53. , class P0, class P1>
  54. struct first_param
  55. < TemplateClass<T, P0, P1> >
  56. { typedef T type; };
  57. template < template //3arg
  58. <class,class,class,class
  59. > class TemplateClass, class T
  60. , class P0, class P1, class P2>
  61. struct first_param
  62. < TemplateClass<T, P0, P1, P2> >
  63. { typedef T type; };
  64. template < template //4arg
  65. <class,class,class,class,class
  66. > class TemplateClass, class T
  67. , class P0, class P1, class P2, class P3>
  68. struct first_param
  69. < TemplateClass<T, P0, P1, P2, P3> >
  70. { typedef T type; };
  71. template < template //5arg
  72. <class,class,class,class,class,class
  73. > class TemplateClass, class T
  74. , class P0, class P1, class P2, class P3, class P4>
  75. struct first_param
  76. < TemplateClass<T, P0, P1, P2, P3, P4> >
  77. { typedef T type; };
  78. template < template //6arg
  79. <class,class,class,class,class,class,class
  80. > class TemplateClass, class T
  81. , class P0, class P1, class P2, class P3, class P4, class P5>
  82. struct first_param
  83. < TemplateClass<T, P0, P1, P2, P3, P4, P5> >
  84. { typedef T type; };
  85. template < template //7arg
  86. <class,class,class,class,class,class,class,class
  87. > class TemplateClass, class T
  88. , class P0, class P1, class P2, class P3, class P4, class P5, class P6>
  89. struct first_param
  90. < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6> >
  91. { typedef T type; };
  92. template < template //8arg
  93. <class,class,class,class,class,class,class,class,class
  94. > class TemplateClass, class T
  95. , class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  96. struct first_param
  97. < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7> >
  98. { typedef T type; };
  99. template < template //9arg
  100. <class,class,class,class,class,class,class,class,class,class
  101. > class TemplateClass, class T
  102. , class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  103. struct first_param
  104. < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7, P8> >
  105. { typedef T type; };
  106. #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  107. template <typename T>
  108. struct has_internal_pointer_element
  109. {
  110. template <typename X>
  111. static char test(int, typename X::element_type*);
  112. template <typename X>
  113. static int test(...);
  114. static const bool value = (1 == sizeof(test<T>(0, 0)));
  115. };
  116. template<class Ptr, bool = has_internal_pointer_element<Ptr>::value>
  117. struct pointer_element_impl
  118. {
  119. typedef typename Ptr::element_type type;
  120. };
  121. template<class Ptr>
  122. struct pointer_element_impl<Ptr, false>
  123. {
  124. typedef typename boost::movelib::detail::first_param<Ptr>::type type;
  125. };
  126. } //namespace detail{
  127. template <typename Ptr>
  128. struct pointer_element
  129. {
  130. typedef typename ::boost::movelib::detail::pointer_element_impl<Ptr>::type type;
  131. };
  132. template <typename T>
  133. struct pointer_element<T*>
  134. { typedef T type; };
  135. } //namespace movelib {
  136. } //namespace boost {
  137. #endif // defined(BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP)