1*e53c461bSKonstantin Varlamov //===----------------------------------------------------------------------===//
2*e53c461bSKonstantin Varlamov //
3*e53c461bSKonstantin Varlamov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e53c461bSKonstantin Varlamov // See https://llvm.org/LICENSE.txt for license information.
5*e53c461bSKonstantin Varlamov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e53c461bSKonstantin Varlamov //
7*e53c461bSKonstantin Varlamov //===----------------------------------------------------------------------===//
8*e53c461bSKonstantin Varlamov
9*e53c461bSKonstantin Varlamov // UNSUPPORTED: c++03, c++11, c++14, c++17
10*e53c461bSKonstantin Varlamov
11*e53c461bSKonstantin Varlamov // constexpr decltype(auto) inner-iterator::operator*() const;
12*e53c461bSKonstantin Varlamov
13*e53c461bSKonstantin Varlamov #include <ranges>
14*e53c461bSKonstantin Varlamov
15*e53c461bSKonstantin Varlamov #include "../types.h"
16*e53c461bSKonstantin Varlamov
test()17*e53c461bSKonstantin Varlamov constexpr bool test() {
18*e53c461bSKonstantin Varlamov // Can call `inner-iterator::operator*`; `View` is a forward range.
19*e53c461bSKonstantin Varlamov {
20*e53c461bSKonstantin Varlamov SplitViewDiff v("abc def", " ");
21*e53c461bSKonstantin Varlamov auto val = *v.begin();
22*e53c461bSKonstantin Varlamov
23*e53c461bSKonstantin Varlamov // Non-const iterator.
24*e53c461bSKonstantin Varlamov {
25*e53c461bSKonstantin Varlamov auto i = val.begin();
26*e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(*i), char&>);
27*e53c461bSKonstantin Varlamov assert(*i == 'a');
28*e53c461bSKonstantin Varlamov assert(*(++i) == 'b');
29*e53c461bSKonstantin Varlamov assert(*(++i) == 'c');
30*e53c461bSKonstantin Varlamov }
31*e53c461bSKonstantin Varlamov
32*e53c461bSKonstantin Varlamov // Const iterator.
33*e53c461bSKonstantin Varlamov {
34*e53c461bSKonstantin Varlamov const auto ci = val.begin();
35*e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(*ci), char&>);
36*e53c461bSKonstantin Varlamov assert(*ci == 'a');
37*e53c461bSKonstantin Varlamov }
38*e53c461bSKonstantin Varlamov }
39*e53c461bSKonstantin Varlamov
40*e53c461bSKonstantin Varlamov // Can call `inner-iterator::operator*`; `View` is an input range.
41*e53c461bSKonstantin Varlamov {
42*e53c461bSKonstantin Varlamov SplitViewInput v("abc def", ' ');
43*e53c461bSKonstantin Varlamov auto val = *v.begin();
44*e53c461bSKonstantin Varlamov
45*e53c461bSKonstantin Varlamov // Non-const iterator.
46*e53c461bSKonstantin Varlamov {
47*e53c461bSKonstantin Varlamov auto i = val.begin();
48*e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(*i), char&>);
49*e53c461bSKonstantin Varlamov assert(*i == 'a');
50*e53c461bSKonstantin Varlamov assert(*(++i) == 'b');
51*e53c461bSKonstantin Varlamov assert(*(++i) == 'c');
52*e53c461bSKonstantin Varlamov }
53*e53c461bSKonstantin Varlamov
54*e53c461bSKonstantin Varlamov // Const iterator.
55*e53c461bSKonstantin Varlamov {
56*e53c461bSKonstantin Varlamov const auto ci = val.begin();
57*e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(*ci), char&>);
58*e53c461bSKonstantin Varlamov // Note: when the underlying range is an input range, `current` is stored in the `lazy_split_view` itself and
59*e53c461bSKonstantin Varlamov // shared between `inner-iterator`s. Consequently, incrementing one iterator effectively increments all of them.
60*e53c461bSKonstantin Varlamov assert(*ci == 'c');
61*e53c461bSKonstantin Varlamov }
62*e53c461bSKonstantin Varlamov }
63*e53c461bSKonstantin Varlamov
64*e53c461bSKonstantin Varlamov return true;
65*e53c461bSKonstantin Varlamov }
66*e53c461bSKonstantin Varlamov
main(int,char **)67*e53c461bSKonstantin Varlamov int main(int, char**) {
68*e53c461bSKonstantin Varlamov test();
69*e53c461bSKonstantin Varlamov static_assert(test());
70*e53c461bSKonstantin Varlamov
71*e53c461bSKonstantin Varlamov return 0;
72*e53c461bSKonstantin Varlamov }
73