Skip to content

Instantly share code, notes, and snippets.

@beached
Last active February 8, 2022 04:08
Show Gist options
  • Save beached/2fe981807b1a96c07d92962dcd031f0e to your computer and use it in GitHub Desktop.
Save beached/2fe981807b1a96c07d92962dcd031f0e to your computer and use it in GitHub Desktop.
Templates for Iterators

Input Iterator

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;
  }
};

Forward Iterator

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;
  }
};

Bidirectional Iterator

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;
  }
};

Random Iterator

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*( ) const {
    return *ptr;
  }  
  
  pointer operator->( ) const {
    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;
  }    
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment