1#ifndef HALCHECK_LIB_ITERATOR_INTERFACE_HPP
2#define HALCHECK_LIB_ITERATOR_INTERFACE_HPP
6#include <halcheck/lib/iterator/base.hpp>
7#include <halcheck/lib/iterator/range.hpp>
8#include <halcheck/lib/numeric.hpp>
9#include <halcheck/lib/type_traits.hpp>
11namespace halcheck {
namespace lib {
29template<
typename I,
typename N>
39template<
typename Self>
56 return *(
static_cast<const I &
>(*this) + n);
70 I &self = *
static_cast<I *
>(
this);
86 ++*
static_cast<I *
>(
this);
100 I &self = *
static_cast<I *
>(
this);
116 --*
static_cast<I *
>(
this);
126 template<
typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::addition, I, lib::iter_difference_t<I>>())>
128 I &self = *
static_cast<I *
>(
this);
140 template<typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::equality, I>())>
141 friend bool operator!=(
const Self &lhs,
const Self &rhs) {
142 return !bool(lhs == rhs);
151 template<typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::difference, I>())>
152 friend bool operator<(
const Self &lhs,
const Self &rhs) {
153 return (lhs - rhs) < 0;
162 template<typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::difference, I>())>
163 friend bool operator>(
const Self &lhs,
const Self &rhs) {
173 template<typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::difference, I>())>
174 friend bool operator<=(
const Self &lhs,
const Self &rhs) {
184 template<typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::difference, I>())>
185 friend bool operator>=(
const Self &lhs,
const Self &rhs) {
196 template<
typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::addition, I, lib::iter_difference_t<I>>())>
209 template<
typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::addition, I, lib::iter_difference_t<I>>())>
222 template<
typename I = Self, HALCHECK_REQUIRE(lib::is_detected<detail::addition, I, lib::iter_difference_t<I>>())>
240 template<
typename T = Self>
242 return static_cast<T &
>(*this);
245 template<
typename T = Self>
246 const T &self()
const {
247 return static_cast<const T &
>(*this);
251 template<typename T = Self, HALCHECK_REQUIRE(lib::is_sized_range<const T>())>
252 constexpr bool empty()
const {
257 constexpr bool empty()
const {
258 return lib::begin(self()) == lib::end(self());
261 template<typename T = Self, HALCHECK_REQUIRE(lib::is_sized_range<T>())>
268 return lib::begin(self()) == lib::end(self());
272 constexpr explicit operator bool()
const {
277 explicit operator bool() {
281 template<typename T = Self, HALCHECK_REQUIRE(lib::is_random_access_range<const T>())>
282 constexpr auto size()
const ->
decltype(
lib::to_unsigned(lib::end(self<T>()) - lib::begin(self<T>()))) {
286 template<typename T = Self, HALCHECK_REQUIRE(lib::is_random_access_range<T>())>
287 auto size() ->
decltype(
lib::to_unsigned(lib::end(self<T>()) - lib::begin(self<T>()))) {
291 template<typename T = Self, HALCHECK_REQUIRE(lib::is_forward_range<const T>())>
292 constexpr auto front()
const ->
decltype(*lib::begin(self<T>())) {
293 return *lib::begin(self());
296 template<typename T = Self, HALCHECK_REQUIRE(lib::is_forward_range<T>())>
297 auto front() ->
decltype(*lib::begin(self<T>())) {
298 return *lib::begin(self());
301 template<typename T = Self, HALCHECK_REQUIRE(lib::is_bidirectional_range<const T>())>
302 constexpr auto back()
const ->
decltype(*
std::prev(lib::end(self<T>()))) {
306 template<typename T = Self, HALCHECK_REQUIRE(lib::is_bidirectional_range<T>())>
307 auto back() ->
decltype(*
std::prev(lib::end(self<T>()))) {
311 template<typename T = Self, HALCHECK_REQUIRE(lib::is_random_access_range<const T>())>
313 return lib::begin(self<T>())[n];
316 template<typename T = Self, HALCHECK_REQUIRE(lib::is_random_access_range<T>())>
318 return lib::begin(self<T>())[n];
I & operator-=(lib::iter_difference_t< I > n)
Advances this iterator the specified number of steps backwards.
Definition interface.hpp:127
void operator++(int)
Advances this iterator.
Definition interface.hpp:85
friend Self operator+(Self i, lib::iter_difference_t< I > n)
Advances an iterator by a specified amount.
Definition interface.hpp:197
I operator--(int)
Advances this iterator a step backwards.
Definition interface.hpp:99
constexpr lib::iter_reference_t< I > operator[](lib::iter_difference_t< I > n) const
Access the element at the specified index.
Definition interface.hpp:55
friend Self operator+(lib::iter_difference_t< I > n, Self i)
Advances an iterator by a specified amount.
Definition interface.hpp:210
I operator++(int)
Advances this iterator.
Definition interface.hpp:69
void operator--(int)
Advances this iterator a step backwards.
Definition interface.hpp:115
friend Self operator-(Self i, lib::iter_difference_t< I > n)
Advances an iterator backwards by a specified amount.
Definition interface.hpp:223
A utility class for easily defining new iterators.
Definition interface.hpp:40
An implementation of std::ranges::view_interface.
Definition interface.hpp:238
typename std::iterator_traits< I >::difference_type iter_difference_t
The return type of operator- for an iterator.
Definition base.hpp:32
typename std::iterator_traits< I >::reference iter_reference_t
The return type of operator* for an iterator.
Definition base.hpp:24
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@25 size
Obtains the size of a range.
lib::iter_difference_t< lib::iterator_t< R > > range_difference_t
The type of value returned by operator- for a range type's iterators.
Definition range.hpp:324
lib::make_unsigned_t< T > to_unsigned(T value)
Converts an integral value into its equivalent unsigned version.
Definition numeric.hpp:55
typename std::remove_cv< T >::type remove_cv_t
An implementation of std::remove_cv_t.
Definition type_traits.hpp:109
typename std::enable_if< Cond, T >::type enable_if_t
An implementation of std::enable_if_t.
Definition type_traits.hpp:93
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
Determines if a type is copy constructible and copy assignable.
Definition type_traits.hpp:355
An implementation of std::experimental::is_detected.
Definition type_traits.hpp:247
Determines whether a type is a range whose iterators satisfy lib::is_forward_iterator.
Definition range.hpp:195