1 /*==============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2010 Bryce Lelbach
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
9 #if !defined(BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR)
10 #define BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR
12 #include <boost/iterator/iterator_adaptor.hpp>
13 #include <boost/range/iterator_range.hpp>
15 namespace boost { namespace spirit
17 //[line_pos_iterator_class
18 /*`The `line_pos_iterator` is a lightweight line position iterator.
19 This iterator adapter only stores the current line number, nothing else.
20 Unlike __classic__'s `position_iterator`, it does not store the
21 column number and does not need an end iterator. The current column can
22 be computed, if needed. */
23 //`[heading Class Reference]
24 template <class Iterator>
25 class line_pos_iterator : public boost::iterator_adaptor<
26 line_pos_iterator<Iterator> // Derived
28 , boost::use_default // Value
29 , boost::forward_traversal_tag // CategoryOrTraversal
34 explicit line_pos_iterator(Iterator);
36 std::size_t position() const;
39 friend class boost::iterator_core_access;
43 std::size_t line; // The line position.
44 typename std::iterator_traits<Iterator>::value_type prev;
48 template <class Iterator>
49 line_pos_iterator<Iterator>::line_pos_iterator() :
50 line_pos_iterator::iterator_adaptor_(), line(1), prev(0) { }
52 template <class Iterator>
53 line_pos_iterator<Iterator>::line_pos_iterator(Iterator base) :
54 line_pos_iterator::iterator_adaptor_(base), line(1), prev(0) { }
56 template <class Iterator>
57 std::size_t line_pos_iterator<Iterator>::position() const
62 template<class Iterator>
63 void line_pos_iterator<Iterator>::increment()
65 typename std::iterator_traits<Iterator>::reference
66 ref = *(this->base());
82 ++this->base_reference();
85 //[line_pos_iterator_utilities
87 template <class Iterator>
88 inline std::size_t get_line(Iterator);
89 /*`Get the line position. Returns -1 if Iterator is not a
90 `line_pos_iterator`. */
92 //`[heading get_line_start]
93 template <class Iterator>
94 inline Iterator get_line_start(Iterator lower_bound, Iterator current);
95 /*`Get an iterator to the beginning of the line. Applicable to any
98 //`[heading get_current_line]
99 template <class Iterator>
100 inline iterator_range<Iterator>
101 get_current_line(Iterator lower_bound, Iterator current,
102 Iterator upper_bound);
103 /*`Get an `iterator_range` containing the current line. Applicable to any
106 //`[heading get_column]
107 template <class Iterator>
108 inline std::size_t get_column(Iterator lower_bound, Iterator current,
109 std::size_t tabs = 4);
110 /*`Get the current column. Applicable to any iterator. */
113 template <class Iterator>
114 inline std::size_t get_line(Iterator)
119 template <class Iterator>
120 inline std::size_t get_line(line_pos_iterator<Iterator> i)
125 template <class Iterator>
126 inline Iterator get_line_start(Iterator lower_bound, Iterator current)
128 Iterator latest = lower_bound;
130 for (Iterator i = lower_bound; i != current; ++i) {
141 template <class Iterator>
142 inline iterator_range<Iterator>
143 get_current_line(Iterator lower_bound,
145 Iterator upper_bound)
147 Iterator first = get_line_start(lower_bound, current);
148 Iterator last = get_line_start(current, upper_bound);
153 return iterator_range<Iterator>(first, last);
156 template <class Iterator>
157 inline std::size_t get_column(Iterator lower_bound,
161 std::size_t column = 1;
162 Iterator first = get_line_start(lower_bound, current);
164 for (Iterator i = first; i != current; ++i) {
167 column += tabs - (column - 1) % tabs;
179 #endif // BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR