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 11 #include <algorithm> 12 #include <array> 13 #include <cassert> 14 #include <concepts> 15 #include <deque> 16 #include <ranges> 17 #include <vector> 18 19 #include "test_iterators.h" 20 #include "type_algorithms.h" 21 22 template <class InContainer, class OutContainer> 23 constexpr void test_containers() { 24 using InIter = typename InContainer::iterator; 25 using OutIter = typename OutContainer::iterator; 26 27 { 28 InContainer in{1, 2, 3, 4}; 29 OutContainer out(4); 30 31 std::same_as<std::ranges::in_out_result<InIter, OutIter>> auto ret = 32 std::ranges::copy(in.begin(), in.end(), out.begin()); 33 assert(std::ranges::equal(in, out)); 34 assert(ret.in == in.end()); 35 assert(ret.out == out.end()); 36 } 37 { 38 InContainer in{1, 2, 3, 4}; 39 OutContainer out(4); 40 std::same_as<std::ranges::in_out_result<InIter, OutIter>> auto ret = std::ranges::copy(in, out.begin()); 41 assert(std::ranges::equal(in, out)); 42 assert(ret.in == in.end()); 43 assert(ret.out == out.end()); 44 } 45 } 46 47 template <class Iter, class Sent> 48 constexpr void test_join_view() { 49 auto to_subranges = std::views::transform([](auto& vec) { 50 return std::ranges::subrange(Iter(vec.data()), Sent(Iter(vec.data() + vec.size()))); 51 }); 52 53 { // segmented -> contiguous 54 std::vector<std::vector<int>> vectors = {}; 55 auto range = vectors | to_subranges; 56 std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end()); 57 std::array<int, 0> arr; 58 59 std::ranges::copy(subrange_vector | std::views::join, arr.begin()); 60 assert(std::ranges::equal(arr, std::array<int, 0>{})); 61 } 62 { // segmented -> contiguous 63 std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}}; 64 auto range = vectors | to_subranges; 65 std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end()); 66 std::array<int, 10> arr; 67 68 std::ranges::copy(subrange_vector | std::views::join, arr.begin()); 69 assert(std::ranges::equal(arr, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); 70 } 71 { // contiguous -> segmented 72 std::vector<std::vector<int>> vectors = {{0, 0, 0, 0}, {0, 0}, {0, 0, 0, 0}, {}}; 73 auto range = vectors | to_subranges; 74 std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end()); 75 std::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 76 77 std::ranges::copy(arr, (subrange_vector | std::views::join).begin()); 78 assert(std::ranges::equal(subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); 79 } 80 { // segmented -> segmented 81 std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}}; 82 auto range1 = vectors | to_subranges; 83 std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range1.begin(), range1.end()); 84 std::vector<std::vector<int>> to_vectors = {{0, 0, 0, 0}, {0, 0, 0, 0}, {}, {0, 0}}; 85 auto range2 = to_vectors | to_subranges; 86 std::vector<std::ranges::subrange<Iter, Sent>> to_subrange_vector(range2.begin(), range2.end()); 87 88 std::ranges::copy(subrange_vector | std::views::join, (to_subrange_vector | std::views::join).begin()); 89 assert(std::ranges::equal(to_subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); 90 } 91 } 92 93 int main(int, char**) { 94 if (!std::is_constant_evaluated()) { 95 test_containers<std::deque<int>, std::deque<int>>(); 96 test_containers<std::deque<int>, std::vector<int>>(); 97 test_containers<std::vector<int>, std::deque<int>>(); 98 test_containers<std::vector<int>, std::vector<int>>(); 99 } 100 101 meta::for_each(meta::forward_iterator_list<int*>{}, []<class Iter> { 102 test_join_view<Iter, Iter>(); 103 test_join_view<Iter, sentinel_wrapper<Iter>>(); 104 test_join_view<Iter, sized_sentinel<Iter>>(); 105 }); 106 107 return 0; 108 } 109