Iros
 
Loading...
Searching...
No Matches
filter_view.h
Go to the documentation of this file.
1#pragma once
2
12#include "di/function/invoke.h"
13#include "di/util/addressof.h"
14#include "di/util/move.h"
18#include "di/util/store_if.h"
19
20namespace di::container {
21template<concepts::InputContainer View, concepts::IndirectUnaryPredicate<meta::ContainerIterator<View>> Pred>
22requires(concepts::View<View> && concepts::Object<Pred>)
23class FilterView : public ViewInterface<FilterView<View, Pred>> {
24private:
25 using SSizeType = meta::ContainerSSizeType<View>;
26 using Value = meta::ContainerValue<View>;
29
30 class Iterator
31 : public IteratorBase<Iterator,
32 meta::Conditional<concepts::BidirectionalIterator<Iter>, BidirectionalIteratorTag,
33 meta::Conditional<concepts::ForwardIterator<Iter>, ForwardIteratorTag,
34 InputIteratorTag>>,
35 Value, SSizeType> {
36 public:
37 Iterator()
39 = default;
40
41 constexpr Iterator(FilterView& parent, Iter base)
42 : m_parent(util::addressof(parent)), m_base(util::move(base)) {}
43
44 constexpr auto base() const& -> Iter const& { return m_base; }
45 constexpr auto base() && -> Iter { return util::move(m_base); }
46
47 constexpr auto operator*() const -> decltype(auto) { return *m_base; }
48 constexpr auto operator->() const -> Iter
50 (concepts::Pointer<Iter> || requires(Iter iter) { iter.operator->(); }) && concepts::Copyable<Iter>)
51 {
52 return m_base;
53 }
54
55 constexpr void advance_one() {
56 m_base = container::find_if(util::move(++m_base), container::end(m_parent->m_base),
57 util::ref(m_parent->m_predicate.value()));
58 }
59
60 constexpr void back_one()
62 {
63 do {
64 --m_base;
65 } while (!function::invoke(m_parent->m_predicate.value(), *m_base));
66 }
67
68 private:
69 constexpr friend auto operator==(Iterator const& a, Iterator const& b) -> bool { return a.base() == b.base(); }
70
71 constexpr friend auto tag_invoke(types::Tag<iterator_move>, Iterator const& a) -> meta::IteratorRValue<Iter> {
73 }
74
75 constexpr friend void tag_invoke(Iterator const& a, Iterator const& b)
77 {
78 return container::iterator_swap(a, b);
79 }
80
81 FilterView* m_parent;
82 Iter m_base;
83 };
84
85 class Sentinel : public SentinelExtension<Sentinel, Sent, Iterator, Iter> {
86 private:
88
89 public:
90 using Base::Base;
91 };
92
93public:
96 = default;
97
98 constexpr explicit FilterView(View base, Pred predicate)
99 : m_base(util::move(base)), m_predicate(util::move(predicate)) {}
100
101 constexpr auto base() const& -> View
102 requires(concepts::CopyConstructible<View>)
103 {
104 return m_base;
105 }
106 constexpr auto base() && -> View { return util::move(m_base); }
107
108 constexpr auto pred() const -> Pred const& { return m_predicate.value(); }
109
110 constexpr auto begin() -> Iterator {
111 if constexpr (!concepts::ForwardContainer<View>) {
112 return Iterator(*this, container::find_if(m_base, util::ref(m_predicate.value())));
113 } else {
114 if (!m_cache.value.has_value()) {
115 m_cache.value = container::find_if(m_base, util::ref(m_predicate.value()));
116 }
117 return Iterator(*this, m_cache.value.value());
118 }
119 }
120
121 constexpr auto end() {
122 if constexpr (concepts::CommonContainer<View>) {
123 return Iterator(*this, container::end(m_base));
124 } else {
125 return Sentinel(container::end(m_base));
126 }
127 }
128
129private:
130 View m_base {};
131 util::RebindableBox<Pred> m_predicate;
133};
134
135template<typename Con, typename Pred>
137}
Definition filter_view.h:23
constexpr auto begin() -> Iterator
Definition filter_view.h:110
constexpr FilterView(View base, Pred predicate)
Definition filter_view.h:98
constexpr auto base() const &-> View requires(concepts::CopyConstructible< View >)
Definition filter_view.h:101
constexpr auto pred() const -> Pred const &
Definition filter_view.h:108
constexpr auto end()
Definition filter_view.h:121
constexpr auto base() &&-> View
Definition filter_view.h:106
Definition sentinel_extension.h:10
Definition view_interface.h:26
Definition view.h:35
Definition rebindable_box.h:42
Definition bidirectional_iterator.h:8
Definition common_container.h:10
Definition operations.h:40
Definition operations.h:27
Definition forward_container.h:8
Definition forward_iterator.h:10
Definition indirectly_swappable.h:7
Definition language.h:61
Definition any_storable.h:9
Definition sequence.h:12
constexpr auto iterator_move
Definition iterator_move.h:56
constexpr auto move
Definition move.h:38
FilterView(Con &&, Pred) -> FilterView< meta::AsView< Con >, Pred >
constexpr auto find_if
Definition find_if.h:31
constexpr auto operator==(MoveIterator< Iter > const &a, MoveIterator< U > const &b) -> bool
Definition move_iterator.h:85
constexpr auto iterator_swap
Definition iterator_swap.h:49
constexpr auto end
Definition end.h:47
auto tag_invoke(types::Tag< util::deduce_create >, InPlaceTemplate< NodeHashMap >, Con &&) -> NodeHashMap< meta::TupleElement< T, 0 >, meta::TupleElement< T, 1 > >
constexpr auto invoke
Definition invoke.h:100
IteratorSSizeType< ContainerIterator< T > > ContainerSSizeType
Definition container_ssize_type.h:8
decltype(container::end(util::declval< T & >())) ContainerSentinel
Definition container_sentinel.h:8
decltype(container::iterator_move(util::declval< T & >())) IteratorRValue
Definition iterator_rvalue.h:9
IteratorValue< ContainerIterator< T > > ContainerValue
Definition container_value.h:8
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto ref
Definition reference_wrapper.h:98
Definition iterator_base.h:14
Definition store_if.h:7