|
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 |
|
|
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=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
struct iterator_traits : public std::iterator_traits<it> {</it>
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
Shinya Kitaoka |
120a6e |
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 |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename iterator_tag =
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::iterator_category></it>
|
|
Shinya Kitaoka |
120a6e |
struct derived_iterator
|
|
Shinya Kitaoka |
120a6e |
: public tcg::iterator_traits<it>::inheritable_iterator_type {</it>
|
|
Shinya Kitaoka |
120a6e |
typedef typename tcg::iterator_traits<it>::inheritable_iterator_type</it>
|
|
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);</der>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
Der operator++(int) {
|
|
Shinya Kitaoka |
120a6e |
return Der(base_iterator::operator++(0), static_cast<der &="">(*this));</der>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
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,>
|
|
Shinya Kitaoka |
120a6e |
: public derived_iterator<it, der,="" std::forward_iterator_tag=""> {</it,>
|
|
Shinya Kitaoka |
120a6e |
typedef typename tcg::iterator_traits<it>::inheritable_iterator_type</it>
|
|
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);</der>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
Der operator--(int) {
|
|
Shinya Kitaoka |
120a6e |
return Der(base_iterator::operator--(0), static_cast<der &="">(*this));</der>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
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,>
|
|
Shinya Kitaoka |
120a6e |
: public derived_iterator<it, der,="" std::bidirectional_iterator_tag=""> {</it,>
|
|
Shinya Kitaoka |
120a6e |
typedef typename tcg::iterator_traits<it>::inheritable_iterator_type</it>
|
|
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,</const>
|
|
Shinya Kitaoka |
120a6e |
static_cast<const &="" der="">(*this));</const>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
Der &operator+=(difference_type d) {
|
|
Shinya Kitaoka |
120a6e |
static_cast<base_iterator &="">(*this) += d;</base_iterator>
|
|
Shinya Kitaoka |
120a6e |
return static_cast<der &="">(*this);</der>
|
|
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,</const>
|
|
Shinya Kitaoka |
120a6e |
static_cast<const &="" der="">(*this));</const>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
Der &operator-=(difference_type d) {
|
|
Shinya Kitaoka |
120a6e |
static_cast<base_iterator &="">(*this) -= d;</base_iterator>
|
|
Shinya Kitaoka |
120a6e |
return static_cast<der &="">(*this);</der>
|
|
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) -</const>
|
|
Shinya Kitaoka |
120a6e |
static_cast<const &="" base_iterator="">(other);</const>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
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
|
|
Shinya Kitaoka |
120a6e |
typename Val = typename traits<
|
|
Shinya Kitaoka |
120a6e |
typename function_traits<func>::ret_type>::referenced_type,</func>
|
|
Shinya Kitaoka |
120a6e |
typename Ref = typename choose_if_match<
|
|
Shinya Kitaoka |
120a6e |
typename function_traits<func>::ret_type &,</func>
|
|
Shinya Kitaoka |
120a6e |
typename traits<val>::reference_type>::type,</val>
|
|
Shinya Kitaoka |
120a6e |
typename Ptr = typename choose_if_match<
|
|
Shinya Kitaoka |
120a6e |
Ref, void, typename traits<val>::pointer_type>::type></val>
|
|
Shinya Kitaoka |
120a6e |
class cast_iterator
|
|
Shinya Kitaoka |
120a6e |
: public derived_iterator<it, cast_iterator<it,="" func,="" ptr="" ref,="" val,="">> {</it,>
|
|
Shinya Kitaoka |
120a6e |
typedef derived_iterator<it, cast_iterator=""> iterator;</it,>
|
|
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;</func>
|
|
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=""></typename>
|
|
Shinya Kitaoka |
120a6e |
pointer ptr(T,
|
|
Shinya Kitaoka |
120a6e |
typename tcg::enable_if<tcg::type_mismatch<pointer, void="">::value,</tcg::type_mismatch<pointer,>
|
|
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 func="" it,="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline cast_iterator<it, func=""> make_cast_it(const It &it, Func func) {</it,>
|
|
Shinya Kitaoka |
120a6e |
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>
|
|
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,</ranit>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<ranit>::difference_type,</ranit>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<ranit>::pointer,</ranit>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<ranit>::reference> {</ranit>
|
|
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
|