File indexing completed on 2024-12-15 04:01:20
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 #pragma once 0007 0008 #include <iterator> 0009 0010 namespace glaxnimate::utils { 0011 0012 /** 0013 * \brief CRTP that adds all the boilerplate of an iterator 0014 * wrapping a random-access iterator. 0015 * 0016 * All you need to do is overload operator->() and operator*(). 0017 */ 0018 template<class Iterator, class BaseIterator> 0019 class RandomAccessIteratorWrapper 0020 { 0021 public: 0022 using iterator_category = std::random_access_iterator_tag; 0023 using difference_type = typename BaseIterator::difference_type; 0024 0025 // Iterator 0026 RandomAccessIteratorWrapper& operator++() { ++iter; return *this; } 0027 0028 // Input/Output Iterator 0029 bool operator==(const RandomAccessIteratorWrapper& o) const { return iter == o.iter; } 0030 bool operator!=(const RandomAccessIteratorWrapper& o) const { return iter != o.iter; } 0031 Iterator operator++(int) { auto copy = *this; ++iter; return copy; } 0032 0033 // Forward Iterator 0034 RandomAccessIteratorWrapper() = default; 0035 0036 // Bidirectional Iterator 0037 Iterator& operator--() { --iter; return *cast_derived(); } 0038 Iterator operator--(int) { auto copy = *this; --iter; return copy; } 0039 0040 // Random Access Iterator 0041 Iterator& operator+= (difference_type i) { iter += i; return *cast_derived(); } 0042 Iterator operator+ (difference_type i) const { return iter + i; } 0043 friend Iterator operator+ (difference_type i, const Iterator& iter) { return iter.iter + i; } 0044 Iterator& operator-= (difference_type i) { iter -= i; return *cast_derived(); } 0045 Iterator operator- (difference_type i) const { return iter - i; } 0046 Iterator operator- (const Iterator& o) const { return iter - o.iter; } 0047 bool operator<(const Iterator& o) const { return iter < o.iter; } 0048 bool operator<=(const Iterator& o) const { return iter <= o.iter; } 0049 bool operator>(const Iterator& o) const { return iter > o.iter; } 0050 bool operator>=(const Iterator& o) const { return iter >= o.iter; } 0051 0052 protected: 0053 using InternalIterator = BaseIterator; 0054 using Parent = RandomAccessIteratorWrapper; 0055 RandomAccessIteratorWrapper(BaseIterator iter) : iter(std::move(iter)) {} 0056 BaseIterator iter; 0057 0058 private: 0059 Iterator* cast_derived() { return static_cast<Iterator*>(this); } 0060 const Iterator* cast_derived() const { return static_cast<const Iterator*>(this); } 0061 }; 0062 } // namespace glaxnimate::utils