1*03c19e91SHristo Hristov //===----------------------------------------------------------------------===//
2*03c19e91SHristo Hristov //
3*03c19e91SHristo Hristov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*03c19e91SHristo Hristov // See https://llvm.org/LICENSE.txt for license information.
5*03c19e91SHristo Hristov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*03c19e91SHristo Hristov //
7*03c19e91SHristo Hristov //===----------------------------------------------------------------------===//
8*03c19e91SHristo Hristov
9*03c19e91SHristo Hristov // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10*03c19e91SHristo Hristov
11*03c19e91SHristo Hristov // <numeric>
12*03c19e91SHristo Hristov
13*03c19e91SHristo Hristov // template<class T>
14*03c19e91SHristo Hristov // constexpr T div_sat(T x, T y) noexcept; // freestanding
15*03c19e91SHristo Hristov
16*03c19e91SHristo Hristov #include <concepts>
17*03c19e91SHristo Hristov #include <numeric>
18*03c19e91SHristo Hristov #include <type_traits>
19*03c19e91SHristo Hristov
20*03c19e91SHristo Hristov #include "test_macros.h"
21*03c19e91SHristo Hristov
22*03c19e91SHristo Hristov // Constraints
23*03c19e91SHristo Hristov
24*03c19e91SHristo Hristov template <typename T, typename U>
25*03c19e91SHristo Hristov concept CanDo = requires(T x, U y) {
26*03c19e91SHristo Hristov { std::div_sat(x, y) } -> std::same_as<T>;
27*03c19e91SHristo Hristov };
28*03c19e91SHristo Hristov
29*03c19e91SHristo Hristov template <typename T, typename U>
test_constraint_success()30*03c19e91SHristo Hristov constexpr void test_constraint_success() {
31*03c19e91SHristo Hristov static_assert(CanDo<T, T>);
32*03c19e91SHristo Hristov static_assert(!CanDo<U, T>);
33*03c19e91SHristo Hristov static_assert(!CanDo<T, U>);
34*03c19e91SHristo Hristov }
35*03c19e91SHristo Hristov
36*03c19e91SHristo Hristov template <typename T>
test_constraint_fail()37*03c19e91SHristo Hristov constexpr void test_constraint_fail() {
38*03c19e91SHristo Hristov using I = int;
39*03c19e91SHristo Hristov static_assert(!CanDo<T, T>);
40*03c19e91SHristo Hristov static_assert(!CanDo<I, T>);
41*03c19e91SHristo Hristov static_assert(!CanDo<T, I>);
42*03c19e91SHristo Hristov }
43*03c19e91SHristo Hristov
test()44*03c19e91SHristo Hristov constexpr void test() {
45*03c19e91SHristo Hristov // Contraint success - Signed
46*03c19e91SHristo Hristov using SI = long long int;
47*03c19e91SHristo Hristov test_constraint_success<signed char, SI>();
48*03c19e91SHristo Hristov test_constraint_success<short int, SI>();
49*03c19e91SHristo Hristov test_constraint_success<signed char, SI>();
50*03c19e91SHristo Hristov test_constraint_success<short int, SI>();
51*03c19e91SHristo Hristov test_constraint_success<int, SI>();
52*03c19e91SHristo Hristov test_constraint_success<long int, SI>();
53*03c19e91SHristo Hristov test_constraint_success<long long int, int>();
54*03c19e91SHristo Hristov #ifndef TEST_HAS_NO_INT128
55*03c19e91SHristo Hristov test_constraint_success<__int128_t, SI>();
56*03c19e91SHristo Hristov #endif
57*03c19e91SHristo Hristov // Contraint success - Unsigned
58*03c19e91SHristo Hristov using UI = unsigned long long int;
59*03c19e91SHristo Hristov test_constraint_success<unsigned char, UI>();
60*03c19e91SHristo Hristov test_constraint_success<unsigned short int, UI>();
61*03c19e91SHristo Hristov test_constraint_success<unsigned int, UI>();
62*03c19e91SHristo Hristov test_constraint_success<unsigned long int, UI>();
63*03c19e91SHristo Hristov test_constraint_success<unsigned long long int, unsigned int>();
64*03c19e91SHristo Hristov #ifndef TEST_HAS_NO_INT128
65*03c19e91SHristo Hristov test_constraint_success<__uint128_t, UI>();
66*03c19e91SHristo Hristov #endif
67*03c19e91SHristo Hristov
68*03c19e91SHristo Hristov // Contraint failure
69*03c19e91SHristo Hristov test_constraint_fail<bool>();
70*03c19e91SHristo Hristov test_constraint_fail<char>();
71*03c19e91SHristo Hristov #ifndef TEST_HAS_NO_INT128
72*03c19e91SHristo Hristov test_constraint_fail<wchar_t>();
73*03c19e91SHristo Hristov #endif
74*03c19e91SHristo Hristov test_constraint_fail<char8_t>();
75*03c19e91SHristo Hristov test_constraint_fail<char16_t>();
76*03c19e91SHristo Hristov test_constraint_fail<char32_t>();
77*03c19e91SHristo Hristov test_constraint_fail<float>();
78*03c19e91SHristo Hristov test_constraint_fail<double>();
79*03c19e91SHristo Hristov test_constraint_fail<long double>();
80*03c19e91SHristo Hristov }
81*03c19e91SHristo Hristov
82*03c19e91SHristo Hristov // A function call expression that violates the precondition in the Preconditions: element is not a core constant expression (7.7 [expr.const]).
83*03c19e91SHristo Hristov
84*03c19e91SHristo Hristov template <auto N>
85*03c19e91SHristo Hristov using QuotT = std::integral_constant<decltype(N), std::div_sat(N, N)>;
86*03c19e91SHristo Hristov
87*03c19e91SHristo Hristov template <auto N>
88*03c19e91SHristo Hristov QuotT<N> div_by_zero();
89*03c19e91SHristo Hristov
90*03c19e91SHristo Hristov template <auto N>
91*03c19e91SHristo Hristov concept CanDivByZero = requires { div_by_zero<N>(); };
92*03c19e91SHristo Hristov
93*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<signed char>(0)>);
94*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<short int>(0)>);
95*03c19e91SHristo Hristov static_assert(!CanDivByZero<0>);
96*03c19e91SHristo Hristov static_assert(!CanDivByZero<0L>);
97*03c19e91SHristo Hristov static_assert(!CanDivByZero<0LL>);
98*03c19e91SHristo Hristov #ifndef TEST_HAS_NO_INT128
99*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<__int128_t>(0)>);
100*03c19e91SHristo Hristov #endif
101*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<unsigned char>(0)>);
102*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<unsigned short int>(0)>);
103*03c19e91SHristo Hristov static_assert(!CanDivByZero<0U>);
104*03c19e91SHristo Hristov static_assert(!CanDivByZero<0UL>);
105*03c19e91SHristo Hristov static_assert(!CanDivByZero<0ULL>);
106*03c19e91SHristo Hristov #ifndef TEST_HAS_NO_INT128
107*03c19e91SHristo Hristov static_assert(!CanDivByZero<static_cast<__uint128_t>(0)>);
108*03c19e91SHristo Hristov #endif
109