1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
13 // template<class _M, class _N>
14 // constexpr common_type_t<_M,_N> gcd(_M __m, _N __n)
20 #include <type_traits>
22 #include "test_macros.h"
40 template <typename Input1
, typename Input2
, typename Output
>
41 constexpr bool test0(int in1
, int in2
, int out
)
43 auto value1
= static_cast<Input1
>(in1
);
44 auto value2
= static_cast<Input2
>(in2
);
45 static_assert(std::is_same_v
<Output
, decltype(std::gcd(value1
, value2
))>, "");
46 static_assert(std::is_same_v
<Output
, decltype(std::gcd(value2
, value1
))>, "");
47 assert(static_cast<Output
>(out
) == std::gcd(value1
, value2
));
52 template <typename Input1
, typename Input2
= Input1
>
53 constexpr bool do_test(int = 0)
55 using S1
= std::make_signed_t
<Input1
>;
56 using S2
= std::make_signed_t
<Input2
>;
57 using U1
= std::make_unsigned_t
<Input1
>;
58 using U2
= std::make_unsigned_t
<Input2
>;
59 bool accumulate
= true;
60 for (auto TC
: Cases
) {
61 { // Test with two signed types
62 using Output
= std::common_type_t
<S1
, S2
>;
63 accumulate
&= test0
<S1
, S2
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
64 accumulate
&= test0
<S1
, S2
, Output
>(-TC
.x
, TC
.y
, TC
.expect
);
65 accumulate
&= test0
<S1
, S2
, Output
>(TC
.x
, -TC
.y
, TC
.expect
);
66 accumulate
&= test0
<S1
, S2
, Output
>(-TC
.x
, -TC
.y
, TC
.expect
);
67 accumulate
&= test0
<S2
, S1
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
68 accumulate
&= test0
<S2
, S1
, Output
>(-TC
.x
, TC
.y
, TC
.expect
);
69 accumulate
&= test0
<S2
, S1
, Output
>(TC
.x
, -TC
.y
, TC
.expect
);
70 accumulate
&= test0
<S2
, S1
, Output
>(-TC
.x
, -TC
.y
, TC
.expect
);
72 { // test with two unsigned types
73 using Output
= std::common_type_t
<U1
, U2
>;
74 accumulate
&= test0
<U1
, U2
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
75 accumulate
&= test0
<U2
, U1
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
77 { // Test with mixed signs
78 using Output
= std::common_type_t
<S1
, U2
>;
79 accumulate
&= test0
<S1
, U2
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
80 accumulate
&= test0
<U2
, S1
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
81 accumulate
&= test0
<S1
, U2
, Output
>(-TC
.x
, TC
.y
, TC
.expect
);
82 accumulate
&= test0
<U2
, S1
, Output
>(TC
.x
, -TC
.y
, TC
.expect
);
84 { // Test with mixed signs
85 using Output
= std::common_type_t
<S2
, U1
>;
86 accumulate
&= test0
<S2
, U1
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
87 accumulate
&= test0
<U1
, S2
, Output
>(TC
.x
, TC
.y
, TC
.expect
);
88 accumulate
&= test0
<S2
, U1
, Output
>(-TC
.x
, TC
.y
, TC
.expect
);
89 accumulate
&= test0
<U1
, S2
, Output
>(TC
.x
, -TC
.y
, TC
.expect
);
95 int main(int argc
, char**)
97 int non_cce
= argc
; // a value that can't possibly be constexpr
99 static_assert(do_test
<signed char>(), "");
100 static_assert(do_test
<short>(), "");
101 static_assert(do_test
<int>(), "");
102 static_assert(do_test
<long>(), "");
103 static_assert(do_test
<long long>(), "");
105 assert(do_test
<signed char>(non_cce
));
106 assert(do_test
<short>(non_cce
));
107 assert(do_test
<int>(non_cce
));
108 assert(do_test
<long>(non_cce
));
109 assert(do_test
<long long>(non_cce
));
111 static_assert(do_test
<std::int8_t>(), "");
112 static_assert(do_test
<std::int16_t>(), "");
113 static_assert(do_test
<std::int32_t>(), "");
114 static_assert(do_test
<std::int64_t>(), "");
116 assert(do_test
<std::int8_t>(non_cce
));
117 assert(do_test
<std::int16_t>(non_cce
));
118 assert(do_test
<std::int32_t>(non_cce
));
119 assert(do_test
<std::int64_t>(non_cce
));
121 static_assert(do_test
<signed char, int>(), "");
122 static_assert(do_test
<int, signed char>(), "");
123 static_assert(do_test
<short, int>(), "");
124 static_assert(do_test
<int, short>(), "");
125 static_assert(do_test
<int, long>(), "");
126 static_assert(do_test
<long, int>(), "");
127 static_assert(do_test
<int, long long>(), "");
128 static_assert(do_test
<long long, int>(), "");
130 assert((do_test
<signed char, int>(non_cce
)));
131 assert((do_test
<int, signed char>(non_cce
)));
132 assert((do_test
<short, int>(non_cce
)));
133 assert((do_test
<int, short>(non_cce
)));
134 assert((do_test
<int, long>(non_cce
)));
135 assert((do_test
<long, int>(non_cce
)));
136 assert((do_test
<int, long long>(non_cce
)));
137 assert((do_test
<long long, int>(non_cce
)));
141 auto res
= std::gcd(static_cast<std::int64_t>(1234), INT32_MIN
);
142 static_assert(std::is_same_v
<decltype(res
), std::int64_t>, "");