211 lines
7.3 KiB
C++
211 lines
7.3 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
|
|
|
// template<input_range V, forward_range Pattern>
|
|
// requires view<V> && view<Pattern> &&
|
|
// indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
|
|
// (forward_range<V> || tiny-range<Pattern>)
|
|
// class lazy_split_view;
|
|
|
|
#include <functional>
|
|
#include <ranges>
|
|
|
|
#include "test_iterators.h"
|
|
#include "types.h"
|
|
|
|
struct ForwardRange {
|
|
forward_iterator<int*> begin() const;
|
|
forward_iterator<int*> end() const;
|
|
};
|
|
static_assert( std::ranges::forward_range<ForwardRange>);
|
|
|
|
template <class View, class Pattern>
|
|
concept CanInstantiate = requires {
|
|
typename std::ranges::lazy_split_view<View, Pattern>;
|
|
};
|
|
|
|
// All constraints satisfied (`View` and `Pattern` are forward views).
|
|
namespace test1 {
|
|
|
|
using View = ForwardView;
|
|
using Pattern = ForwardView;
|
|
static_assert( std::ranges::forward_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert( CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test1
|
|
|
|
// All constraints satisfied (`View` is an input view and `Pattern` is a tiny view).
|
|
namespace test2 {
|
|
|
|
using View = InputView;
|
|
using Pattern = ForwardTinyView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert( CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test2
|
|
|
|
// `View` is not an input range.
|
|
namespace test3 {
|
|
|
|
struct AlmostInputIterator {
|
|
using value_type = char;
|
|
using difference_type = ptrdiff_t;
|
|
using iterator_concept = int;
|
|
|
|
constexpr const char& operator*() const;
|
|
constexpr AlmostInputIterator& operator++();
|
|
constexpr void operator++(int);
|
|
constexpr bool operator==(const AlmostInputIterator&) const;
|
|
};
|
|
|
|
static_assert( std::input_or_output_iterator<AlmostInputIterator>);
|
|
static_assert(!std::input_iterator<AlmostInputIterator>);
|
|
|
|
struct NonInputView : std::ranges::view_base {
|
|
AlmostInputIterator begin() const;
|
|
AlmostInputIterator end() const;
|
|
};
|
|
|
|
using View = NonInputView;
|
|
using Pattern = ForwardTinyView;
|
|
static_assert(!std::ranges::input_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test3
|
|
|
|
// `View` is not a view.
|
|
namespace test4 {
|
|
|
|
using View = ForwardRange;
|
|
using Pattern = ForwardView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
static_assert(!std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test4
|
|
|
|
// `Pattern` is not a forward range.
|
|
namespace test5 {
|
|
|
|
using View = ForwardView;
|
|
using Pattern = InputView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert(!std::ranges::forward_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test5
|
|
|
|
// Not indirectly comparable.
|
|
namespace test6 {
|
|
|
|
struct Empty{};
|
|
struct IntForwardView : std::ranges::view_base {
|
|
constexpr forward_iterator<Empty*> begin() const { return {}; }
|
|
constexpr forward_iterator<Empty*> end() const { return {}; }
|
|
};
|
|
|
|
using View = ForwardView;
|
|
using Pattern = IntForwardView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert(!std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test6
|
|
|
|
// `View` is an input range and `Pattern` is not a tiny range.
|
|
namespace test7 {
|
|
|
|
using View = InputView;
|
|
using Pattern = ForwardView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert(!std::ranges::forward_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test7
|
|
|
|
// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` function is not `constexpr`.
|
|
namespace test8 {
|
|
|
|
struct AlmostTinyRange : std::ranges::view_base {
|
|
int* begin() const;
|
|
int* end() const;
|
|
static size_t size() { return 1; }
|
|
};
|
|
|
|
using View = InputView;
|
|
using Pattern = AlmostTinyRange;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert(!std::ranges::forward_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test8
|
|
|
|
// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` returns a number `>2`.
|
|
namespace test9 {
|
|
|
|
struct AlmostTinyRange : std::ranges::view_base {
|
|
int* begin() const;
|
|
int* end() const;
|
|
constexpr static size_t size() { return 2; }
|
|
};
|
|
|
|
using View = InputView;
|
|
using Pattern = ForwardView;
|
|
static_assert( std::ranges::input_range<View>);
|
|
static_assert(!std::ranges::forward_range<View>);
|
|
static_assert( std::ranges::forward_range<Pattern>);
|
|
LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
|
|
static_assert( std::ranges::view<View>);
|
|
static_assert( std::ranges::view<Pattern>);
|
|
static_assert( std::indirectly_comparable<
|
|
std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
|
|
static_assert(!CanInstantiate<View, Pattern>);
|
|
|
|
} // namespace test9
|