StormByte C++ Library 0.0.9999
StormByte is a comprehensive, cross-platform C++ library aimed at easing system programming, configuration management, logging, and database handling tasks. This library provides a unified API that abstracts away the complexities and inconsistencies of different platforms (Windows, Linux).
Loading...
Searching...
No Matches
iterable.hxx
1#pragma once
2
3#include <StormByte/exception.hxx>
4#include <StormByte/type_traits.hxx>
5
6#include <iterator>
7#include <utility>
8
16namespace StormByte {
25 template <typename Container>
26 class Iterable {
27 protected:
28 Container m_data;
29 public:
30 using value_type = typename Container::value_type;
31 using size_type = typename Container::size_type;
32 using difference_type = typename Container::difference_type;
33 using reference = typename Container::reference;
34 using const_reference = typename Container::const_reference;
35 using pointer = typename Container::pointer;
36 using const_pointer = typename Container::const_pointer;
37
42 class Iterator {
43 friend class Iterable;
44 public:
45 using iterator_category = std::random_access_iterator_tag;
46 using value_type = typename Container::value_type;
47 using difference_type = typename Container::difference_type;
48 using pointer = typename Container::pointer;
49 using reference = typename Container::reference;
50
55 reference operator*() { return *m_it; }
56
61 pointer operator->() { return m_it.operator->(); }
62
67 Iterator& operator++() { ++m_it; return *this; }
68
73 Iterator operator++(int) { Iterator tmp = *this; ++m_it; return tmp; }
74
79 Iterator& operator--() { --m_it; return *this; }
80
85 Iterator operator--(int) { Iterator tmp = *this; --m_it; return tmp; }
86
92 Iterator& operator+=(difference_type n) { m_it += n; return *this; }
93
99 Iterator& operator-=(difference_type n) { m_it -= n; return *this; }
100
106 Iterator operator+(difference_type n) const { return Iterator(m_it + n); }
107
113 Iterator operator-(difference_type n) const { return Iterator(m_it - n); }
114
120 difference_type operator-(const Iterator& other) const { return m_it - other.m_it; }
121
127 bool operator==(const Iterator& other) const { return m_it == other.m_it; }
128
134 bool operator!=(const Iterator& other) const { return m_it != other.m_it; }
135
136 private:
137 typename Container::iterator m_it;
138
143 Iterator(typename Container::iterator it): m_it(it) {}
144 };
145
151 friend class Iterable;
152 public:
153 using iterator_category = std::random_access_iterator_tag;
154 using value_type = typename Container::value_type;
155 using difference_type = typename Container::difference_type;
156 using pointer = typename Container::const_pointer;
157 using reference = typename Container::const_reference;
158
163 reference operator*() const { return *m_it; }
164
169 pointer operator->() const { return m_it.operator->(); }
170
175 ConstIterator& operator++() { ++m_it; return *this; }
176
181 ConstIterator operator++(int) { ConstIterator tmp = *this; ++m_it; return tmp; }
182
187 ConstIterator& operator--() { --m_it; return *this; }
188
193 ConstIterator operator--(int) { ConstIterator tmp = *this; --m_it; return tmp; }
194
200 ConstIterator& operator+=(difference_type n) { m_it += n; return *this; }
201
207 ConstIterator& operator-=(difference_type n) { m_it -= n; return *this; }
208
214 ConstIterator operator+(difference_type n) const { return ConstIterator(m_it + n); }
215
221 ConstIterator operator-(difference_type n) const { return ConstIterator(m_it - n); }
222
228 difference_type operator-(const ConstIterator& other) const { return m_it - other.m_it; }
229
235 bool operator==(const ConstIterator& other) const { return m_it == other.m_it; }
236
242 bool operator!=(const ConstIterator& other) const { return m_it != other.m_it; }
243
244 private:
245 typename Container::const_iterator m_it;
246
251 ConstIterator(typename Container::const_iterator it): m_it(it) {}
252 };
253
254 using iterator = Iterator;
255 using const_iterator = ConstIterator;
256 using reverse_iterator = std::reverse_iterator<iterator>;
257 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
258
262 Iterable() = default;
263
268 explicit Iterable(const Container& data): m_data(data) {}
269
274 explicit Iterable(Container&& data): m_data(std::move(data)) {}
275
279 Iterable(const Iterable&) = default;
280
284 Iterable(Iterable&&) = default;
285
289 virtual ~Iterable() = default;
290
296 Iterable& operator=(const Iterable&) = default;
297
304
310 bool operator==(const Iterable& other) const { return m_data == other.m_data; }
311
317 bool operator!=(const Iterable& other) const { return m_data != other.m_data; }
318
323 iterator begin() noexcept { return iterator(m_data.begin()); }
324
329 const_iterator begin() const noexcept { return const_iterator(m_data.begin()); }
330
335 iterator end() noexcept { return iterator(m_data.end()); }
336
341 const_iterator end() const noexcept { return const_iterator(m_data.end()); }
342
347 const_iterator cbegin() const noexcept { return const_iterator(m_data.cbegin()); }
348
353 const_iterator cend() const noexcept { return const_iterator(m_data.cend()); }
354
359 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
360
365 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
366
371 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
372
377 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
378
383 const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
384
389 const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
390
395 size_type size() const noexcept { return m_data.size(); }
396
401 bool empty() const noexcept { return m_data.empty(); }
402
408 reference operator[](size_type i)
410 if (i >= m_data.size())
411 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
412 return m_data[i];
413 }
414
415 reference operator[](size_type i)
417 if (i >= m_data.size())
418 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
419 auto it = m_data.begin();
420 std::advance(it, i);
421 return *it;
422 }
423
430 auto operator[](size_type i) -> decltype(auto)
432 if (i >= m_data.size())
433 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
434 auto it = m_data.begin();
435 std::advance(it, i);
436 return *it;
437 }
438
439
440 /*
441 * @brief Key-based access for associative containers (non-const)
442 * @param key The key to access in the underlying container
443 * @return Reference to the mapped value (forward to container's operator[])
444 */
445 template<typename K>
446 auto operator[](K const &key) -> decltype(auto)
448 return m_data[static_cast<typename Container::key_type>(key)];
449 }
450
451 /*
452 * @brief Key-based access for associative containers (const)
453 * @param key The key to access in the underlying container
454 * @return Const reference to the mapped value (searches and throws if not found)
455 */
456 template<typename K>
457 auto operator[](K const &key) const -> decltype(auto)
458 requires (Type::HasMappedType<const Container>) {
459 auto k = static_cast<typename Container::key_type>(key);
460 auto it = m_data.find(k);
461 if (it == m_data.cend())
462 throw OutOfBoundsError("Key not found in Iterable::operator[]");
463 return it->second;
464 }
465
471 const_reference operator[](size_type i) const
473 if (i >= m_data.size())
474 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
475 return m_data[i];
476 }
477
484 const_reference operator[](size_type i) const
486 if (i >= m_data.size())
487 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
488 auto it = m_data.cbegin();
489 std::advance(it, i);
490 return *it;
491 }
492
499 auto operator[](size_type i) const -> decltype(auto)
501 if (i >= m_data.size())
502 throw OutOfBoundsError("Index {} out of bounds in Iterable::operator[]", i);
503 auto it = m_data.cbegin();
504 std::advance(it, i);
505 return *it;
506 }
507
512 void add(const value_type& value) requires Type::HasPushBack<decltype(m_data)> {
513 m_data.push_back(value);
514 }
515
520 void add(const value_type& value) requires (!Type::HasPushBack<decltype(m_data)> and Type::HasPushFront<decltype(m_data)>) {
521 m_data.push_front(value);
522 }
523
527 void add(const value_type& value) requires (!Type::HasPushBack<decltype(m_data)> and !Type::HasPushFront<decltype(m_data)> and Type::HasInsert<decltype(m_data)>) {
528 m_data.insert(value);
529 }
530
535 void add(value_type&& value) requires Type::HasPushBack<decltype(m_data)> {
536 m_data.push_back(std::move(value));
537 }
538
543 void add(value_type&& value) requires (!Type::HasPushBack<decltype(m_data)> and Type::HasPushFront<decltype(m_data)>) {
544 m_data.push_front(std::move(value));
545 }
546
550 void add(value_type&& value) requires (!Type::HasPushBack<decltype(m_data)> and !Type::HasPushFront<decltype(m_data)> and Type::HasInsert<decltype(m_data)>) {
551 m_data.insert(std::move(value));
552 }
553
559 bool has_item(const value_type& value) const {
560 for (const auto& item : m_data) {
561 if (item == value) {
562 return true;
563 }
564 }
565 return false;
566 }
567
573 template<typename M>
574 bool has_item(M const &value) const
575 requires Type::HasMappedType<const Container> && std::convertible_to<M, typename Container::mapped_type> {
576 for (const auto &item : m_data) {
577 if (item.second == value) return true;
578 }
579 return false;
580 }
581
587 template<typename K>
588 bool has_key(const K& key) const
590 auto k = static_cast<typename Container::key_type>(key);
591 return m_data.find(k) != m_data.cend();
592
593 }
594 };
595}
Wrapper const iterator for Iterable.
Definition iterable.hxx:150
ConstIterator operator++(int)
Post-increment operator.
Definition iterable.hxx:181
ConstIterator & operator-=(difference_type n)
Compound subtraction operator.
Definition iterable.hxx:207
ConstIterator & operator--()
Pre-decrement operator.
Definition iterable.hxx:187
ConstIterator operator-(difference_type n) const
Subtraction operator.
Definition iterable.hxx:221
reference operator*() const
Dereference operator.
Definition iterable.hxx:163
pointer operator->() const
Arrow operator.
Definition iterable.hxx:169
ConstIterator operator+(difference_type n) const
Addition operator.
Definition iterable.hxx:214
bool operator!=(const ConstIterator &other) const
Inequality operator.
Definition iterable.hxx:242
ConstIterator & operator++()
Pre-increment operator.
Definition iterable.hxx:175
ConstIterator operator--(int)
Post-decrement operator.
Definition iterable.hxx:193
bool operator==(const ConstIterator &other) const
Subscript operator.
Definition iterable.hxx:235
difference_type operator-(const ConstIterator &other) const
Subtraction operator between two const iterators.
Definition iterable.hxx:228
ConstIterator & operator+=(difference_type n)
Compound addition operator.
Definition iterable.hxx:200
Wrapper iterator for Iterable.
Definition iterable.hxx:42
Iterator & operator++()
Pre-increment operator.
Definition iterable.hxx:67
bool operator!=(const Iterator &other) const
Inequality operator.
Definition iterable.hxx:134
reference operator*()
Dereference operator.
Definition iterable.hxx:55
Iterator & operator+=(difference_type n)
Compound addition operator.
Definition iterable.hxx:92
Iterator operator++(int)
Post-increment operator.
Definition iterable.hxx:73
Iterator operator--(int)
Post-decrement operator.
Definition iterable.hxx:85
Iterator & operator-=(difference_type n)
Compound subtraction operator.
Definition iterable.hxx:99
Iterator operator+(difference_type n) const
Addition operator.
Definition iterable.hxx:106
bool operator==(const Iterator &other) const
Subscript operator.
Definition iterable.hxx:127
Iterator & operator--()
Pre-decrement operator.
Definition iterable.hxx:79
Iterator operator-(difference_type n) const
Subtraction operator.
Definition iterable.hxx:113
pointer operator->()
Arrow operator.
Definition iterable.hxx:61
difference_type operator-(const Iterator &other) const
Subtraction operator between two iterators.
Definition iterable.hxx:120
A generic iterable container wrapper.
Definition iterable.hxx:26
const_reverse_iterator crbegin() const noexcept
Gets const reverse begin iterator.
Definition iterable.hxx:383
const_iterator cend() const noexcept
Gets const end iterator.
Definition iterable.hxx:353
reverse_iterator rend() noexcept
Gets reverse end iterator.
Definition iterable.hxx:365
const_reverse_iterator rbegin() const noexcept
Gets const reverse begin iterator.
Definition iterable.hxx:371
virtual ~Iterable()=default
Virtual destructor.
bool has_key(const K &key) const
Checks if the container has a specific key (for associative containers)
Definition iterable.hxx:588
const_reference operator[](size_type i) const
Access element at given index (const version)
Definition iterable.hxx:471
bool has_item(const value_type &value) const
Checks if the container has a specific item.
Definition iterable.hxx:559
iterator end() noexcept
Gets end iterator.
Definition iterable.hxx:335
Iterable(Container &&data)
Move constructor from existing container.
Definition iterable.hxx:274
const_iterator cbegin() const noexcept
Gets const begin iterator.
Definition iterable.hxx:347
void add(value_type &&value)
Adds an element to associative containers via insert (move version)
Definition iterable.hxx:550
Iterable(Iterable &&)=default
Move constructor.
reverse_iterator rbegin() noexcept
Gets reverse begin iterator.
Definition iterable.hxx:359
Iterable()=default
Default constructor.
reference operator[](size_type i)
Access element at given index.
Definition iterable.hxx:408
void add(const value_type &value)
Adds an element to the container.
Definition iterable.hxx:520
bool empty() const noexcept
Checks if the container is empty.
Definition iterable.hxx:401
auto operator[](size_type i) -> decltype(auto)
Access element at given index (non-const version)
Definition iterable.hxx:430
void add(const value_type &value)
Adds an element to the container.
Definition iterable.hxx:512
bool operator==(const Iterable &other) const
Equality operator.
Definition iterable.hxx:310
void add(value_type &&value)
Adds an element to the container (move version)
Definition iterable.hxx:543
const_iterator end() const noexcept
Gets const end iterator.
Definition iterable.hxx:341
Iterable(const Iterable &)=default
Copy constructor.
const_reverse_iterator rend() const noexcept
Gets const reverse end iterator.
Definition iterable.hxx:377
size_type size() const noexcept
Gets the size of the container.
Definition iterable.hxx:395
Container m_data
Underlying container.
Definition iterable.hxx:28
Iterable(const Container &data)
Constructor from existing container.
Definition iterable.hxx:268
auto operator[](size_type i) const -> decltype(auto)
Access element at given index (const version)
Definition iterable.hxx:499
const_reference operator[](size_type i) const
Access element at given index (const version)
Definition iterable.hxx:484
bool has_item(M const &value) const
Checks if the container has a specific item (for associative containers)
Definition iterable.hxx:574
iterator begin() noexcept
Gets begin iterator.
Definition iterable.hxx:323
const_reverse_iterator crend() const noexcept
Gets const reverse end iterator.
Definition iterable.hxx:389
void add(const value_type &value)
Adds an element to associative containers via insert
Definition iterable.hxx:527
bool operator!=(const Iterable &other) const
Inequality operator.
Definition iterable.hxx:317
const_iterator begin() const noexcept
Gets const begin iterator.
Definition iterable.hxx:329
void add(value_type &&value)
Adds an element to the container (move version)
Definition iterable.hxx:535
Iterable & operator=(Iterable &&)=default
Move assignment operator.
Iterable & operator=(const Iterable &)=default
Copy assignment operator.
Exception thrown when an out-of-bounds access is attempted.
Definition exception.hxx:130
Concept that checks whether a container supports insert with a value.
Definition type_traits.hxx:121
Concept to check if a container has a mapped_type member type.
Definition type_traits.hxx:156
Concept that checks whether a container supports push_back.
Definition type_traits.hxx:105
Concept that checks whether a container supports push_front.
Definition type_traits.hxx:113
Concept that checks whether a container supports operator[] for a given key/index type U.
Definition type_traits.hxx:132
Main namespace for the StormByte library.