Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / utilities / meta / meta.trans / meta.trans.other / common_reference.compile.pass.cpp
blob9332865eaa2450ed1de537567cdc850619f5d20d
1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++03, c++11, c++14, c++17
12 // type_traits
13 // common_reference
15 #include <tuple>
16 #include <type_traits>
17 #include <utility>
19 #include "test_macros.h"
21 template <class T>
22 constexpr bool has_type = requires {
23 typename T::type;
26 // A slightly simplified variation of std::tuple
27 template <class...>
28 struct UserTuple {};
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>...>;
37 namespace std {
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>...> > {};
41 } // namespace std
43 struct X2 {};
44 struct Y2 {};
45 struct Z2 {};
47 namespace std {
48 template <>
49 struct common_type<X2, Y2> {
50 using type = Z2;
52 template <>
53 struct common_type<Y2, X2> {
54 using type = Z2;
56 } // namespace std
58 // (6.1)
59 // -- If sizeof...(T) is zero, there shall be no member type.
60 static_assert(!has_type<std::common_reference<> >);
62 // (6.2)
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 (&&)()>);
78 // (6.3)
79 // -- Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in
80 // the pack T. Then
81 // (6.3.1)
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.
84 struct B {};
85 struct D : B {};
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]>);
109 // (6.3.2)
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>&>);
119 // (6.3.3)
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
135 struct MyIntRef {
136 MyIntRef(int&);
138 static_assert(std::is_same_v<std::common_reference_t<int&, MyIntRef>, MyIntRef>);
140 // (6.3.4)
141 // -- Otherwise, if common_type_t<T1, T2> is well-formed, then the member
142 // typedef type denotes that type.
143 struct moveonly {
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>);
156 // (6.3.5)
157 // -- Otherwise, there shall be no member type.
158 static_assert(!has_type<std::common_reference<volatile UserTuple<short>&, const UserTuple<int, short>&> >);
160 // (6.4)
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:
164 // (6.4.1)
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>);
171 // (6.4.2)
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>>);
192 struct A {};
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>>);
219 #endif