From e767c3cbbc844f8d8e21bf5df18e332b5f4a88f0 Mon Sep 17 00:00:00 2001 From: slymz Date: Thu, 8 Jun 2023 23:47:34 -0700 Subject: [PATCH] Removed last range being sized from concat-is-random-access. (incomplete implementation, expected failing test) --- concat.lwg.feedback.md | 2 +- concat.md | 28 ++++++++++++++++++++-------- impl/concat/concat.hpp | 24 +++++++++++++++++------- impl/concat/test/basics.cpp | 13 +++++++++++++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/concat.lwg.feedback.md b/concat.lwg.feedback.md index ca4cb59..490473e 100644 --- a/concat.lwg.feedback.md +++ b/concat.lwg.feedback.md @@ -76,7 +76,7 @@ - [Done] that "expect" needs to be "except" - Hui: could not find any expect - Levent: I checked earliest revisions. No "expect" indeed. Not sure what this was. - - Hui: I found that in the mattermost chat, Thomasz suggested wording for concat-bidi which has expect. It should refer to that. I also used his suggested wording now + - Hui: I found that in the mattermost chat, Tomasz suggested wording for concat-bidi which has expect. It should refer to that. I also used his suggested wording now # Todos diff --git a/concat.md b/concat.md index d8e3d8a..90eeb60 100644 --- a/concat.md +++ b/concat.md @@ -533,9 +533,7 @@ namespace std::ranges { concept @_concatable_@ = @*see below*@; // exposition only template - concept @_concat-is-random-access_@ = // exposition only - ((random_access_range<@*maybe-const*@> && - sized_range<@*maybe-const*@>) && ...); + concept @_concat-is-random-access_@ = @*see below*@; // exposition only template concept @_constant-time-reversible_@ = // exposition only @@ -639,7 +637,16 @@ concept @_concat-is-bidirectional_@ = @*see below*@; // exposition only :::bq -[3]{.pnum} Let `V` be the last element of `Rs`, and `Fs` be the pack that consists of all elements of `Rs` except `V`, then `@_concat-is-bidirectional_@` is equivalent to: +[3]{.pnum} Let `Fs` be the pack that consists of all elements of `Rs` except the last, then `@_concat-is-random-access_@` is equivalent to: + +```cpp +template +concept @_concat-is-random-access_@ = // exposition only + (@*all-random-access*@ && ...) && + (sized_range<@*maybe-const*@> && ...) +``` + +[4]{.pnum} Let `V` be the last element of `Rs`, and `Fs` be the pack that consists of all elements of `Rs` except `V`, then `@_concat-is-bidirectional_@` is equivalent to: ```cpp template @@ -655,7 +662,7 @@ constexpr explicit concat_view(Views... views); :::bq -[4]{.pnum} *Effects*: Initializes `@*views_*@` with `std::move(views)...`. +[5]{.pnum} *Effects*: Initializes `@*views_*@` with `std::move(views)...`. ::: @@ -667,7 +674,7 @@ constexpr @_iterator_@ begin() const :::bq -[5]{.pnum} *Effects*: Let `@*is-const*@` be `true` for the const-qualified overload, +[6]{.pnum} *Effects*: Let `@*is-const*@` be `true` for the const-qualified overload, and `false` otherwise. Equivalent to: ```cpp @@ -685,7 +692,7 @@ constexpr auto end() const requires(range&&...); :::bq -[6]{.pnum} *Effects*: Let `@*is-const*@` be `true` for the const-qualified overload, +[7]{.pnum} *Effects*: Let `@*is-const*@` be `true` for the const-qualified overload, and `false` otherwise, and let `@_last-view_@` be the last element of the pack `const Views...` for the const-qualified overload, and the last element of the pack `Views...` otherwise. Equivalent to: @@ -709,7 +716,7 @@ constexpr auto size() const requires(sized_range&&...); :::bq -[7]{.pnum} *Effects*: Equivalent to: +[8]{.pnum} *Effects*: Equivalent to: ```cpp return apply( @@ -1403,6 +1410,11 @@ only if: For every combination of two types `X` and `Y` in the set of all types in the parameter pack `iterator_t<@_maybe-const_@>>...`, `indirectly_swappable` is modelled. +requires(indirectly_swappable>> && ... && + swappable_with...>, + xo::concat_reference_t<__maybe_const...>>) + + ::: ## Feature Test Macro diff --git a/impl/concat/concat.hpp b/impl/concat/concat.hpp index cdfdf76..43c5d4f 100644 --- a/impl/concat/concat.hpp +++ b/impl/concat/concat.hpp @@ -16,6 +16,13 @@ namespace std::ranges { namespace xo { // exposition only things (and persevering face) +template +concept all_random_access = (random_access_range<__maybe_const> && ...); +template +concept all_bidirectional = (bidirectional_range<__maybe_const> && ...); +template +concept all_forward = (forward_range<__maybe_const> && ...); + inline namespace not_to_spec { template @@ -63,24 +70,27 @@ template using back = tuple_element_t>; template -consteval bool all_but_last(std::index_sequence) { +consteval bool all_but_last_impl(std::index_sequence) { return ((I == sizeof...(I) - 1 || b) && ...); } + +template +constexpr bool all_but_last = all_but_last_impl(make_index_sequence{}); + } // namespace not_to_spec template -concept concat_is_random_access = ((random_access_range<__maybe_const> && - sized_range<__maybe_const>)&&...); +concept concat_is_random_access = (all_random_access && ...) && + (all_but_last>...>); template -concept constant_time_reversible = - (bidirectional_range && common_range) || (sized_range && random_access_range); +concept constant_time_reversible = (bidirectional_range && common_range) || + (sized_range && random_access_range); template concept concat_bidirectional = - all_but_last...>(index_sequence_for{}) && - bidirectional_range>; + all_but_last...> && bidirectional_range>; static_assert(true); // clang-format badness diff --git a/impl/concat/test/basics.cpp b/impl/concat/test/basics.cpp index 538b432..dab2593 100644 --- a/impl/concat/test/basics.cpp +++ b/impl/concat/test/basics.cpp @@ -161,6 +161,19 @@ TEST_POINT("end_last_range_non_common_but_random_sized") { REQUIRE(it2 == st2); } +TEST_POINT("end_last_range_non_common_but_random_and_not_sized") { + std::vector v1{1}; + auto io = std::views::iota(0); + static_assert(!std::ranges::sized_range); + std::ranges::concat_view cv1{v1, io}; + std::ranges::concat_view cv2{io, v1}; + static_assert(std::ranges::random_access_range); + static_assert(!std::ranges::random_access_range); + static_assert(std::ranges::sized_range); + static_assert(!std::ranges::sized_range); +} + + TEST_POINT("operator++") { using V = std::vector; V v1{}, v2{4, 5}, v3{}, v4{6};