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