12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298 |
- /*=============================================================================
- Copyright (c) 2001, Daniel C. Nuffer
- http://spirit.sourceforge.net/
- Distributed under 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_ITERATOR_MULTI_PASS_HPP
- #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
- #include <boost/config.hpp>
- #include <boost/throw_exception.hpp>
- #include <deque>
- #include <iterator>
- #include <iostream>
- #include <algorithm> // for std::swap
- #include <exception> // for std::exception
- #include <boost/limits.hpp>
- #include <boost/spirit/home/classic/namespace.hpp>
- #include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
- #include <boost/spirit/home/classic/iterator/fixed_size_queue.hpp>
- #include <boost/spirit/home/classic/iterator/multi_pass_fwd.hpp>
- namespace boost { namespace spirit {
- BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
- namespace impl {
- template <typename T>
- inline void mp_swap(T& t1, T& t2);
- }
- namespace multi_pass_policies
- {
- ///////////////////////////////////////////////////////////////////////////////
- // class ref_counted
- // Implementation of an OwnershipPolicy used by multi_pass.
- //
- // Implementation modified from RefCounted class from the Loki library by
- // Andrei Alexandrescu
- ///////////////////////////////////////////////////////////////////////////////
- class ref_counted
- {
- protected:
- ref_counted()
- : count(new std::size_t(1))
- {}
- ref_counted(ref_counted const& x)
- : count(x.count)
- {}
- // clone is called when a copy of the iterator is made, so increment
- // the ref-count.
- void clone()
- {
- ++*count;
- }
- // called when a copy is deleted. Decrement the ref-count. Return
- // value of true indicates that the last copy has been released.
- bool release()
- {
- if (!--*count)
- {
- delete count;
- count = 0;
- return true;
- }
- return false;
- }
- void swap(ref_counted& x)
- {
- impl::mp_swap(count, x.count);
- }
- public:
- // returns true if there is only one iterator in existence.
- // std_deque StoragePolicy will free it's buffered data if this
- // returns true.
- bool unique() const
- {
- return *count == 1;
- }
- private:
- std::size_t* count;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class first_owner
- // Implementation of an OwnershipPolicy used by multi_pass
- // This ownership policy dictates that the first iterator created will
- // determine the lifespan of the shared components. This works well for
- // spirit, since no dynamic allocation of iterators is done, and all copies
- // are make on the stack.
- //
- // There is a caveat about using this policy together with the std_deque
- // StoragePolicy. Since first_owner always returns false from unique(),
- // std_deque will only release the queued data if clear_queue() is called.
- ///////////////////////////////////////////////////////////////////////////////
- class first_owner
- {
- protected:
- first_owner()
- : first(true)
- {}
- first_owner(first_owner const&)
- : first(false)
- {}
- void clone()
- {
- }
- // return true to indicate deletion of resources
- bool release()
- {
- return first;
- }
- void swap(first_owner&)
- {
- // if we're the first, we still remain the first, even if assigned
- // to, so don't swap first_. swap is only called from operator=
- }
- public:
- bool unique() const
- {
- return false; // no way to know, so always return false
- }
- private:
- bool first;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class illegal_backtracking
- // thrown by buf_id_check CheckingPolicy if an instance of an iterator is
- // used after another one has invalidated the queue
- ///////////////////////////////////////////////////////////////////////////////
- class BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception
- {
- public:
- illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
- ~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
- const char*
- what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
- { return "BOOST_SPIRIT_CLASSIC_NS::illegal_backtracking"; }
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class buf_id_check
- // Implementation of the CheckingPolicy used by multi_pass
- // This policy is most effective when used together with the std_deque
- // StoragePolicy.
- // If used with the fixed_size_queue StoragePolicy, it will not detect
- // iterator dereferences that are out of the range of the queue.
- ///////////////////////////////////////////////////////////////////////////////
- class buf_id_check
- {
- protected:
- buf_id_check()
- : shared_buf_id(new unsigned long(0))
- , buf_id(0)
- {}
- buf_id_check(buf_id_check const& x)
- : shared_buf_id(x.shared_buf_id)
- , buf_id(x.buf_id)
- {}
- // will be called from the destructor of the last iterator.
- void destroy()
- {
- delete shared_buf_id;
- shared_buf_id = 0;
- }
- void swap(buf_id_check& x)
- {
- impl::mp_swap(shared_buf_id, x.shared_buf_id);
- impl::mp_swap(buf_id, x.buf_id);
- }
- // called to verify that everything is okay.
- void check_if_valid() const
- {
- if (buf_id != *shared_buf_id)
- {
- boost::throw_exception(illegal_backtracking());
- }
- }
- // called from multi_pass::clear_queue, so we can increment the count
- void clear_queue()
- {
- ++*shared_buf_id;
- ++buf_id;
- }
- private:
- unsigned long* shared_buf_id;
- unsigned long buf_id;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class no_check
- // Implementation of the CheckingPolicy used by multi_pass
- // It does not do anything :-)
- ///////////////////////////////////////////////////////////////////////////////
- class no_check
- {
- protected:
- no_check() {}
- no_check(no_check const&) {}
- void destroy() {}
- void swap(no_check&) {}
- void check_if_valid() const {}
- void clear_queue() {}
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class std_deque
- // Implementation of the StoragePolicy used by multi_pass
- // This stores all data in a std::deque, and keeps an offset to the current
- // position. It stores all the data unless there is only one
- // iterator using the queue.
- // Note: a position is used instead of an iterator, because a push_back on
- // a deque can invalidate any iterators.
- ///////////////////////////////////////////////////////////////////////////////
- class std_deque
- {
- public:
- template <typename ValueT>
- class inner
- {
- private:
- typedef std::deque<ValueT> queue_type;
- queue_type* queuedElements;
- mutable typename queue_type::size_type queuePosition;
- protected:
- inner()
- : queuedElements(new queue_type)
- , queuePosition(0)
- {}
- inner(inner const& x)
- : queuedElements(x.queuedElements)
- , queuePosition(x.queuePosition)
- {}
- // will be called from the destructor of the last iterator.
- void destroy()
- {
- BOOST_SPIRIT_ASSERT(NULL != queuedElements);
- delete queuedElements;
- queuedElements = 0;
- }
- void swap(inner& x)
- {
- impl::mp_swap(queuedElements, x.queuedElements);
- impl::mp_swap(queuePosition, x.queuePosition);
- }
- // This is called when the iterator is dereferenced. It's a template
- // method so we can recover the type of the multi_pass iterator
- // and call unique and access the m_input data member.
- template <typename MultiPassT>
- static typename MultiPassT::reference dereference(MultiPassT const& mp)
- {
- if (mp.queuePosition == mp.queuedElements->size())
- {
- // check if this is the only iterator
- if (mp.unique())
- {
- // free up the memory used by the queue.
- if (mp.queuedElements->size() > 0)
- {
- mp.queuedElements->clear();
- mp.queuePosition = 0;
- }
- }
- return mp.get_input();
- }
- else
- {
- return (*mp.queuedElements)[mp.queuePosition];
- }
- }
- // This is called when the iterator is incremented. It's a template
- // method so we can recover the type of the multi_pass iterator
- // and call unique and access the m_input data member.
- template <typename MultiPassT>
- static void increment(MultiPassT& mp)
- {
- if (mp.queuePosition == mp.queuedElements->size())
- {
- // check if this is the only iterator
- if (mp.unique())
- {
- // free up the memory used by the queue.
- if (mp.queuedElements->size() > 0)
- {
- mp.queuedElements->clear();
- mp.queuePosition = 0;
- }
- }
- else
- {
- mp.queuedElements->push_back(mp.get_input());
- ++mp.queuePosition;
- }
- mp.advance_input();
- }
- else
- {
- ++mp.queuePosition;
- }
- }
- // called to forcibly clear the queue
- void clear_queue()
- {
- queuedElements->clear();
- queuePosition = 0;
- }
- // called to determine whether the iterator is an eof iterator
- template <typename MultiPassT>
- static bool is_eof(MultiPassT const& mp)
- {
- return mp.queuePosition == mp.queuedElements->size() &&
- mp.input_at_eof();
- }
- // called by operator==
- bool equal_to(inner const& x) const
- {
- return queuePosition == x.queuePosition;
- }
- // called by operator<
- bool less_than(inner const& x) const
- {
- return queuePosition < x.queuePosition;
- }
- }; // class inner
- }; // class std_deque
- ///////////////////////////////////////////////////////////////////////////////
- // class fixed_size_queue
- // Implementation of the StoragePolicy used by multi_pass
- // fixed_size_queue keeps a circular buffer (implemented by
- // BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue class) that is size N+1 and stores N elements.
- // It is up to the user to ensure that there is enough look ahead for their
- // grammar. Currently there is no way to tell if an iterator is pointing
- // to forgotten data. The leading iterator will put an item in the queue
- // and remove one when it is incremented. No dynamic allocation is done,
- // except on creation of the queue (fixed_size_queue constructor).
- ///////////////////////////////////////////////////////////////////////////////
- template < std::size_t N>
- class fixed_size_queue
- {
- public:
- template <typename ValueT>
- class inner
- {
- private:
- typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<ValueT, N> queue_type;
- queue_type * queuedElements;
- mutable typename queue_type::iterator queuePosition;
- protected:
- inner()
- : queuedElements(new queue_type)
- , queuePosition(queuedElements->begin())
- {}
- inner(inner const& x)
- : queuedElements(x.queuedElements)
- , queuePosition(x.queuePosition)
- {}
- // will be called from the destructor of the last iterator.
- void destroy()
- {
- BOOST_SPIRIT_ASSERT(NULL != queuedElements);
- delete queuedElements;
- queuedElements = 0;
- }
- void swap(inner& x)
- {
- impl::mp_swap(queuedElements, x.queuedElements);
- impl::mp_swap(queuePosition, x.queuePosition);
- }
- // This is called when the iterator is dereferenced. It's a template
- // method so we can recover the type of the multi_pass iterator
- // and access the m_input data member.
- template <typename MultiPassT>
- static typename MultiPassT::reference dereference(MultiPassT const& mp)
- {
- if (mp.queuePosition == mp.queuedElements->end())
- {
- return mp.get_input();
- }
- else
- {
- return *mp.queuePosition;
- }
- }
- // This is called when the iterator is incremented. It's a template
- // method so we can recover the type of the multi_pass iterator
- // and access the m_input data member.
- template <typename MultiPassT>
- static void increment(MultiPassT& mp)
- {
- if (mp.queuePosition == mp.queuedElements->end())
- {
- // don't let the queue get larger than N
- if (mp.queuedElements->size() >= N)
- mp.queuedElements->pop_front();
- mp.queuedElements->push_back(mp.get_input());
- mp.advance_input();
- }
- ++mp.queuePosition;
- }
- // no-op
- void clear_queue()
- {}
- // called to determine whether the iterator is an eof iterator
- template <typename MultiPassT>
- static bool is_eof(MultiPassT const& mp)
- {
- return mp.queuePosition == mp.queuedElements->end() &&
- mp.input_at_eof();
- }
- // called by operator==
- bool equal_to(inner const& x) const
- {
- return queuePosition == x.queuePosition;
- }
- // called by operator<
- bool less_than(inner const& x) const
- {
- return queuePosition < x.queuePosition;
- }
- }; // class inner
- }; // class fixed_size_queue
- ///////////////////////////////////////////////////////////////////////////////
- // class input_iterator
- // Implementation of the InputPolicy used by multi_pass
- // input_iterator encapsulates an input iterator of type InputT
- ///////////////////////////////////////////////////////////////////////////////
- class input_iterator
- {
- public:
- template <typename InputT>
- class inner
- {
- private:
- typedef
- typename std::iterator_traits<InputT>::value_type
- result_type;
- public:
- typedef result_type value_type;
- private:
- struct Data {
- Data(InputT const &input_)
- : input(input_), was_initialized(false)
- {}
-
- InputT input;
- value_type curtok;
- bool was_initialized;
- };
- // Needed by compilers not implementing the resolution to DR45. For
- // reference, see
- // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
- friend struct Data;
- public:
- typedef
- typename std::iterator_traits<InputT>::difference_type
- difference_type;
- typedef
- typename std::iterator_traits<InputT>::pointer
- pointer;
- typedef
- typename std::iterator_traits<InputT>::reference
- reference;
- protected:
- inner()
- : data(0)
- {}
- inner(InputT x)
- : data(new Data(x))
- {}
- inner(inner const& x)
- : data(x.data)
- {}
- void destroy()
- {
- delete data;
- data = 0;
- }
- bool same_input(inner const& x) const
- {
- return data == x.data;
- }
- typedef
- typename std::iterator_traits<InputT>::value_type
- value_t;
- void swap(inner& x)
- {
- impl::mp_swap(data, x.data);
- }
- void ensure_initialized() const
- {
- if (data && !data->was_initialized) {
- data->curtok = *data->input; // get the first token
- data->was_initialized = true;
- }
- }
- public:
- reference get_input() const
- {
- BOOST_SPIRIT_ASSERT(NULL != data);
- ensure_initialized();
- return data->curtok;
- }
- void advance_input()
- {
- BOOST_SPIRIT_ASSERT(NULL != data);
- data->was_initialized = false; // should get the next token
- ++data->input;
- }
- bool input_at_eof() const
- {
- return !data || data->input == InputT();
- }
- private:
- Data *data;
- };
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class lex_input
- // Implementation of the InputPolicy used by multi_pass
- // lex_input gets tokens (ints) from yylex()
- ///////////////////////////////////////////////////////////////////////////////
- class lex_input
- {
- public:
- template <typename InputT>
- class inner
- {
- public:
- typedef int value_type;
- typedef std::ptrdiff_t difference_type;
- typedef int* pointer;
- typedef int& reference;
- protected:
- inner()
- : curtok(new int(0))
- {}
- inner(InputT x)
- : curtok(new int(x))
- {}
- inner(inner const& x)
- : curtok(x.curtok)
- {}
- void destroy()
- {
- delete curtok;
- curtok = 0;
- }
- bool same_input(inner const& x) const
- {
- return curtok == x.curtok;
- }
- void swap(inner& x)
- {
- impl::mp_swap(curtok, x.curtok);
- }
- public:
- reference get_input() const
- {
- return *curtok;
- }
- void advance_input()
- {
- extern int yylex();
- *curtok = yylex();
- }
- bool input_at_eof() const
- {
- return *curtok == 0;
- }
- private:
- int* curtok;
- };
- };
- ///////////////////////////////////////////////////////////////////////////////
- // class functor_input
- // Implementation of the InputPolicy used by multi_pass
- // functor_input gets tokens from a functor
- // Note: the functor must have a typedef for result_type
- // It also must have a static variable of type result_type defined to
- // represent eof that is called eof.
- ///////////////////////////////////////////////////////////////////////////////
- class functor_input
- {
- public:
- template <typename FunctorT>
- class inner
- {
- typedef typename FunctorT::result_type result_type;
- public:
- typedef result_type value_type;
- typedef std::ptrdiff_t difference_type;
- typedef result_type* pointer;
- typedef result_type& reference;
- protected:
- inner()
- : ftor(0)
- , curtok(0)
- {}
- inner(FunctorT const& x)
- : ftor(new FunctorT(x))
- , curtok(new result_type((*ftor)()))
- {}
- inner(inner const& x)
- : ftor(x.ftor)
- , curtok(x.curtok)
- {}
- void destroy()
- {
- delete ftor;
- ftor = 0;
- delete curtok;
- curtok = 0;
- }
- bool same_input(inner const& x) const
- {
- return ftor == x.ftor;
- }
- void swap(inner& x)
- {
- impl::mp_swap(curtok, x.curtok);
- impl::mp_swap(ftor, x.ftor);
- }
- public:
- reference get_input() const
- {
- return *curtok;
- }
- void advance_input()
- {
- if (curtok) {
- *curtok = (*ftor)();
- }
- }
- bool input_at_eof() const
- {
- return !curtok || *curtok == ftor->eof;
- }
- FunctorT& get_functor() const
- {
- return *ftor;
- }
- private:
- FunctorT* ftor;
- result_type* curtok;
- };
- };
- } // namespace multi_pass_policies
- ///////////////////////////////////////////////////////////////////////////////
- // iterator_base_creator
- ///////////////////////////////////////////////////////////////////////////////
- namespace iterator_ { namespace impl {
- // Meta-function to generate a std::iterator<>-like base class for multi_pass.
- template <typename InputPolicyT, typename InputT>
- struct iterator_base_creator
- {
- typedef typename InputPolicyT::BOOST_NESTED_TEMPLATE inner<InputT> input_t;
- struct type {
- typedef std::forward_iterator_tag iterator_category;
- typedef typename input_t::value_type value_type;
- typedef typename input_t::difference_type difference_type;
- typedef typename input_t::pointer pointer;
- typedef typename input_t::reference reference;
- };
- };
- }}
- ///////////////////////////////////////////////////////////////////////////////
- // class template multi_pass
- ///////////////////////////////////////////////////////////////////////////////
- // The default multi_pass instantiation uses a ref-counted std_deque scheme.
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- class multi_pass
- : public OwnershipPolicy
- , public CheckingPolicy
- , public StoragePolicy::template inner<
- typename InputPolicy::template inner<InputT>::value_type>
- , public InputPolicy::template inner<InputT>
- , public iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
- {
- typedef OwnershipPolicy OP;
- typedef CheckingPolicy CHP;
- typedef typename StoragePolicy::template inner<
- typename InputPolicy::template inner<InputT>::value_type> SP;
- typedef typename InputPolicy::template inner<InputT> IP;
- typedef typename
- iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
- IB;
- public:
- typedef typename IB::value_type value_type;
- typedef typename IB::difference_type difference_type;
- typedef typename IB::reference reference;
- typedef typename IB::pointer pointer;
- typedef InputT iterator_type;
- multi_pass();
- explicit multi_pass(InputT input);
- #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- multi_pass(int);
- #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- ~multi_pass();
- multi_pass(multi_pass const&);
- multi_pass& operator=(multi_pass const&);
- void swap(multi_pass& x);
- reference operator*() const;
- pointer operator->() const;
- multi_pass& operator++();
- multi_pass operator++(int);
- void clear_queue();
- bool operator==(const multi_pass& y) const;
- bool operator<(const multi_pass& y) const;
- private: // helper functions
- bool is_eof() const;
- };
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- multi_pass()
- : OP()
- , CHP()
- , SP()
- , IP()
- {
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- multi_pass(InputT input)
- : OP()
- , CHP()
- , SP()
- , IP(input)
- {
- }
- #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- // The standard library shipped with gcc-3.1 has a bug in
- // bits/basic_string.tcc. It tries to use iter::iter(0) to
- // construct an iterator. Ironically, this happens in sanity
- // checking code that isn't required by the standard.
- // The workaround is to provide an additional constructor that
- // ignores its int argument and behaves like the default constructor.
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- multi_pass(int)
- : OP()
- , CHP()
- , SP()
- , IP()
- {
- }
- #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- ~multi_pass()
- {
- if (OP::release())
- {
- CHP::destroy();
- SP::destroy();
- IP::destroy();
- }
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- multi_pass(
- multi_pass const& x)
- : OP(x)
- , CHP(x)
- , SP(x)
- , IP(x)
- {
- OP::clone();
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator=(
- multi_pass const& x)
- {
- multi_pass temp(x);
- temp.swap(*this);
- return *this;
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline void
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- swap(multi_pass& x)
- {
- OP::swap(x);
- CHP::swap(x);
- SP::swap(x);
- IP::swap(x);
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- reference
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator*() const
- {
- CHP::check_if_valid();
- return SP::dereference(*this);
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- pointer
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator->() const
- {
- return &(operator*());
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator++()
- {
- CHP::check_if_valid();
- SP::increment(*this);
- return *this;
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator++(int)
- {
- multi_pass
- <
- InputT,
- InputPolicy,
- OwnershipPolicy,
- CheckingPolicy,
- StoragePolicy
- > tmp(*this);
- ++*this;
- return tmp;
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline void
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- clear_queue()
- {
- SP::clear_queue();
- CHP::clear_queue();
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline bool
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- is_eof() const
- {
- return SP::is_eof(*this);
- }
- ///// Comparisons
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline bool
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator==(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y) const
- {
- bool is_eof_ = SP::is_eof(*this);
- bool y_is_eof_ = SP::is_eof(y);
-
- if (is_eof_ && y_is_eof_)
- {
- return true; // both are EOF
- }
- else if (is_eof_ ^ y_is_eof_)
- {
- return false; // one is EOF, one isn't
- }
- else if (!IP::same_input(y))
- {
- return false;
- }
- else
- {
- return SP::equal_to(y);
- }
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline bool
- multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
- operator<(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y) const
- {
- return SP::less_than(y);
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- bool operator!=(
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& x,
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y)
- {
- return !(x == y);
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- bool operator>(
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& x,
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y)
- {
- return y < x;
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- bool operator>=(
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& x,
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y)
- {
- return !(x < y);
- }
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- inline
- bool operator<=(
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& x,
- const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
- StoragePolicy>& y)
- {
- return !(y < x);
- }
- ///// Generator function
- template <typename InputT>
- inline multi_pass<InputT,
- multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
- multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>
- make_multi_pass(InputT i)
- {
- return multi_pass<InputT,
- multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
- multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>(i);
- }
- // this could be a template typedef, since such a thing doesn't
- // exist in C++, we'll use inheritance to accomplish the same thing.
- template <typename InputT, std::size_t N>
- class look_ahead :
- public multi_pass<
- InputT,
- multi_pass_policies::input_iterator,
- multi_pass_policies::first_owner,
- multi_pass_policies::no_check,
- multi_pass_policies::fixed_size_queue<N> >
- {
- typedef multi_pass<
- InputT,
- multi_pass_policies::input_iterator,
- multi_pass_policies::first_owner,
- multi_pass_policies::no_check,
- multi_pass_policies::fixed_size_queue<N> > base_t;
- public:
- look_ahead()
- : base_t() {}
- explicit look_ahead(InputT x)
- : base_t(x) {}
- look_ahead(look_ahead const& x)
- : base_t(x) {}
- #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- look_ahead(int) // workaround for a bug in the library
- : base_t() {} // shipped with gcc 3.1
- #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
- // default generated operators destructor and assignment operator are okay.
- };
- template
- <
- typename InputT,
- typename InputPolicy,
- typename OwnershipPolicy,
- typename CheckingPolicy,
- typename StoragePolicy
- >
- void swap(
- multi_pass<
- InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
- > &x,
- multi_pass<
- InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
- > &y)
- {
- x.swap(y);
- }
- namespace impl {
- template <typename T>
- inline void mp_swap(T& t1, T& t2)
- {
- using std::swap;
- using BOOST_SPIRIT_CLASSIC_NS::swap;
- swap(t1, t2);
- }
- }
- BOOST_SPIRIT_CLASSIC_NAMESPACE_END
- }} // namespace BOOST_SPIRIT_CLASSIC_NS
- #endif // BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
|