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
11#ifndef BOOST_INTRUSIVE_DETAIL_POINTER_ELEMENT_HPP
12#define BOOST_INTRUSIVE_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_INTRUSIVE_DETAIL_WORKAROUND_HPP
23#include <boost/intrusive/detail/workaround.hpp>
24#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
25
26namespace boost {
27namespace intrusive {
28namespace detail{
29
30//////////////////////
31//struct first_param
32//////////////////////
33
34template <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
129template <typename T>
130struct 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
141template<class Ptr, bool = has_internal_pointer_element<Ptr>::value>
142struct pointer_element_impl
143{
144 typedef typename Ptr::element_type type;
145};
146
147template<class Ptr>
148struct pointer_element_impl<Ptr, false>
149{
150 typedef typename boost::intrusive::detail::first_param<Ptr>::type type;
151};
152
153} //namespace detail{
154
155template <typename Ptr>
156struct pointer_element
157{
158 typedef typename ::boost::intrusive::detail::pointer_element_impl<Ptr>::type type;
159};
160
161template <typename T>
162struct pointer_element<T*>
163{ typedef T type; };
164
165} //namespace container {
166} //namespace boost {
167
168#endif // defined(BOOST_INTRUSIVE_DETAIL_POINTER_ELEMENT_HPP)
169