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, c++20 10 11 // <ranges> 12 13 // chunk_by_view() requires std::default_initializable<View> && 14 // std::default_initializable<Pred> = default; 15 16 #include <ranges> 17 18 #include <cassert> 19 #include <cstddef> 20 #include <type_traits> 21 22 constexpr int buff[] = {-2, 1, -1, 2}; 23 24 struct DefaultConstructibleView : std::ranges::view_base { 25 DefaultConstructibleView() = default; 26 constexpr int const* begin() const { return buff; } 27 constexpr int const* end() const { return buff + 4; } 28 }; 29 30 struct DefaultConstructiblePredicate { 31 DefaultConstructiblePredicate() = default; 32 constexpr bool operator()(int x, int y) const { return x != -y; } 33 }; 34 35 struct NoDefaultView : std::ranges::view_base { 36 NoDefaultView() = delete; 37 int* begin() const; 38 int* end() const; 39 }; 40 41 struct NoDefaultPredicate { 42 NoDefaultPredicate() = delete; 43 constexpr bool operator()(int, int) const; 44 }; 45 46 struct NoexceptView : std::ranges::view_base { 47 NoexceptView() noexcept; 48 int const* begin() const; 49 int const* end() const; 50 }; 51 52 struct NoexceptPredicate { 53 NoexceptPredicate() noexcept; 54 bool operator()(int, int) const; 55 }; 56 57 struct MayThrowView : std::ranges::view_base { 58 MayThrowView() noexcept(false); 59 int const* begin() const; 60 int const* end() const; 61 }; 62 63 struct MayThrowPredicate { 64 MayThrowPredicate() noexcept(false); 65 bool operator()(int, int) const; 66 }; 67 68 constexpr void compareRanges(std::ranges::subrange<const int*> v, std::initializer_list<int> list) { 69 assert(v.size() == list.size()); 70 for (size_t i = 0; i < v.size(); ++i) { 71 assert(v[i] == list.begin()[i]); 72 } 73 } 74 75 constexpr bool test() { 76 // Check default constructor with default initialization 77 { 78 using View = std::ranges::chunk_by_view<DefaultConstructibleView, DefaultConstructiblePredicate>; 79 View view; 80 auto it = view.begin(), end = view.end(); 81 compareRanges(*it++, {-2, 1}); 82 compareRanges(*it++, {-1, 2}); 83 assert(it == end); 84 } 85 86 // Check default construction with copy-list-initialization 87 { 88 using View = std::ranges::chunk_by_view<DefaultConstructibleView, DefaultConstructiblePredicate>; 89 View view = {}; 90 auto it = view.begin(), end = view.end(); 91 compareRanges(*it++, {-2, 1}); 92 compareRanges(*it++, {-1, 2}); 93 assert(it == end); 94 } 95 96 // Check cases where the default constructor isn't provided 97 { 98 static_assert( 99 !std::is_default_constructible_v<std::ranges::chunk_by_view<NoDefaultView, DefaultConstructiblePredicate>>); 100 static_assert( 101 !std::is_default_constructible_v<std::ranges::chunk_by_view<DefaultConstructibleView, NoDefaultPredicate>>); 102 static_assert(!std::is_default_constructible_v<std::ranges::chunk_by_view<NoDefaultView, NoDefaultPredicate>>); 103 } 104 105 // Check noexcept-ness 106 { 107 { 108 using View = std::ranges::chunk_by_view<MayThrowView, MayThrowPredicate>; 109 static_assert(!noexcept(View())); 110 } 111 { 112 using View = std::ranges::chunk_by_view<MayThrowView, NoexceptPredicate>; 113 static_assert(!noexcept(View())); 114 } 115 { 116 using View = std::ranges::chunk_by_view<NoexceptView, MayThrowPredicate>; 117 static_assert(!noexcept(View())); 118 } 119 { 120 using View = std::ranges::chunk_by_view<NoexceptView, NoexceptPredicate>; 121 static_assert(noexcept(View())); 122 } 123 } 124 125 return true; 126 } 127 128 int main(int, char**) { 129 test(); 130 static_assert(test()); 131 132 return 0; 133 } 134