188 lines
5.5 KiB
C++
188 lines
5.5 KiB
C++
#pragma once
|
|
#include <iterator>
|
|
|
|
template<typename ContainerT, typename T>
|
|
class IndexIterator : public std::iterator<std::random_access_iterator_tag, T>
|
|
{
|
|
protected:
|
|
size_t mIndex;
|
|
ContainerT* mContainer;
|
|
public:
|
|
typedef std::random_access_iterator_tag iterator_category;
|
|
typedef
|
|
typename iterator<std::random_access_iterator_tag, T>::value_type
|
|
value_type;
|
|
typedef
|
|
typename iterator<std::random_access_iterator_tag, T>::difference_type
|
|
difference_type;
|
|
typedef
|
|
typename iterator<std::random_access_iterator_tag, T>::reference
|
|
reference;
|
|
typedef
|
|
typename iterator<std::random_access_iterator_tag, T>::pointer
|
|
pointer;
|
|
|
|
|
|
IndexIterator() : mContainer(NULL), mIndex(0) {}
|
|
IndexIterator(ContainerT* container) : mContainer(container), mIndex(0) {}
|
|
IndexIterator(ContainerT* container, size_t index) : mContainer(container), mIndex(index) {}
|
|
IndexIterator(const IndexIterator<ContainerT, T>& r) : mContainer(r.mContainer), mIndex(r.mIndex) {}
|
|
|
|
IndexIterator& operator=(const IndexIterator& r)
|
|
{
|
|
mIndex = r.mIndex; mContainer = r.mContainer; return *this;
|
|
}
|
|
|
|
IndexIterator& operator++() // PREFIX
|
|
{
|
|
++mIndex; return *this;
|
|
}
|
|
|
|
IndexIterator& operator--() // PREFIX
|
|
{
|
|
--mIndex; return *this;
|
|
}
|
|
|
|
IndexIterator operator++(int) // POSTFIX
|
|
{
|
|
return IndexIterator(mContainer, mIndex++);
|
|
}
|
|
|
|
IndexIterator operator--(int) // POSTFIX
|
|
{
|
|
return IndexIterator(mContainer, mIndex--);
|
|
}
|
|
|
|
IndexIterator operator+(const difference_type& n) const
|
|
{
|
|
return IndexIterator(mContainer, mIndex + n);
|
|
}
|
|
|
|
IndexIterator& operator+=(const difference_type& n)
|
|
{
|
|
mIndex += n; return *this;
|
|
}
|
|
|
|
IndexIterator operator-(const difference_type& n) const
|
|
{
|
|
return IndexIterator(mContainer, mIndex - n);
|
|
}
|
|
|
|
IndexIterator& operator-=(const difference_type& n)
|
|
{
|
|
mIndex -= n; return *this;
|
|
}
|
|
|
|
reference operator*() const
|
|
{
|
|
return mContainer->operator[](mIndex);
|
|
}
|
|
|
|
pointer operator->() const
|
|
{
|
|
return &mContainer->operator[](mIndex);
|
|
}
|
|
|
|
reference operator[](const difference_type& n) const
|
|
{
|
|
return mContainer->operator[](mIndex + n);
|
|
}
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator==(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator!=(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator<(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator>(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator<=(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend bool operator>=(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend typename IndexIterator<ContainerTypeT, TypeT>::difference_type operator+(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
|
|
template<typename ContainerTypeT, typename TypeT>
|
|
friend typename IndexIterator<ContainerTypeT, TypeT>::difference_type operator-(
|
|
const IndexIterator<ContainerTypeT, TypeT>& r1,
|
|
const IndexIterator<ContainerTypeT, TypeT>& r2);
|
|
};
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator==(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
return (r1.mIndex == r2.mIndex && r1.mContainer == r2.mContainer);
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator!=(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
return ((r1.mIndex != r2.mIndex) || (r1.mContainer != r2.mContainer));
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator<(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
if (r1.mContainer != r2.mContainer) return r1.mContainer < r2.mContainer;
|
|
return (r1.mIndex < r2.mIndex);
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator>(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
if (r1.mContainer != r2.mContainer) return r1.mContainer > r2.mContainer;
|
|
return (r1.mIndex > r2.mIndex);
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator<=(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
if (r1.mContainer != r2.mContainer) return r1.mContainer < r2.mContainer;
|
|
return (r1.mIndex <= r2.mIndex);
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
bool operator>=(const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
if (r1.mContainer != r2.mContainer) return r1.mContainer > r2.mContainer;
|
|
return (r1.mIndex >= r2.mIndex);
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
typename IndexIterator<ContainerT, T>::difference_type operator+(
|
|
const IndexIterator<ContainerT, T>& r1,
|
|
const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
assert(r1.mContainer == r2.mContainer);
|
|
return r1.mIndex + r2.mIndex;
|
|
}
|
|
|
|
template<typename ContainerT, typename T>
|
|
typename IndexIterator<ContainerT, T>::difference_type operator-(
|
|
const IndexIterator<ContainerT, T>& r1, const IndexIterator<ContainerT, T>& r2)
|
|
{
|
|
assert(r1.mContainer == r2.mContainer);
|
|
return r1.mIndex - r2.mIndex;
|
|
}
|