Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -8343,7 +8343,7 @@ namespace ranges {

template <viewable_range _Rng>
_NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_Rng&&) _CONST_CALL_OPERATOR noexcept
requires (_Nx == 0)
requires (_Nx == 0) && forward_range<_Rng>
{
return empty_view<tuple<>>{};
}
Expand Down Expand Up @@ -8679,7 +8679,8 @@ namespace ranges {
template <viewable_range _Rng, class _Fn>
_NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_Rng&&, _Fn&& _Func) _CONST_CALL_OPERATOR
noexcept(noexcept(views::zip_transform(_STD forward<_Fn>(_Func))))
requires (_Nx == 0) && requires { views::zip_transform(_STD forward<_Fn>(_Func)); }
requires (_Nx == 0)
&& forward_range<_Rng> && requires { views::zip_transform(_STD forward<_Fn>(_Func)); }
{
return views::zip_transform(_STD forward<_Fn>(_Func));
}
Expand Down
68 changes: 63 additions & 5 deletions tests/std/tests/P2321R2_views_adjacent/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static_assert(same_as<repeated_tuple<int, 5>, tuple<int, int, int, int, int>>);
// Check views::pairwise
static_assert(same_as<decltype(views::pairwise), decltype(views::adjacent<2>)>);

template <size_t N, ranges::input_range Rng, class Expected>
template <size_t N, ranges::forward_range Rng, class Expected>
constexpr bool test_one(Rng&& rng, Expected&& expected) {
using ranges::adjacent_view, ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range,
ranges::sized_range, ranges::common_range, ranges::iterator_t, ranges::sentinel_t, ranges::const_iterator_t,
Expand All @@ -55,7 +55,6 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) {
using R = adjacent_view<V, N>;

static_assert(ranges::view<R>);
static_assert(ranges::input_range<R>);
static_assert(forward_range<R>);
static_assert(bidirectional_range<R> == bidirectional_range<Rng>);
static_assert(random_access_range<R> == random_access_range<Rng>);
Expand Down Expand Up @@ -732,7 +731,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) {
return true;
}

template <ranges::input_range Rng>
template <ranges::forward_range Rng>
constexpr void test_adjacent0(Rng&& rng) {
static_assert(!CanConstructAdjacentView<Rng, 0>);
using V = views::all_t<Rng>;
Expand Down Expand Up @@ -783,7 +782,7 @@ constexpr void test_adjacent0(Rng&& rng) {
}
}

