#pragma once #include #include enum class iterator_type_t{ contiguous_iterator, non_contiguous_iterator, lazy_iterator }; template struct pointer_iterator final { T* data; typedef T value_type; typedef std::size_t difference_type; static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; constexpr pointer_iterator(const pointer_iterator& oth) : data{oth.data} {} constexpr pointer_iterator(T* ptr) : data{ptr} {} constexpr T& operator*() { return *data; } constexpr pointer_iterator& operator++() { data += sign; return *this; } constexpr pointer_iterator operator++(int) { auto p = *this; data += sign; return p; } constexpr pointer_iterator& operator--() { data -= sign; return *this; } constexpr pointer_iterator operator--(int) { auto p = *this; data -= sign; return p; } constexpr pointer_iterator operator+(const std::size_t offset) { return pointer_iterator{data+sign*offset}; } constexpr pointer_iterator operator+(const int offset) { return pointer_iterator{data+sign*offset}; } constexpr pointer_iterator operator-(const std::size_t offset) { return pointer_iterator{data-sign*offset}; } constexpr pointer_iterator operator-(const int offset) { return pointer_iterator{data-sign*offset}; } constexpr difference_type operator-(const pointer_iterator& oth) const { return ((T*)data-(T*)oth.data)*sign; } constexpr bool operator==(const pointer_iterator oth) { return data==oth.data; } constexpr bool operator!=(pointer_iterator oth) { return data!=oth.data; } constexpr bool before_or_equal(const pointer_iterator oth) { return reinterpret_cast(data) <= reinterpret_cast(oth.data); } constexpr bool operator<=(const pointer_iterator oth) { return before_or_equal(oth); } }; template struct const_pointer_iterator final { const T* data; typedef T value_type; typedef std::size_t difference_type; static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; constexpr const_pointer_iterator(const const_pointer_iterator& oth) : data{oth.data} {} constexpr const_pointer_iterator(const T* ptr) : data{ptr} {} constexpr const T& operator*() { return *data; } constexpr const_pointer_iterator& operator++() { data += sign; return *this; } constexpr const_pointer_iterator operator++(int) { auto p = data; data += sign; return const_pointer_iterator{p}; } constexpr const_pointer_iterator& operator--() { data -= sign; return *this; } constexpr const_pointer_iterator operator--(int) { auto p = data; data -= sign; return const_pointer_iterator{p}; } constexpr const_pointer_iterator operator+(const std::size_t offset) { return const_pointer_iterator{data+sign*offset}; } constexpr const_pointer_iterator operator+(const int offset) { return const_pointer_iterator{data+sign*offset}; } constexpr const_pointer_iterator operator-(const std::size_t offset) { return const_pointer_iterator{data-sign*offset}; } constexpr const_pointer_iterator operator-(const int offset) { return const_pointer_iterator{data-sign*offset}; } constexpr difference_type operator-(const const_pointer_iterator& oth) const { return ((T*)data-(T*)oth.data)*sign; } constexpr bool operator==(const const_pointer_iterator oth) { return data==oth.data; } constexpr bool operator!=(const_pointer_iterator oth) { return data!=oth.data; } constexpr bool before_or_equal(const const_pointer_iterator oth) { return reinterpret_cast(data) <= reinterpret_cast(oth.data); } constexpr bool operator<=(const const_pointer_iterator oth) { return before_or_equal(oth); } };