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></iterator>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Traits
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename it=""></typename>
Toshihiro Shimizu 890ddd
struct iterator_traits : public std::iterator_traits<it> {</it>
Toshihiro Shimizu 890ddd
	typedef It inheritable_iterator_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct iterator_traits<t *=""> : public std::iterator_traits<t *=""> {</t></t>
Toshihiro Shimizu 890ddd
	typedef ptr<t> inheritable_iterator_type;</t>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
//    Derived Iterator  definition
Toshihiro Shimizu 890ddd
//****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename der,="" it,="" iterator_tag="typename" std::iterator_traits<it="" typename="">::iterator_category></typename>
Toshihiro Shimizu 890ddd
struct derived_iterator : public tcg::iterator_traits<it>::inheritable_iterator_type {</it>
Toshihiro Shimizu 890ddd
	typedef typename tcg::iterator_traits<it>::inheritable_iterator_type base_iterator;</it>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	derived_iterator() : base_iterator() {}
Toshihiro Shimizu 890ddd
	derived_iterator(const base_iterator &it) : base_iterator(it) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Der &operator++()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		base_iterator::operator++();
Toshihiro Shimizu 890ddd
		return static_cast<der &="">(*this);</der>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	Der operator++(int) { return Der(base_iterator::operator++(0), static_cast<der &="">(*this)); }</der>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename der="" it,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct derived_iterator<it, der,="" std::bidirectional_iterator_tag=""></it,>
Toshihiro Shimizu 890ddd
	: public derived_iterator<it, der,="" std::forward_iterator_tag=""> {</it,>
Toshihiro Shimizu 890ddd
	typedef typename tcg::iterator_traits<it>::inheritable_iterator_type base_iterator;</it>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	derived_iterator() : _iter() {}
Toshihiro Shimizu 890ddd
	derived_iterator(const base_iterator &it) : _iter(it) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Der &operator--()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		base_iterator::operator--();
Toshihiro Shimizu 890ddd
		return static_cast<der &="">(*this);</der>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	Der operator--(int) { return Der(base_iterator::operator--(0), static_cast<der &="">(*this)); }</der>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	typedef derived_iterator<it, der,="" std::forward_iterator_tag=""> _iter;</it,>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename der="" it,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct derived_iterator<it, der,="" std::random_access_iterator_tag=""></it,>
Toshihiro Shimizu 890ddd
	: public derived_iterator<it, der,="" std::bidirectional_iterator_tag=""> {</it,>
Toshihiro Shimizu 890ddd
	typedef typename tcg::iterator_traits<it>::inheritable_iterator_type base_iterator;</it>
Toshihiro Shimizu 890ddd
	typedef typename base_iterator::difference_type difference_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	derived_iterator() : _iter() {}
Toshihiro Shimizu 890ddd
	derived_iterator(const base_iterator &it) : _iter(it) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Der operator+(difference_type d) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return Der(static_cast<const &="" base_iterator="">(*this) + d,</const>
Toshihiro Shimizu 890ddd
				   static_cast<const &="" der="">(*this));</const>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	Der &operator+=(difference_type d)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		static_cast<base_iterator &="">(*this) += d;</base_iterator>
Toshihiro Shimizu 890ddd
		return static_cast<der &="">(*this);</der>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Der operator-(difference_type d) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return Der(static_cast<const &="" base_iterator="">(*this) - d,</const>
Toshihiro Shimizu 890ddd
				   static_cast<const &="" der="">(*this));</const>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	Der &operator-=(difference_type d)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		static_cast<base_iterator &="">(*this) -= d;</base_iterator>
Toshihiro Shimizu 890ddd
		return static_cast<der &="">(*this);</der>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	difference_type operator-(const Der &other) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return static_cast<const &="" base_iterator="">(*this) -</const>
Toshihiro Shimizu 890ddd
			   static_cast<const &="" base_iterator="">(other);</const>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	typedef derived_iterator<it, der,="" std::bidirectional_iterator_tag=""> _iter;</it,>
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 
Toshihiro Shimizu 890ddd
		  typename Val = typename traits<typename function_traits<func="">::ret_type>::referenced_type,</typename>
Toshihiro Shimizu 890ddd
		  typename Ref = typename choose_if_match<typename function_traits<func="">::ret_type &, typename traits<val>::reference_type>::type,</val></typename>
Toshihiro Shimizu 890ddd
		  typename Ptr = typename choose_if_match<ref, traits<val="" typename="" void,="">::pointer_type>::type></ref,>
Toshihiro Shimizu 890ddd
class cast_iterator : public derived_iterator<it, cast_iterator<it,="" func,="" ptr="" ref,="" val,="">></it,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	typedef derived_iterator<it, cast_iterator=""> iterator;</it,>
Toshihiro Shimizu 890ddd
	typedef typename iterator::base_iterator base_iterator;
Toshihiro Shimizu 890ddd
	typedef Func function;
Toshihiro Shimizu 890ddd
	typedef typename function_traits<func>::ret_type ret_type;</func>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef Ref reference;
Toshihiro Shimizu 890ddd
	typedef Ptr pointer;
Toshihiro Shimizu 890ddd
	typedef Val value_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	cast_iterator() : iterator(), m_func() {}
Toshihiro Shimizu 890ddd
	cast_iterator(const Func &func) : iterator(), m_func(func) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	cast_iterator(const base_iterator &it) : iterator(it), m_func() {}
Toshihiro Shimizu 890ddd
	cast_iterator(const base_iterator &it, const Func &func) : iterator(it), m_func(func) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	cast_iterator(const base_iterator &it, const cast_iterator &other)
Toshihiro Shimizu 890ddd
		: iterator(it), m_func(other.m_func) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ret_type operator*() { return m_func(iterator::operator*()); }
Toshihiro Shimizu 890ddd
	pointer operator->() { return ptr(0); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	Func m_func;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	pointer ptr(T, typename tcg::enable_if<tcg::type_mismatch<pointer, void="">::value, T>::type = 0) const</tcg::type_mismatch<pointer,>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return &operator*();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	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 func="" it,="" typename=""></typename>
Toshihiro Shimizu 890ddd
inline cast_iterator<it, func=""> make_cast_it(const It &it, Func func)</it,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return cast_iterator<it, func="">(it, func);</it,>
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=""></typename>
Toshihiro Shimizu 890ddd
class step_iterator
Toshihiro Shimizu 890ddd
	: public std::iterator
Toshihiro Shimizu 890ddd
						   typename std::iterator_traits<ranit>::value_type,</ranit>
Toshihiro Shimizu 890ddd
						   typename std::iterator_traits<ranit>::difference_type,</ranit>
Toshihiro Shimizu 890ddd
						   typename std::iterator_traits<ranit>::pointer,</ranit>
Toshihiro Shimizu 890ddd
						   typename std::iterator_traits<ranit>::reference></ranit>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	RanIt m_it;
Toshihiro Shimizu 890ddd
	typename step_iterator::difference_type m_step;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	step_iterator() {}
Toshihiro Shimizu 890ddd
	step_iterator(const RanIt &it, typename step_iterator::difference_type step) : m_it(it), m_step(step) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator &operator++()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_it += m_step;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator &operator--()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_it -= m_step;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator operator++(int)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		step_iterator it(*this);
Toshihiro Shimizu 890ddd
		operator++();
Toshihiro Shimizu 890ddd
		return it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator operator--(int)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		step_iterator it(*this);
Toshihiro Shimizu 890ddd
		operator--();
Toshihiro Shimizu 890ddd
		return it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator &operator+=(const typename step_iterator::difference_type &val)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_it += val * m_step;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator &operator-=(const typename step_iterator::difference_type &val)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_it -= val * m_step;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typename step_iterator::difference_type operator-(const step_iterator &it) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return (m_it - it.m_it) / m_step;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator operator+(const typename step_iterator::difference_type &val) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		step_iterator it(*this);
Toshihiro Shimizu 890ddd
		it += val;
Toshihiro Shimizu 890ddd
		return it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	step_iterator operator-(const typename step_iterator::difference_type &val) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		step_iterator it(*this);
Toshihiro Shimizu 890ddd
		it -= val;
Toshihiro Shimizu 890ddd
		return it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typename step_iterator::reference operator*() const { return *m_it; }
Toshihiro Shimizu 890ddd
	typename step_iterator::pointer operator->() const { return m_it.operator->(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const RanIt &it() const { return m_it; }
Toshihiro Shimizu 890ddd
	int step() const { return m_step; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator==(const step_iterator &it) const { return m_it == it.m_it; }
Toshihiro Shimizu 890ddd
	bool operator!=(const step_iterator &it) const { return !operator==(it); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator<(const step_iterator &it) const { return m_it < it.m_it; }
Toshihiro Shimizu 890ddd
	bool operator>(const step_iterator &it) const { return m_it > it.m_it; }
Toshihiro Shimizu 890ddd
	bool operator<=(const step_iterator &it) const { return m_it <= it.m_it; }
Toshihiro Shimizu 890ddd
	bool operator>=(const step_iterator &it) const { return m_it >= it.m_it; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace tcg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TCG_ITERATOR_OPS_H