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