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