Skip to content

Commit

Permalink
code update for random_access
Browse files Browse the repository at this point in the history
  • Loading branch information
huixie90 committed Jun 9, 2023
1 parent 1a1d09f commit bdbfd61
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
20 changes: 15 additions & 5 deletions impl/concat/concat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ concept concat_is_random_access = (all_random_access<Const, Views> && ...) &&
(all_but_last<sized_range<__maybe_const<Const, Views>>...>);

template <class R>
concept constant_time_reversible = (bidirectional_range<R> && common_range<R>) ||
(sized_range<R> && random_access_range<R>);
concept constant_time_reversible =
(bidirectional_range<R> && common_range<R>) || (sized_range<R> && random_access_range<R>);

template <class... Rs>
concept concat_bidirectional =
Expand Down Expand Up @@ -510,7 +510,15 @@ class concat_view : public view_interface<concat_view<Views...>> {
// distance(y, yend) + size(ranges_in_between)... + distance(xbegin, x)
const auto all_sizes = std::apply(
[&](const auto&... views) {
return std::array{static_cast<difference_type>(ranges::size(views))...};
const auto getSize = [](const auto& view) {
if constexpr (ranges::sized_range<decay_t<decltype(view)>>) {
return ranges::size(view);
} else {
return 0u; // only the last range can be non-sized, and its value is
// not used
}
};
return std::array{static_cast<difference_type>(getSize(views))...};
},
x.get_parent_views());
auto in_between = std::accumulate(all_sizes.data() + iy + 1, all_sizes.data() + ix,
Expand Down Expand Up @@ -538,7 +546,8 @@ class concat_view : public view_interface<concat_view<Views...>> {
}

friend constexpr difference_type operator-(const iterator& it, default_sentinel_t)
requires xo::concat_is_random_access<Const, Views...>
requires(xo::concat_is_random_access<Const, Views...> &&
sized_range<xo::back<__maybe_const<Const, Views>...>>)
{

const auto idx = it.it_.index();
Expand All @@ -558,7 +567,8 @@ class concat_view : public view_interface<concat_view<Views...>> {
}

friend constexpr difference_type operator-(default_sentinel_t, const iterator& it)
requires xo::concat_is_random_access<Const, Views...>
requires(xo::concat_is_random_access<Const, Views...> &&
sized_range<xo::back<__maybe_const<Const, Views>...>>)
{
return -(it - default_sentinel);
}
Expand Down
40 changes: 30 additions & 10 deletions impl/concat/test/basics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
namespace {

template <typename... R>
concept concat_viewable = requires(R&&... r) {
std::ranges::views::concat((R &&) r...);
};
concept concat_viewable = requires(R&&... r) { std::ranges::views::concat((R&&)r...); };


template <typename R>
Expand Down Expand Up @@ -163,14 +161,36 @@ TEST_POINT("end_last_range_non_common_but_random_sized") {

TEST_POINT("end_last_range_non_common_but_random_and_not_sized") {
std::vector<int> v1{1};
auto io = std::views::iota(0);
std::vector<int> v2{2, 3};
auto io = std::views::iota(4);
static_assert(!std::ranges::sized_range<decltype(io)>);
std::ranges::concat_view cv1{v1, io};
std::ranges::concat_view cv2{io, v1};
std::ranges::concat_view cv1{v1, v2, io};
std::ranges::concat_view cv2{io, v1, v2};
static_assert(std::ranges::random_access_range<decltype(cv1)>);
static_assert(!std::ranges::random_access_range<decltype(cv2)>);
static_assert(std::ranges::sized_range<decltype(cv1)>);
static_assert(
!std::ranges::sized_range<decltype(cv1)>); // should not be sized! (fixed after constrained
// the operator- (default_sentinel) properly)
static_assert(!std::ranges::sized_range<decltype(cv2)>);

auto it1 = cv1.begin();
auto it2 = it1 + 1;
CHECK(*it2 == 2);

auto it3 = it1 + 5;
CHECK(*it3 == 6);

auto it4 = it3 - 1;
CHECK(*it4 == 5);

auto it5 = it3 - 3;
CHECK(*it5 == 3);

auto it6 = it3 - 5;
CHECK(*it6 == 1);

CHECK(it3 -it1 == 5);
CHECK(it3 -it2 == 4);
}


Expand Down Expand Up @@ -336,13 +356,13 @@ TEST_POINT("bidirectional_noncommon_random_access_sized") {
}


struct NonCommonRandomSized : std::ranges::view_base{
struct NonCommonRandomSized : std::ranges::view_base {
const int* begin() const;
std::nullptr_t end() const;
std::size_t size() const;
};

TEST_POINT("random_but_not_bidi_impossible"){
TEST_POINT("random_but_not_bidi_impossible") {
using namespace std::ranges;
static_assert(!common_range<NonCommonRandomSized>);
static_assert(random_access_range<NonCommonRandomSized>);
Expand Down Expand Up @@ -729,7 +749,7 @@ TEST_POINT("cpp20 input range") {


TEST_POINT("size") {
std::vector v1 = {1,2};
std::vector v1 = {1, 2};
auto cv1 = std::ranges::concat_view(std::views::all(v1));
CHECK(cv1.size() == 2);

Expand Down

0 comments on commit bdbfd61

Please sign in to comment.