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 | |