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