Files
CDAG/Research/core/Util/IndexIterator.h

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;
}