5 #ifndef CONCAT_WITH_VIEW_HPP
6 #define CONCAT_WITH_VIEW_HPP
10 #include <type_traits>
36 template<
typename Pattern,
typename... Rngs>
37 using concat_with_compatible = conjunction<
38 has_typename_type<common_type<range_value_t<Pattern>, range_value_t<Rngs>...>>,
39 has_typename_type<common_reference<range_reference_t<Pattern>, range_reference_t<Rngs>...>>,
40 has_typename_type<common_reference<range_rvalue_reference_t<Pattern>, range_rvalue_reference_t<Rngs>...>>
48 template<
typename Pattern,
typename... Rngs>
50 static_assert(
sizeof...(Rngs) != 0,
"Constraints not satisfied");
59 static constexpr std::size_t cranges =
sizeof...(Rngs);
60 std::tuple<Rngs...> bases_{};
64 template<
bool IsConst>
79 : end_(ranges::
end(
std::
get<cranges - 1>(parent.bases_))) {}
84 template<
bool AntiConst, std::enable_if_t<
conjunction<
89 : end_(
std::move(that.end_)) {}
92 template<
bool IsConst>
115 template<std::size_t N, std::enable_if_t<(N < cranges - 1),
int> = 0>
116 void satisfy(std::integral_constant<std::size_t, N>) {
117 if (std::get<N>(its_) ==
ranges::end(std::get<N>(parent_->bases_))) {
118 its_.template emplace<N + 1>(
ranges::begin(std::get<N + 1>(parent_->bases_)));
119 this->satisfy(std::integral_constant<size_t, N + 1>{});
123 template<std::
size_t N, std::enable_if_t<(N >= cranges - 1),
int> = 0>
124 void satisfy(std::integral_constant<std::size_t, N>) { }
126 struct next_raw_visitor {
129 template<
typename I, std::
size_t N>
132 pos->satisfy(std::integral_constant<size_t, N>{});
138 struct prev_raw_visitor {
146 template<
typename I, std::size_t N, std::enable_if_t<
conjunction<
151 if (it ==
ranges::begin(std::get<N>(pos->parent_->bases_))) {
152 auto&& rng =
std::get<N - 1>(pos->parent_->bases_);
155 vccc::detail::variant_raw_visit(pos->its_.
index(), pos->its_._base().storage(), *
this);
164 struct advance_fwd_raw_visitor {
175 auto last =
ranges::end(std::get<N>(pos->parent_->bases_));
181 pos->satisfy(std::integral_constant<size_t, N>{});
183 vccc::detail::variant_raw_visit(
184 pos->its_.
index(), pos->its_._base().storage(), advance_fwd_raw_visitor{pos, rest});
191 struct advance_rev_raw_visitor {
204 auto&& rng =
std::get<N - 1>(pos->parent_->bases_);
206 vccc::detail::variant_raw_visit(pos->its_.
index(), pos->its_._base().storage(), *
this);
210 vccc::detail::variant_raw_visit(
211 pos->its_.
index(), pos->its_._base().storage(), advance_rev_raw_visitor{pos, rest});
224 template<std::
size_t N>
226 if (from.its_.index() > N)
227 return iterator::distance_to_(std::integral_constant<size_t, N + 1>{}, from,
to);
229 if (from.its_.index() == N) {
230 if (
to.its_.index() == N)
231 return ranges::distance(vccc::detail::variant_raw_get(from.its_._base().storage(), in_place_index<N>),
232 vccc::detail::variant_raw_get(
to.its_._base().storage(), in_place_index<N>));
233 return ranges::distance(vccc::detail::variant_raw_get(from.its_._base().storage(), in_place_index<N>),
235 + iterator::distance_to_(std::integral_constant<size_t, N + 1>{}, from,
to);
238 if (from.its_.index() < N &&
to.its_.index() > N)
240 + iterator::distance_to_(std::integral_constant<size_t, N + 1>{}, from,
to);
243 vccc::detail::variant_raw_get(
to.its_._base().storage(), in_place_index<N>));
249 template<std::
size_t I,
typename It>
254 this->satisfy(std::integral_constant<size_t, I>{});
266 : parent_(that.parent_)
267 , its_(std::move(that.its_)) {}
269 constexpr decltype(
auto) operator*()
const {
273 template<
typename V = variant<iterator_t<maybe_const<IsConst, Rngs>>...>, std::enable_if_t<
274 equality_comparable<V>
277 return x.its_ == y.its_;
280 template<
typename V = variant<iterator_t<maybe_const<IsConst, Rngs>>...>, std::enable_if_t<
281 equality_comparable<V>
304 return its_.
index() == cranges - 1 &&
std::get<cranges - 1>(its_) == pos.end_;
308 vccc::detail::variant_raw_visit(its_.
index(), its_._base().storage(), next_raw_visitor{this});
312 template<
typename Dummy = void, std::enable_if_t<
conjunction<
320 template<
typename Dummy = void, std::enable_if_t<
conjunction<
330 template<
typename Dummy = void, std::enable_if_t<
conjunction<
335 vccc::detail::variant_raw_visit(its_.
index(), its_._base().storage(), prev_raw_visitor{this});
339 template<
typename Dummy = void, std::enable_if_t<
conjunction<
349 template<
typename Dummy = void, std::enable_if_t<
conjunction<
355 vccc::detail::variant_raw_visit(its_.
index(), its_._base().storage(), advance_fwd_raw_visitor{this, n});
357 vccc::detail::variant_raw_visit(its_.
index(), its_._base().storage(), advance_rev_raw_visitor{this, n});
362 template<
typename Dummy = void, std::enable_if_t<
conjunction<
371 template<
typename Dummy = void, std::enable_if_t<
conjunction<
377 return -iterator::distance_to_(std::integral_constant<std::size_t, 0>{}, x, y);
378 return iterator::distance_to_(std::integral_constant<std::size_t, 0>{}, y, x);
387 : bases_{
std::move(rngs)...} {}
394 template<
typename Dummy = void, std::enable_if_t<
conjunction<
402 template<
typename Dummy = void, std::enable_if_t<
conjunction<
411 template<
typename Dummy = void, std::enable_if_t<
conjunction<
420 template<
typename Dummy = void, std::enable_if_t<
conjunction<
424 constexpr
auto end()
const {
428 template<
typename Dummy = void, std::enable_if_t<
conjunction<
440 template<
typename Dummy = void, std::enable_if_t<
conjunction<
453 constexpr iterator<true> end_impl(std::true_type )
const {
462 #if __cplusplus >= 201703L
464 template<
typename... Rng>
474 template<
typename... R, std::enable_if_t<
conjunction<
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr decltype(auto) back()
Definition: view_interface.hpp:255
a type-safe discriminated union
Definition: variant.hpp:589
constexpr std::size_t index() const noexcept
Definition: variant.hpp:662
constexpr decltype(auto) visit(Visitor &&vis) &
Definition: variant.hpp:707
constexpr VCCC_INLINE_OR_STATIC detail::advance_niebloid advance
Definition: advance.hpp:158
constexpr VCCC_INLINE_OR_STATIC detail::next_niebloid next
Definition: next.hpp:65
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
std::random_access_iterator_tag random_access_iterator_tag
Definition: iterator_tag.hpp:19
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
constexpr std::enable_if_t<(detail::ranges_to_1_tag< C, R, Args... >::value > 0), C > to(R &&r, Args &&... args)
Constructs an object of type C from the elements of r
Definition: to.hpp:446
constexpr iterator & operator--()
Definition: concat_with_view.hpp:334
constexpr iterator(Parent *parent, in_place_index_t< I >, It &&it)
Definition: concat_with_view.hpp:250
common_type_t< range_difference_t< Rngs >... > difference_type
Definition: concat_with_view.hpp:105
constexpr iterator & operator--(int)
Definition: concat_with_view.hpp:343
concat_with_view()=default
std::conditional_t< conjunction< random_access_range< Rngs >... >::value, random_access_iterator_tag, std::conditional_t< conjunction< bidirectional_range< Rngs >... >::value, bidirectional_iterator_tag, std::conditional_t< conjunction< forward_range< Rngs >... >::value, forward_iterator_tag, input_iterator_tag > >> iterator_concept
Definition: concat_with_view.hpp:103
void pointer
Definition: concat_with_view.hpp:107
constexpr friend bool operator==(const sentinel< IsConst > &y, const iterator &x)
Definition: concat_with_view.hpp:295
constexpr auto get(const subrange< I, S, K > &r)
Definition: subrange.hpp:371
constexpr auto size() const
Definition: concat_with_view.hpp:444
constexpr auto size()
Definition: concat_with_view.hpp:432
common_reference_t< range_reference_t< maybe_const< IsConst, Rngs > >... > reference
Definition: concat_with_view.hpp:106
constexpr friend difference_type operator-(const iterator &x, const iterator &y)
Definition: concat_with_view.hpp:375
constexpr void operator++(int)
Definition: concat_with_view.hpp:316
constexpr auto begin()
Definition: concat_with_view.hpp:389
concat_with_view(Rngs... rngs)
Definition: concat_with_view.hpp:386
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
iterator * pos
Definition: concat_with_view.hpp:127
difference_type n
Definition: concat_with_view.hpp:166
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr friend bool operator==(const iterator &x, const iterator &y)
Definition: concat_with_view.hpp:276
void operator()(I &it, in_place_index_t< 0 >)
Definition: concat_with_view.hpp:196
constexpr VCCC_INLINE_OR_STATIC detail::distance_niebloid distance
Definition: distance.hpp:72
common_type_t< range_value_t< maybe_const< IsConst, Rngs > >... > value_type
Definition: concat_with_view.hpp:104
constexpr friend bool operator!=(const iterator &x, const iterator &y)
Definition: concat_with_view.hpp:283
constexpr auto end()
Definition: concat_with_view.hpp:406
void operator()(I &it, in_place_index_t< 0 >)
Definition: concat_with_view.hpp:142
constexpr iterator & operator-=(difference_type n)
Definition: concat_with_view.hpp:366
constexpr friend bool operator==(const iterator &x, const sentinel< IsConst > &y)
Definition: concat_with_view.hpp:287
constexpr VCCC_INLINE_OR_STATIC detail::concat_with_niebloid concat_with
concatenate ranges
Definition: concat_with_view.hpp:486
constexpr auto end() const
Definition: concat_with_view.hpp:424
void operator()(I &it, in_place_index_t< N >)
Definition: concat_with_view.hpp:174
constexpr friend bool operator!=(const sentinel< IsConst > &y, const iterator &x)
Definition: concat_with_view.hpp:299
constexpr iterator & operator+=(difference_type n)
Definition: concat_with_view.hpp:353
input_iterator_tag iterator_category
Definition: concat_with_view.hpp:94
constexpr iterator< true > begin() const
Definition: concat_with_view.hpp:398
void operator()(I &it, in_place_index_t< N >)
Definition: concat_with_view.hpp:130
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
void operator()(U &, in_place_index_t< variant_npos >)
Definition: concat_with_view.hpp:135
constexpr iterator(iterator< Other > that)
Definition: concat_with_view.hpp:265
constexpr bool equal(const sentinel< IsConst > &pos) const
Definition: concat_with_view.hpp:303
constexpr friend bool operator!=(const iterator &x, const sentinel< IsConst > &y)
Definition: concat_with_view.hpp:291
constexpr iterator & operator++()
Definition: concat_with_view.hpp:307
constexpr VCCC_INLINE_OR_STATIC detail::all_adaptor_closure all
a view that includes all elements of a range
Definition: all.hpp:82
void operator()(I &it, in_place_index_t< cranges - 1 >)
Definition: concat_with_view.hpp:169
constexpr auto tuple_fold_left(Tuple &&tuple, T &&init, F &&f)
Left fold operation for each tuple elements.
Definition: tuple_fold.hpp:52
constexpr auto tuple_transform(Tuple &&t, F &&f) noexcept(noexcept(detail::tuple_transform_impl(std::forward< Tuple >(t), std::forward< F >(f), std::make_index_sequence< std::tuple_size< remove_cvref_t< Tuple >>::value >{})))
Constructs a new tuple with each elements transformed.
Definition: tuple_transform.hpp:36
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
std::conditional_t< Const, const V, V > maybe_const
Definition: maybe_const.hpp:16
constexpr VCCC_INLINE_OR_STATIC in_place_index_t< I > in_place_index
Definition: in_place.hpp:53
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
constexpr std::enable_if_t<(I< m *n), typename vccc::Matrix< T, m, n >::value_type & > get(vccc::Matrix< T, m, n > &matrix)
Definition: matrix.hpp:499
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 0 > first
Definition: key_value.hpp:34
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
specifies that a forward_iterator is a bidirectional iterator, supporting movement backwards
Definition: bidirectional_iterator.hpp:58
Definition: conjunction.hpp:22
Models std::convertible_to
Definition: convertible_to.hpp:38
Definition: in_place.hpp:35
Definition: negation.hpp:23
specifies a range whose iterator type satisfies bidirectional_iterator
Definition: bidirectional_range.hpp:49
Definition: common_range.hpp:41
Definition: concat_view.hpp:50
Definition: concat_with_view.hpp:93
constexpr iterator operator++(int)
Definition: concat_with_view.hpp:324
Definition: concat_with_view.hpp:68
Definition: concat_with_view.hpp:49
constexpr auto end()
Definition: concat_with_view.hpp:415
specifies a range whose iterator type satisfies forward_iterator
Definition: forward_range.hpp:47
specifies a range whose iterator type satisfies random_access_iterator
Definition: random_access_range.hpp:48
specifies that a type is a range, that is, it provides a begin iterator and an end sentinel
Definition: range.hpp:53
specifies that a range knows its size in constant time
Definition: sized_range.hpp:38
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31
specifies the requirements for a range to be safely convertible to a view
Definition: viewable_range.hpp:59
Definition: concat_with_view.hpp:473
constexpr auto operator()(R &&... rs) const
Definition: concat_with_view.hpp:478
specifies that the - operator can be applied to an iterator and a sentinel to calculate their differe...
Definition: sized_sentinel_for.hpp:75
Definition: type_sequence.hpp:110