//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 // std::views::lazy_split #include #include #include #include #include #include #include "test_iterators.h" #include "test_range.h" #include "types.h" struct SomeView : std::ranges::view_base { const std::string_view* v_; constexpr SomeView(const std::string_view& v) : v_(&v) {} constexpr auto begin() const { return v_->begin(); } constexpr auto end() const { return v_->end(); } }; struct NotAView { }; static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert( std::is_invocable_v); // Regression test for #75002, views::lazy_split shouldn't be a range adaptor closure static_assert(!CanBePiped); static_assert(!CanBePiped); static_assert(!CanBePiped); static_assert(!CanBePiped); static_assert(CanBePiped); static_assert(CanBePiped); static_assert(!CanBePiped); static_assert(!CanBePiped); static_assert(std::same_as); constexpr bool test() { std::string_view input = "abc"; std::string_view sep = "a"; // Test that `std::views::lazy_split` is a range adaptor. // Test `views::lazy_split(input, sep)`. { SomeView view(input); using Result = std::ranges::lazy_split_view; std::same_as decltype(auto) result = std::views::lazy_split(view, sep); assert(result.base().begin() == input.begin()); assert(result.base().end() == input.end()); } // Test `views::lazy_split(sep)(input)`. { SomeView view(input); using Result = std::ranges::lazy_split_view; std::same_as decltype(auto) result = std::views::lazy_split(sep)(view); assert(result.base().begin() == input.begin()); assert(result.base().end() == input.end()); } // Test `view | views::lazy_split`. { SomeView view(input); using Result = std::ranges::lazy_split_view; std::same_as decltype(auto) result = view | std::views::lazy_split(sep); assert(result.base().begin() == input.begin()); assert(result.base().end() == input.end()); } // Test `adaptor | views::lazy_split`. { SomeView view(input); auto f = [](char c) { return c; }; auto partial = std::views::transform(f) | std::views::lazy_split(sep); using Result = std::ranges::lazy_split_view, std::string_view>; std::same_as decltype(auto) result = partial(view); assert(result.base().base().begin() == input.begin()); assert(result.base().base().end() == input.end()); } // Test `views::lazy_split | adaptor`. { SomeView view(input); auto f = [](auto v) { return v; }; auto partial = std::views::lazy_split(sep) | std::views::transform(f); using Result = std::ranges::transform_view, decltype(f)>; std::same_as decltype(auto) result = partial(view); assert(result.base().base().begin() == input.begin()); assert(result.base().base().end() == input.end()); } // Test that one can call `std::views::lazy_split` with arbitrary stuff, as long as we // don't try to actually complete the call by passing it a range. // // That makes no sense and we can't do anything with the result, but it's valid. { struct X { }; [[maybe_unused]] auto partial = std::views::lazy_split(X{}); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }