lxgui
Loading...
Searching...
No Matches
utils_view.hpp
1#ifndef LXGUI_UTILS_VIEW_HPP
2#define LXGUI_UTILS_VIEW_HPP
3
4#include "lxgui/lxgui.hpp"
5
6#include <utility>
7
9
11template<typename BaseIterator>
13 using data_type = decltype(*std::declval<BaseIterator>());
14 static data_type dereference(const BaseIterator& iter) {
15 return *iter;
16 }
17};
18
20template<typename BaseIterator>
22 using data_type = decltype(*std::declval<BaseIterator>()->get());
23 static data_type dereference(const BaseIterator& iter) {
24 return *iter->get();
25 }
26};
27
29template<typename BaseIterator>
31 using data_type = decltype(**std::declval<BaseIterator>());
32 static data_type dereference(const BaseIterator& iter) {
33 return **iter;
34 }
35};
36
38template<typename BaseIterator>
39struct no_filter {
40 static bool is_included(const BaseIterator&) {
41 return true;
42 }
43};
44
46template<typename BaseIterator>
48 static bool is_included(const BaseIterator& iter) {
49 return *iter != nullptr;
50 }
51};
52
54template<
55 typename ContainerType,
56 template<typename>
57 class Dereferencer,
58 template<typename>
59 class Filter>
60class adaptor {
61public:
62 using base_iterator = std::conditional_t<
63 std::is_const_v<ContainerType>,
64 typename ContainerType::const_iterator,
65 typename ContainerType::iterator>;
66 using dereferencer = Dereferencer<base_iterator>;
67 using filter = Filter<base_iterator>;
68 using data_type = typename dereferencer::data_type;
69
70 explicit adaptor(ContainerType& collection) : collection_(collection) {}
71 explicit adaptor(ContainerType& collection, dereferencer&& deref, filter&& filt) :
72 collection_(collection), deref_(std::move(deref)), filter_(std::move(filt)) {}
73
74 adaptor(const adaptor& other) : collection_(other.collection_) {}
75 adaptor(adaptor&& other) : collection_(other.collection_) {}
76 adaptor& operator=(const adaptor& other) {
77 collection_ = other.collection_;
78 return *this;
79 }
81 collection_ = other.collection_;
82 return *this;
83 }
84
85 class iterator {
86 public:
87 explicit iterator(const adaptor& adaptor, base_iterator iter) :
88 adaptor_(adaptor), iter_(iter) {}
89
91 do {
92 ++iter_;
93 } while (iter_ != adaptor_.collection_.end() && !adaptor_.filter_.is_included(iter_));
94
95 return *this;
96 }
97
99 iterator old = *this;
100 this-> operator++();
101 return old;
102 }
103
104 bool operator==(const iterator& other) const {
105 return iter_ == other.iter_;
106 }
107 bool operator!=(const iterator& other) const {
108 return iter_ != other.iter_;
109 }
110
112 return adaptor_.deref_.dereference(iter_);
113 }
115 return adaptor_.deref_.dereference(iter_);
116 }
117
118 private:
119 const adaptor& adaptor_;
120 base_iterator iter_;
121 };
122
123 iterator begin() const {
124 iterator iter(*this, collection_.begin());
125 if (collection_.begin() != collection_.end() && !filter_.is_included(collection_.begin())) {
126 ++iter;
127 }
128 return iter;
129 }
130
131 iterator end() const {
132 return iterator(*this, collection_.end());
133 }
134
135private:
136 ContainerType& collection_;
137 dereferencer deref_;
138 filter filter_;
139};
140
141} // namespace lxgui::utils::view
142
143#endif
bool operator==(const iterator &other) const
iterator(const adaptor &adaptor, base_iterator iter)
bool operator!=(const iterator &other) const
Allow iterating over a container without access to the container itself.
adaptor(const adaptor &other)
adaptor & operator=(adaptor &&other)
adaptor(ContainerType &collection, dereferencer &&deref, filter &&filt)
Dereferencer< base_iterator > dereferencer
std::conditional_t< std::is_const_v< ContainerType >, typename ContainerType::const_iterator, typename ContainerType::iterator > base_iterator
adaptor & operator=(const adaptor &other)
typename dereferencer::data_type data_type
Filter< base_iterator > filter
adaptor(ContainerType &collection)
STL namespace.
static bool is_included(const BaseIterator &)
static bool is_included(const BaseIterator &iter)
De-reference an iterator twice.
decltype(**std::declval< BaseIterator >()) data_type
static data_type dereference(const BaseIterator &iter)
Convert unique_ptr or shared_ptr to standard pointer.
static data_type dereference(const BaseIterator &iter)
decltype(*std::declval< BaseIterator >() ->get()) data_type
De-reference an iterator normally.
decltype(*std::declval< BaseIterator >()) data_type
static data_type dereference(const BaseIterator &iter)