| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #pragma once
- #include "base/assertion.h"
- namespace base {
- template <typename Container>
- class index_based_iterator {
- public:
- using iterator_category = std::random_access_iterator_tag;
- using value_type = typename Container::value_type;
- using difference_type = typename Container::difference_type;
- using pointer = std::conditional_t<
- std::is_const_v<Container>,
- typename Container::const_pointer,
- typename Container::pointer>;
- using reference = std::conditional_t<
- std::is_const_v<Container>,
- typename Container::const_reference,
- typename Container::reference>;
- using base_type = std::conditional_t<
- std::is_const_v<Container>,
- typename Container::const_iterator,
- typename Container::iterator>;
- index_based_iterator(Container *container, base_type impl)
- : _container(container)
- , _index(impl - _container->begin()) {
- }
- reference operator*() const {
- return *(_container->begin() + _index);
- }
- pointer operator->() const {
- return std::addressof(**this);
- }
- index_based_iterator &operator++() {
- ++_index;
- return *this;
- }
- index_based_iterator operator++(int) {
- auto copy = *this;
- ++*this;
- return copy;
- }
- index_based_iterator &operator--() {
- --_index;
- return *this;
- }
- index_based_iterator operator--(int) {
- auto copy = *this;
- --*this;
- return copy;
- }
- index_based_iterator &operator+=(difference_type offset) {
- _index += offset;
- return *this;
- }
- index_based_iterator operator+(difference_type offset) const {
- auto copy = *this;
- copy += offset;
- return copy;
- }
- index_based_iterator &operator-=(difference_type offset) {
- _index -= offset;
- return *this;
- }
- index_based_iterator operator-(difference_type offset) const {
- auto copy = *this;
- copy -= offset;
- return copy;
- }
- difference_type operator-(const index_based_iterator &other) const {
- return _index - other._index;
- }
- reference operator[](difference_type offset) const {
- return *(*this + offset);
- }
- bool operator==(const index_based_iterator &other) const {
- Expects(_container == other._container);
- return _index == other._index;
- }
- bool operator!=(const index_based_iterator &other) const {
- Expects(_container == other._container);
- return _index != other._index;
- }
- bool operator<(const index_based_iterator &other) const {
- Expects(_container == other._container);
- return _index < other._index;
- }
- bool operator>(const index_based_iterator &other) const {
- return other < *this;
- }
- bool operator<=(const index_based_iterator &other) const {
- return !(other < *this);
- }
- bool operator>=(const index_based_iterator &other) const {
- return !(*this < other);
- }
- base_type base() const {
- return _container->begin() + _index;
- }
- private:
- Container *_container = nullptr;
- difference_type _index = 0;
- };
- template <typename Container>
- index_based_iterator<Container> index_based_begin(Container &container) {
- return { &container, std::begin(container) };
- }
- template <typename Container>
- index_based_iterator<Container> index_based_end(Container &container) {
- return { &container, std::end(container) };
- }
- } // namespace base
|