Skip to content

Commit

Permalink
implement more functions
Browse files Browse the repository at this point in the history
  • Loading branch information
changkhothuychung committed Nov 20, 2024
1 parent cb611e3 commit bfbec38
Showing 1 changed file with 134 additions and 23 deletions.
157 changes: 134 additions & 23 deletions libcxx/include/__ranges/concat_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_object.h>
#include <__type_traits/maybe_const.h>
#include <__type_traits/is_nothrow_convertible.h>
#include <__type_traits/is_nothrow_convertible.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
Expand Down Expand Up @@ -306,11 +308,11 @@ template <input_range... Views>
get<N>(it_) += static_cast<underlying_diff_type>(steps);
}
else {
auto n_size = ranges::__distance(get<N>(parent_->views_));
difference_type n_size = ranges::size(get<N>(parent_->views_));
if (offset + steps < n_size) {
get<N>(it_) += static_cast<underlying_diff_type>(steps);
} else {
it_.emplace<N + 1>(ranges::begin(get<N + 1>(parent_->views_)));
it_.template emplace<N + 1>(ranges::begin(get<N + 1>(parent_->views_)));
advance_fwd<N + 1>(0, offset + steps - n_size);
}
}
Expand All @@ -326,7 +328,7 @@ template <input_range... Views>
if (offset >= steps) {
get<N>(it_) -= static_cast<underlying_diff_type>(steps);
} else {
auto prev_size = ranges::distance(get<N - 1>(parent_->views_));
auto prev_size = ranges::__distance(get<N - 1>(parent_->views_));
it_.emplace<N - 1>(ranges::begin(get<N - 1>(parent_->views_)) + prev_size);
advance_bwd<N - 1>(prev_size, steps - offset);
}
Expand Down Expand Up @@ -422,6 +424,7 @@ template <input_range... Views>
constexpr void apply_advance_fwd_by_index(size_t index, Func&& func) {
apply_advance_fwd_by_index(index, std::forward<Func>(func), std::make_index_sequence<N>{});
}


constexpr iterator& operator+=(difference_type n)
requires concat_is_random_access<Const, Views...>
Expand Down Expand Up @@ -452,48 +455,156 @@ template <input_range... Views>
return *this;
}

/*
constexpr iterator operator--(int)
requires concat-is-bidirectional<Const, Views...>;
requires concat_is_bidirectional<Const, Views...>
{
size_t active_index = it_.index();
apply_advance_fwd_by_index<std::variant_size_v<decltype(it_)>>(active_index, [&](auto index_constant){
constexpr size_t i = index_constant.value;
prev<i>();
});
return *this;
}

constexpr iterator& operator-=(difference_type n)
requires concat-is-random-access<Const, Views...>;
requires concat_is_random_access<Const, Views...>
{
*this += -n;
return *this;
}

friend constexpr bool operator==(const iterator& it, default_sentinel_t);
friend constexpr bool operator==(const iterator& it, default_sentinel_t)
{
constexpr auto last_idx = sizeof...(Views) - 1;
return it.it_.index() == last_idx &&
std::get<last_idx>(it.it_) == ranges::end(std::get<last_idx>(it.parent_->views_));
}

friend constexpr bool operator<(const iterator& x, const iterator& y)
requires all-random-access<Const, Views...>;
requires (random_access_range<__maybe_const<Const, Views>> && ...)
{
return x.it_ < y.it_;
}

friend constexpr bool operator>(const iterator& x, const iterator& y)
requires all-random-access<Const, Views...>;
requires (random_access_range<__maybe_const<Const, Views>> && ...)
{
return x.it_ > y.it_;
}

friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires all-random-access<Const, Views...>;
requires (random_access_range<__maybe_const<Const, Views>> && ...)
{
return x.it_ <= y.it_;
}

friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires (random_access_range<__maybe_const<Const, Views>> && ...)
{
return x.it_ >= y.it_;
}

friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires all-random-access<Const, Views...>;

friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires (all-random-access<Const, Views...> &&
(three_way_comparable<maybe-const<Const, Views>> &&...));
requires ((random_access_range<__maybe_const<Const, Views>> && ...) &&
(three_way_comparable<__maybe_const<Const, Views>> &&...))
{
return x.it_ <=> y.it_;
}


friend constexpr iterator operator-(const iterator& it, difference_type n)
requires concat_is_random_access<Const, Views...>
{
auto temp = it;
temp -= n;
return temp;
}


friend constexpr decltype(auto) iter_move(const iterator& it)

{
return std::visit(
[](const auto& i) ->
concat_rvalue_reference_t<__maybe_const<Const, Views>...> {
return ranges::iter_move(i);
},
it.it_);
}


friend constexpr void iter_swap(const iterator& x, const iterator& y)
requires swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>> &&
(... && indirectly_swappable<iterator_t<__maybe_const<Const, Views>>>)
{
std::visit(
[&](const auto& it1, const auto& it2) {
if constexpr (is_same_v<decltype(it1), decltype(it2)>) {
ranges::iter_swap(it1, it2);
} else {
ranges::swap(*x, *y);
}
},
x.it_, y.it_);
}

friend constexpr iterator operator-(const iterator& it, difference_type n)
requires concat-is-random-access<Const, Views...>;

friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires concat-is-random-access<Const, Views...>;

friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires concat_is_random_access<Const, Views...>
{
size_t ix = x.it_.index();
size_t iy = y.it_.index();

if(ix > iy)
{
std::visit(
[&](auto& it_x, auto& it_y) {
it_x.apply_advance_fwd_by_index<std::tuple_size_v<decltype(x.parent_->views_)>>(ix, [&](auto index_constant){
constexpr size_t index_x = index_constant.value;
auto dx = ranges::__distance(ranges::begin(std::get<index_x>(x.parent_->views_)), it_x);

it_y.apply_advance_fwd_by_index<std::tuple_size_v<decltype(y.parent_->views_)>>(iy, [&](auto index_constant){
constexpr size_t index_y = index_constant.value;
auto dy = ranges::__distance(ranges::begin(std::get<index_y>(y.parent_->views_)), it_y);
difference_type s = 0;
for(size_t idx = index_y + 1; idx < index_x; idx++)
{
s += ranges::size(std::get<idx>(x.parent_->views_));
}
return dy + s + dx;
});
});
},
x.it_, y.it_);
}
else if(ix < iy)
{
return -(y - x);
}
else
{
std::visit(
[&](const auto& it1, const auto& it2) {
return it1 - it2;
},
x.it_, y.it_);
}

}




/*
friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
requires see below;
friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
requires see below;
friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
requires see below;
*/
};
Expand Down

0 comments on commit bfbec38

Please sign in to comment.