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 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11*e53c461bSKonstantin Varlamov
12*e53c461bSKonstantin Varlamov // template <class R, class P>
13*e53c461bSKonstantin Varlamov // lazy_split_view(R&&, P&&) -> lazy_split_view<views::all_t<R>, views::all_t<P>>;
14*e53c461bSKonstantin Varlamov //
15*e53c461bSKonstantin Varlamov // template <input_range R>
16*e53c461bSKonstantin Varlamov // lazy_split_view(R&&, range_value_t<R>) -> lazy_split_view<views::all_t<R>, single_view<range_value_t<R>>>;
17*e53c461bSKonstantin Varlamov
18*e53c461bSKonstantin Varlamov #include <ranges>
19*e53c461bSKonstantin Varlamov
20*e53c461bSKonstantin Varlamov #include <concepts>
21*e53c461bSKonstantin Varlamov #include <type_traits>
22*e53c461bSKonstantin Varlamov #include <utility>
23*e53c461bSKonstantin Varlamov #include "types.h"
24*e53c461bSKonstantin Varlamov
25*e53c461bSKonstantin Varlamov struct ForwardRange {
26*e53c461bSKonstantin Varlamov forward_iterator<const char*> begin() const;
27*e53c461bSKonstantin Varlamov forward_iterator<const char*> end() const;
28*e53c461bSKonstantin Varlamov };
29*e53c461bSKonstantin Varlamov static_assert( std::ranges::forward_range<ForwardRange>);
30*e53c461bSKonstantin Varlamov
31*e53c461bSKonstantin Varlamov struct InputRange {
32*e53c461bSKonstantin Varlamov cpp20_input_iterator<const char*> begin() const;
33*e53c461bSKonstantin Varlamov sentinel_wrapper<cpp20_input_iterator<const char*>> end() const;
34*e53c461bSKonstantin Varlamov };
35*e53c461bSKonstantin Varlamov static_assert(std::ranges::input_range<InputRange>);
36*e53c461bSKonstantin Varlamov
37*e53c461bSKonstantin Varlamov template <class I1, class I2, class ExpectedView, class ExpectedPattern>
test()38*e53c461bSKonstantin Varlamov constexpr void test() {
39*e53c461bSKonstantin Varlamov I1 i1{};
40*e53c461bSKonstantin Varlamov I2 i2{};
41*e53c461bSKonstantin Varlamov
42*e53c461bSKonstantin Varlamov std::ranges::lazy_split_view v(std::move(i1), std::move(i2));
43*e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(v), std::ranges::lazy_split_view<ExpectedView, ExpectedPattern>>);
44*e53c461bSKonstantin Varlamov using O = decltype(std::move(v).base());
45*e53c461bSKonstantin Varlamov static_assert(std::same_as<O, ExpectedView>);
46*e53c461bSKonstantin Varlamov }
47*e53c461bSKonstantin Varlamov
testCtad()48*e53c461bSKonstantin Varlamov constexpr void testCtad() {
49*e53c461bSKonstantin Varlamov // (Range, Pattern)
50*e53c461bSKonstantin Varlamov test<ForwardView, ForwardView, ForwardView, ForwardView>();
51*e53c461bSKonstantin Varlamov test<ForwardRange, ForwardRange, std::ranges::views::all_t<ForwardRange>, std::ranges::views::all_t<ForwardRange>>();
52*e53c461bSKonstantin Varlamov
53*e53c461bSKonstantin Varlamov // (Range, RangeElement)
54*e53c461bSKonstantin Varlamov test<ForwardRange, char, std::ranges::views::all_t<ForwardRange>, std::ranges::single_view<char>>();
55*e53c461bSKonstantin Varlamov test<InputRange, char, std::ranges::views::all_t<InputRange>, std::ranges::single_view<char>>();
56*e53c461bSKonstantin Varlamov
57*e53c461bSKonstantin Varlamov // (Range, RangeElement) with implicit conversion.
58*e53c461bSKonstantin Varlamov test<ForwardRange, bool, std::ranges::views::all_t<ForwardRange>, std::ranges::single_view<char>>();
59*e53c461bSKonstantin Varlamov test<InputRange, bool, std::ranges::views::all_t<InputRange>, std::ranges::single_view<char>>();
60*e53c461bSKonstantin Varlamov
61*e53c461bSKonstantin Varlamov // Note: CTAD from (InputRange, ForwardTinyRange) doesn't work -- the deduction guide wraps the pattern in
62*e53c461bSKonstantin Varlamov // `views::all_t`, resulting in `views::owning_view<ForwardTinyRange>`. That type would never satisfy `tiny-range`
63*e53c461bSKonstantin Varlamov // because `views::owning_view` contains a member function `size()` that shadows the static `size()` in
64*e53c461bSKonstantin Varlamov // `ForwardTinyRange`.
65*e53c461bSKonstantin Varlamov }
66