|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_CYCLIC_H
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_CYCLIC_H
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include <iterator></iterator>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "numeric_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tcg {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Cyclic helpers
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace cyclic_ops {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline bool ll(Scalar a, Scalar b, Scalar c) {
|
|
Shinya Kitaoka |
120a6e |
return a <= c ? a < b && b < c : c > b || b > a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline bool lel(Scalar a, Scalar b, Scalar c) {
|
|
Shinya Kitaoka |
120a6e |
return a <= c ? a <= b && b < c : c > b || b >= a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline bool lle(Scalar a, Scalar b, Scalar c) {
|
|
Shinya Kitaoka |
120a6e |
return a <= c ? a < b && b <= c : c >= b || b > a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline bool lele(Scalar a, Scalar b, Scalar c) {
|
|
Shinya Kitaoka |
120a6e |
return a <= c ? a <= b && b <= c : c >= b || b >= a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef min
|
|
Toshihiro Shimizu |
890ddd |
#undef min
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
Scalar min(Scalar a, Scalar b, Scalar ref) {
|
|
Shinya Kitaoka |
120a6e |
return lel(ref, a, b) ? a : b;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef max
|
|
Toshihiro Shimizu |
890ddd |
#undef max
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename scalar=""></typename>
|
|
Shinya Kitaoka |
120a6e |
Scalar max(Scalar a, Scalar b, Scalar ref) {
|
|
Shinya Kitaoka |
120a6e |
return lel(ref, a, b) ? a : b;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename diff_type="" typename="" value_type,=""></typename>
|
|
Shinya Kitaoka |
120a6e |
value_type increased(const value_type &val, const value_type &start,
|
|
Shinya Kitaoka |
120a6e |
diff_type length) {
|
|
Shinya Kitaoka |
120a6e |
return start + numeric_ops::mod(val - start + 1, length);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename diff_type="" typename="" value_type,=""></typename>
|
|
Shinya Kitaoka |
120a6e |
value_type increased(const value_type &val, const value_type &start,
|
|
Shinya Kitaoka |
120a6e |
diff_type length, diff_type add) {
|
|
Shinya Kitaoka |
120a6e |
return start + numeric_ops::mod(val - start + add, length);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename diff_type="" typename="" value_type,=""></typename>
|
|
Shinya Kitaoka |
120a6e |
value_type decreased(const value_type &val, const value_type &start,
|
|
Shinya Kitaoka |
120a6e |
diff_type length) {
|
|
Shinya Kitaoka |
120a6e |
return start + numeric_ops::mod(val - start - 1, length);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename diff_type="" typename="" value_type,=""></typename>
|
|
Shinya Kitaoka |
120a6e |
value_type decreased(const value_type &val, const value_type &start,
|
|
Shinya Kitaoka |
120a6e |
diff_type length, diff_type add) {
|
|
Shinya Kitaoka |
120a6e |
return start + numeric_ops::mod(val - start - add, length);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace cyclic_ops
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Cyclic Iterators
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename Cat = typename std::iterator_traits<it>::iterator_category></it>
|
|
Toshihiro Shimizu |
890ddd |
class cyclic_iterator;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename it=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
class cyclic_iterator<it, std::forward_iterator_tag=""></it,>
|
|
Shinya Kitaoka |
120a6e |
: public std::iterator
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::value_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::difference_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::pointer,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::reference> {</it>
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
It m_it, m_begin, m_end;
|
|
Shinya Kitaoka |
120a6e |
int m_lap;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator() : m_lap(0) {}
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator(const It &it, const It &begin, const It &end, int lap = 0)
|
|
Shinya Kitaoka |
120a6e |
: m_it(it), m_begin(begin), m_end(end), m_lap(lap) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator++() {
|
|
Shinya Kitaoka |
120a6e |
if (++m_it == m_end) ++m_lap, m_it = m_begin;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator++(int) {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
operator++();
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::reference operator*() { return *m_it; }
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::pointer operator->() { return m_it.operator->(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_it == it.m_it && m_lap == it.m_lap;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const cyclic_iterator &it) const { return !operator==(it); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename it=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
class cyclic_iterator<it, std::bidirectional_iterator_tag=""></it,>
|
|
Shinya Kitaoka |
120a6e |
: public std::iterator
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::value_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::difference_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::pointer,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::reference> {</it>
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
It m_it, m_begin, m_end;
|
|
Shinya Kitaoka |
120a6e |
int m_lap;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator() : m_lap(0) {}
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator(const It &it, const It &begin, const It &end, int lap = 0)
|
|
Shinya Kitaoka |
120a6e |
: m_it(it), m_begin(begin), m_end(end), m_lap(lap) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator++() {
|
|
Shinya Kitaoka |
120a6e |
if (++m_it == m_end) ++m_lap, m_it = m_begin;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator--() {
|
|
Shinya Kitaoka |
120a6e |
if (m_it == m_begin) --m_lap, m_it = m_end;
|
|
Shinya Kitaoka |
120a6e |
--m_it;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator++(int) {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
operator++();
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator--(int) {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
operator--();
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::reference operator*() { return *m_it; }
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::pointer operator->() { return m_it.operator->(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_it == it.m_it && m_lap == it.m_lap;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const cyclic_iterator &it) const { return !operator==(it); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename it=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
class cyclic_iterator<it, std::random_access_iterator_tag=""></it,>
|
|
Shinya Kitaoka |
120a6e |
: public std::iterator
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::value_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::difference_type,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::pointer,</it>
|
|
Shinya Kitaoka |
120a6e |
typename std::iterator_traits<it>::reference> {</it>
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
It m_it, m_begin, m_end;
|
|
Shinya Kitaoka |
120a6e |
int m_lap;
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::difference_type m_count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator() : m_lap(0), m_count(0) {}
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator(const It &it, const It &begin, const It &end, int lap = 0)
|
|
Shinya Kitaoka |
120a6e |
: m_it(it)
|
|
Shinya Kitaoka |
120a6e |
, m_begin(begin)
|
|
Shinya Kitaoka |
120a6e |
, m_end(end)
|
|
Shinya Kitaoka |
120a6e |
, m_lap(lap)
|
|
Shinya Kitaoka |
120a6e |
, m_count(m_end - m_begin) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator++() {
|
|
Shinya Kitaoka |
120a6e |
if (++m_it == m_end) ++m_lap, m_it = m_begin;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator--() {
|
|
Shinya Kitaoka |
120a6e |
if (m_it == m_begin) --m_lap, m_it = m_end;
|
|
Shinya Kitaoka |
120a6e |
--m_it;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator++(int) {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
operator++();
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator--(int) {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
operator--();
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator+=(
|
|
Shinya Kitaoka |
120a6e |
const typename cyclic_iterator::difference_type &val) {
|
|
Shinya Kitaoka |
120a6e |
m_lap += (val + (m_it - m_begin)) / m_count;
|
|
Shinya Kitaoka |
120a6e |
m_it = cyclic_ops::increased(m_it, m_begin, m_count, val);
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator &operator-=(
|
|
Shinya Kitaoka |
120a6e |
const typename cyclic_iterator::difference_type &val) {
|
|
Shinya Kitaoka |
120a6e |
m_lap -= (val + (m_end - m_it)) / m_count;
|
|
Shinya Kitaoka |
120a6e |
m_it = cyclic_ops::decreased(m_it, m_begin, m_count, val);
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::difference_type operator-(
|
|
Shinya Kitaoka |
120a6e |
const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
assert(m_begin == it.m_begin && m_end == it.m_end);
|
|
Shinya Kitaoka |
120a6e |
return m_it - it.m_it + m_lap * m_count - it.m_lap * it.m_count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator+(
|
|
Shinya Kitaoka |
120a6e |
const typename cyclic_iterator::difference_type &val) const {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
it += val;
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator operator-(
|
|
Shinya Kitaoka |
120a6e |
const typename cyclic_iterator::difference_type &val) const {
|
|
Shinya Kitaoka |
120a6e |
cyclic_iterator it(*this);
|
|
Shinya Kitaoka |
120a6e |
it -= val;
|
|
Shinya Kitaoka |
120a6e |
return it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::reference operator*() const { return *m_it; }
|
|
Shinya Kitaoka |
120a6e |
typename cyclic_iterator::pointer operator->() const {
|
|
Shinya Kitaoka |
120a6e |
return m_it.operator->();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_it == it.m_it && m_lap == it.m_lap;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const cyclic_iterator &it) const { return !operator==(it); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator<(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_lap < it.m_lap || m_it < it.m_it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator>(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_lap > it.m_lap || m_it > it.m_it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator<=(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_lap <= it.m_lap || m_it <= it.m_it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator>=(const cyclic_iterator &it) const {
|
|
Shinya Kitaoka |
120a6e |
return m_lap >= it.m_lap || m_it >= it.m_it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#endif // TCG_CYCLIC_H
|