214 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// This is a compile-only test, so "inline function is not defined" warnings are irrelevant.12// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-undefined-inline13 14// template<input_range V, forward_range Pattern>15// requires view<V> && view<Pattern> &&16// indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&17// (forward_range<V> || tiny-range<Pattern>)18// class lazy_split_view;19 20#include <functional>21#include <ranges>22 23#include "test_iterators.h"24#include "types.h"25 26struct ForwardRange {27 forward_iterator<int*> begin() const;28 forward_iterator<int*> end() const;29};30static_assert( std::ranges::forward_range<ForwardRange>);31 32template <class View, class Pattern>33concept CanInstantiate = requires {34 typename std::ranges::lazy_split_view<View, Pattern>;35};36 37// All constraints satisfied (`View` and `Pattern` are forward views).38namespace test1 {39 40 using View = ForwardView;41 using Pattern = ForwardView;42 static_assert( std::ranges::forward_range<View>);43 static_assert( std::ranges::forward_range<Pattern>);44 static_assert( std::ranges::view<View>);45 static_assert( std::ranges::view<Pattern>);46 static_assert( std::indirectly_comparable<47 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);48 static_assert( CanInstantiate<View, Pattern>);49 50} // namespace test151 52// All constraints satisfied (`View` is an input view and `Pattern` is a tiny view).53namespace test2 {54 55 using View = InputView;56 using Pattern = ForwardTinyView;57 static_assert( std::ranges::input_range<View>);58 static_assert( std::ranges::forward_range<Pattern>);59 static_assert( std::ranges::view<View>);60 static_assert( std::ranges::view<Pattern>);61 static_assert( std::indirectly_comparable<62 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);63 static_assert( CanInstantiate<View, Pattern>);64 65} // namespace test266 67// `View` is not an input range.68namespace test3 {69 70 struct AlmostInputIterator {71 using value_type = char;72 using difference_type = std::ptrdiff_t;73 using iterator_concept = int;74 75 constexpr const char& operator*() const;76 constexpr AlmostInputIterator& operator++();77 constexpr void operator++(int);78 constexpr bool operator==(const AlmostInputIterator&) const;79 };80 81 static_assert( std::input_or_output_iterator<AlmostInputIterator>);82 static_assert(!std::input_iterator<AlmostInputIterator>);83 84 struct NonInputView : std::ranges::view_base {85 AlmostInputIterator begin() const;86 AlmostInputIterator end() const;87 };88 89 using View = NonInputView;90 using Pattern = ForwardTinyView;91 static_assert(!std::ranges::input_range<View>);92 static_assert( std::ranges::forward_range<Pattern>);93 static_assert( std::ranges::view<View>);94 static_assert( std::ranges::view<Pattern>);95 static_assert( std::indirectly_comparable<96 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);97 static_assert(!CanInstantiate<View, Pattern>);98 99} // namespace test3100 101// `View` is not a view.102namespace test4 {103 104 using View = ForwardRange;105 using Pattern = ForwardView;106 static_assert( std::ranges::input_range<View>);107 static_assert( std::ranges::forward_range<Pattern>);108 static_assert(!std::ranges::view<View>);109 static_assert( std::ranges::view<Pattern>);110 static_assert( std::indirectly_comparable<111 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);112 static_assert(!CanInstantiate<View, Pattern>);113 114} // namespace test4115 116// `Pattern` is not a forward range.117namespace test5 {118 119 using View = ForwardView;120 using Pattern = InputView;121 static_assert( std::ranges::input_range<View>);122 static_assert(!std::ranges::forward_range<Pattern>);123 static_assert( std::ranges::view<View>);124 static_assert( std::ranges::view<Pattern>);125 static_assert( std::indirectly_comparable<126 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);127 static_assert(!CanInstantiate<View, Pattern>);128 129} // namespace test5130 131// Not indirectly comparable.132namespace test6 {133 134 struct Empty{};135 struct IntForwardView : std::ranges::view_base {136 constexpr forward_iterator<Empty*> begin() const { return {}; }137 constexpr forward_iterator<Empty*> end() const { return {}; }138 };139 140 using View = ForwardView;141 using Pattern = IntForwardView;142 static_assert( std::ranges::input_range<View>);143 static_assert( std::ranges::forward_range<Pattern>);144 static_assert( std::ranges::view<View>);145 static_assert( std::ranges::view<Pattern>);146 static_assert(!std::indirectly_comparable<147 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);148 static_assert(!CanInstantiate<View, Pattern>);149 150} // namespace test6151 152// `View` is an input range and `Pattern` is not a tiny range.153namespace test7 {154 155 using View = InputView;156 using Pattern = ForwardView;157 static_assert( std::ranges::input_range<View>);158 static_assert(!std::ranges::forward_range<View>);159 static_assert( std::ranges::forward_range<Pattern>);160 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);161 static_assert( std::ranges::view<View>);162 static_assert( std::ranges::view<Pattern>);163 static_assert( std::indirectly_comparable<164 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);165 static_assert(!CanInstantiate<View, Pattern>);166 167} // namespace test7168 169// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` function is not `constexpr`.170namespace test8 {171 172 struct AlmostTinyRange : std::ranges::view_base {173 int* begin() const;174 int* end() const;175 static std::size_t size() { return 1; }176 };177 178 using View = InputView;179 using Pattern = AlmostTinyRange;180 static_assert( std::ranges::input_range<View>);181 static_assert(!std::ranges::forward_range<View>);182 static_assert( std::ranges::forward_range<Pattern>);183 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);184 static_assert( std::ranges::view<View>);185 static_assert( std::ranges::view<Pattern>);186 static_assert( std::indirectly_comparable<187 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);188 static_assert(!CanInstantiate<View, Pattern>);189 190} // namespace test8191 192// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` returns a number `>2`.193namespace test9 {194 195 struct AlmostTinyRange : std::ranges::view_base {196 int* begin() const;197 int* end() const;198 constexpr static std::size_t size() { return 2; }199 };200 201 using View = InputView;202 using Pattern = ForwardView;203 static_assert( std::ranges::input_range<View>);204 static_assert(!std::ranges::forward_range<View>);205 static_assert( std::ranges::forward_range<Pattern>);206 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);207 static_assert( std::ranges::view<View>);208 static_assert( std::ranges::view<Pattern>);209 static_assert( std::indirectly_comparable<210 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);211 static_assert(!CanInstantiate<View, Pattern>);212 213} // namespace test9214