template <size_t N, ranges::input_range Rng>
template <size_t N, ranges::forward_range Rng>
requires indirectly_swappable<ranges::iterator_t<Rng>>
constexpr void test_iter_swap(Rng& rng) {
// This test assumes that 'ranges::size(views::adjacent<N>(rng))' is at least 2
Expand Down Expand Up @@ -841,7 +840,7 @@ using test_range =

struct instantiator {
#ifdef TEST_EVERYTHING
template <ranges::input_range R>
template <ranges::forward_range R>
static constexpr void call() {
R r{some_ints};
test_one<1>(r, adjacent1_result);
Expand Down Expand Up @@ -899,6 +898,62 @@ constexpr void instantiation_test() {
#endif // TEST_EVERYTHING
}

// LWG-4098 views::adjacent<0> should reject non-forward ranges
template <size_t N, ranges::input_range Rng>
constexpr void test_input_only(Rng&&) {
if constexpr (!ranges::forward_range<Rng>) {
static_assert(!CanViewAdjacent<Rng&, N>);
static_assert(!CanViewAdjacent<Rng, N>);
static_assert(!CanConstructAdjacentView<Rng&, N>);
static_assert(!CanConstructAdjacentView<Rng, N>);
}

if constexpr (!ranges::forward_range<const Rng>) {
static_assert(!CanViewAdjacent<const Rng&, N>);
static_assert(!CanViewAdjacent<const Rng, N>);
static_assert(!CanConstructAdjacentView<const Rng&, N>);
static_assert(!CanConstructAdjacentView<const Rng, N>);
}
}

struct input_only_instantiator {
#ifdef TEST_EVERYTHING
template <ranges::input_range R>
static constexpr void call() {
R r{some_ints};
test_input_only<0>(r);
test_input_only<1>(r);
test_input_only<2>(r);
test_input_only<4>(r);
test_input_only<7>(r);
}
#else // ^^^ test all input range permutations / test only "interesting" permutations vvv
template <class Tag, test::Common IsCommon, test::Sized IsSized>
static constexpr void call() {
test_range<const int, Tag, IsCommon, IsSized> r{some_ints};
test_input_only<0>(r);
test_input_only<1>(r);
test_input_only<2>(r);
test_input_only<4>(r);
test_input_only<7>(r);
}
#endif // TEST_EVERYTHING
};

constexpr void instantiation_input_only_test() {
#ifdef TEST_EVERYTHING
test_in<input_only_instantiator, const int>();
#else // ^^^ test all input range permutations / test only "interesting" permutations vvv
using test::Common, test::Sized;

// The view is sensitive to category, commonality, and size, but oblivious to proxyness and differencing
input_only_instantiator::call<input_iterator_tag, Common::no, Sized::yes>();
input_only_instantiator::call<input_iterator_tag, Common::no, Sized::no>();
input_only_instantiator::call<input_iterator_tag, Common::yes, Sized::yes>();
input_only_instantiator::call<input_iterator_tag, Common::yes, Sized::no>();
#endif // TEST_EVERYTHING
}

template <class Category, test::Common IsCommon, bool is_random = derived_from<Category, random_access_iterator_tag>>
using move_only_view = test::range<Category, const int, test::Sized{is_random}, test::CanDifference{is_random},
IsCommon, test::CanCompare::yes, test::ProxyRef{!derived_from<Category, contiguous_iterator_tag>},
Expand Down Expand Up @@ -939,4 +994,7 @@ int main() {

static_assert((instantiation_test(), true));
instantiation_test();

static_assert((instantiation_input_only_test(), true));
instantiation_input_only_test();
}
64 changes: 60 additions & 4 deletions tests/std/tests/P2321R2_views_adjacent_transform/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ using invoke_result_with_repeated_type = invoke_result_with_repeated_type_impl<F
static_assert(same_as<invoke_result_with_repeated_type<plus<int>, int, 2>, int>);
static_assert(same_as<invoke_result_with_repeated_type<equal_to<int>, int, 2>, bool>);

template <size_t N, ranges::input_range Rng, class Expected, class Fn>
template <size_t N, ranges::forward_range Rng, class Expected, class Fn>
constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) {
using ranges::adjacent_transform_view, ranges::adjacent_view, ranges::forward_range, ranges::bidirectional_range,
ranges::random_access_range, ranges::sized_range, ranges::common_range, ranges::iterator_t,
Expand All @@ -86,7 +86,6 @@ constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) {
using R = adjacent_transform_view<V, decay_t<Fn>, N>;

static_assert(ranges::view<R>);
static_assert(ranges::input_range<R>);
static_assert(forward_range<R>);
static_assert(bidirectional_range<R> == bidirectional_range<Rng>);
static_assert(random_access_range<R> == random_access_range<Rng>);
Expand Down Expand Up @@ -790,7 +789,7 @@ constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) {
return true;
}

template <ranges::input_range Rng>
template <ranges::forward_range Rng>
constexpr void test_adjacent0(Rng&& rng) {
auto func = [] { return 602; };
using Fn = decltype(func);
Expand Down Expand Up @@ -884,7 +883,7 @@ using test_range =
test::ProxyRef{!derived_from<Category, contiguous_iterator_tag>}>;

struct instantiator {
template <ranges::input_range R>
template <ranges::forward_range R>
static constexpr void call() {
R r{some_ints};
test_one<1>(r, adjacent1_fn, adjacent1_result);
Expand Down Expand Up @@ -926,6 +925,60 @@ constexpr void instantiation_test() {
#endif // TEST_EVERYTHING
}

// LWG-4098 views::adjacent<0> should reject non-forward ranges
template <size_t N, ranges::input_range Rng, class Fn>
constexpr void test_input_only(Rng&&, Fn&&) {
if constexpr (!ranges::forward_range<Rng>) {
static_assert(!CanViewAdjacentTransform<Rng&, Fn, N>);
static_assert(!CanViewAdjacentTransform<Rng, Fn, N>);
}

if constexpr (!ranges::forward_range<const Rng>) {
static_assert(!CanViewAdjacentTransform<const Rng&, Fn, N>);
static_assert(!CanViewAdjacentTransform<const Rng, Fn, N>);
}
}

struct input_only_instantiator {
#ifdef TEST_EVERYTHING
template <ranges::input_range R>
static constexpr void call() {
R r{some_ints};
auto nullary_fn = [] { return 1729; };
test_input_only<0>(r, nullary_fn);
test_input_only<1>(r, adjacent1_fn);
test_input_only<2>(r, pairwise_fn);
test_input_only<4>(r, adjacent4_fn);
test_input_only<7>(r, adjacent7_fn);
}
#else // ^^^ test all input range permutations / test only "interesting" permutations vvv
template <class Tag, test::Common IsCommon, test::Sized IsSized>
static constexpr void call() {
test_range<Tag, IsCommon, IsSized> r{some_ints};
auto nullary_fn = [] { return 1729; };
test_input_only<0>(r, nullary_fn);
test_input_only<1>(r, adjacent1_fn);
test_input_only<2>(r, pairwise_fn);
test_input_only<4>(r, adjacent4_fn);
test_input_only<7>(r, adjacent7_fn);
}
#endif // TEST_EVERYTHING
};

constexpr void instantiation_input_only_test() {
#ifdef TEST_EVERYTHING
test_in<input_only_instantiator, const int>();
#else // ^^^ test all input range permutations / test only "interesting" permutations vvv
using test::Common, test::Sized;

// The view is sensitive to category, commonality, and size, but oblivious to proxyness and differencing
input_only_instantiator::call<input_iterator_tag, Common::no, Sized::yes>();
input_only_instantiator::call<input_iterator_tag, Common::no, Sized::no>();
input_only_instantiator::call<input_iterator_tag, Common::yes, Sized::yes>();
input_only_instantiator::call<input_iterator_tag, Common::yes, Sized::no>();
#endif // TEST_EVERYTHING
}

template <class Category, test::Common IsCommon, bool IsRandom = derived_from<Category, random_access_iterator_tag>>
using move_only_view = test::range<Category, const int, test::Sized{IsRandom}, test::CanDifference{IsRandom}, IsCommon,
test::CanCompare::yes, test::ProxyRef{!derived_from<Category, contiguous_iterator_tag>}, test::CanView::yes,
Expand Down Expand Up @@ -988,4 +1041,7 @@ int main() {

static_assert((instantiation_test(), true));
instantiation_test();

static_assert((instantiation_input_only_test(), true));
instantiation_input_only_test();
}