Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:09:01

0001 /*=============================================================================
0002     Copyright (c) 2002 Juan Carlos Arevalo-Baeza
0003     Copyright (c) 2002-2006 Hartmut Kaiser
0004     Copyright (c) 2003 Giovanni Bajo
0005     http://spirit.sourceforge.net/
0006 
0007   Distributed under the Boost Software License, Version 1.0. (See accompanying
0008   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 #ifndef BOOST_SPIRIT_POSITION_ITERATOR_HPP
0011 #define BOOST_SPIRIT_POSITION_ITERATOR_HPP
0012 
0013 #include <string>
0014 #include <boost/config.hpp>
0015 
0016 #include <boost/spirit/home/classic/namespace.hpp>
0017 #include <boost/spirit/home/classic/iterator/position_iterator_fwd.hpp>
0018 
0019 namespace boost { namespace spirit {
0020 
0021 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0022 
0023 ///////////////////////////////////////////////////////////////////////////////
0024 //
0025 //  file_position_without_column
0026 //
0027 //  A structure to hold positional information. This includes the file,
0028 //  and the line number
0029 //
0030 ///////////////////////////////////////////////////////////////////////////////
0031 template <typename String>
0032 struct file_position_without_column_base {
0033     String file;
0034     int line;
0035 
0036     file_position_without_column_base(String const& file_ = String(),
0037                   int line_ = 1):
0038         file    (file_),
0039         line    (line_)
0040     {}
0041 
0042     bool operator==(const file_position_without_column_base& fp) const
0043     { return line == fp.line && file == fp.file; }
0044 };
0045 
0046 ///////////////////////////////////////////////////////////////////////////////
0047 //
0048 //  file_position
0049 //
0050 //  This structure holds complete file position, including file name,
0051 //  line and column number
0052 //
0053 ///////////////////////////////////////////////////////////////////////////////
0054 template <typename String>
0055 struct file_position_base : public file_position_without_column_base<String> {
0056     int column;
0057 
0058     file_position_base(String const& file_ = String(),
0059                        int line_ = 1, int column_ = 1):
0060         file_position_without_column_base<String> (file_, line_),
0061         column                       (column_)
0062     {}
0063 
0064     bool operator==(const file_position_base& fp) const
0065     { return column == fp.column && this->line == fp.line && this->file == fp.file; }
0066 };
0067 
0068 ///////////////////////////////////////////////////////////////////////////////
0069 //
0070 //  position_policy<>
0071 //
0072 //  This template is the policy to handle the file position. It is specialized
0073 //  on the position type. Providing a custom file_position also requires
0074 //  providing a specialization of this class.
0075 //
0076 //  Policy interface:
0077 //
0078 //    Default constructor of the custom position class must be accessible.
0079 //    set_tab_chars(unsigned int chars) - Set the tabstop width
0080 //    next_char(PositionT& pos)  - Notify that a new character has been
0081 //      processed
0082 //    tabulation(PositionT& pos) - Notify that a tab character has been
0083 //      processed
0084 //    next_line(PositionT& pos)  - Notify that a new line delimiter has
0085 //      been reached.
0086 //
0087 ///////////////////////////////////////////////////////////////////////////////
0088 template <typename PositionT> class position_policy;
0089 
0090 ///////////////////////////////////////////////////////////////////////////////
0091 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0092 
0093 }} /* namespace BOOST_SPIRIT_CLASSIC_NS */
0094 
0095 
0096 // This must be included here for full compatibility with old MSVC
0097 #include <boost/spirit/home/classic/iterator/impl/position_iterator.ipp>
0098 
0099 ///////////////////////////////////////////////////////////////////////////////
0100 namespace boost { namespace spirit {
0101 
0102 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0103 
0104 ///////////////////////////////////////////////////////////////////////////////
0105 //
0106 //  position_iterator
0107 //
0108 //  It wraps an iterator, and keeps track of the current position in the input,
0109 //  as it gets incremented.
0110 //
0111 //  The wrapped iterator must be at least a Forward iterator. The position
0112 //  iterator itself will always be a non-mutable Forward iterator.
0113 //
0114 //  In order to have begin/end iterators constructed, the end iterator must be
0115 //  empty constructed. Similar to what happens with stream iterators. The begin
0116 //  iterator must be constructed from both, the begin and end iterators of the
0117 //  wrapped iterator type. This is necessary to implement the lookahead of
0118 //  characters necessary to parse CRLF sequences.
0119 //
0120 //  In order to extract the current positional data from the iterator, you may
0121 //  use the get_position member function.
0122 //
0123 //  You can also use the set_position member function to reset the current
0124 //  position to something new.
0125 //
0126 //  The structure that holds the current position can be customized through a
0127 //  template parameter, and the class position_policy must be specialized
0128 //  on the new type to define how to handle it. Currently, it's possible
0129 //  to choose between the file_position and file_position_without_column
0130 //  (which saves some overhead if managing current column is not required).
0131 //
0132 ///////////////////////////////////////////////////////////////////////////////
0133 
0134 #if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
0135      BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0136 #error "Please use at least Boost V1.31.0 while compiling the position_iterator class!"
0137 #else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0138 
0139 ///////////////////////////////////////////////////////////////////////////////
0140 //
0141 //  Uses the newer iterator_adaptor version (should be released with
0142 //  Boost V1.31.0)
0143 //
0144 ///////////////////////////////////////////////////////////////////////////////
0145 template <
0146     typename ForwardIteratorT,
0147     typename PositionT,
0148     typename SelfT
0149 >
0150 class position_iterator
0151 :   public iterator_::impl::position_iterator_base_generator<
0152         SelfT,
0153         ForwardIteratorT,
0154         PositionT
0155     >::type,
0156     public position_policy<PositionT>
0157 {
0158 private:
0159 
0160     typedef position_policy<PositionT> position_policy_t;
0161     typedef typename iterator_::impl::position_iterator_base_generator<
0162             SelfT,
0163             ForwardIteratorT,
0164             PositionT
0165         >::type base_t;
0166     typedef typename iterator_::impl::position_iterator_base_generator<
0167             SelfT,
0168             ForwardIteratorT,
0169             PositionT
0170         >::main_iter_t main_iter_t;
0171 
0172 public:
0173 
0174     typedef PositionT position_t;
0175 
0176     position_iterator()
0177     :   _isend(true)
0178     {}
0179 
0180     position_iterator(
0181         const ForwardIteratorT& begin,
0182         const ForwardIteratorT& end)
0183     :   base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end)
0184     {}
0185 
0186     template <typename FileNameT>
0187     position_iterator(
0188         const ForwardIteratorT& begin,
0189         const ForwardIteratorT& end,
0190         FileNameT fileName)
0191     :   base_t(begin), _end(end), _pos(PositionT(fileName)),
0192         _isend(begin == end)
0193     {}
0194 
0195     template <typename FileNameT, typename LineT>
0196     position_iterator(
0197         const ForwardIteratorT& begin,
0198         const ForwardIteratorT& end,
0199         FileNameT fileName, LineT line)
0200     :   base_t(begin), _end(end), _pos(PositionT(fileName, line)),
0201         _isend(begin == end)
0202     {}
0203 
0204     template <typename FileNameT, typename LineT, typename ColumnT>
0205     position_iterator(
0206         const ForwardIteratorT& begin,
0207         const ForwardIteratorT& end,
0208         FileNameT fileName, LineT line, ColumnT column)
0209     :   base_t(begin), _end(end), _pos(PositionT(fileName, line, column)),
0210         _isend(begin == end)
0211     {}
0212 
0213     position_iterator(
0214         const ForwardIteratorT& begin,
0215         const ForwardIteratorT& end,
0216         const PositionT& pos)
0217     :   base_t(begin), _end(end), _pos(pos), _isend(begin == end)
0218     {}
0219 
0220     position_iterator(const position_iterator& iter)
0221     :   base_t(iter.base()), position_policy_t(iter),
0222         _end(iter._end), _pos(iter._pos), _isend(iter._isend)
0223     {}
0224 
0225     position_iterator& operator=(const position_iterator& iter)
0226     {
0227         base_t::operator=(iter);
0228         position_policy_t::operator=(iter);
0229         _end = iter._end;
0230         _pos = iter._pos;
0231         _isend = iter._isend;
0232         return *this;
0233     }
0234 
0235     void set_position(PositionT const& newpos) { _pos = newpos; }
0236     PositionT& get_position() { return _pos; }
0237     PositionT const& get_position() const { return _pos; }
0238 
0239     void set_tabchars(unsigned int chars)
0240     {
0241         // This function (which comes from the position_policy) has a
0242         //  different name on purpose, to avoid messing with using
0243         //  declarations or qualified calls to access the base template
0244         //  function, which might break some compilers.
0245         this->position_policy_t::set_tab_chars(chars);
0246     }
0247 
0248 private:
0249     friend class boost::iterator_core_access;
0250 
0251     void increment()
0252     {
0253         typename base_t::reference val = *(this->base());
0254         if (val == '\n') {
0255             ++this->base_reference();
0256             this->next_line(_pos);
0257             static_cast<main_iter_t &>(*this).newline();
0258         }
0259         else if ( val == '\r') {
0260             ++this->base_reference();
0261             if (this->base_reference() == _end || *(this->base()) != '\n')
0262             {
0263                 this->next_line(_pos);
0264                 static_cast<main_iter_t &>(*this).newline();
0265             }
0266         }
0267         else if (val == '\t') {
0268             this->tabulation(_pos);
0269             ++this->base_reference();
0270         }
0271         else {
0272             this->next_char(_pos);
0273             ++this->base_reference();
0274         }
0275 
0276         // The iterator is at the end only if it's the same
0277         //  of the
0278         _isend = (this->base_reference() == _end);
0279     }
0280 
0281     template <
0282         typename OtherDerivedT, typename OtherIteratorT,
0283         typename V, typename C, typename R, typename D
0284     >
0285     bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
0286         const &x) const
0287     {
0288         OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
0289         bool x_is_end = rhs._isend;
0290 
0291         return (_isend == x_is_end) && (_isend || this->base() == rhs.base());
0292     }
0293 
0294 protected:
0295 
0296     void newline()
0297     {}
0298 
0299     ForwardIteratorT _end;
0300     PositionT _pos;
0301     bool _isend;
0302 };
0303 
0304 #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0305 
0306 ///////////////////////////////////////////////////////////////////////////////
0307 //
0308 //  position_iterator2
0309 //
0310 //  Equivalent to position_iterator, but it is able to extract the current
0311 //  line into a string. This is very handy for error reports.
0312 //
0313 //  Notice that the footprint of this class is higher than position_iterator,
0314 //  (how much depends on how bulky the underlying iterator is), so it should
0315 //  be used only if necessary.
0316 //
0317 ///////////////////////////////////////////////////////////////////////////////
0318 
0319 template
0320 <
0321     typename ForwardIteratorT,
0322     typename PositionT
0323 >
0324 class position_iterator2
0325     : public position_iterator
0326     <
0327         ForwardIteratorT,
0328         PositionT,
0329         position_iterator2<ForwardIteratorT, PositionT>
0330     >
0331 {
0332     typedef position_iterator
0333     <
0334         ForwardIteratorT,
0335         PositionT,
0336         position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03
0337     >  base_t;
0338 
0339 public:
0340     typedef typename base_t::value_type value_type;
0341     typedef PositionT position_t;
0342 
0343     position_iterator2()
0344     {}
0345 
0346     position_iterator2(
0347         const ForwardIteratorT& begin,
0348         const ForwardIteratorT& end):
0349         base_t(begin, end),
0350         _startline(begin)
0351     {}
0352 
0353     template <typename FileNameT>
0354     position_iterator2(
0355         const ForwardIteratorT& begin,
0356         const ForwardIteratorT& end,
0357         FileNameT file):
0358         base_t(begin, end, file),
0359         _startline(begin)
0360     {}
0361 
0362     template <typename FileNameT, typename LineT>
0363     position_iterator2(
0364         const ForwardIteratorT& begin,
0365         const ForwardIteratorT& end,
0366         FileNameT file, LineT line):
0367         base_t(begin, end, file, line),
0368         _startline(begin)
0369     {}
0370 
0371     template <typename FileNameT, typename LineT, typename ColumnT>
0372     position_iterator2(
0373         const ForwardIteratorT& begin,
0374         const ForwardIteratorT& end,
0375         FileNameT file, LineT line, ColumnT column):
0376         base_t(begin, end, file, line, column),
0377         _startline(begin)
0378     {}
0379 
0380     position_iterator2(
0381         const ForwardIteratorT& begin,
0382         const ForwardIteratorT& end,
0383         const PositionT& pos):
0384         base_t(begin, end, pos),
0385         _startline(begin)
0386     {}
0387 
0388     position_iterator2(const position_iterator2& iter)
0389         : base_t(iter), _startline(iter._startline)
0390     {}
0391 
0392     position_iterator2& operator=(const position_iterator2& iter)
0393     {
0394         base_t::operator=(iter);
0395         _startline = iter._startline;
0396         return *this;
0397     }
0398 
0399     ForwardIteratorT get_currentline_begin() const
0400     { return _startline; }
0401 
0402     ForwardIteratorT get_currentline_end() const
0403     { return get_endline(); }
0404 
0405     std::basic_string<value_type> get_currentline() const
0406     {
0407         return std::basic_string<value_type>
0408             (get_currentline_begin(), get_currentline_end());
0409     }
0410 
0411 protected:
0412     ForwardIteratorT _startline;
0413 
0414     friend class position_iterator<ForwardIteratorT, PositionT,
0415         position_iterator2<ForwardIteratorT, PositionT> >;
0416 
0417     ForwardIteratorT get_endline() const
0418     {
0419         ForwardIteratorT endline = _startline;
0420         while (endline != this->_end && *endline != '\r' && *endline != '\n')
0421         {
0422             ++endline;
0423         }
0424         return endline;
0425     }
0426 
0427     void newline()
0428     { _startline = this->base(); }
0429 };
0430 
0431 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0432 
0433 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0434 
0435 #endif