1 #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
2 #define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_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/detail/composite_pointer_type.hpp>
13 #include <boost/type_traits/remove_pointer.hpp>
14 #include <boost/type_traits/is_base_of.hpp>
15 #include <boost/type_traits/conditional.hpp>
16 #include <boost/config.hpp>
17 #include <cstddef>
18 
19 namespace boost
20 {
21 
22 namespace type_traits_detail
23 {
24 
25 template<class T, class U> struct composite_member_pointer_type;
26 
27 // nullptr_t
28 
29 #if !defined( BOOST_NO_CXX11_NULLPTR )
30 
31 #if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
32 
33 template<class C, class T> struct composite_member_pointer_type<T C::*, decltype(nullptr)>
34 {
35     typedef T C::* type;
36 };
37 
38 template<class C, class T> struct composite_member_pointer_type<decltype(nullptr), T C::*>
39 {
40     typedef T C::* type;
41 };
42 
43 template<> struct composite_member_pointer_type<decltype(nullptr), decltype(nullptr)>
44 {
45     typedef decltype(nullptr) type;
46 };
47 
48 #else
49 
50 template<class C, class T> struct composite_member_pointer_type<T C::*, std::nullptr_t>
51 {
52     typedef T C::* type;
53 };
54 
55 template<class C, class T> struct composite_member_pointer_type<std::nullptr_t, T C::*>
56 {
57     typedef T C::* type;
58 };
59 
60 template<> struct composite_member_pointer_type<std::nullptr_t, std::nullptr_t>
61 {
62     typedef std::nullptr_t type;
63 };
64 
65 #endif
66 
67 #endif // !defined( BOOST_NO_CXX11_NULLPTR )
68 
69 template<class C1, class C2> struct common_member_class;
70 
71 template<class C> struct common_member_class<C, C>
72 {
73     typedef C type;
74 };
75 
76 template<class C1, class C2> struct common_member_class
77 {
78     typedef typename boost::conditional<
79 
80         boost::is_base_of<C1, C2>::value,
81         C2,
82         typename boost::conditional<boost::is_base_of<C2, C1>::value, C1, void>::type
83 
84     >::type type;
85 };
86 
87 //This indirection avoids compilation errors on some older
88 //compilers like MSVC 7.1
89 template<class CT, class CB>
90 struct common_member_class_pointer_to_member
91 {
92     typedef CT CB::* type;
93 };
94 
95 template<class C1, class T1, class C2, class T2> struct composite_member_pointer_type<T1 C1::*, T2 C2::*>
96 {
97 private:
98 
99     typedef typename composite_pointer_type<T1*, T2*>::type CPT;
100     typedef typename boost::remove_pointer<CPT>::type CT;
101 
102     typedef typename common_member_class<C1, C2>::type CB;
103 
104 public:
105 
106     typedef typename common_member_class_pointer_to_member<CT, CB>::type type;
107 };
108 
109 } // namespace type_traits_detail
110 
111 } // namespace boost
112 
113 #endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
114