blob: 41d6b43fa4e8f4c047f577bf09ddd54f683bdf23 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2010 Daniel James
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_QUICKBOOK_ITERATOR_HPP)
#define BOOST_SPIRIT_QUICKBOOK_ITERATOR_HPP
#include <boost/operators.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/range/iterator_range.hpp>
#include <iterator>
namespace quickbook
{
struct file_position
{
file_position() : line(1), column(1) {}
file_position(int l, int c) : line(l), column(c) {}
int line;
int column;
};
template <typename Iterator>
struct position_iterator
: boost::forward_iterator_helper<
position_iterator<Iterator>,
typename boost::iterator_value<Iterator>::type,
typename boost::iterator_difference<Iterator>::type,
typename boost::iterator_pointer<Iterator>::type,
typename boost::iterator_reference<Iterator>::type
>
{
position_iterator() {}
explicit position_iterator(Iterator base)
: original_(base), base_(base), previous_('\0'), position_() {}
explicit position_iterator(Iterator base, file_position const& position)
: original_(base), base_(base), previous_('\0'), position_(position) {}
friend bool operator==(
position_iterator const& x,
position_iterator const& y)
{
return x.base_ == y.base_;
}
position_iterator& operator++()
{
char val = *base_;
if (val == '\r') {
++position_.line;
position_.column = 1;
}
else if (val == '\n') {
if (previous_ != '\r') {
++position_.line;
position_.column = 1;
}
}
else {
++position_.column;
}
previous_ = val;
++base_;
return *this;
}
typename boost::iterator_reference<Iterator>::type operator*() const
{
return *base_;
}
file_position const& get_position() const {
return position_;
}
Iterator base() const {
return base_;
}
typedef boost::iterator_range<std::reverse_iterator<Iterator> >
lookback_range;
lookback_range lookback() const
{
return lookback_range(base_, original_);
}
private:
Iterator original_;
Iterator base_;
char previous_;
file_position position_;
};
}
#endif