1 #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
2 #define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_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/common_arithmetic_type.hpp>
13 #include <boost/type_traits/detail/composite_pointer_type.hpp>
14 #include <boost/type_traits/detail/composite_member_pointer_type.hpp>
15 #include <boost/type_traits/type_identity.hpp>
16 #include <boost/type_traits/is_class.hpp>
17 #include <boost/type_traits/is_union.hpp>
18 #include <boost/type_traits/is_convertible.hpp>
19 #include <boost/type_traits/is_pointer.hpp>
20 #include <boost/type_traits/is_member_pointer.hpp>
21 #include <boost/type_traits/conditional.hpp>
22 
23 namespace boost
24 {
25 
26 namespace type_traits_detail
27 {
28 
29 // the arguments to common_type_impl have already been passed through decay<>
30 
31 template<class T, class U> struct common_type_impl;
32 
33 // same type
34 
35 template<class T> struct common_type_impl<T, T>
36 {
37     typedef T type;
38 };
39 
40 // one of the operands is a class type, try conversions in both directions
41 
42 template<class T, class U> struct ct_class
43 {
44     BOOST_STATIC_CONSTANT( bool, ct = boost::is_class<T>::value || boost::is_union<T>::value );
45     BOOST_STATIC_CONSTANT( bool, cu = boost::is_class<U>::value || boost::is_union<U>::value );
46 
47     BOOST_STATIC_CONSTANT( bool, value = ct || cu );
48 };
49 
50 template<class T, class U> struct common_type_impl3;
51 
52 template<class T, class U> struct common_type_class: public boost::conditional<
53 
54     boost::is_convertible<T, U>::value && !boost::is_convertible<U, T>::value,
55     boost::type_identity<U>,
56 
57     typename boost::conditional<
58 
59         boost::is_convertible<U, T>::value && !boost::is_convertible<T, U>::value,
60         boost::type_identity<T>,
61 
62         common_type_impl3<T, U>
63     >::type
64 >::type
65 {
66 };
67 
68 template<class T, class U> struct common_type_impl: public boost::conditional<
69     ct_class<T, U>::value,
70     common_type_class<T, U>,
71     common_type_impl3<T, U> >::type
72 {
73 };
74 
75 // pointers
76 
77 template<class T, class U> struct common_type_impl4;
78 
79 template<class T, class U> struct common_type_impl3: public boost::conditional<
80     boost::is_pointer<T>::value || boost::is_pointer<U>::value,
81     composite_pointer_type<T, U>,
82     common_type_impl4<T, U> >::type
83 {
84 };
85 
86 // pointers to members
87 
88 template<class T, class U> struct common_type_impl5;
89 
90 template<class T, class U> struct common_type_impl4: public boost::conditional<
91     boost::is_member_pointer<T>::value || boost::is_member_pointer<U>::value,
92     composite_member_pointer_type<T, U>,
93     common_type_impl5<T, U> >::type
94 {
95 };
96 
97 // arithmetic types (including class types w/ conversions to arithmetic and enums)
98 
99 template<class T, class U> struct common_type_impl5: public common_arithmetic_type<T, U>
100 {
101 };
102 
103 } // namespace type_traits_detail
104 
105 } // namespace boost
106 
107 #endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
108