MakeIterator.h
// MakeIterator.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2010
#pragma once
#ifndef Ceda_cxUtils_MakeIterator_H
#define Ceda_cxUtils_MakeIterator_H
#include "cxUtils.h"
#include <iterator>
namespace ceda
{
template <class _Iter>
using iterator_category_type = typename std::iterator_traits<_Iter>::iterator_category;
template <class _Ty, class = void>
inline constexpr bool is_iterator_v = false;
template <class _Ty>
inline constexpr bool is_iterator_v<_Ty, std::void_t<iterator_category_type<_Ty>>> = true;
/*
// Define both iterators using a given policy
struct Policy
{
typename iterator_category
typename value_type
typename difference_type
typename pointer
typename reference
bool operator==(const Policy& rhs) const;
void next();
void prev();
value_type& deref() const;
const value_type& const_deref() const;
};
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Policy>
struct make_iterator : public Policy
{
using pointer = typename Policy::pointer;
using reference = typename Policy::reference;
using difference_type = typename Policy::difference_type;
make_iterator() {}
explicit make_iterator(const Policy& p) : Policy(p) {}
// Prefix
make_iterator& operator++() { Policy::next(); return *this; }
make_iterator& operator--() { Policy::prev(); return *this; }
// Postfix
const make_iterator operator++(int) { make_iterator it = *this; Policy::next(); return it; }
const make_iterator operator--(int) { make_iterator it = *this; Policy::prev(); return it; }
reference operator*() const { return Policy::deref(); }
auto operator->() const { return &Policy::deref(); }
bool operator<(const make_iterator& rhs) const { return Policy::operator<(rhs); }
bool operator<=(const make_iterator& rhs) const { return !(rhs < *this); }
bool operator>(const make_iterator& rhs) const { return rhs < *this; }
bool operator>=(const make_iterator& rhs) const { return !(*this < rhs); }
bool operator==(const make_iterator& rhs) const { return Policy::operator==(rhs); }
bool operator!=(const make_iterator& rhs) const { return !operator==(rhs); }
// The methods below are only supported on random access iterators
make_iterator operator+(difference_type x) const { return make_iterator(Policy::operator+(x)); }
make_iterator operator-(difference_type x) const { return make_iterator(Policy::operator+(-x)); }
difference_type operator-(const make_iterator& rhs) const { return Policy::operator-(rhs); }
make_iterator& operator+=(difference_type x)
{
*this = *this + x;
return *this;
}
make_iterator& operator-=(difference_type x)
{
*this = *this - x;
return *this;
}
};
template <typename Policy>
struct make_const_iterator : public Policy
{
using value_type = typename Policy::value_type;
using pointer = typename Policy::const_pointer;
using reference = typename Policy::const_reference;
using difference_type = typename Policy::difference_type;
make_const_iterator() {}
explicit make_const_iterator(const Policy& p) : Policy(p) {}
make_const_iterator(const make_iterator<Policy>& i) : Policy(i) {}
// Prefix
make_const_iterator& operator++() { Policy::next(); return *this; }
make_const_iterator& operator--() { Policy::prev(); return *this; }
// Postfix
const make_const_iterator operator++(int) { make_const_iterator it = *this; Policy::next(); return it; }
const make_const_iterator operator--(int) { make_const_iterator it = *this; Policy::prev(); return it; }
reference operator*() const { return Policy::const_deref(); }
auto operator->() const { return &Policy::const_deref(); }
bool operator<(const make_const_iterator& rhs) const { return Policy::operator<(rhs); }
bool operator<=(const make_const_iterator& rhs) const { return !(rhs < *this); }
bool operator>(const make_const_iterator& rhs) const { return rhs < *this; }
bool operator>=(const make_const_iterator& rhs) const { return !(*this < rhs); }
bool operator==(const make_const_iterator& rhs) const { return Policy::operator==(rhs); }
bool operator!=(const make_const_iterator& rhs) const { return !operator==(rhs); }
// The methods below are only supported on random access iterators
make_const_iterator operator+(difference_type x) const { return make_const_iterator(Policy::operator+(x)); }
make_const_iterator operator-(difference_type x) const { return make_const_iterator(Policy::operator-(x)); }
difference_type operator-(const make_const_iterator& rhs) const { return Policy::operator-(rhs); }
make_const_iterator& operator+=(difference_type x)
{
*this = *this + x;
return *this;
}
make_const_iterator& operator-=(difference_type x)
{
*this = *this - x;
return *this;
}
};
} // namespace ceda
#endif // include guard