xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.view.pass.cpp (revision 881718857f6d0189eecd1d7391aa1c3778959a80)
1a2b3ab8fSHui //===----------------------------------------------------------------------===//
2a2b3ab8fSHui //
3a2b3ab8fSHui // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a2b3ab8fSHui // See https://llvm.org/LICENSE.txt for license information.
5a2b3ab8fSHui // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a2b3ab8fSHui //
7a2b3ab8fSHui //===----------------------------------------------------------------------===//
8a2b3ab8fSHui 
9a2b3ab8fSHui // UNSUPPORTED: c++03, c++11, c++14, c++17
10a2b3ab8fSHui 
1140aaa272SHristo Hristov // constexpr split_view(View base, Pattern pattern); // explicit since C++23
12a2b3ab8fSHui 
13a2b3ab8fSHui #include <algorithm>
14a2b3ab8fSHui #include <cassert>
15a2b3ab8fSHui #include <ranges>
16a2b3ab8fSHui #include <string_view>
17a2b3ab8fSHui #include <utility>
18a2b3ab8fSHui 
1940aaa272SHristo Hristov #include "test_convertible.h"
2040aaa272SHristo Hristov #include "test_macros.h"
2140aaa272SHristo Hristov 
22a2b3ab8fSHui struct ViewWithCounting : std::ranges::view_base {
23a2b3ab8fSHui   int* times_copied = nullptr;
24a2b3ab8fSHui   int* times_moved  = nullptr;
25a2b3ab8fSHui 
ViewWithCountingViewWithCounting26a2b3ab8fSHui   constexpr ViewWithCounting(int& copies_ctr, int& moves_ctr) : times_copied(&copies_ctr), times_moved(&moves_ctr) {}
27a2b3ab8fSHui 
ViewWithCountingViewWithCounting28a2b3ab8fSHui   constexpr ViewWithCounting(const ViewWithCounting& rhs)
29a2b3ab8fSHui       : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
30a2b3ab8fSHui     ++(*times_copied);
31a2b3ab8fSHui   }
ViewWithCountingViewWithCounting32a2b3ab8fSHui   constexpr ViewWithCounting(ViewWithCounting&& rhs) : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
33a2b3ab8fSHui     ++(*times_moved);
34a2b3ab8fSHui   }
35a2b3ab8fSHui 
beginViewWithCounting36a2b3ab8fSHui   constexpr const char* begin() const { return nullptr; }
endViewWithCounting37a2b3ab8fSHui   constexpr const char* end() const { return nullptr; }
38a2b3ab8fSHui 
39a2b3ab8fSHui   constexpr ViewWithCounting& operator=(const ViewWithCounting&) = default;
40a2b3ab8fSHui   constexpr ViewWithCounting& operator=(ViewWithCounting&&)      = default;
operator ==ViewWithCounting41a2b3ab8fSHui   constexpr bool operator==(const ViewWithCounting&) const { return true; }
42a2b3ab8fSHui };
43a2b3ab8fSHui 
4440aaa272SHristo Hristov using View    = ViewWithCounting;
4540aaa272SHristo Hristov using Pattern = ViewWithCounting;
4640aaa272SHristo Hristov 
4740aaa272SHristo Hristov // SFINAE tests.
4840aaa272SHristo Hristov 
4940aaa272SHristo Hristov #if TEST_STD_VER >= 23
5040aaa272SHristo Hristov 
5140aaa272SHristo Hristov static_assert(!test_convertible<std::ranges::split_view<View, Pattern>, View, Pattern>(),
5240aaa272SHristo Hristov               "This constructor must be explicit");
5340aaa272SHristo Hristov 
5440aaa272SHristo Hristov #else
5540aaa272SHristo Hristov 
5640aaa272SHristo Hristov static_assert( test_convertible<std::ranges::split_view<View, Pattern>, View, Pattern>(),
5740aaa272SHristo Hristov               "This constructor must not be explicit");
5840aaa272SHristo Hristov 
5940aaa272SHristo Hristov #endif // TEST_STD_VER >= 23
6040aaa272SHristo Hristov 
test()61a2b3ab8fSHui constexpr bool test() {
62a2b3ab8fSHui   {
63a2b3ab8fSHui     std::string_view input = "abc def";
64*88171885SKonstantin Varlamov     std::ranges::split_view<std::string_view, std::string_view> v(input, " ");
65a2b3ab8fSHui     assert(v.base() == input);
66a2b3ab8fSHui     assert(std::ranges::equal(*v.begin(), std::string_view{"abc"}));
67a2b3ab8fSHui   }
68a2b3ab8fSHui 
69a2b3ab8fSHui   // Make sure the arguments are moved, not copied.
70a2b3ab8fSHui   {
71a2b3ab8fSHui     // Arguments are lvalues.
72a2b3ab8fSHui     {
73a2b3ab8fSHui       int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0;
74a2b3ab8fSHui       View view(view_copied, view_moved);
75a2b3ab8fSHui       Pattern pattern(pattern_copied, pattern_moved);
76a2b3ab8fSHui 
77a2b3ab8fSHui       std::ranges::split_view<View, Pattern> v(view, pattern);
78a2b3ab8fSHui       assert(view_copied == 1); // The local variable is copied into the argument.
79a2b3ab8fSHui       assert(view_moved == 1);
80a2b3ab8fSHui       assert(pattern_copied == 1);
81a2b3ab8fSHui       assert(pattern_moved == 1);
82a2b3ab8fSHui     }
83a2b3ab8fSHui 
84a2b3ab8fSHui     // Arguments are rvalues.
85a2b3ab8fSHui     {
86a2b3ab8fSHui       int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0;
87a2b3ab8fSHui       std::ranges::split_view<View, Pattern> v(View(view_copied, view_moved), Pattern(pattern_copied, pattern_moved));
88a2b3ab8fSHui       assert(view_copied == 0);
89a2b3ab8fSHui       assert(view_moved == 1);
90a2b3ab8fSHui       assert(pattern_copied == 0);
91a2b3ab8fSHui       assert(pattern_moved == 1);
92a2b3ab8fSHui     }
93a2b3ab8fSHui   }
94a2b3ab8fSHui 
95a2b3ab8fSHui   return true;
96a2b3ab8fSHui }
97a2b3ab8fSHui 
main(int,char **)98a2b3ab8fSHui int main(int, char**) {
99a2b3ab8fSHui   test();
100a2b3ab8fSHui   static_assert(test());
101a2b3ab8fSHui 
102a2b3ab8fSHui   return 0;
103a2b3ab8fSHui }
104