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-has-no-incomplete-ranges 11 12 // constexpr lazy_split_view(View base, Pattern pattern); 13 14 #include <ranges> 15 16 #include <cassert> 17 #include <string_view> 18 #include <utility> 19 #include "types.h" 20 21 struct ViewWithCounting : std::ranges::view_base { 22 int* times_copied = nullptr; 23 int* times_moved = nullptr; 24 25 constexpr ViewWithCounting(int& copies_ctr, int& moves_ctr) : times_copied(&copies_ctr), times_moved(&moves_ctr) {} 26 27 constexpr ViewWithCounting(const ViewWithCounting& rhs) 28 : times_copied(rhs.times_copied) 29 , times_moved(rhs.times_moved) { 30 ++(*times_copied); 31 } 32 constexpr ViewWithCounting(ViewWithCounting&& rhs) 33 : times_copied(rhs.times_copied) 34 , times_moved(rhs.times_moved) { 35 ++(*times_moved); 36 } 37 38 constexpr const char* begin() const { return nullptr; } 39 constexpr const char* end() const { return nullptr; } 40 41 constexpr ViewWithCounting& operator=(const ViewWithCounting&) = default; 42 constexpr ViewWithCounting& operator=(ViewWithCounting&&) = default; 43 constexpr bool operator==(const ViewWithCounting&) const { return true; } 44 }; 45 static_assert(std::ranges::forward_range<ViewWithCounting>); 46 static_assert(std::ranges::view<ViewWithCounting>); 47 48 constexpr bool test() { 49 // Calling the constructor with `(ForwardView, ForwardView)`. 50 { 51 CopyableView input = "abc def"; 52 std::ranges::lazy_split_view<CopyableView, CopyableView> v(input, " "); 53 assert(v.base() == input); 54 } 55 56 // Calling the constructor with `(InputView, TinyView)`. 57 { 58 InputView input = "abc def"; 59 std::ranges::lazy_split_view<InputView, ForwardTinyView> v(input, ' '); 60 // Note: `InputView` isn't equality comparable. 61 (void)v; 62 } 63 64 // Make sure the arguments are moved, not copied. 65 { 66 using View = ViewWithCounting; 67 using Pattern = ViewWithCounting; 68 69 // Arguments are lvalues. 70 { 71 int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0; 72 View view(view_copied, view_moved); 73 Pattern pattern(pattern_copied, pattern_moved); 74 75 std::ranges::lazy_split_view<View, Pattern> v(view, pattern); 76 assert(view_copied == 1); // The local variable is copied into the argument. 77 assert(view_moved == 1); 78 assert(pattern_copied == 1); 79 assert(pattern_moved == 1); 80 } 81 82 // Arguments are rvalues. 83 { 84 int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0; 85 std::ranges::lazy_split_view<View, Pattern> v( 86 View(view_copied, view_moved), Pattern(pattern_copied, pattern_moved)); 87 assert(view_copied == 0); 88 assert(view_moved == 1); 89 assert(pattern_copied == 0); 90 assert(pattern_moved == 1); 91 } 92 } 93 94 return true; 95 } 96 97 int main(int, char**) { 98 test(); 99 static_assert(test()); 100 101 return 0; 102 } 103