position_iterator.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 433 行
HPP
433 行
/*============================================================================= Copyright (c) 2002 Juan Carlos Arevalo-Baeza Copyright (c) 2002-2003 Hartmut Kaiser Copyright (c) 2003 Giovanni Bajo http://spirit.sourceforge.net/ 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)=============================================================================*/#ifndef BOOST_SPIRIT_POSITION_ITERATOR_HPP#define BOOST_SPIRIT_POSITION_ITERATOR_HPP#include <string>#include <boost/config.hpp>#include <boost/concept_check.hpp>namespace boost { namespace spirit {/////////////////////////////////////////////////////////////////////////////////// file_position_without_column//// A structure to hold positional information. This includes the file,// and the line number/////////////////////////////////////////////////////////////////////////////////struct file_position_without_column { std::string file; int line; file_position_without_column(std::string const& file_ = std::string(), int line_ = 1): file (file_), line (line_) {} bool operator==(const file_position_without_column& fp) const { return line == fp.line && file == fp.file; }};/////////////////////////////////////////////////////////////////////////////////// file_position//// This structure holds complete file position, including file name,// line and column number/////////////////////////////////////////////////////////////////////////////////struct file_position : public file_position_without_column { int column; file_position(std::string const& file_ = std::string(), int line_ = 1, int column_ = 1): file_position_without_column (file_, line_), column (column_) {} bool operator==(const file_position& fp) const { return column == fp.column && line == fp.line && file == fp.file; }};/////////////////////////////////////////////////////////////////////////////////// position_policy<>//// This template is the policy to handle the file position. It is specialized// on the position type. Providing a custom file_position also requires// providing a specialization of this class.//// Policy interface://// Default constructor of the custom position class must be accessible.// set_tab_chars(unsigned int chars) - Set the tabstop width// next_char(PositionT& pos) - Notify that a new character has been// processed// tabulation(PositionT& pos) - Notify that a tab character has been// processed// next_line(PositionT& pos) - Notify that a new line delimiter has// been reached./////////////////////////////////////////////////////////////////////////////////template <typename PositionT>class position_policy;// Forward declarationtemplate <typename ForwardIteratorT, typename PositionT, typename SelfT>class position_iterator;///////////////////////////////////////////////////////////////////////////////}} /* namespace boost::spirit */// This must be included here for full compatibility with old MSVC#include "impl/position_iterator.ipp"///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit {/////////////////////////////////////////////////////////////////////////////////// position_iterator//// It wraps an iterator, and keeps track of the current position in the input,// as it gets incremented.//// The wrapped iterator must be at least a Forward iterator. The position// iterator itself will always be a non-mutable Forward iterator.//// In order to have begin/end iterators constructed, the end iterator must be// empty constructed. Similar to what happens with stream iterators. The begin// iterator must be constructed from both, the begin and end iterators of the// wrapped iterator type. This is necessary to implement the lookahead of// characters necessary to parse CRLF sequences.//// In order to extract the current positional data from the iterator, you may// use the get_position member function.//// You can also use the set_position member function to reset the current// position to something new.//// The structure that holds the current position can be customized through a// template parameter, and the class position_policy must be specialized// on the new type to define how to handle it. Currently, it's possible// to choose between the file_position and file_position_without_column// (which saves some overhead if managing current column is not required)./////////////////////////////////////////////////////////////////////////////////#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \ BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200#error "Please use at least Boost V1.31.0 while compiling the position_iterator class!"#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200/////////////////////////////////////////////////////////////////////////////////// Uses the newer iterator_adaptor version (should be released with// Boost V1.31.0)/////////////////////////////////////////////////////////////////////////////////template < typename ForwardIteratorT, typename PositionT = file_position, typename SelfT = nil_t>class position_iterator: public iterator_::impl::position_iterator_base_generator< SelfT, ForwardIteratorT, PositionT >::type, public position_policy<PositionT>{private: typedef position_policy<PositionT> position_policy_t; typedef typename iterator_::impl::position_iterator_base_generator< SelfT, ForwardIteratorT, PositionT >::type base_t; typedef typename iterator_::impl::position_iterator_base_generator< SelfT, ForwardIteratorT, PositionT >::main_iter_t main_iter_t;public: typedef PositionT position_t; position_iterator() : _isend(true) {} position_iterator( const ForwardIteratorT& begin, const ForwardIteratorT& end) : base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end) {} template <typename FileNameT> position_iterator( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT fileName) : base_t(begin), _end(end), _pos(PositionT(fileName)), _isend(begin == end) {} template <typename FileNameT, typename LineT> position_iterator( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT fileName, LineT line) : base_t(begin), _end(end), _pos(PositionT(fileName, line)), _isend(begin == end) {} template <typename FileNameT, typename LineT, typename ColumnT> position_iterator( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT fileName, LineT line, ColumnT column) : base_t(begin), _end(end), _pos(PositionT(fileName, line, column)), _isend(begin == end) {} position_iterator( const ForwardIteratorT& begin, const ForwardIteratorT& end, const PositionT& pos) : base_t(begin), _end(end), _pos(pos), _isend(begin == end) {} position_iterator(const position_iterator& iter) : base_t(iter.base()), position_policy_t(iter), _end(iter._end), _pos(iter._pos), _isend(iter._isend) {} position_iterator& operator=(const position_iterator& iter) { base_t::operator=(iter); position_policy_t::operator=(iter); _end = iter._end; _pos = iter._pos; _isend = iter._isend; return *this; } void set_position(PositionT const& newpos) { _pos = newpos; } PositionT& get_position() { return _pos; } PositionT const& get_position() const { return _pos; } void set_tabchars(unsigned int chars) { // This function (which comes from the position_policy) has a // different name on purpose, to avoid messing with using // declarations or qualified calls to access the base template // function, which might break some compilers. this->position_policy_t::set_tab_chars(chars); }private: friend class boost::iterator_core_access; void increment() { typename base_t::reference val = *(this->base()); if (val == '\n' || val == '\r') { ++this->base_reference(); if (this->base_reference() != _end) { typename base_t::reference val2 = *(this->base()); if ((val == '\n' && val2 == '\r') || (val == '\r' && val2 == '\n')) { ++this->base_reference(); } } this->next_line(_pos); static_cast<main_iter_t &>(*this).newline(); } else if (val == '\t') { this->tabulation(_pos); ++this->base_reference(); } else { this->next_char(_pos); ++this->base_reference(); } // The iterator is at the end only if it's the same // of the _isend = (this->base_reference() == _end); } template < typename OtherDerivedT, typename OtherIteratorT, typename V, typename C, typename R, typename D > bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D> const &x) const { OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x); bool x_is_end = rhs._isend; return (_isend && x_is_end) || (!_isend && !x_is_end && this->base() == rhs.base()); }protected: void newline(void) {} ForwardIteratorT _end; PositionT _pos; bool _isend;};#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200/////////////////////////////////////////////////////////////////////////////////// position_iterator2//// Equivalent to position_iterator, but it is able to extract the current// line into a string. This is very handy for error reports.//// Notice that the footprint of this class is higher than position_iterator,// (how much depends on how bulky the underlying iterator is), so it should// be used only if necessary./////////////////////////////////////////////////////////////////////////////////template< typename ForwardIteratorT, typename PositionT = file_position>class position_iterator2 : public position_iterator < ForwardIteratorT, PositionT, position_iterator2<ForwardIteratorT, PositionT> >{ typedef position_iterator < ForwardIteratorT, PositionT, position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03 > base_t;public: typedef typename base_t::value_type value_type; typedef PositionT position_t; position_iterator2() {} position_iterator2( const ForwardIteratorT& begin, const ForwardIteratorT& end): base_t(begin, end), _startline(begin) {} template <typename FileNameT> position_iterator2( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT file): base_t(begin, end, file), _startline(begin) {} template <typename FileNameT, typename LineT> position_iterator2( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT file, LineT line): base_t(begin, end, file, line), _startline(begin) {} template <typename FileNameT, typename LineT, typename ColumnT> position_iterator2( const ForwardIteratorT& begin, const ForwardIteratorT& end, FileNameT file, LineT line, ColumnT column): base_t(begin, end, file, line, column), _startline(begin) {} position_iterator2( const ForwardIteratorT& begin, const ForwardIteratorT& end, const PositionT& pos): base_t(begin, end, pos), _startline(begin) {} position_iterator2(const position_iterator2& iter) : base_t(iter), _startline(iter._startline) {} position_iterator2& operator=(const position_iterator2& iter) { base_t::operator=(iter); _startline = iter._startline; return *this; } ForwardIteratorT get_currentline_begin(void) const { return _startline; } ForwardIteratorT get_currentline_end(void) const { return get_endline(); } std::basic_string<value_type> get_currentline(void) const { return std::basic_string<value_type> (get_currentline_begin(), get_currentline_end()); }protected: ForwardIteratorT _startline; friend class position_iterator<ForwardIteratorT, PositionT, position_iterator2<ForwardIteratorT, PositionT> >; ForwardIteratorT get_endline() const { ForwardIteratorT endline = _startline; while (endline != this->_end && *endline != '\r' && *endline != '\n') { ++endline; } return endline; } void newline(void) { _startline = this->base(); }};}} // namespace boost::spirit#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?