IndirectContainer.hpp
1 #pragma once
2 #include <array>
3 #include <memory>
4 #include <vector>
5 
6 namespace score
7 {
8 template <typename base_iterator_t>
10 {
12  using iterator = self_type;
13  using const_iterator = self_type;
14  using value_type = std::remove_reference_t<
15  decltype(*std::declval<typename base_iterator_t::value_type>())>;
16  using reference = value_type&;
17  using pointer = value_type*;
18  using iterator_category = std::forward_iterator_tag;
19  using difference_type = int;
20 
21  base_iterator_t it;
22 
23  self_type operator++() noexcept
24  {
25  ++it;
26  return *this;
27  }
28  self_type operator++(int) noexcept
29  {
30  self_type i = *this;
31  it++;
32  return i;
33  }
34 
35  value_type& operator*() const noexcept { return **it; }
36  value_type* operator->() const noexcept { return *it; }
37  bool operator==(const self_type& rhs) const noexcept { return it == rhs.it; }
38  bool operator!=(const self_type& rhs) const noexcept { return it != rhs.it; }
39  bool operator<(const self_type& rhs) const noexcept { return it < rhs.it; }
40 };
41 
42 template <typename T>
43 indirect_iterator<T> make_indirect_iterator(const T& it) noexcept
44 {
45  return indirect_iterator<T>{it};
46 }
47 
48 template <typename base_iterator_t>
50 {
52  using iterator = self_type;
53  using const_iterator = self_type;
54  using value_type = std::remove_reference_t<decltype(*std::declval<base_iterator_t>())>;
55  using reference = value_type&;
56  using pointer = value_type*;
57  using iterator_category = std::forward_iterator_tag;
58  using difference_type = int;
59 
60  base_iterator_t it;
61 
62  self_type operator++() noexcept
63  {
64  ++it;
65  return *this;
66  }
67  self_type operator++(int) noexcept
68  {
69  self_type i = *this;
70  it++;
71  return i;
72  }
73 
74  auto& operator*() const noexcept { return **it; }
75  auto operator->() const noexcept { return it; }
76  bool operator==(const self_type& rhs) const noexcept { return it == rhs.it; }
77  bool operator!=(const self_type& rhs) const noexcept { return it != rhs.it; }
78  bool operator<(const self_type& rhs) const noexcept { return it < rhs.it; }
79 };
80 
81 template <typename T>
82 indirect_ptr_iterator<T> make_indirect_ptr_iterator(const T& it)
83 {
84  return indirect_ptr_iterator<T>{it};
85 }
86 
87 template <typename base_iterator_t>
89 {
91  using iterator = self_type;
92  using const_iterator = self_type;
93  using value_type = std::remove_reference_t<
94  decltype(*std::declval<typename base_iterator_t::value_type::second_type>())>;
95  using reference = value_type&;
96  using pointer = value_type*;
97  using iterator_category = std::forward_iterator_tag;
98  using difference_type = int;
99 
100  base_iterator_t it;
101 
102  self_type operator++() noexcept
103  {
104  ++it;
105  return *this;
106  }
107  self_type operator++(int) noexcept
108  {
109  self_type i = *this;
110  it++;
111  return i;
112  }
113 
114  auto& operator*() const noexcept { return *it->second; }
115  auto operator->() const noexcept { return it->second; }
116  bool operator==(const self_type& rhs) const noexcept { return it == rhs.it; }
117  bool operator!=(const self_type& rhs) const noexcept { return it != rhs.it; }
118  bool operator<(const self_type& rhs) const noexcept { return it < rhs.it; }
119 };
120 
121 template <typename T>
122 indirect_map_iterator<T> make_indirect_map_iterator(const T& it)
123 {
124  return indirect_map_iterator<T>{it};
125 }
126 
127 template <typename T, typename U = std::allocator<T*>>
128 class IndirectContainer : std::vector<T*, U>
129 {
130 public:
131  using ctnr_t = std::vector<T*, U>;
132  using ctnr_t::ctnr_t;
133  using ctnr_t::reserve;
134  using ctnr_t::resize;
135  using value_type = T;
136 
137  auto begin() noexcept { return make_indirect_ptr_iterator(ctnr_t::begin()); }
138  auto end() noexcept { return make_indirect_ptr_iterator(ctnr_t::end()); }
139  auto begin() const noexcept { return make_indirect_ptr_iterator(ctnr_t::begin()); }
140  auto end() const noexcept { return make_indirect_ptr_iterator(ctnr_t::end()); }
141 
142  auto rbegin() noexcept { return make_indirect_ptr_iterator(ctnr_t::rbegin()); }
143  auto rend() noexcept { return make_indirect_ptr_iterator(ctnr_t::rend()); }
144  auto rbegin() const noexcept { return make_indirect_ptr_iterator(ctnr_t::rbegin()); }
145  auto rend() const noexcept { return make_indirect_ptr_iterator(ctnr_t::rend()); }
146 
147  auto cbegin() const noexcept { return make_indirect_ptr_iterator(ctnr_t::cbegin()); }
148  auto cend() const noexcept { return make_indirect_ptr_iterator(ctnr_t::cend()); }
149 
150  auto size() const noexcept { return ctnr_t::size(); }
151  auto empty() const noexcept { return ctnr_t::empty(); }
152 
153  auto push_back(T* ptr) { return ctnr_t::push_back(ptr); }
154 
155  auto& front() const noexcept { return *ctnr_t::front(); }
156  auto& back() const noexcept { return *ctnr_t::back(); }
157 
158  auto& operator[](int pos) noexcept { return *ctnr_t::operator[](pos); }
159  auto& operator[](int pos) const noexcept { return *ctnr_t::operator[](pos); }
160 };
161 
162 template <class Container>
164 {
165 public:
166  Container& container;
167 
168  auto begin() { return make_indirect_iterator(container.begin()); }
169  auto end() { return make_indirect_iterator(container.end()); }
170  auto begin() const { return make_indirect_iterator(container.begin()); }
171  auto end() const { return make_indirect_iterator(container.end()); }
172  auto cbegin() const { return make_indirect_iterator(container.cbegin()); }
173  auto cend() const { return make_indirect_iterator(container.cend()); }
174 };
175 
176 template <typename T>
177 auto wrap_indirect(T& container)
178 {
179  return IndirectContainerWrapper<T>{container};
180 }
181 
182 template <typename T, int N>
184 {
185  std::array<T*, N> array;
186 
187 public:
188  using value_type = T;
189  template <typename... Args>
190  IndirectArray(Args&&... args) noexcept
191  : array{{std::forward<Args>(args)...}}
192  {
193  }
194 
195  auto begin() noexcept { return make_indirect_ptr_iterator(array.begin()); }
196  auto end() noexcept { return make_indirect_ptr_iterator(array.end()); }
197  auto begin() const noexcept { return make_indirect_ptr_iterator(array.begin()); }
198  auto end() const noexcept { return make_indirect_ptr_iterator(array.end()); }
199  auto cbegin() const noexcept { return make_indirect_ptr_iterator(array.cbegin()); }
200  auto cend() const noexcept { return make_indirect_ptr_iterator(array.cend()); }
201 
202  auto& operator[](int pos) noexcept { return *array[pos]; }
203  auto& operator[](int pos) const noexcept { return *array[pos]; }
204 };
205 
206 template <typename Map_T>
208 {
209 public:
210  auto begin() noexcept { return make_indirect_iterator(map.begin()); }
211  auto begin() const noexcept { return make_indirect_iterator(map.begin()); }
212 
213  auto cbegin() noexcept { return make_indirect_iterator(map.cbegin()); }
214  auto cbegin() const noexcept { return make_indirect_iterator(map.cbegin()); }
215 
216  auto end() noexcept { return make_indirect_iterator(map.end()); }
217  auto end() const noexcept { return make_indirect_iterator(map.end()); }
218 
219  auto cend() noexcept { return make_indirect_iterator(map.cend()); }
220  auto cend() const noexcept { return make_indirect_iterator(map.cend()); }
221 
222  auto empty() const noexcept { return map.empty(); }
223 
224  template <typename K>
225  auto find(K&& key) const noexcept
226  {
227  return map.find(std::forward<K>(key));
228  }
229 
230  template <typename E>
231  auto insert(E&& elt)
232  {
233  return map.insert(std::forward<E>(elt));
234  }
235 
236 protected:
237  Map_T map;
238 };
239 
240 template <typename Map_T>
242 {
243  using base_iterator_t = typename Map_T::iterator;
244  using base_const_iterator_t = typename Map_T::const_iterator;
245 
246 public:
247  using value_type = typename base_iterator_t::value_type;
248  IndirectUnorderedMap() noexcept = default;
249 
250  auto begin() noexcept { return make_indirect_map_iterator(map.begin()); }
251  auto begin() const noexcept { return make_indirect_map_iterator(map.begin()); }
252 
253  auto cbegin() noexcept { return make_indirect_map_iterator(map.cbegin()); }
254  auto cbegin() const noexcept { return make_indirect_map_iterator(map.cbegin()); }
255 
256  auto end() noexcept { return make_indirect_map_iterator(map.end()); }
257  auto end() const noexcept { return make_indirect_map_iterator(map.end()); }
258 
259  auto cend() noexcept { return make_indirect_map_iterator(map.cend()); }
260  auto cend() const noexcept { return make_indirect_map_iterator(map.cend()); }
261 
262  auto empty() const noexcept { return map.empty(); }
263 
264  template <typename K>
265  auto find(K&& key) const noexcept
266  {
267  return make_indirect_map_iterator(map.find(std::forward<K>(key)));
268  }
269 
270  template <typename E>
271  auto insert(E&& elt)
272  {
273  return map.insert(std::forward<E>(elt));
274  }
275 
276 protected:
277  Map_T map;
278 
279 private:
282  IndirectUnorderedMap& operator=(const IndirectUnorderedMap&) = delete;
283  IndirectUnorderedMap& operator=(IndirectUnorderedMap&&) = delete;
284 };
285 }
Definition: IndirectContainer.hpp:184
Definition: IndirectContainer.hpp:129
Definition: IndirectContainer.hpp:164
Definition: IndirectContainer.hpp:208
Definition: IndirectContainer.hpp:242
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: IndirectContainer.hpp:10
Definition: IndirectContainer.hpp:89
Definition: IndirectContainer.hpp:50