constant_iterator.h

Back to Iterator

pastel/sys/iterator/

// Description: ConstantIterator class
// Detail: A constant value iterator 
// Documentation: iterator.txt

#ifndef PASTELSYS_CONSTANT_ITERATOR_H
#define PASTELSYS_CONSTANT_ITERATOR_H

#include "pastel/sys/mytypes.h"
#include "pastel/sys/range.h"

#include <boost/operators.hpp>

#include <iterator>

namespace Pastel
{

    template <typename Type>
    class ConstantIterator
        : public boost::random_access_iterator_helper<
        ConstantIterator<Type>, Type, integer, const Type*, const Type>
    {
    public:
        // Note the reference is const Type and not const Type&.
        // You can't return a reference since a temporary 
        // iterator can get destructed before the data
        // is accessed.

        // Using default copy constructor.
        // Using default assignment.
        // Using default destructor.

        ConstantIterator()
            : index_(0)
            , data_()
        {
        }

        explicit ConstantIterator(const Type& data, integer index = 0)
            : index_(index)
            , data_(data)
        {
        }

        ConstantIterator& operator++()
        {
            ++index_;
            return *this;
        }

        ConstantIterator& operator--()
        {
            --index_;
            return *this;
        }

        ConstantIterator& operator+=(integer that)
        {
            index_ += that;
            return *this;
        }

        ConstantIterator& operator-=(integer that)
        {
            index_ -= that;
            return *this;
        }

        integer operator-(const ConstantIterator& that) const
        {
            return index_ - that.index_;
        }

        //const Type& operator*() const
        Type operator*() const
        {
            return data_;
        }

        bool operator==(const ConstantIterator& that) const
        {
            return index_ == that.index_;
        }

        bool operator<(const ConstantIterator& that) const
        {
            return index_ < that.index_;
        }

    private:
        integer index_;
        Type data_;
    };

    template <typename Type>
    ConstantIterator<Type> constantIterator(
        const Type& that, integer index = 0)
    {
        return ConstantIterator<Type>(that, index);
    }

    template <typename Type>
    using ConstantRange = 
        boost::iterator_range<ConstantIterator<Type>>;

    template <typename Type>
    ConstantRange<Type> constantRange(
        const Type& that, integer size = 1)
    {
        return Pastel::range(constantIterator(that), constantIterator(that, size));
    }

}

#endif