Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_ITERATOR_OPS_H
Toshihiro Shimizu 890ddd
#define TCG_ITERATOR_OPS_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "traits.h"
Toshihiro Shimizu 890ddd
#include "ptr.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <iterator>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Traits
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename It>
Toshihiro Shimizu 890ddd
struct iterator_traits : public std::iterator_traits<It> {
Shinya Kitaoka 120a6e
  typedef It inheritable_iterator_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
struct iterator_traits<T *> : public std::iterator_traits<T *> {
Shinya Kitaoka 120a6e
  typedef ptr<T> inheritable_iterator_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Derived Iterator  definition
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
template 
Shinya Kitaoka 120a6e
          typename iterator_tag =
Shinya Kitaoka 120a6e
              typename std::iterator_traits<It>::iterator_category>
Shinya Kitaoka 120a6e
struct derived_iterator
Shinya Kitaoka 120a6e
    : public tcg::iterator_traits<It>::inheritable_iterator_type {
Shinya Kitaoka 120a6e
  typedef typename tcg::iterator_traits<It>::inheritable_iterator_type
Shinya Kitaoka 120a6e
      base_iterator;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  derived_iterator() : base_iterator() {}
Shinya Kitaoka 120a6e
  derived_iterator(const base_iterator &it) : base_iterator(it) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Der &operator++() {
Shinya Kitaoka 120a6e
    base_iterator::operator++();
Shinya Kitaoka 120a6e
    return static_cast<Der &>(*this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  Der operator++(int) {
Shinya Kitaoka 120a6e
    return Der(base_iterator::operator++(0), static_cast<Der &>(*this));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename It, typename Der>
Toshihiro Shimizu 890ddd
struct derived_iterator<It, Der, std::bidirectional_iterator_tag>
Shinya Kitaoka 120a6e
    : public derived_iterator<It, Der, std::forward_iterator_tag> {
Shinya Kitaoka 120a6e
  typedef typename tcg::iterator_traits<It>::inheritable_iterator_type
Shinya Kitaoka 120a6e
      base_iterator;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  derived_iterator() : _iter() {}
Shinya Kitaoka 120a6e
  derived_iterator(const base_iterator &it) : _iter(it) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Der &operator--() {
Shinya Kitaoka 120a6e
    base_iterator::operator--();
Shinya Kitaoka 120a6e
    return static_cast<Der &>(*this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  Der operator--(int) {
Shinya Kitaoka 120a6e
    return Der(base_iterator::operator--(0), static_cast<Der &>(*this));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  typedef derived_iterator<It, Der, std::forward_iterator_tag> _iter;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename It, typename Der>
Toshihiro Shimizu 890ddd
struct derived_iterator<It, Der, std::random_access_iterator_tag>
Shinya Kitaoka 120a6e
    : public derived_iterator<It, Der, std::bidirectional_iterator_tag> {
Shinya Kitaoka 120a6e
  typedef typename tcg::iterator_traits<It>::inheritable_iterator_type
Shinya Kitaoka 120a6e
      base_iterator;
Shinya Kitaoka 120a6e
  typedef typename base_iterator::difference_type difference_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  derived_iterator() : _iter() {}
Shinya Kitaoka 120a6e
  derived_iterator(const base_iterator &it) : _iter(it) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Der operator+(difference_type d) const {
Shinya Kitaoka 120a6e
    return Der(static_cast<const base_iterator &>(*this) + d,
Shinya Kitaoka 120a6e
               static_cast<const Der &>(*this));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  Der &operator+=(difference_type d) {
Shinya Kitaoka 120a6e
    static_cast<base_iterator &>(*this) += d;
Shinya Kitaoka 120a6e
    return static_cast<Der &>(*this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Der operator-(difference_type d) const {
Shinya Kitaoka 120a6e
    return Der(static_cast<const base_iterator &>(*this) - d,
Shinya Kitaoka 120a6e
               static_cast<const Der &>(*this));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  Der &operator-=(difference_type d) {
Shinya Kitaoka 120a6e
    static_cast<base_iterator &>(*this) -= d;
Shinya Kitaoka 120a6e
    return static_cast<Der &>(*this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  difference_type operator-(const Der &other) const {
Shinya Kitaoka 120a6e
    return static_cast<const base_iterator &>(*this) -
Shinya Kitaoka 120a6e
           static_cast<const base_iterator &>(other);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  typedef derived_iterator<It, Der, std::bidirectional_iterator_tag> _iter;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Cast Iterator  definition
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  A cast iterator is a utility iterator wrapper that can be used to access
Toshihiro Shimizu 890ddd
  an iterator's data through a supplied functor intermediary, proving to be
Toshihiro Shimizu 890ddd
  especially useful when converting data from a container to another with
Toshihiro Shimizu 890ddd
  minimal effort.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template 
Shinya Kitaoka 120a6e
          typename Val = typename traits<
Shinya Kitaoka 120a6e
              typename function_traits<Func>::ret_type>::referenced_type,
Shinya Kitaoka 120a6e
          typename Ref = typename choose_if_match<
Shinya Kitaoka 120a6e
              typename function_traits<Func>::ret_type &,
Shinya Kitaoka 120a6e
              typename traits<Val>::reference_type>::type,
Shinya Kitaoka 120a6e
          typename Ptr = typename choose_if_match<
Shinya Kitaoka 120a6e
              Ref, void, typename traits<Val>::pointer_type>::type>
Shinya Kitaoka 120a6e
class cast_iterator
Shinya Kitaoka 120a6e
    : public derived_iterator<It, cast_iterator<It, Func, Val, Ref, Ptr>> {
Shinya Kitaoka 120a6e
  typedef derived_iterator<It, cast_iterator> iterator;
Shinya Kitaoka 120a6e
  typedef typename iterator::base_iterator base_iterator;
Shinya Kitaoka 120a6e
  typedef Func function;
Shinya Kitaoka 120a6e
  typedef typename function_traits<Func>::ret_type ret_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef Ref reference;
Shinya Kitaoka 120a6e
  typedef Ptr pointer;
Shinya Kitaoka 120a6e
  typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  cast_iterator() : iterator(), m_func() {}
Shinya Kitaoka 120a6e
  cast_iterator(const Func &func) : iterator(), m_func(func) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  cast_iterator(const base_iterator &it) : iterator(it), m_func() {}
Shinya Kitaoka 120a6e
  cast_iterator(const base_iterator &it, const Func &func)
Shinya Kitaoka 120a6e
      : iterator(it), m_func(func) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  cast_iterator(const base_iterator &it, const cast_iterator &other)
Shinya Kitaoka 120a6e
      : iterator(it), m_func(other.m_func) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ret_type operator*() { return m_func(iterator::operator*()); }
Shinya Kitaoka 120a6e
  pointer operator->() { return ptr(0); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  Func m_func;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  template <typename T>
Shinya Kitaoka 120a6e
  pointer ptr(T,
Shinya Kitaoka 120a6e
              typename tcg::enable_if<tcg::type_mismatch<pointer, void>::value,
Shinya Kitaoka 120a6e
                                      T>::type = 0) const {
Shinya Kitaoka 120a6e
    return &operator*();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void ptr(char) const {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Utility maker function
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename It, typename Func>
Shinya Kitaoka 120a6e
inline cast_iterator<It, Func> make_cast_it(const It &it, Func func) {
Shinya Kitaoka 120a6e
  return cast_iterator<It, Func>(it, func);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***********************************************************************
Toshihiro Shimizu 890ddd
//    Step Iterator class
Toshihiro Shimizu 890ddd
//***********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  The Step Iterator class is a simple random access iterator wrapper which
Toshihiro Shimizu 890ddd
  moves by a fixed number of items.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\warning The size of the container referenced by the wrapped iterator should
Toshihiro Shimizu 890ddd
  always be a multiple of the specified step.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename RanIt>
Shinya Kitaoka 120a6e
class step_iterator : public std::iterator<
Shinya Kitaoka 120a6e
                          std::random_access_iterator_tag,
Shinya Kitaoka 120a6e
                          typename std::iterator_traits<RanIt>::value_type,
Shinya Kitaoka 120a6e
                          typename std::iterator_traits<RanIt>::difference_type,
Shinya Kitaoka 120a6e
                          typename std::iterator_traits<RanIt>::pointer,
Shinya Kitaoka 120a6e
                          typename std::iterator_traits<RanIt>::reference> {
Shinya Kitaoka 120a6e
  RanIt m_it;
Shinya Kitaoka 120a6e
  typename step_iterator::difference_type m_step;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  step_iterator() {}
Shinya Kitaoka 120a6e
  step_iterator(const RanIt &it, typename step_iterator::difference_type step)
Shinya Kitaoka 120a6e
      : m_it(it), m_step(step) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator &operator++() {
Shinya Kitaoka 120a6e
    m_it += m_step;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator &operator--() {
Shinya Kitaoka 120a6e
    m_it -= m_step;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator operator++(int) {
Shinya Kitaoka 120a6e
    step_iterator it(*this);
Shinya Kitaoka 120a6e
    operator++();
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator operator--(int) {
Shinya Kitaoka 120a6e
    step_iterator it(*this);
Shinya Kitaoka 120a6e
    operator--();
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator &operator+=(
Shinya Kitaoka 120a6e
      const typename step_iterator::difference_type &val) {
Shinya Kitaoka 120a6e
    m_it += val * m_step;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator &operator-=(
Shinya Kitaoka 120a6e
      const typename step_iterator::difference_type &val) {
Shinya Kitaoka 120a6e
    m_it -= val * m_step;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typename step_iterator::difference_type operator-(
Shinya Kitaoka 120a6e
      const step_iterator &it) const {
Shinya Kitaoka 120a6e
    return (m_it - it.m_it) / m_step;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator operator+(
Shinya Kitaoka 120a6e
      const typename step_iterator::difference_type &val) const {
Shinya Kitaoka 120a6e
    step_iterator it(*this);
Shinya Kitaoka 120a6e
    it += val;
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  step_iterator operator-(
Shinya Kitaoka 120a6e
      const typename step_iterator::difference_type &val) const {
Shinya Kitaoka 120a6e
    step_iterator it(*this);
Shinya Kitaoka 120a6e
    it -= val;
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typename step_iterator::reference operator*() const { return *m_it; }
Shinya Kitaoka 120a6e
  typename step_iterator::pointer operator->() const {
Shinya Kitaoka 120a6e
    return m_it.operator->();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const RanIt &it() const { return m_it; }
Shinya Kitaoka 120a6e
  int step() const { return m_step; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const step_iterator &it) const { return m_it == it.m_it; }
Shinya Kitaoka 120a6e
  bool operator!=(const step_iterator &it) const { return !operator==(it); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator<(const step_iterator &it) const { return m_it < it.m_it; }
Shinya Kitaoka 120a6e
  bool operator>(const step_iterator &it) const { return m_it > it.m_it; }
Shinya Kitaoka 120a6e
  bool operator<=(const step_iterator &it) const { return m_it <= it.m_it; }
Shinya Kitaoka 120a6e
  bool operator>=(const step_iterator &it) const { return m_it >= it.m_it; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_ITERATOR_OPS_H