5 #ifndef VCCC_RANGES_VIEWS_JOIN_VIEW_HPP_
6 #define VCCC_RANGES_VIEWS_JOIN_VIEW_HPP_
44 template<
typename Base>
45 using join_view_iterator_concept =
48 std::is_reference<range_reference_t<Base>>,
49 bidirectional_range<Base>,
50 bidirectional_range<range_reference_t<Base>>
55 std::is_reference<range_reference_t<Base>>,
57 forward_range<range_reference_t<Base>>
64 template<
typename Base,
typename IteratorConcept = join_view_iterator_concept<Base>>
65 struct join_view_iterator_category {
66 #if __cplusplus < 202002L
67 using iterator_category = iterator_ignore;
71 template<
typename Base>
74 using OuterC =
typename cxx20_iterator_traits<iterator_t<Base>>::iterator_category;
75 using InnerC =
typename cxx20_iterator_traits<iterator_t<range_reference_t<Base>>>::iterator_category;
78 using iterator_category =
81 derived_from<OuterC, bidirectional_iterator_tag>,
82 derived_from<InnerC, bidirectional_iterator_tag>
87 derived_from<OuterC, forward_iterator_tag>,
88 derived_from<InnerC, forward_iterator_tag>
108 template <
bool Const>
112 template<
bool Const>
class iterator;
114 template<
bool Const>
class sentinel;
117 class iterator : detail::join_view_iterator_category<maybe_const<Const, V>> {
122 static constexpr
bool ref_is_glvalue = std::is_reference<range_reference_t<Base>>
::value;
132 #if __cplusplus < 202002L
137 template<
typename O = OuterIter, std::enable_if_t<
conjunction<
142 : outer_(), inner_(), parent_(nullptr) {}
144 constexpr
iterator(Parent& parent, OuterIter outer)
150 template<
bool AntiConst, std::enable_if_t<
conjunction<
156 : outer_(
std::move(i.outer_)), inner_(
std::move(i.inner_)), parent_(i.parent_) {}
158 constexpr decltype(
auto) operator*()
const {
162 template<
typename II = InnerIter, std::enable_if_t<
conjunction<
166 constexpr decltype(
auto) operator->()
const {
170 template<
bool B = ref_is_glvalue, std::enable_if_t<B,
int> = 0>
172 auto&& inner_rng = *outer_;
180 template<
bool B = ref_is_glvalue, std::enable_if_t<B == false,
int> = 0>
182 auto&& inner_rng = *parent_->inner_;
190 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
199 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
210 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
225 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
241 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
247 return (x.outer_ == y.outer_) && (*x.inner_ == *y.inner_);
250 template<
bool B = ref_is_glvalue, std::enable_if_t<
conjunction<
260 noexcept(noexcept(ranges::
iter_move(*i.inner_)))
273 constexpr OuterIter& get_outer() noexcept {
276 constexpr
const OuterIter& get_outer() const noexcept {
277 return get_outer(forward_range<Base>{});
279 constexpr OuterIter& get_outer_impl(std::true_type ) noexcept {
282 constexpr OuterIter& get_outer_impl(std::false_type ) noexcept {
283 return *parent_->outer_;
285 constexpr OuterIter& get_outer_impl(std::true_type )
const noexcept {
288 constexpr OuterIter& get_outer_impl(std::false_type )
const noexcept {
289 return *parent_->outer_;
292 constexpr decltype(
auto) update_inner_impl(const
iterator_t<Base>& x,
std::true_type ) {
295 constexpr decltype(
auto) update_inner_impl(const
iterator_t<Base>& x,
std::false_type ) {
296 return parent_->inner_.emplace(x);
299 constexpr decltype(
auto) update_inner(const
iterator_t<Base>& x) {
300 return update_inner_impl(x, bool_constant<ref_is_glvalue>{});
303 constexpr
void satisfy_impl(std::true_type ) {
304 for (; outer_ !=
ranges::end(parent_->base_); ++outer_) {
305 auto&& inner = update_inner(outer_);
311 inner_ = InnerIter();
313 constexpr
void satisfy_impl(std::false_type ) {
314 for (; outer_ !=
ranges::end(parent_->base_); ++outer_) {
315 auto&& inner = update_inner(outer_);;
323 movable_box<InnerIter> inner_;
336 : end_(ranges::
end(parent.base_)) {}
338 template<
bool AntiConst, std::enable_if_t<
conjunction<
343 : end_(
std::move(s.end_)) {}
347 return x.get_outer() == y.end_;
377 return std::move(base_);
385 template<
typename V2 = V, std::enable_if_t<
conjunction<
387 std::is_reference<range_reference_t<const V2>>
403 template<
typename V2 = V, std::enable_if_t<
conjunction<
405 std::is_reference<range_reference_t<const V2>>
407 constexpr
auto end()
const {
418 constexpr
auto end_impl(std::true_type) {
421 constexpr
auto end_impl(std::false_type) {
425 constexpr
auto end_impl(std::true_type)
const {
428 constexpr
auto end_impl(std::false_type)
const {
429 return sentinel<true>{*
this};
435 #if __cplusplus >= 201703L
438 explicit join_view(R&&) -> join_view<views::all_t<R>>;
Definition: join_view.hpp:117
constexpr iterator & operator--()
Definition: join_view.hpp:216
void pointer
Definition: join_view.hpp:133
iterator()
Definition: join_view.hpp:141
common_type_t< range_difference_t< Base >, range_difference_t< range_reference_t< Base > >> difference_type
Definition: join_view.hpp:131
constexpr void operator++(int)
Definition: join_view.hpp:195
constexpr iterator(iterator< AntiConst > i)
Definition: join_view.hpp:155
constexpr friend bool operator==(const iterator &x, const iterator &y)
Definition: join_view.hpp:246
detail::join_view_iterator_concept< Base > iterator_concept
Definition: join_view.hpp:128
constexpr decltype(auto) friend iter_move(const iterator &i) noexcept(noexcept(ranges::iter_move(*i.inner_)))
Definition: join_view.hpp:259
constexpr friend bool operator!=(const iterator &x, const iterator &y)
Definition: join_view.hpp:255
constexpr friend void iter_swap(const iterator &x, const iterator &y) noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
Definition: join_view.hpp:266
constexpr iterator operator--(int)
Definition: join_view.hpp:231
constexpr iterator operator++(int)
Definition: join_view.hpp:204
constexpr void satisfy()
Definition: join_view.hpp:237
constexpr iterator & operator++()
Definition: join_view.hpp:171
decltype(**std::declval< movable_box< InnerIter > & >()) reference
Definition: join_view.hpp:134
constexpr iterator(Parent &parent, OuterIter outer)
Definition: join_view.hpp:144
range_value_t< range_reference_t< Base > > value_type
Definition: join_view.hpp:130
Definition: join_view.hpp:328
constexpr sentinel(Parent &parent)
Definition: join_view.hpp:335
constexpr friend bool operator==(const sentinel &y, const iterator< Const > &x)
Definition: join_view.hpp:350
constexpr friend bool operator==(const iterator< Const > &x, const sentinel &y)
Definition: join_view.hpp:345
constexpr sentinel(sentinel< AntiConst > s)
Definition: join_view.hpp:342
constexpr friend bool operator!=(const iterator< Const > &x, const sentinel &y)
Definition: join_view.hpp:354
constexpr friend bool operator!=(const sentinel &y, const iterator< Const > &x)
Definition: join_view.hpp:358
Definition: join_view.hpp:101
constexpr V base() const &
Definition: join_view.hpp:372
constexpr auto begin()
Definition: join_view.hpp:380
join_view()
Definition: join_view.hpp:367
constexpr V base() &&
Definition: join_view.hpp:376
constexpr auto end()
Definition: join_view.hpp:393
constexpr auto end() const
Definition: join_view.hpp:407
constexpr auto begin() const
Definition: join_view.hpp:389
constexpr join_view(V base)
Definition: join_view.hpp:369
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
constexpr VCCC_INLINE_OR_STATIC detail_iter_swap::iter_swap_niebloid iter_swap
Definition: iter_swap.hpp:90
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
typename range_difference< R >::type range_difference_t
Used to obtain the difference type of the iterator type of range type R.
Definition: range_difference_t.hpp:41
typename range_reference< R >::type range_reference_t
Used to obtain the reference type of the iterator type of range type R.
Definition: range_reference_t.hpp:42
typename range_value< R >::type range_value_t
Used to obtain the value type of the iterator type of range type R.
Definition: range_value_t.hpp:42
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
Definition: matrix.hpp:495
Definition: cxx20_rel_ops.hpp:17
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
Models std::convertible_to
Definition: convertible_to.hpp:38
specifies that an object of a type can be copied, moved, and swapped
Definition: copyable.hpp:59
specifies that an object of a type can be default constructed
Definition: default_initializable.hpp:62
specifies that operator == is an equivalence relation
Definition: equality_comparable.hpp:30
Definition: has_operator_arrow.hpp:18
specifies a range whose iterator type satisfies bidirectional_iterator
Definition: bidirectional_range.hpp:49
Definition: common_range.hpp:41
specifies a range whose iterator type satisfies forward_iterator
Definition: forward_range.hpp:47
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31