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 // UNSUPPORTED: libcpp-no-concepts
11 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
12 
13 // constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
14 
15 #include "test_macros.h"
16 
17 #if defined(TEST_COMPILER_CLANG) || defined(TEST_COMPILER_GCC)
18 #pragma GCC diagnostic ignored "-Wsign-compare"
19 #elif defined(TEST_COMPILER_MSVC)
20 #pragma warning(disable: 4018) // various "signed/unsigned mismatch"
21 #endif
22 
23 #include <ranges>
24 #include <cassert>
25 
26 #include "../types.h"
27 
28 struct NotNoexceptCopy {
29   using difference_type = int;
30 
31   int value_;
32   constexpr explicit NotNoexceptCopy(int value = 0) : value_(value) {}
33   NotNoexceptCopy(const NotNoexceptCopy&) noexcept(false) = default;
34 
35   bool operator==(const NotNoexceptCopy&) const = default;
36 
37   friend constexpr NotNoexceptCopy& operator+=(NotNoexceptCopy &lhs, const NotNoexceptCopy& rhs) {
38     lhs.value_ += rhs.value_; return lhs;
39   }
40   friend constexpr NotNoexceptCopy& operator-=(NotNoexceptCopy &lhs, const NotNoexceptCopy& rhs) {
41     lhs.value_ -= rhs.value_; return lhs;
42   }
43 
44   friend constexpr NotNoexceptCopy operator+(NotNoexceptCopy lhs, NotNoexceptCopy rhs) {
45     return NotNoexceptCopy{lhs.value_ + rhs.value_};
46   }
47   friend constexpr int operator-(NotNoexceptCopy lhs, NotNoexceptCopy rhs) {
48     return lhs.value_ - rhs.value_;
49   }
50 
51   constexpr NotNoexceptCopy& operator++()     { ++value_; return *this; }
52   constexpr void              operator++(int) { ++value_;               }
53 };
54 
55 template<class T>
56 constexpr void testType() {
57   {
58     std::ranges::iota_view<T> io(T(0));
59     auto iter = io.begin();
60     for (int i = 0; i < 100; ++i, ++iter)
61       assert(*iter == T(i));
62 
63     static_assert(noexcept(*iter) == !std::same_as<T, NotNoexceptCopy>);
64   }
65   {
66     std::ranges::iota_view<T> io(T(10));
67     auto iter = io.begin();
68     for (int i = 10; i < 100; ++i, ++iter)
69       assert(*iter == T(i));
70   }
71   {
72     const std::ranges::iota_view<T> io(T(0));
73     auto iter = io.begin();
74     for (int i = 0; i < 100; ++i, ++iter)
75       assert(*iter == T(i));
76   }
77   {
78     const std::ranges::iota_view<T> io(T(10));
79     auto iter = io.begin();
80     for (int i = 10; i < 100; ++i, ++iter)
81       assert(*iter == T(i));
82   }
83 }
84 
85 constexpr bool test() {
86   testType<SomeInt>();
87   testType<NotNoexceptCopy>();
88   testType<signed long>();
89   testType<unsigned long>();
90   testType<int>();
91   testType<unsigned>();
92   testType<short>();
93   testType<unsigned short>();
94 
95   // Tests a mix of signed unsigned types.
96   {
97     const std::ranges::iota_view<int, unsigned> io(0, 10);
98     auto iter = io.begin();
99     for (int i = 0; i < 10; ++i, ++iter)
100       assert(*iter == i);
101   }
102 
103   return true;
104 }
105 
106 int main(int, char**) {
107   test();
108   static_assert(test());
109 
110   return 0;
111 }
112