Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:43

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     Definition of the unput queue iterator
0005 
0006     http://www.boost.org/
0007 
0008     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0009     Software License, Version 1.0. (See accompanying file
0010     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0011 =============================================================================*/
0012 #if !defined(BOOST_UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)
0013 #define BOOST_UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED
0014 
0015 #include <list>
0016 
0017 #include <boost/assert.hpp>
0018 #include <boost/iterator_adaptors.hpp>
0019 
0020 #include <boost/wave/wave_config.hpp>
0021 #include <boost/wave/token_ids.hpp>     // token_id
0022 
0023 // this must occur after all of the includes and before any code appears
0024 #ifdef BOOST_HAS_ABI_HEADERS
0025 #include BOOST_ABI_PREFIX
0026 #endif
0027 
0028 ///////////////////////////////////////////////////////////////////////////////
0029 namespace boost {
0030 namespace wave {
0031 namespace util {
0032 
0033 ///////////////////////////////////////////////////////////////////////////////
0034 //
0035 //  unput_queue_iterator
0036 //
0037 //      The unput_queue_iterator templates encapsulates an unput_queue together
0038 //      with the direct input to be read after the unput queue is emptied
0039 //
0040 //      This version is for the new iterator_adaptors (was released with
0041 //      Boost V1.31.0)
0042 //
0043 ///////////////////////////////////////////////////////////////////////////////
0044 template <typename IteratorT, typename TokenT, typename ContainerT>
0045 class unput_queue_iterator
0046 :   public boost::iterator_adaptor<
0047         unput_queue_iterator<IteratorT, TokenT, ContainerT>,
0048             IteratorT, TokenT const, std::forward_iterator_tag>
0049 {
0050     typedef boost::iterator_adaptor<
0051                 unput_queue_iterator<IteratorT, TokenT, ContainerT>,
0052                 IteratorT, TokenT const, std::forward_iterator_tag>
0053         base_type;
0054 
0055 public:
0056     typedef ContainerT  container_type;
0057     typedef IteratorT   iterator_type;
0058 
0059     unput_queue_iterator(IteratorT const &it, ContainerT &queue)
0060     :   base_type(it), unput_queue(queue)
0061     {}
0062 
0063     ContainerT &get_unput_queue()
0064         { return unput_queue; }
0065     ContainerT const &get_unput_queue() const
0066         { return unput_queue; }
0067     IteratorT &get_base_iterator()
0068         { return base_type::base_reference(); }
0069     IteratorT const &get_base_iterator() const
0070         { return base_type::base_reference(); }
0071 
0072     unput_queue_iterator &operator= (unput_queue_iterator const &rhs)
0073     {
0074         if (this != &rhs) {
0075             unput_queue = rhs.unput_queue;
0076             base_type::operator=(rhs);
0077         }
0078         return *this;
0079     }
0080 
0081     typename base_type::reference dereference() const
0082     {
0083         if (!unput_queue.empty())
0084             return unput_queue.front();
0085         return *base_type::base_reference();
0086     }
0087 
0088     void increment()
0089     {
0090         if (!unput_queue.empty()) {
0091             // there exist pending tokens in the unput queue
0092             unput_queue.pop_front();
0093         }
0094         else {
0095             // the unput_queue is empty, so advance the base iterator
0096             ++base_type::base_reference();
0097         }
0098     }
0099 
0100     template <
0101         typename OtherDerivedT, typename OtherIteratorT,
0102         typename V, typename C, typename R, typename D
0103     >
0104     bool equal(
0105         boost::iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
0106         const &x) const
0107     {
0108     // two iterators are equal, if both begin() iterators of the queue
0109     // objects are equal and the base iterators are equal as well
0110         OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
0111         return
0112             ((unput_queue.empty() && rhs.unput_queue.empty()) ||
0113               (&unput_queue == &rhs.unput_queue &&
0114                unput_queue.begin() == rhs.unput_queue.begin()
0115               )
0116             ) &&
0117             (get_base_iterator() == rhs.get_base_iterator());
0118     }
0119 
0120 private:
0121     ContainerT &unput_queue;
0122 };
0123 
0124 namespace impl {
0125 
0126     ///////////////////////////////////////////////////////////////////////////
0127     template <typename IteratorT, typename TokenT, typename ContainerT>
0128     struct gen_unput_queue_iterator
0129     {
0130         typedef ContainerT  container_type;
0131         typedef IteratorT iterator_type;
0132         typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
0133             return_type;
0134 
0135         static container_type last;
0136 
0137         static return_type
0138         generate(iterator_type const &it)
0139         {
0140             return return_type(it, last);
0141         }
0142 
0143         static return_type
0144         generate(ContainerT &queue, iterator_type const &it)
0145         {
0146             return return_type(it, queue);
0147         }
0148     };
0149 
0150     template <typename IteratorT, typename TokenT, typename ContainerT>
0151     typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
0152           container_type
0153         gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::last =
0154             typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
0155                   container_type();
0156 
0157     ///////////////////////////////////////////////////////////////////////////
0158     template <typename IteratorT, typename TokenT, typename ContainerT>
0159     struct gen_unput_queue_iterator<
0160         unput_queue_iterator<IteratorT, TokenT, ContainerT>,
0161             TokenT, ContainerT>
0162     {
0163         typedef ContainerT  container_type;
0164         typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
0165             iterator_type;
0166         typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
0167             return_type;
0168 
0169         static container_type last;
0170 
0171         static return_type
0172         generate(iterator_type &it)
0173         {
0174             return return_type(it.base(), last);
0175         }
0176 
0177         static return_type
0178         generate(ContainerT &queue, iterator_type &it)
0179         {
0180             return return_type(it.base(), queue);
0181         }
0182     };
0183 
0184     ///////////////////////////////////////////////////////////////////////////
0185     template <typename IteratorT>
0186     struct assign_iterator
0187     {
0188         static void
0189         do_ (IteratorT &dest, IteratorT const &src)
0190         {
0191             dest = src;
0192         }
0193     };
0194 
0195     ///////////////////////////////////////////////////////////////////////////
0196     //
0197     // Look for the first non-whitespace token and return this token id.
0198     // Note though, that the embedded unput_queues are not touched in any way!
0199     //
0200     template <typename IteratorT>
0201     struct next_token
0202     {
0203         static boost::wave::token_id
0204         peek(IteratorT it, IteratorT end, bool skip_whitespace = true)
0205         {
0206             using namespace boost::wave;
0207             if (skip_whitespace) {
0208                 for (++it; it != end; ++it) {
0209                     if (!IS_CATEGORY(*it, WhiteSpaceTokenType) &&
0210                         T_NEWLINE != token_id(*it))
0211                     {
0212                         break;  // stop at the first non-whitespace token
0213                     }
0214                 }
0215             }
0216             else {
0217                 ++it;           // we have at least to look ahead
0218             }
0219             if (it != end)
0220                 return token_id(*it);
0221             return T_EOI;
0222         }
0223     };
0224 
0225     template <typename IteratorT, typename TokenT, typename ContainerT>
0226     struct next_token<
0227         unput_queue_iterator<IteratorT, TokenT, ContainerT> > {
0228 
0229         typedef unput_queue_iterator<IteratorT, TokenT, ContainerT> iterator_type;
0230 
0231         static boost::wave::token_id
0232         peek(iterator_type it, iterator_type end, bool skip_whitespace = true)
0233         {
0234             using namespace boost::wave;
0235 
0236         typename iterator_type::container_type &queue = it.get_unput_queue();
0237 
0238         // first try to find it in the unput_queue
0239             if (0 != queue.size()) {
0240             typename iterator_type::container_type::iterator cit = queue.begin();
0241             typename iterator_type::container_type::iterator cend = queue.end();
0242 
0243                 if (skip_whitespace) {
0244                     for (++cit; cit != cend; ++cit) {
0245                         if (!IS_CATEGORY(*cit, WhiteSpaceTokenType) &&
0246                             T_NEWLINE != token_id(*cit))
0247                         {
0248                             break;  // stop at the first non-whitespace token
0249                         }
0250                     }
0251                 }
0252                 else {
0253                     ++cit;          // we have at least to look ahead
0254                 }
0255                 if (cit != cend)
0256                     return token_id(*cit);
0257             }
0258 
0259         // second try to move on into the base iterator stream
0260         typename iterator_type::iterator_type base_it = it.get_base_iterator();
0261         typename iterator_type::iterator_type base_end = end.get_base_iterator();
0262 
0263             if (0 == queue.size())
0264                 ++base_it;  // advance, if the unput queue is empty
0265 
0266             if (skip_whitespace) {
0267                 for (/**/; base_it != base_end; ++base_it) {
0268                     if (!IS_CATEGORY(*base_it, WhiteSpaceTokenType) &&
0269                         T_NEWLINE != token_id(*base_it))
0270                     {
0271                         break;  // stop at the first non-whitespace token
0272                     }
0273                 }
0274             }
0275             if (base_it == base_end)
0276                 return T_EOI;
0277 
0278             return token_id(*base_it);
0279         }
0280     };
0281 
0282 ///////////////////////////////////////////////////////////////////////////////
0283 }   // namespace impl
0284 
0285 ///////////////////////////////////////////////////////////////////////////////
0286 }   // namespace util
0287 }   // namespace wave
0288 }   // namespace boost
0289 
0290 // the suffix header occurs after all of the code
0291 #ifdef BOOST_HAS_ABI_HEADERS
0292 #include BOOST_ABI_SUFFIX
0293 #endif
0294 
0295 #endif // !defined(BOOST_UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)