struct input_iterator {
using value_type = T;
using reference = T const &;
using pointer = T const *;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
pointer ptr;
value_type operator*( ) const {
return *ptr;
}
input_iterator & operator++( ) {
++ptr;
return *this;
}
input_iterator operator++( int ) {
input_iterator result = *this;
++ptr;
return result;
}
friend bool operator==( input_iterator const & lhs, input_iterator const & rhs ) {
return lhs.ptr == rhs.ptr;
}
friend bool operator!=( input_iterator const & lhs, input_iterator const & rhs ) {
return lhs.ptr != rhs.ptr;
}
};
struct forward_iterator {
using value_type = T;
using pointer = std::add_pointer_t<value_type>;
using const_pointer = std::add_pointer_t<std::add_const_t<value_type>>;
using iterator_category = std::forward_iterator_tag;
using reference = std::add_lvalue_reference_t<value_type>;
using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>;
using difference_type = std::ptrdiff_t;
pointer ptr;
reference operator*( ) const {
return *ptr;
}
pointer operator->( ) const {
return ptr;
}
const_reference operator*( ) const {
return *ptr;
}
const_pointer operator->( ) const {
return ptr;
}
forward_iterator & operator++( ) {
++ptr;
return *this;
}
forward_iterator operator++( int ) {
input_iterator result = *this;
++ptr;
return result;
}
friend bool operator==( forward_iterator const & lhs, forward_iterator const & rhs ) {
return lhs.ptr == rhs.ptr;
}
friend bool operator!=( forward_iterator const & lhs, forward_iterator const & rhs ) {
return lhs.ptr != rhs.ptr;
}
};
struct bidiretional_iterator {
using value_type = T;
using pointer = std::add_pointer_t<value_type>;
using const_pointer = std::add_pointer_t<std::add_const_t<value_type>>;
using iterator_category = std::bidirectional_iterator_tag;
using reference = std::add_lvalue_reference_t<value_type>;
using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>;
using difference_type = std::ptrdiff_t;
pointer ptr;
reference operator*( ) const {
return *ptr;
}
pointer operator->( ) const {
return ptr;
}
const_reference operator*( ) const {
return *ptr;
}
const_pointer operator->( ) const {
return ptr;
}
bidiretional_iterator & operator++( ) {
++ptr;
return *this;
}
bidiretional_iterator operator++( int ) {
bidirectional_iterator result = *this;
++ptr;
return result;
}
bidiretional_iterator & operator--( ) {
--ptr;
return *this;
}
bidiretional_iterator operator--( int ) {
bidirectional_iterator result = *this;
--ptr;
return result;
}
friend bool operator==( bidirectional_iterator const & lhs, bidirectional_iterator const & rhs ) {
return lhs.ptr == lhs.ptr;
}
friend bool operator!=( bidirectional_iterator const & lhs, bidirectional_iterator const & rhs ) {
return lhs.ptr != lhs.ptr;
}
};
struct random_iterator {
using difference_type = std::ptrdiff_t;
using size_type = std::size_t;
using value_type = T;
using pointer = std::add_pointer_t<value_type>;
using const_pointer = std::add_pointer_t<std::add_const_t<value_type>>;
using iterator_category = std::random_access_iterator_tag;
using reference = std::add_lvalue_reference_t<value_type>;
using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>;
pointer ptr;
reference operator*( ) {
return *ptr;
}
pointer operator->( ) {
return ptr;
}
const_reference operator*( ) const {
return *ptr;
}
const_pointer operator->( ) const {
return ptr;
}
random_iterator & operator++( ) {
++ptr;
return *this;
}
random_iterator operator++( int ) {
random_iterator result = *this;
++ptr;
return result;
}
random_iterator & operator--( ) {
--ptr;
return *this;
}
random_iterator operator--( int ) {
random_iterator result = *this;
--ptr;
return result;
}
random_iterator &operator+=( difference_type n ) {
m_pointer += n;
return *this;
}
random_iterator &operator-=( difference_type n ) {
m_pointer -= n;
return *this;
}
random_iterator operator+( difference_type n ) const noexcept {
random_iterator result = *this;
ptr += n;
return result;
}
random_iterator operator-( difference_type n ) const noexcept {
random_iterator result = *this;
ptr -= n;
return result;
}
reference operator[]( size_type n ) noexcept {
return *(ptr + static_cast<difference_type>( n ) );
}
const_reference operator[]( size_type n ) const noexcept {
return *(ptr + static_cast<difference_type>( n ) );
}
friend bool operator==( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr == rhs.ptr;
}
friend bool operator!=( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr != rhs.ptr;
}
friend bool operator<( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr < rhs.ptr;
}
friend bool operator<=( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr <= rhs.ptr;
}
friend bool operator>( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr > rhs.ptr;
}
friend bool operator>=( random_iterator const & lhs, random_iterator const & rhs ) {
return lhs.ptr >= rhs.ptr;
}
};