Skip to content

Commit cfb8b73

Browse files
fix test
1 parent 397227f commit cfb8b73

File tree

1 file changed

+34
-50
lines changed

1 file changed

+34
-50
lines changed

libcxx/test/std/ranges/range.adaptors/range.concat/iterator/iter_move.pass.cpp

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323
#include "test_macros.h"
2424
#include "../types.h"
2525

26-
template <bool NoThrow>
26+
template <typename T, bool NoThrow>
2727
struct ThowingIter {
2828
using iterator_concept = std::forward_iterator_tag;
2929
using iterator_category = std::forward_iterator_tag;
3030
using difference_type = std::ptrdiff_t;
31-
using value_type = int;
31+
using value_type = T;
3232

33-
int* p = nullptr;
33+
T* p = nullptr;
3434

35-
constexpr int& operator*() const noexcept { return *p; }
35+
constexpr T& operator*() const noexcept { return *p; }
3636
constexpr ThowingIter& operator++() noexcept {
3737
++p;
3838
return *this;
@@ -44,7 +44,7 @@ struct ThowingIter {
4444
}
4545
friend constexpr bool operator==(ThowingIter, ThowingIter) = default;
4646

47-
friend constexpr int&& iter_move(const ThowingIter& it) noexcept(NoThrow) { return std::move(*it.p); }
47+
friend constexpr T&& iter_move(const ThowingIter& it) noexcept(NoThrow) { return std::move(*it.p); }
4848
};
4949

5050
struct Range : std::ranges::view_base {
@@ -59,61 +59,26 @@ struct Range : std::ranges::view_base {
5959
int* end_;
6060
};
6161

62-
struct ThrowingValue {
63-
int v{};
64-
ThrowingValue() = default;
65-
explicit ThrowingValue(int x) noexcept(false) : v(x) {}
66-
ThrowingValue(const ThrowingValue&) noexcept(false) = default;
67-
ThrowingValue(ThrowingValue&&) noexcept(false) = default;
68-
};
69-
70-
template <bool DerefNoThrow>
71-
struct PValIter {
72-
using iterator_concept = std::input_iterator_tag;
73-
using iterator_category = std::input_iterator_tag;
74-
using difference_type = std::ptrdiff_t;
75-
using value_type = std::conditional_t<DerefNoThrow, int, ThrowingValue>;
76-
77-
int* p = nullptr;
78-
79-
decltype(auto) operator*() const noexcept(DerefNoThrow) {
80-
if constexpr (DerefNoThrow)
81-
return *p; // int (noexcept)
82-
else
83-
return ThrowingValue{*p}; // not noexcept
84-
}
85-
PValIter& operator++() noexcept {
86-
++p;
87-
return *this;
88-
}
89-
void operator++(int) noexcept { ++p; }
90-
friend bool operator==(PValIter, PValIter) = default;
91-
};
92-
93-
static_assert(std::input_iterator<LRefIter<true>>);
94-
static_assert(std::input_iterator<LRefIter<false>>);
95-
static_assert(std::input_iterator<PValIter<true>>);
96-
static_assert(std::input_iterator<PValIter<false>>);
97-
98-
template <class Iter>
62+
template <class Iter, class Sentinel>
9963
struct MiniView : std::ranges::view_base {
100-
Iter b{}, e{};
64+
Iter b{};
65+
Sentinel e{};
10166
constexpr MiniView() = default;
102-
constexpr MiniView(Iter first, Iter last) : b(first), e(last) {}
67+
constexpr MiniView(Iter first, Sentinel last) : b(first), e(last) {}
10368
constexpr Iter begin() const noexcept { return b; }
104-
constexpr Iter end() const noexcept { return e; }
69+
constexpr Sentinel end() const noexcept { return e; }
10570
};
10671

10772
constexpr bool test() {
10873
int buf1[] = {1, 2, 3, 4};
10974
int buf2[] = {5, 6, 7};
11075
{
11176
// All underlying iter_move are noexcept -> concat iterator's iter_move is noexcept
112-
using I1 = ThowingIter<true>;
113-
using S1 = sentinel_wrapper<I1>;
114-
using V1 = MiniView<I1>;
115-
V1 v1(I1(buf1), I1(buf1 + 4));
116-
V1 v2(I1(buf2), I1(buf2 + 3));
77+
using Iter_NoThrow = ThowingIter<int, true>;
78+
using Sentinel_NoThrow = sentinel_wrapper<Iter_NoThrow>;
79+
using View_NoThrow = MiniView<Iter_NoThrow, Sentinel_NoThrow>;
80+
View_NoThrow v1(Iter_NoThrow(buf1), Sentinel_NoThrow(Iter_NoThrow(buf1 + 4)));
81+
View_NoThrow v2(Iter_NoThrow(buf2), Sentinel_NoThrow(Iter_NoThrow(buf2 + 3)));
11782

11883
auto cv = std::views::concat(v1, v2);
11984
using Iter = decltype(cv.begin());
@@ -126,6 +91,25 @@ constexpr bool test() {
12691
(void)std::ranges::iter_move(it);
12792
}
12893

94+
{
95+
// One underlying may throw -> concat iter_move is NOT noexcept
96+
using Iter_NoThrow = ThowingIter<int, true>;
97+
using Iter_Throw = ThowingIter<int, false>;
98+
using Sentinel_NoThrow = sentinel_wrapper<Iter_NoThrow>;
99+
using Sentinel_Throw = sentinel_wrapper<Iter_Throw>;
100+
using View_NoThrow = MiniView<Iter_NoThrow, Sentinel_NoThrow>;
101+
using View_Throw = MiniView<Iter_Throw, Sentinel_Throw>;
102+
103+
auto cv = std::views::concat(View_NoThrow{Iter_NoThrow{buf1}, Sentinel_NoThrow{Iter_NoThrow{buf1 + 4}}},
104+
View_Throw{Iter_Throw{buf2}, Sentinel_Throw{Iter_Throw{buf2 + 3}}});
105+
106+
using Iter = decltype(cv.begin());
107+
using CIter = decltype(std::as_const(cv).begin());
108+
109+
static_assert(!noexcept(std::ranges::iter_move(std::declval<Iter&>())));
110+
static_assert(!noexcept(std::ranges::iter_move(std::declval<CIter&>())));
111+
}
112+
129113
return true;
130114
}
131115

0 commit comments

Comments
 (0)