lalr/PositionIterator.hpp
2018-04-03 19:09:26 +12:00

110 lines
3.3 KiB
C++

#ifndef LALR_POSITIONITERATOR_HPP_INCLUDED
#define LALR_POSITIONITERATOR_HPP_INCLUDED
#include <iterator>
namespace lalr
{
/**
// An iterator wrapper that adds line number tracking to iterators or
// pointers.
*/
template <class Iterator>
class PositionIterator
{
public:
typedef std::forward_iterator_tag iterator_category; ///< The type of this iterator (always forward regardless of the underlying iterator).
typedef typename std::iterator_traits<Iterator>::difference_type difference_type; ///< The type to represent the difference between two iterators.
typedef typename std::iterator_traits<Iterator>::value_type value_type; ///< The type of the element the iterator can point to.
typedef typename std::iterator_traits<Iterator>::pointer pointer; ///< The type of a pointer to an element the iterator can point to.
typedef typename std::iterator_traits<Iterator>::reference reference; ///< Type to represent a reference to an element pointed by the iterator.
private:
Iterator position_; ///< The current position of this iterator.
Iterator end_; ///< One past the last position of the input sequence for this iterator.
bool ended_; ///< True if this iterator has reached its end.
int line_; ///< The current line number of this iterator.
public:
PositionIterator()
: position_(),
end_(),
ended_( true ),
line_( 1 )
{
}
PositionIterator( Iterator begin, Iterator end )
: position_( begin ),
end_( end ),
ended_( begin == end ),
line_( 1 )
{
}
PositionIterator( const PositionIterator& iterator )
: position_( iterator.position_ ),
end_( iterator.end_ ),
ended_( iterator.ended_ ),
line_( iterator.line_ )
{
}
PositionIterator& operator=( const PositionIterator& iterator )
{
if ( this != &iterator )
{
position_ = iterator.position_;
end_ = iterator.end_;
ended_ = iterator.ended_;
line_ = iterator.line_;
}
return *this;
}
PositionIterator& operator++()
{
int character = *position_;
++position_;
if ( character == '\n' || (character == '\r' && (position_ == end_ || *position_ != '\n')) )
{
++line_;
}
ended_ = position_ == end_;
return *this;
}
value_type operator*() const
{
return *position_;
}
int line() const
{
return line_;
}
bool operator!=( const PositionIterator& iterator ) const
{
return ended_ || iterator.ended_ ? ended_ != iterator.ended_ : position_ != iterator.position_;
}
bool operator==( const PositionIterator& iterator ) const
{
return ended_ || iterator.ended_ ? ended_ == iterator.ended_ : position_ == iterator.position_;
}
};
}
#endif