AIToolbox
A library that offers tools for AI problem solving.
IndexMap.hpp
Go to the documentation of this file.
1 #ifndef AI_TOOLBOX_UTILS_INDEX_MAP_HEADER_FILE
2 #define AI_TOOLBOX_UTILS_INDEX_MAP_HEADER_FILE
3 
4 #include <AIToolbox/Types.hpp>
5 
6 #include <utility>
7 #include <type_traits>
8 
9 namespace AIToolbox {
13  template <typename IdsIterator, typename Container>
15  public:
16  using iterator_category = typename IdsIterator::iterator_category;
17  using value_type = typename Container::value_type;
18  using pointer = value_type *;
19  using reference = value_type &;
20  using difference_type = typename IdsIterator::difference_type;
21 
25  IndexMapIterator() : items_(nullptr) {}
26 
33  IndexMapIterator(IdsIterator id, Container & items) :
34  currentId_(id), items_(&items) {}
35 
39  auto toContainerId() const { return *currentId_; }
40 
41  // Input iterator methods
42  auto& operator*() { return (*items_)[toContainerId()]; }
43  const auto& operator*() const { return (*items_)[toContainerId()]; }
44 
45  auto operator->() { return &(operator*()); }
46  auto operator->() const { return &(operator*()); }
47 
48  bool operator==(IndexMapIterator other) const {
49  // Note that comparing against different containers is undefined.
50  return currentId_ == other.currentId_;
51  }
52  bool operator!=(IndexMapIterator other) const { return !(*this == other); }
53 
54  auto& operator++() {
55  ++currentId_;
56  return *this;
57  }
58 
59  auto operator++(int) {
60  auto tmp = *this;
61  ++currentId_;
62  return tmp;
63  }
64 
65  // Bidirectional iterator methods
66  template <typename U = iterator_category,
67  typename = std::enable_if_t<std::is_same_v<U, std::bidirectional_iterator_tag> ||
68  std::is_same_v<U, std::random_access_iterator_tag>>>
69  auto operator--() {
70  --currentId_;
71  return *this;
72  }
73 
74  template <typename U = iterator_category,
75  typename = std::enable_if_t<std::is_same_v<U, std::bidirectional_iterator_tag> ||
76  std::is_same_v<U, std::random_access_iterator_tag>>>
77  auto operator--(int) {
78  auto tmp = *this;
79  --currentId_;
80  return tmp;
81  }
82 
83  // Random access iterator methods
84  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
85  auto operator+(difference_type diff) const {
86  auto retval = IndexMapIterator(currentId_, *items_);
87  retval.currentId_ += diff;
88  return retval;
89  }
90 
91  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
93  currentId_ += diff;
94  return *this;
95  }
96 
97  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
98  auto operator-(difference_type diff) const {
99  auto retval = IndexMapIterator(currentId_, *items_);
100  retval.currentId_ -= diff;
101  return *this;
102  }
103 
104  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
106  currentId_ -= diff;
107  return *this;
108  }
109 
110  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
111  auto operator-(IndexMapIterator other) const {
112  return currentId_ - other.currentId_;
113  }
114 
115  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
116  bool operator<(IndexMapIterator other) const {
117  return currentId_ < other.currentId_;
118  }
119 
120  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
121  bool operator>(IndexMapIterator other) const {
122  return currentId_ > other.currentId_;
123  }
124 
125  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
126  bool operator<=(IndexMapIterator other) const {
127  return !(currentId_ > other.currentId_ );
128  }
129 
130  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
131  bool operator>=(IndexMapIterator other) const {
132  return !(currentId_ < other.currentId_ );
133  }
134 
135  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
137  return (*items_)[*(currentId_ + diff)];
138  }
139 
140  template <typename U = iterator_category, typename = std::enable_if_t<std::is_same_v<U, std::random_access_iterator_tag>>>
141  const auto & operator[](difference_type diff) const {
142  return (*items_)[*(currentId_ + diff)];
143  }
144 
145  private:
146  IdsIterator currentId_;
147  Container * items_;
148  };
149 
168  template <typename IdsContainer, typename Container>
169  class IndexMap {
170  public:
177  static constexpr bool OwnsIds = !std::is_pointer_v<IdsContainer>;
178  using IdsStorage = std::conditional_t<OwnsIds,
179  IdsContainer,
180  const std::remove_pointer_t<IdsContainer> &
181  >;
182 
183  using value_type = typename Container::value_type;
184 
187 
204  template <bool Tmp = OwnsIds, std::enable_if_t<Tmp, int> = 0>
205  IndexMap(IdsContainer ids, Container & items) : ids_(std::move(ids)), items_(items) {}
206 
225  template <bool Tmp = OwnsIds, std::enable_if_t<!Tmp, int> = 0>
226  IndexMap(IdsContainer ids, Container & items) : ids_(*ids), items_(items) {}
227 
231  template <bool Tmp = OwnsIds, std::enable_if_t<Tmp, int> = 0>
232  void sort() {
233  std::sort(std::begin(ids_), std::end(ids_), [this](auto lhs, auto rhs) {
234  return items_[lhs] < items_[rhs];
235  });
236  }
237 
241  auto begin() { return iterator(ids_.begin(), items_); }
242 
246  auto begin() const { return cbegin(); }
247 
251  auto cbegin() const { return const_iterator(ids_.cbegin(), items_); }
252 
256  auto end() { return iterator(ids_.end(), items_); };
257 
261  auto end() const { return cend(); }
262 
266  auto cend() const { return const_iterator(ids_.cend(), items_); }
267 
271  auto size() const { return ids_.size(); }
272 
273  private:
274  friend iterator;
275  friend const_iterator;
276 
277  // Const reference if non-owning, const value otherwise.
278  IdsStorage ids_;
279  Container & items_;
280  };
281 
282  template <class T, class Container>
283  IndexMap(std::initializer_list<T> i, Container c) -> IndexMap<std::vector<T>, Container>;
284 
285  // This is to stop clang++ complaints
286  template <typename IdsContainer, typename Container>
287  IndexMap(IdsContainer, Container &) -> IndexMap<IdsContainer, Container>;
288 
292  template <typename IdsContainer, typename Container>
294  public:
295  using iterator_category = std::forward_iterator_tag;
296  using value_type = typename Container::value_type;
297  using size_type = typename Container::size_type;
298  using pointer = value_type *;
300  using difference_type = std::ptrdiff_t;
301 
309  IndexSkipMapIterator(size_type start, const IdsContainer & ids, Container & items) :
310  currentId_(start), currentSkipId_(0), ids_(ids), items_(items)
311  {
312  // Skip initial unwanted elements
313  skip();
314  }
315 
316  auto& operator*() { return items_[toContainerId()]; }
317  const auto& operator*() const { return items_[toContainerId()]; }
318 
319  auto operator->() { return &(operator*()); }
320  auto operator->() const { return &(operator*()); }
321 
325  auto toContainerId() const { return currentId_; }
326 
327  auto& operator++() {
328  ++currentId_;
329  skip();
330  return *this;
331  }
332 
333  bool operator==(const IndexSkipMapIterator & other) const {
334  return (&(items_) == &(other.items_)) &&
335  (&(ids_) == &(other.ids_)) &&
336  (currentId_ == other.currentId_);
337  }
338  bool operator!=(const IndexSkipMapIterator & other) const { return !(*this == other); }
339 
340  private:
341  void skip() {
342  while (currentId_ < items_.size() &&
343  currentSkipId_ < ids_.size() &&
344  currentId_ == ids_[currentSkipId_])
345  {
346  ++currentId_;
347  ++currentSkipId_;
348  }
349  }
350 
351  size_type currentId_;
352  typename IdsContainer::size_type currentSkipId_;
353  const IdsContainer & ids_;
354  Container & items_;
355  };
356 
375  template <typename IdsContainer, typename Container>
376  class IndexSkipMap {
377  public:
384  static constexpr bool OwnsIds = !std::is_pointer_v<IdsContainer>;
385  using IdsStorage = std::conditional_t<OwnsIds,
386  const IdsContainer,
387  const std::remove_pointer_t<IdsContainer> &
388  >;
389 
390  using value_type = typename Container::value_type;
391 
394 
411  template <bool Tmp = OwnsIds, std::enable_if_t<Tmp, int> = 0>
412  IndexSkipMap(IdsContainer ids, Container & items) : ids_(std::move(ids)), items_(items) {}
413 
432  template <bool Tmp = OwnsIds, std::enable_if_t<!Tmp, int> = 0>
433  IndexSkipMap(IdsContainer ids, Container & items) : ids_(*ids), items_(items) {}
434 
438  auto begin() { return iterator(0, ids_, items_); }
439 
443  auto begin() const { return cbegin(); }
444 
448  auto cbegin() const { return const_iterator(0, ids_, items_); }
449 
453  auto end() { return iterator(items_.size(), ids_, items_); };
454 
458  auto end() const { return cend(); }
459 
463  auto cend() const { return const_iterator(items_.size(), ids_, items_); }
464 
468  auto size() const { return ids_.size(); }
469 
470  private:
471  friend iterator;
472  friend const_iterator;
473 
474  // Const reference if non-owning, const value otherwise.
475  IdsStorage ids_;
476  Container & items_;
477  };
478 
479  template<class T, class Container>
480  IndexSkipMap(std::initializer_list<T> i, Container c) -> IndexSkipMap<std::vector<T>, Container>;
481 
482  // This is to stop clang++ complaints
483  template <typename IdsContainer, typename Container>
484  IndexSkipMap(IdsContainer, Container &) -> IndexSkipMap<IdsContainer, Container>;
485 }
486 
487 #endif
AIToolbox::IndexSkipMap::cend
auto cend() const
This function returns a const_iterator to the end of this filtered range.
Definition: IndexMap.hpp:463
AIToolbox::IndexSkipMap::const_iterator
IndexSkipMapIterator< std::remove_reference_t< IdsStorage >, const Container > const_iterator
Definition: IndexMap.hpp:393
AIToolbox::IndexSkipMapIterator::operator++
auto & operator++()
Definition: IndexMap.hpp:327
AIToolbox::IndexSkipMap::size
auto size() const
This function returns the size of the range covered.
Definition: IndexMap.hpp:468
AIToolbox::IndexMapIterator::operator!=
bool operator!=(IndexMapIterator other) const
Definition: IndexMap.hpp:52
AIToolbox::IndexMapIterator::operator[]
const auto & operator[](difference_type diff) const
Definition: IndexMap.hpp:141
AIToolbox::IndexMap
This class is an iterable construct on a list of ids on a given container.
Definition: IndexMap.hpp:169
AIToolbox::IndexSkipMapIterator::pointer
value_type * pointer
Definition: IndexMap.hpp:298
AIToolbox::IndexSkipMap::value_type
typename Container::value_type value_type
Definition: IndexMap.hpp:390
AIToolbox::IndexMap::IdsStorage
std::conditional_t< OwnsIds, IdsContainer, const std::remove_pointer_t< IdsContainer > & > IdsStorage
Definition: IndexMap.hpp:181
AIToolbox::IndexMapIterator
This class is a simple iterator to iterate over a container with the specified ids.
Definition: IndexMap.hpp:14
AIToolbox::IndexMap::IndexMap
IndexMap(IdsContainer ids, Container &items)
Basic constructor for owning iterable.
Definition: IndexMap.hpp:205
AIToolbox::IndexSkipMapIterator::operator->
auto operator->()
Definition: IndexMap.hpp:319
AIToolbox::IndexMap::end
auto end() const
This function returns a const_iterator to the end of this filtered range.
Definition: IndexMap.hpp:261
AIToolbox::IndexSkipMapIterator::IndexSkipMapIterator
IndexSkipMapIterator(size_type start, const IdsContainer &ids, Container &items)
Basic constructor for begin iterators.
Definition: IndexMap.hpp:309
AIToolbox::IndexSkipMap::end
auto end()
This function returns an iterator to the end of this filtered range.
Definition: IndexMap.hpp:453
AIToolbox::IndexSkipMap
This class is an iterable construct on a list of ids on a given container.
Definition: IndexMap.hpp:376
AIToolbox::IndexSkipMapIterator::operator!=
bool operator!=(const IndexSkipMapIterator &other) const
Definition: IndexMap.hpp:338
AIToolbox::IndexSkipMap::IdsStorage
std::conditional_t< OwnsIds, const IdsContainer, const std::remove_pointer_t< IdsContainer > & > IdsStorage
Definition: IndexMap.hpp:388
AIToolbox::IndexSkipMapIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: IndexMap.hpp:295
AIToolbox::IndexMap::end
auto end()
This function returns an iterator to the end of this filtered range.
Definition: IndexMap.hpp:256
AIToolbox::IndexMapIterator::operator--
auto operator--()
Definition: IndexMap.hpp:69
AIToolbox::IndexSkipMap::begin
auto begin() const
This function returns a const_iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:443
AIToolbox::IndexMap::OwnsIds
static constexpr bool OwnsIds
The type used to contain the ids in the iterable.
Definition: IndexMap.hpp:177
AIToolbox::IndexSkipMapIterator::reference
value_type & reference
Definition: IndexMap.hpp:299
AIToolbox::IndexMapIterator::operator>=
bool operator>=(IndexMapIterator other) const
Definition: IndexMap.hpp:131
AIToolbox::IndexMapIterator::operator[]
auto & operator[](difference_type diff)
Definition: IndexMap.hpp:136
AIToolbox::IndexMapIterator::operator-
auto operator-(IndexMapIterator other) const
Definition: IndexMap.hpp:111
AIToolbox::IndexMapIterator::operator++
auto & operator++()
Definition: IndexMap.hpp:54
AIToolbox::IndexMapIterator::operator*
auto & operator*()
Definition: IndexMap.hpp:42
AIToolbox::IndexMapIterator::operator--
auto operator--(int)
Definition: IndexMap.hpp:77
AIToolbox::IndexMap::const_iterator
IndexMapIterator< decltype(std::declval< IdsStorage >().cbegin()), const Container > const_iterator
Definition: IndexMap.hpp:186
AIToolbox::IndexMapIterator::operator->
auto operator->() const
Definition: IndexMap.hpp:46
AIToolbox::IndexMapIterator::operator+
auto operator+(difference_type diff) const
Definition: IndexMap.hpp:85
AIToolbox::IndexSkipMapIterator::difference_type
std::ptrdiff_t difference_type
Definition: IndexMap.hpp:300
AIToolbox::IndexSkipMapIterator::operator*
auto & operator*()
Definition: IndexMap.hpp:316
AIToolbox::IndexMap
IndexMap(std::initializer_list< T > i, Container c) -> IndexMap< std::vector< T >, Container >
AIToolbox
Definition: Experience.hpp:6
AIToolbox::IndexSkipMapIterator::operator*
const auto & operator*() const
Definition: IndexMap.hpp:317
AIToolbox::IndexMap::sort
void sort()
This function sorts the indeces of the map so that the view is sorted.
Definition: IndexMap.hpp:232
AIToolbox::IndexMapIterator::operator->
auto operator->()
Definition: IndexMap.hpp:45
AIToolbox::IndexMapIterator::difference_type
typename IdsIterator::difference_type difference_type
Definition: IndexMap.hpp:20
AIToolbox::IndexMapIterator::operator++
auto operator++(int)
Definition: IndexMap.hpp:59
AIToolbox::IndexSkipMap::end
auto end() const
This function returns a const_iterator to the end of this filtered range.
Definition: IndexMap.hpp:458
AIToolbox::IndexMap::cbegin
auto cbegin() const
This function returns a const_iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:251
AIToolbox::IndexSkipMapIterator::operator==
bool operator==(const IndexSkipMapIterator &other) const
Definition: IndexMap.hpp:333
AIToolbox::IndexSkipMapIterator::operator->
auto operator->() const
Definition: IndexMap.hpp:320
AIToolbox::IndexMapIterator::operator<
bool operator<(IndexMapIterator other) const
Definition: IndexMap.hpp:116
AIToolbox::IndexSkipMap::IndexSkipMap
IndexSkipMap(IdsContainer ids, Container &items)
Basic constructor for owning iterable.
Definition: IndexMap.hpp:412
AIToolbox::IndexMapIterator::operator>
bool operator>(IndexMapIterator other) const
Definition: IndexMap.hpp:121
AIToolbox::IndexMap::begin
auto begin()
This function returns an iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:241
AIToolbox::IndexSkipMap::cbegin
auto cbegin() const
This function returns a const_iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:448
Types.hpp
AIToolbox::IndexMapIterator::IndexMapIterator
IndexMapIterator(IdsIterator id, Container &items)
Basic constructor.
Definition: IndexMap.hpp:33
AIToolbox::IndexSkipMap::OwnsIds
static constexpr bool OwnsIds
The type used to contain the ids in the iterable.
Definition: IndexMap.hpp:384
AIToolbox::IndexMapIterator::IndexMapIterator
IndexMapIterator()
Basic constructor to respect iterator interface.
Definition: IndexMap.hpp:25
AIToolbox::IndexSkipMap::iterator
IndexSkipMapIterator< std::remove_reference_t< IdsStorage >, Container > iterator
Definition: IndexMap.hpp:392
AIToolbox::IndexMapIterator::reference
value_type & reference
Definition: IndexMap.hpp:19
AIToolbox::IndexMap::iterator
IndexMapIterator< decltype(std::declval< IdsStorage >().begin()), Container > iterator
Definition: IndexMap.hpp:185
AIToolbox::IndexMap::value_type
typename Container::value_type value_type
Definition: IndexMap.hpp:183
AIToolbox::IndexMapIterator::operator<=
bool operator<=(IndexMapIterator other) const
Definition: IndexMap.hpp:126
AIToolbox::IndexMapIterator::value_type
typename Container::value_type value_type
Definition: IndexMap.hpp:17
AIToolbox::IndexMapIterator::operator-
auto operator-(difference_type diff) const
Definition: IndexMap.hpp:98
AIToolbox::IndexMapIterator::iterator_category
typename IdsIterator::iterator_category iterator_category
Definition: IndexMap.hpp:16
AIToolbox::IndexSkipMap::begin
auto begin()
This function returns an iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:438
AIToolbox::IndexSkipMap
IndexSkipMap(std::initializer_list< T > i, Container c) -> IndexSkipMap< std::vector< T >, Container >
AIToolbox::IndexMapIterator::operator-=
auto operator-=(difference_type diff)
Definition: IndexMap.hpp:105
AIToolbox::IndexMapIterator::operator*
const auto & operator*() const
Definition: IndexMap.hpp:43
AIToolbox::IndexSkipMapIterator::toContainerId
auto toContainerId() const
This function returns the equivalent item id of this iterator in its container.
Definition: IndexMap.hpp:325
AIToolbox::IndexMapIterator::pointer
value_type * pointer
Definition: IndexMap.hpp:18
AIToolbox::IndexMap::begin
auto begin() const
This function returns a const_iterator to the beginning of this filtered range.
Definition: IndexMap.hpp:246
AIToolbox::IndexMapIterator::operator+=
auto operator+=(difference_type diff)
Definition: IndexMap.hpp:92
AIToolbox::IndexSkipMapIterator::value_type
typename Container::value_type value_type
Definition: IndexMap.hpp:296
AIToolbox::IndexMapIterator::toContainerId
auto toContainerId() const
This function returns the equivalent item id of this iterator in its container.
Definition: IndexMap.hpp:39
AIToolbox::IndexMapIterator::operator==
bool operator==(IndexMapIterator other) const
Definition: IndexMap.hpp:48
AIToolbox::IndexMap::size
auto size() const
This function returns the size of the range covered.
Definition: IndexMap.hpp:271
AIToolbox::IndexSkipMapIterator::size_type
typename Container::size_type size_type
Definition: IndexMap.hpp:297
AIToolbox::IndexMap::cend
auto cend() const
This function returns a const_iterator to the end of this filtered range.
Definition: IndexMap.hpp:266
AIToolbox::IndexSkipMapIterator
This class is a simple iterator to iterate over a container without the specified ids.
Definition: IndexMap.hpp:293