1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++03, c++11, c++14, c++17
16 #include <type_traits>
19 #include "test_macros.h"
22 constexpr bool has_type
= requires
{
26 // A slightly simplified variation of std::tuple
30 template <class, class, class>
31 struct Tuple_helper
{};
32 template <class... Ts
, class... Us
>
33 struct Tuple_helper
<std::void_t
<std::common_reference_t
<Ts
, Us
>...>, UserTuple
<Ts
...>, UserTuple
<Us
...> > {
34 using type
= UserTuple
<std::common_reference_t
<Ts
, Us
>...>;
38 template <class... Ts
, class... Us
, template <class> class TQual
, template <class> class UQual
>
39 struct basic_common_reference
< ::UserTuple
<Ts
...>, ::UserTuple
<Us
...>, TQual
, UQual
>
40 : ::Tuple_helper
<void, UserTuple
<TQual
<Ts
>...>, UserTuple
<UQual
<Us
>...> > {};
49 struct common_type
<X2
, Y2
> {
53 struct common_type
<Y2
, X2
> {
59 // -- If sizeof...(T) is zero, there shall be no member type.
60 static_assert(!has_type
<std::common_reference
<> >);
63 // -- Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the
64 // pack T. The member typedef type shall denote the same type as T0.
65 static_assert(std::is_same_v
<std::common_reference_t
<void>, void>);
66 static_assert(std::is_same_v
<std::common_reference_t
<int>, int>);
67 static_assert(std::is_same_v
<std::common_reference_t
<int&>, int&>);
68 static_assert(std::is_same_v
<std::common_reference_t
<int&&>, int&&>);
69 static_assert(std::is_same_v
<std::common_reference_t
<int const>, int const>);
70 static_assert(std::is_same_v
<std::common_reference_t
<int const&>, int const&>);
71 static_assert(std::is_same_v
<std::common_reference_t
<int const&&>, int const&&>);
72 static_assert(std::is_same_v
<std::common_reference_t
<int volatile[]>, int volatile[]>);
73 static_assert(std::is_same_v
<std::common_reference_t
<int volatile (&)[]>, int volatile (&)[]>);
74 static_assert(std::is_same_v
<std::common_reference_t
<int volatile (&&)[]>, int volatile (&&)[]>);
75 static_assert(std::is_same_v
<std::common_reference_t
<void (&)()>, void (&)()>);
76 static_assert(std::is_same_v
<std::common_reference_t
<void (&&)()>, void (&&)()>);
79 // -- Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in
82 // -- If T1 and T2 are reference types and COMMON_REF(T1, T2) is well-formed,
83 // then the member typedef type denotes that type.
86 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
&>, B
&>);
87 static_assert(std::is_same_v
<std::common_reference_t
<B
const&, D
&>, B
const&>);
88 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
const&>, B
const&>);
89 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
const&, D
&>, B
const&>);
90 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
&, B
&, D
&>, B
&>);
92 static_assert(std::is_same_v
<std::common_reference_t
<B
&&, D
&&>, B
&&>);
93 static_assert(std::is_same_v
<std::common_reference_t
<B
const&&, D
&&>, B
const&&>);
94 static_assert(std::is_same_v
<std::common_reference_t
<B
&&, D
const&&>, B
const&&>);
95 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
&&>, B
const&>);
96 static_assert(std::is_same_v
<std::common_reference_t
<B
&, D
const&&>, B
const&>);
97 static_assert(std::is_same_v
<std::common_reference_t
<B
const&, D
&&>, B
const&>);
99 static_assert(std::is_same_v
<std::common_reference_t
<B
&&, D
&>, B
const&>);
100 static_assert(std::is_same_v
<std::common_reference_t
<B
&&, D
const&>, B
const&>);
101 static_assert(std::is_same_v
<std::common_reference_t
<B
const&&, D
&>, B
const&>);
103 static_assert(std::is_same_v
<std::common_reference_t
<int const&, int volatile&>, int const volatile&>);
104 static_assert(std::is_same_v
<std::common_reference_t
<int const volatile&&, int volatile&&>, int const volatile&&>);
106 static_assert(std::is_same_v
<std::common_reference_t
<int (&)[10], int (&&)[10]>, int const (&)[10]>);
107 static_assert(std::is_same_v
<std::common_reference_t
<int const (&)[10], int volatile (&)[10]>, int const volatile (&)[10]>);
110 // -- Otherwise, if basic_common_reference<remove_cvref_t<T1>,
111 // remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type is well-formed, then the
112 // member typedef type denotes that type.
113 static_assert(std::is_same_v
<std::common_reference_t
<const UserTuple
<int, short>&, UserTuple
<int&, short volatile&>>,
114 UserTuple
<const int&, const volatile short&>>);
116 static_assert(std::is_same_v
<std::common_reference_t
<volatile UserTuple
<int, short>&, const UserTuple
<int, short>&>,
117 const volatile UserTuple
<int, short>&>);
120 // -- Otherwise, if COND_RES(T1, T2) is well-formed, then the member typedef
121 // type denotes that type.
122 static_assert(std::is_same_v
<std::common_reference_t
<void, void>, void>);
123 static_assert(std::is_same_v
<std::common_reference_t
<int, short>, int>);
124 static_assert(std::is_same_v
<std::common_reference_t
<int, short&>, int>);
125 static_assert(std::is_same_v
<std::common_reference_t
<int&, short&>, int>);
126 static_assert(std::is_same_v
<std::common_reference_t
<int&, short>, int>);
128 // tricky volatile reference case
129 static_assert(std::is_same_v
<std::common_reference_t
<int&&, int volatile&>, int>);
130 static_assert(std::is_same_v
<std::common_reference_t
<int volatile&, int&&>, int>);
132 static_assert(std::is_same_v
<std::common_reference_t
<int (&)[10], int (&)[11]>, int*>);
134 // https://github.com/ericniebler/stl2/issues/338
138 static_assert(std::is_same_v
<std::common_reference_t
<int&, MyIntRef
>, MyIntRef
>);
141 // -- Otherwise, if common_type_t<T1, T2> is well-formed, then the member
142 // typedef type denotes that type.
144 moveonly() = default;
145 moveonly(moveonly
&&) = default;
146 moveonly
& operator=(moveonly
&&) = default;
148 struct moveonly2
: moveonly
{};
150 static_assert(std::is_same_v
<std::common_reference_t
<moveonly
const&, moveonly
>, moveonly
>);
151 static_assert(std::is_same_v
<std::common_reference_t
<moveonly2
const&, moveonly
>, moveonly
>);
152 static_assert(std::is_same_v
<std::common_reference_t
<moveonly
const&, moveonly2
>, moveonly
>);
154 static_assert(std::is_same_v
<std::common_reference_t
<X2
&, Y2
const&>, Z2
>);
157 // -- Otherwise, there shall be no member type.
158 static_assert(!has_type
<std::common_reference
<volatile UserTuple
<short>&, const UserTuple
<int, short>&> >);
161 // -- Otherwise, if sizeof...(T) is greater than two, let T1, T2, and Rest,
162 // respectively, denote the first, second, and (pack of) remaining types
163 // comprising T. Let C be the type common_reference_t<T1, T2>. Then:
165 // -- If there is such a type C, the member typedef type shall denote the
166 // same type, if any, as common_reference_t<C, Rest...>.
167 static_assert(std::is_same_v
<std::common_reference_t
<int, int, int>, int>);
168 static_assert(std::is_same_v
<std::common_reference_t
<int&&, int const&, int volatile&>, int const volatile&>);
169 static_assert(std::is_same_v
<std::common_reference_t
<int&&, int const&, float&>, float>);
172 // -- Otherwise, there shall be no member type.
173 static_assert(!has_type
<std::common_reference
<int, short, int, char*> >);
175 #if TEST_STD_VER > 20
176 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int, int>>, std::tuple
<int, int>>);
177 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int, long>, std::tuple
<long, int>>, std::tuple
<long, long>>);
178 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int&, const int&>, std::tuple
<const int&, int>>,
179 std::tuple
<const int&, int>>);
180 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int&, volatile int&>, std::tuple
<volatile int&, int>>,
181 std::tuple
<volatile int&, int>>);
182 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int&, const volatile int&>, std::tuple
<const volatile int&, int>>,
183 std::tuple
<const volatile int&, int>>);
184 static_assert(!has_type
<std::common_reference_t
<std::tuple
<const int&, volatile int&>, std::tuple
<volatile int&, const int&>>>);
186 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int, X2
>, std::tuple
<int, Y2
>>, std::tuple
<int, Z2
>>);
187 static_assert(std::is_same_v
<std::common_reference_t
<std::tuple
<int, X2
>, std::tuple
<int, Y2
>>, std::tuple
<int, Z2
>>);
188 static_assert(!has_type
<std::common_reference
<std::tuple
<int, const X2
>, std::tuple
<float, const Z2
>>>);
189 static_assert(!has_type
<std::common_reference
<std::tuple
<int, X2
>, std::tuple
<float, Z2
>>>);
190 static_assert(!has_type
<std::common_reference
<std::tuple
<int, X2
>, int, X2
>>);
193 template <template<class> class TQual
, template<class> class UQual
>
194 struct std::basic_common_reference
<A
, std::tuple
<B
>, TQual
, UQual
> {
195 using type
= tuple
<UQual
<B
>>;
198 static_assert(std::is_same_v
<std::common_reference_t
<A
, std::tuple
<B
>, std::tuple
<D
>>, std::tuple
<B
>>);
201 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int, int>>,
202 std::pair
<int, int>>);
203 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int, long>, std::pair
<long, int>>,
204 std::pair
<long, long>>);
205 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int&, const int&>, std::pair
<const int&, int>>,
206 std::pair
<const int&, int>>);
207 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int&, volatile int&>, std::pair
<volatile int&, int>>,
208 std::pair
<volatile int&, int>>);
209 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int&, const volatile int&>, std::pair
<const volatile int&, int>>,
210 std::pair
<const volatile int&, int>>);
211 static_assert(!has_type
<std::common_reference_t
<std::pair
<const int&, volatile int&>,
212 std::pair
<volatile int&, const int&>>>);
214 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int, X2
>, std::pair
<int, Y2
>>, std::pair
<int, Z2
>>);
215 static_assert(std::is_same_v
<std::common_reference_t
<std::pair
<int, X2
>, std::pair
<int, Y2
>>, std::pair
<int, Z2
>>);
216 static_assert(!has_type
<std::common_reference
<std::pair
<int, const X2
>, std::pair
<float, const Z2
>>>);
217 static_assert(!has_type
<std::common_reference
<std::pair
<int, X2
>, std::pair
<float, Z2
>>>);
218 static_assert(!has_type
<std::common_reference
<std::pair
<int, X2
>, int, X2
>>);