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