Horizon
common_type.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-present
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_UTILITY_COMMON_TYPE_HPP
15 #define RANGES_V3_UTILITY_COMMON_TYPE_HPP
16 
17 #include <tuple>
18 #include <utility>
19 
20 #include <meta/meta.hpp>
21 
22 #include <concepts/type_traits.hpp>
23 
24 #include <range/v3/range_fwd.hpp>
25 
26 #include <range/v3/detail/prologue.hpp>
27 
28 // Sadly, this is necessary because of:
29 // - std::common_type is !SFINAE-friendly, and
30 // - The specification of std::common_type makes it impossibly
31 // difficult to specialize on user-defined types without spamming
32 // out a bajillion copies to handle all combinations of cv and ref
33 // qualifiers.
34 
35 namespace ranges
36 {
37  template<typename... Ts>
38  using common_type = concepts::common_type<Ts...>;
39 
40  template<typename... Ts>
41  using common_type_t = concepts::common_type_t<Ts...>;
42 
43  template<typename... Ts>
44  using common_reference = concepts::common_reference<Ts...>;
45 
46  template<typename... Ts>
47  using common_reference_t = concepts::common_reference_t<Ts...>;
48 
50  template<typename F, typename S>
51  struct common_pair;
52 
53  template<typename... Ts>
54  struct common_tuple;
56 } // namespace ranges
57 
59 // Specializations for pair and tuple
60 namespace concepts
61 {
62  // common_type for std::pairs
63  template<typename F1, typename S1, typename F2, typename S2>
64  struct common_type<std::pair<F1, S1>, ::ranges::common_pair<F2, S2>>;
65 
66  template<typename F1, typename S1, typename F2, typename S2>
67  struct common_type<::ranges::common_pair<F1, S1>, std::pair<F2, S2>>;
68 
69  template<typename F1, typename S1, typename F2, typename S2>
70  struct common_type<::ranges::common_pair<F1, S1>, ::ranges::common_pair<F2, S2>>;
71 
72  // common_type for std::tuples
73  template<typename... Ts, typename... Us>
74  struct common_type<::ranges::common_tuple<Ts...>, std::tuple<Us...>>;
75 
76  template<typename... Ts, typename... Us>
77  struct common_type<std::tuple<Ts...>, ::ranges::common_tuple<Us...>>;
78 
79  template<typename... Ts, typename... Us>
80  struct common_type<::ranges::common_tuple<Ts...>, ::ranges::common_tuple<Us...>>;
81 
82  // A common reference for std::pairs
83  template<typename F1, typename S1, typename F2, typename S2,
84  template<typename> class Qual1, template<typename> class Qual2>
85  struct basic_common_reference<::ranges::common_pair<F1, S1>, std::pair<F2, S2>, Qual1, Qual2>;
86 
87  template<typename F1, typename S1, typename F2, typename S2,
88  template<typename> class Qual1, template<typename> class Qual2>
89  struct basic_common_reference<std::pair<F1, S1>, ::ranges::common_pair<F2, S2>, Qual1, Qual2>;
90 
91  template<typename F1, typename S1, typename F2, typename S2,
92  template<typename> class Qual1, template<typename> class Qual2>
93  struct basic_common_reference<::ranges::common_pair<F1, S1>, ::ranges::common_pair<F2, S2>, Qual1, Qual2>;
94 
95  // A common reference for std::tuples
96  template<typename... Ts, typename... Us, template<typename> class Qual1,
97  template<typename> class Qual2>
98  struct basic_common_reference<::ranges::common_tuple<Ts...>, std::tuple<Us...>, Qual1, Qual2>;
99 
100  template<typename... Ts, typename... Us, template<typename> class Qual1,
101  template<typename> class Qual2>
102  struct basic_common_reference<std::tuple<Ts...>, ::ranges::common_tuple<Us...>, Qual1, Qual2>;
103 
104  template<typename... Ts, typename... Us, template<typename> class Qual1,
105  template<typename> class Qual2>
106  struct basic_common_reference<::ranges::common_tuple<Ts...>, ::ranges::common_tuple<Us...>, Qual1, Qual2>;
107 } // namespace concepts
108 
109 #if RANGES_CXX_VER > RANGES_CXX_STD_17
110 RANGES_DIAGNOSTIC_PUSH
111 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
112 RANGES_BEGIN_NAMESPACE_STD
113 RANGES_BEGIN_NAMESPACE_VERSION
114 
115  template<typename...>
116  struct common_type;
117 
118  // common_type for std::pairs
119  template<typename F1, typename S1, typename F2, typename S2>
120  struct common_type<std::pair<F1, S1>, ::ranges::common_pair<F2, S2>>;
121 
122  template<typename F1, typename S1, typename F2, typename S2>
123  struct common_type<::ranges::common_pair<F1, S1>, std::pair<F2, S2>>;
124 
125  template<typename F1, typename S1, typename F2, typename S2>
126  struct common_type<::ranges::common_pair<F1, S1>, ::ranges::common_pair<F2, S2>>;
127 
128  // common_type for std::tuples
129  template<typename... Ts, typename... Us>
130  struct common_type<::ranges::common_tuple<Ts...>, std::tuple<Us...>>;
131 
132  template<typename... Ts, typename... Us>
133  struct common_type<std::tuple<Ts...>, ::ranges::common_tuple<Us...>>;
134 
135  template<typename... Ts, typename... Us>
136  struct common_type<::ranges::common_tuple<Ts...>, ::ranges::common_tuple<Us...>>;
137 
138  template<typename, typename, template<typename> class, template<typename> class>
139  struct basic_common_reference;
140 
141  // A common reference for std::pairs
142  template<typename F1, typename S1, typename F2, typename S2,
143  template<typename> class Qual1, template<typename> class Qual2>
144  struct basic_common_reference<::ranges::common_pair<F1, S1>, std::pair<F2, S2>, Qual1, Qual2>;
145 
146  template<typename F1, typename S1, typename F2, typename S2,
147  template<typename> class Qual1, template<typename> class Qual2>
148  struct basic_common_reference<std::pair<F1, S1>, ::ranges::common_pair<F2, S2>, Qual1, Qual2>;
149 
150  template<typename F1, typename S1, typename F2, typename S2,
151  template<typename> class Qual1, template<typename> class Qual2>
152  struct basic_common_reference<::ranges::common_pair<F1, S1>, ::ranges::common_pair<F2, S2>, Qual1, Qual2>;
153 
154  // A common reference for std::tuples
155  template<typename... Ts, typename... Us, template<typename> class Qual1,
156  template<typename> class Qual2>
157  struct basic_common_reference<::ranges::common_tuple<Ts...>, std::tuple<Us...>, Qual1, Qual2>;
158 
159  template<typename... Ts, typename... Us, template<typename> class Qual1,
160  template<typename> class Qual2>
161  struct basic_common_reference<std::tuple<Ts...>, ::ranges::common_tuple<Us...>, Qual1, Qual2>;
162 
163  template<typename... Ts, typename... Us, template<typename> class Qual1,
164  template<typename> class Qual2>
165  struct basic_common_reference<::ranges::common_tuple<Ts...>, ::ranges::common_tuple<Us...>, Qual1, Qual2>;
166 
167 RANGES_END_NAMESPACE_VERSION
168 RANGES_END_NAMESPACE_STD
169 RANGES_DIAGNOSTIC_POP
170 #endif // RANGES_CXX_VER > RANGES_CXX_STD_17
172 
173 #include <range/v3/detail/epilogue.hpp>
174 
175 #endif
template(typename ActionFn, typename Rng)(concept(invocable_action_closure_)(ActionFn
\concept invocable_action_closure_
list< F, S > pair
A list with exactly two elements.
Definition: meta.hpp:2246
Tiny meta-programming library.
Users can specialize this to hook the common_reference_with concept.
Definition: type_traits.hpp:356
Users should specialize this to hook the common_with concept until std gets a SFINAE-friendly std::co...
Definition: type_traits.hpp:242
Definition: common_tuple.hpp:313