]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED |
2 | #define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED | |
3 | ||
4 | // | |
5 | // Copyright 2015 Peter Dimov | |
6 | // | |
7 | // Distributed under the Boost Software License, Version 1.0. | |
8 | // See accompanying file LICENSE_1_0.txt or copy at | |
9 | // http://www.boost.org/LICENSE_1_0.txt | |
10 | // | |
11 | ||
12 | #include <boost/type_traits/copy_cv.hpp> | |
13 | #include <boost/type_traits/remove_cv.hpp> | |
14 | #include <boost/type_traits/is_same.hpp> | |
15 | #include <boost/type_traits/is_void.hpp> | |
16 | #include <boost/type_traits/is_base_of.hpp> | |
17 | #include <boost/config.hpp> | |
18 | #include <cstddef> | |
19 | ||
20 | namespace boost | |
21 | { | |
22 | ||
23 | namespace type_traits_detail | |
24 | { | |
25 | ||
26 | template<class T, class U> struct composite_pointer_type; | |
27 | ||
28 | // same type | |
29 | ||
30 | template<class T> struct composite_pointer_type<T*, T*> | |
31 | { | |
32 | typedef T* type; | |
33 | }; | |
34 | ||
35 | // nullptr_t | |
36 | ||
37 | #if !defined( BOOST_NO_CXX11_NULLPTR ) | |
38 | ||
39 | #if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) | |
40 | ||
41 | template<class T> struct composite_pointer_type<T*, decltype(nullptr)> | |
42 | { | |
43 | typedef T* type; | |
44 | }; | |
45 | ||
46 | template<class T> struct composite_pointer_type<decltype(nullptr), T*> | |
47 | { | |
48 | typedef T* type; | |
49 | }; | |
50 | ||
51 | template<> struct composite_pointer_type<decltype(nullptr), decltype(nullptr)> | |
52 | { | |
53 | typedef decltype(nullptr) type; | |
54 | }; | |
55 | ||
56 | #else | |
57 | ||
58 | template<class T> struct composite_pointer_type<T*, std::nullptr_t> | |
59 | { | |
60 | typedef T* type; | |
61 | }; | |
62 | ||
63 | template<class T> struct composite_pointer_type<std::nullptr_t, T*> | |
64 | { | |
65 | typedef T* type; | |
66 | }; | |
67 | ||
68 | template<> struct composite_pointer_type<std::nullptr_t, std::nullptr_t> | |
69 | { | |
70 | typedef std::nullptr_t type; | |
71 | }; | |
72 | ||
73 | #endif | |
74 | ||
75 | #endif // !defined( BOOST_NO_CXX11_NULLPTR ) | |
76 | ||
77 | namespace detail | |
78 | { | |
79 | ||
80 | template<class T, class U> struct has_common_pointee | |
81 | { | |
82 | private: | |
83 | ||
84 | typedef typename boost::remove_cv<T>::type T2; | |
85 | typedef typename boost::remove_cv<U>::type U2; | |
86 | ||
87 | public: | |
88 | ||
89 | BOOST_STATIC_CONSTANT( bool, value = | |
90 | (boost::is_same<T2, U2>::value) | |
91 | || boost::is_void<T2>::value | |
92 | || boost::is_void<U2>::value | |
93 | || (boost::is_base_of<T2, U2>::value) | |
94 | || (boost::is_base_of<U2, T2>::value) ); | |
95 | }; | |
96 | ||
97 | template<class T, class U> struct common_pointee | |
98 | { | |
99 | private: | |
100 | ||
101 | typedef typename boost::remove_cv<T>::type T2; | |
102 | typedef typename boost::remove_cv<U>::type U2; | |
103 | ||
104 | public: | |
105 | ||
106 | typedef typename boost::conditional< | |
107 | ||
108 | boost::is_same<T2, U2>::value || boost::is_void<T2>::value || boost::is_base_of<T2, U2>::value, | |
109 | typename boost::copy_cv<T, U>::type, | |
110 | typename boost::copy_cv<U, T>::type | |
111 | ||
112 | >::type type; | |
113 | }; | |
114 | ||
115 | template<class T, class U> struct composite_pointer_impl | |
116 | { | |
117 | private: | |
118 | ||
119 | typedef typename boost::remove_cv<T>::type T2; | |
120 | typedef typename boost::remove_cv<U>::type U2; | |
121 | ||
122 | public: | |
123 | ||
124 | typedef typename boost::copy_cv<typename boost::copy_cv<typename composite_pointer_type<T2, U2>::type const, T>::type, U>::type type; | |
125 | }; | |
126 | ||
127 | //Old compilers like MSVC-7.1 have problems using boost::conditional in | |
128 | //composite_pointer_type. Partially specializing on has_common_pointee<T, U>::value | |
129 | //seems to make their life easier | |
130 | template<class T, class U, bool = has_common_pointee<T, U>::value > | |
131 | struct composite_pointer_type_dispatch | |
132 | : common_pointee<T, U> | |
133 | {}; | |
134 | ||
135 | template<class T, class U> | |
136 | struct composite_pointer_type_dispatch<T, U, false> | |
137 | : composite_pointer_impl<T, U> | |
138 | {}; | |
139 | ||
140 | ||
141 | } // detail | |
142 | ||
143 | ||
144 | template<class T, class U> struct composite_pointer_type<T*, U*> | |
145 | { | |
146 | typedef typename detail::composite_pointer_type_dispatch<T, U>::type* type; | |
147 | }; | |
148 | ||
149 | } // namespace type_traits_detail | |
150 | ||
151 | } // namespace boost | |
152 | ||
153 | #endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED |