1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // <utility>
12 
13 // template<class R, class T>
14 //   constexpr bool in_range(T t) noexcept;               // C++20
15 
16 #include <utility>
17 #include <limits>
18 #include <numeric>
19 #include <tuple>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 
24 template <typename T>
25 struct Tuple {
26   T min;
27   T max;
28   T mid;
29   constexpr Tuple() {
30     min = std::numeric_limits<T>::min();
31     max = std::numeric_limits<T>::max();
32     mid = std::midpoint(min, max);
33   }
34 };
35 
36 template <typename T>
37 constexpr void test_in_range1() {
38   constexpr Tuple<T> tup;
39   assert(std::in_range<T>(tup.min));
40   assert(std::in_range<T>(tup.min + 1));
41   assert(std::in_range<T>(tup.max));
42   assert(std::in_range<T>(tup.max - 1));
43   assert(std::in_range<T>(tup.mid));
44   assert(std::in_range<T>(tup.mid - 1));
45   assert(std::in_range<T>(tup.mid + 1));
46 }
47 
48 constexpr void test_in_range() {
49   constexpr Tuple<uint8_t> utup8;
50   constexpr Tuple<int8_t> stup8;
51   assert(!std::in_range<int8_t>(utup8.max));
52   assert(std::in_range<short>(utup8.max));
53   assert(!std::in_range<uint8_t>(stup8.min));
54   assert(std::in_range<int8_t>(utup8.mid));
55   assert(!std::in_range<uint8_t>(stup8.mid));
56   assert(!std::in_range<uint8_t>(-1));
57 }
58 
59 template <class... Ts>
60 constexpr void test1(const std::tuple<Ts...>&) {
61   (test_in_range1<Ts>() , ...);
62 }
63 
64 constexpr bool test() {
65   std::tuple<
66 #ifndef TEST_HAS_NO_INT128
67       __int128_t, __uint128_t,
68 #endif
69       unsigned long long, long long, unsigned long, long, unsigned int, int,
70       unsigned short, short, unsigned char, signed char> types;
71   test1(types);
72   test_in_range();
73   return true;
74 }
75 
76 int main(int, char**) {
77   ASSERT_NOEXCEPT(std::in_range<int>(-1));
78   test();
79   static_assert(test());
80   return 0;
81 }
82