multi_pass.hpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. /*=============================================================================
  2. Copyright (c) 2001, Daniel C. Nuffer
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #ifndef BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
  8. #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
  9. #include <boost/config.hpp>
  10. #include <boost/throw_exception.hpp>
  11. #include <deque>
  12. #include <iterator>
  13. #include <iostream>
  14. #include <algorithm> // for std::swap
  15. #include <exception> // for std::exception
  16. #include <boost/limits.hpp>
  17. #include <boost/spirit/home/classic/namespace.hpp>
  18. #include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
  19. #include <boost/spirit/home/classic/iterator/fixed_size_queue.hpp>
  20. #include <boost/spirit/home/classic/iterator/multi_pass_fwd.hpp>
  21. namespace boost { namespace spirit {
  22. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  23. namespace impl {
  24. template <typename T>
  25. inline void mp_swap(T& t1, T& t2);
  26. }
  27. namespace multi_pass_policies
  28. {
  29. ///////////////////////////////////////////////////////////////////////////////
  30. // class ref_counted
  31. // Implementation of an OwnershipPolicy used by multi_pass.
  32. //
  33. // Implementation modified from RefCounted class from the Loki library by
  34. // Andrei Alexandrescu
  35. ///////////////////////////////////////////////////////////////////////////////
  36. class ref_counted
  37. {
  38. protected:
  39. ref_counted()
  40. : count(new std::size_t(1))
  41. {}
  42. ref_counted(ref_counted const& x)
  43. : count(x.count)
  44. {}
  45. // clone is called when a copy of the iterator is made, so increment
  46. // the ref-count.
  47. void clone()
  48. {
  49. ++*count;
  50. }
  51. // called when a copy is deleted. Decrement the ref-count. Return
  52. // value of true indicates that the last copy has been released.
  53. bool release()
  54. {
  55. if (!--*count)
  56. {
  57. delete count;
  58. count = 0;
  59. return true;
  60. }
  61. return false;
  62. }
  63. void swap(ref_counted& x)
  64. {
  65. impl::mp_swap(count, x.count);
  66. }
  67. public:
  68. // returns true if there is only one iterator in existence.
  69. // std_deque StoragePolicy will free it's buffered data if this
  70. // returns true.
  71. bool unique() const
  72. {
  73. return *count == 1;
  74. }
  75. private:
  76. std::size_t* count;
  77. };
  78. ///////////////////////////////////////////////////////////////////////////////
  79. // class first_owner
  80. // Implementation of an OwnershipPolicy used by multi_pass
  81. // This ownership policy dictates that the first iterator created will
  82. // determine the lifespan of the shared components. This works well for
  83. // spirit, since no dynamic allocation of iterators is done, and all copies
  84. // are make on the stack.
  85. //
  86. // There is a caveat about using this policy together with the std_deque
  87. // StoragePolicy. Since first_owner always returns false from unique(),
  88. // std_deque will only release the queued data if clear_queue() is called.
  89. ///////////////////////////////////////////////////////////////////////////////
  90. class first_owner
  91. {
  92. protected:
  93. first_owner()
  94. : first(true)
  95. {}
  96. first_owner(first_owner const&)
  97. : first(false)
  98. {}
  99. void clone()
  100. {
  101. }
  102. // return true to indicate deletion of resources
  103. bool release()
  104. {
  105. return first;
  106. }
  107. void swap(first_owner&)
  108. {
  109. // if we're the first, we still remain the first, even if assigned
  110. // to, so don't swap first_. swap is only called from operator=
  111. }
  112. public:
  113. bool unique() const
  114. {
  115. return false; // no way to know, so always return false
  116. }
  117. private:
  118. bool first;
  119. };
  120. ///////////////////////////////////////////////////////////////////////////////
  121. // class illegal_backtracking
  122. // thrown by buf_id_check CheckingPolicy if an instance of an iterator is
  123. // used after another one has invalidated the queue
  124. ///////////////////////////////////////////////////////////////////////////////
  125. class BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception
  126. {
  127. public:
  128. illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
  129. ~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
  130. virtual const char*
  131. what() const BOOST_NOEXCEPT_OR_NOTHROW
  132. { return "BOOST_SPIRIT_CLASSIC_NS::illegal_backtracking"; }
  133. };
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // class buf_id_check
  136. // Implementation of the CheckingPolicy used by multi_pass
  137. // This policy is most effective when used together with the std_deque
  138. // StoragePolicy.
  139. // If used with the fixed_size_queue StoragePolicy, it will not detect
  140. // iterator derefereces that are out of the range of the queue.
  141. ///////////////////////////////////////////////////////////////////////////////
  142. class buf_id_check
  143. {
  144. protected:
  145. buf_id_check()
  146. : shared_buf_id(new unsigned long(0))
  147. , buf_id(0)
  148. {}
  149. buf_id_check(buf_id_check const& x)
  150. : shared_buf_id(x.shared_buf_id)
  151. , buf_id(x.buf_id)
  152. {}
  153. // will be called from the destructor of the last iterator.
  154. void destroy()
  155. {
  156. delete shared_buf_id;
  157. shared_buf_id = 0;
  158. }
  159. void swap(buf_id_check& x)
  160. {
  161. impl::mp_swap(shared_buf_id, x.shared_buf_id);
  162. impl::mp_swap(buf_id, x.buf_id);
  163. }
  164. // called to verify that everything is okay.
  165. void check_if_valid() const
  166. {
  167. if (buf_id != *shared_buf_id)
  168. {
  169. boost::throw_exception(illegal_backtracking());
  170. }
  171. }
  172. // called from multi_pass::clear_queue, so we can increment the count
  173. void clear_queue()
  174. {
  175. ++*shared_buf_id;
  176. ++buf_id;
  177. }
  178. private:
  179. unsigned long* shared_buf_id;
  180. unsigned long buf_id;
  181. };
  182. ///////////////////////////////////////////////////////////////////////////////
  183. // class no_check
  184. // Implementation of the CheckingPolicy used by multi_pass
  185. // It does not do anything :-)
  186. ///////////////////////////////////////////////////////////////////////////////
  187. class no_check
  188. {
  189. protected:
  190. no_check() {}
  191. no_check(no_check const&) {}
  192. void destroy() {}
  193. void swap(no_check&) {}
  194. void check_if_valid() const {}
  195. void clear_queue() {}
  196. };
  197. ///////////////////////////////////////////////////////////////////////////////
  198. // class std_deque
  199. // Implementation of the StoragePolicy used by multi_pass
  200. // This stores all data in a std::deque, and keeps an offset to the current
  201. // position. It stores all the data unless there is only one
  202. // iterator using the queue.
  203. // Note: a position is used instead of an iterator, because a push_back on
  204. // a deque can invalidate any iterators.
  205. ///////////////////////////////////////////////////////////////////////////////
  206. class std_deque
  207. {
  208. public:
  209. template <typename ValueT>
  210. class inner
  211. {
  212. private:
  213. typedef std::deque<ValueT> queue_type;
  214. queue_type* queuedElements;
  215. mutable typename queue_type::size_type queuePosition;
  216. protected:
  217. inner()
  218. : queuedElements(new queue_type)
  219. , queuePosition(0)
  220. {}
  221. inner(inner const& x)
  222. : queuedElements(x.queuedElements)
  223. , queuePosition(x.queuePosition)
  224. {}
  225. // will be called from the destructor of the last iterator.
  226. void destroy()
  227. {
  228. BOOST_SPIRIT_ASSERT(NULL != queuedElements);
  229. delete queuedElements;
  230. queuedElements = 0;
  231. }
  232. void swap(inner& x)
  233. {
  234. impl::mp_swap(queuedElements, x.queuedElements);
  235. impl::mp_swap(queuePosition, x.queuePosition);
  236. }
  237. // This is called when the iterator is dereferenced. It's a template
  238. // method so we can recover the type of the multi_pass iterator
  239. // and call unique and access the m_input data member.
  240. template <typename MultiPassT>
  241. static typename MultiPassT::reference dereference(MultiPassT const& mp)
  242. {
  243. if (mp.queuePosition == mp.queuedElements->size())
  244. {
  245. // check if this is the only iterator
  246. if (mp.unique())
  247. {
  248. // free up the memory used by the queue.
  249. if (mp.queuedElements->size() > 0)
  250. {
  251. mp.queuedElements->clear();
  252. mp.queuePosition = 0;
  253. }
  254. }
  255. return mp.get_input();
  256. }
  257. else
  258. {
  259. return (*mp.queuedElements)[mp.queuePosition];
  260. }
  261. }
  262. // This is called when the iterator is incremented. It's a template
  263. // method so we can recover the type of the multi_pass iterator
  264. // and call unique and access the m_input data member.
  265. template <typename MultiPassT>
  266. static void increment(MultiPassT& mp)
  267. {
  268. if (mp.queuePosition == mp.queuedElements->size())
  269. {
  270. // check if this is the only iterator
  271. if (mp.unique())
  272. {
  273. // free up the memory used by the queue.
  274. if (mp.queuedElements->size() > 0)
  275. {
  276. mp.queuedElements->clear();
  277. mp.queuePosition = 0;
  278. }
  279. }
  280. else
  281. {
  282. mp.queuedElements->push_back(mp.get_input());
  283. ++mp.queuePosition;
  284. }
  285. mp.advance_input();
  286. }
  287. else
  288. {
  289. ++mp.queuePosition;
  290. }
  291. }
  292. // called to forcibly clear the queue
  293. void clear_queue()
  294. {
  295. queuedElements->clear();
  296. queuePosition = 0;
  297. }
  298. // called to determine whether the iterator is an eof iterator
  299. template <typename MultiPassT>
  300. static bool is_eof(MultiPassT const& mp)
  301. {
  302. return mp.queuePosition == mp.queuedElements->size() &&
  303. mp.input_at_eof();
  304. }
  305. // called by operator==
  306. bool equal_to(inner const& x) const
  307. {
  308. return queuePosition == x.queuePosition;
  309. }
  310. // called by operator<
  311. bool less_than(inner const& x) const
  312. {
  313. return queuePosition < x.queuePosition;
  314. }
  315. }; // class inner
  316. }; // class std_deque
  317. ///////////////////////////////////////////////////////////////////////////////
  318. // class fixed_size_queue
  319. // Implementation of the StoragePolicy used by multi_pass
  320. // fixed_size_queue keeps a circular buffer (implemented by
  321. // BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue class) that is size N+1 and stores N elements.
  322. // It is up to the user to ensure that there is enough look ahead for their
  323. // grammar. Currently there is no way to tell if an iterator is pointing
  324. // to forgotten data. The leading iterator will put an item in the queue
  325. // and remove one when it is incremented. No dynamic allocation is done,
  326. // except on creation of the queue (fixed_size_queue constructor).
  327. ///////////////////////////////////////////////////////////////////////////////
  328. template < std::size_t N>
  329. class fixed_size_queue
  330. {
  331. public:
  332. template <typename ValueT>
  333. class inner
  334. {
  335. private:
  336. typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<ValueT, N> queue_type;
  337. queue_type * queuedElements;
  338. mutable typename queue_type::iterator queuePosition;
  339. protected:
  340. inner()
  341. : queuedElements(new queue_type)
  342. , queuePosition(queuedElements->begin())
  343. {}
  344. inner(inner const& x)
  345. : queuedElements(x.queuedElements)
  346. , queuePosition(x.queuePosition)
  347. {}
  348. // will be called from the destructor of the last iterator.
  349. void destroy()
  350. {
  351. BOOST_SPIRIT_ASSERT(NULL != queuedElements);
  352. delete queuedElements;
  353. queuedElements = 0;
  354. }
  355. void swap(inner& x)
  356. {
  357. impl::mp_swap(queuedElements, x.queuedElements);
  358. impl::mp_swap(queuePosition, x.queuePosition);
  359. }
  360. // This is called when the iterator is dereferenced. It's a template
  361. // method so we can recover the type of the multi_pass iterator
  362. // and access the m_input data member.
  363. template <typename MultiPassT>
  364. static typename MultiPassT::reference dereference(MultiPassT const& mp)
  365. {
  366. if (mp.queuePosition == mp.queuedElements->end())
  367. {
  368. return mp.get_input();
  369. }
  370. else
  371. {
  372. return *mp.queuePosition;
  373. }
  374. }
  375. // This is called when the iterator is incremented. It's a template
  376. // method so we can recover the type of the multi_pass iterator
  377. // and access the m_input data member.
  378. template <typename MultiPassT>
  379. static void increment(MultiPassT& mp)
  380. {
  381. if (mp.queuePosition == mp.queuedElements->end())
  382. {
  383. // don't let the queue get larger than N
  384. if (mp.queuedElements->size() >= N)
  385. mp.queuedElements->pop_front();
  386. mp.queuedElements->push_back(mp.get_input());
  387. mp.advance_input();
  388. }
  389. ++mp.queuePosition;
  390. }
  391. // no-op
  392. void clear_queue()
  393. {}
  394. // called to determine whether the iterator is an eof iterator
  395. template <typename MultiPassT>
  396. static bool is_eof(MultiPassT const& mp)
  397. {
  398. return mp.queuePosition == mp.queuedElements->end() &&
  399. mp.input_at_eof();
  400. }
  401. // called by operator==
  402. bool equal_to(inner const& x) const
  403. {
  404. return queuePosition == x.queuePosition;
  405. }
  406. // called by operator<
  407. bool less_than(inner const& x) const
  408. {
  409. return queuePosition < x.queuePosition;
  410. }
  411. }; // class inner
  412. }; // class fixed_size_queue
  413. ///////////////////////////////////////////////////////////////////////////////
  414. // class input_iterator
  415. // Implementation of the InputPolicy used by multi_pass
  416. // input_iterator encapsulates an input iterator of type InputT
  417. ///////////////////////////////////////////////////////////////////////////////
  418. class input_iterator
  419. {
  420. public:
  421. template <typename InputT>
  422. class inner
  423. {
  424. private:
  425. typedef
  426. typename std::iterator_traits<InputT>::value_type
  427. result_type;
  428. public:
  429. typedef result_type value_type;
  430. private:
  431. struct Data {
  432. Data(InputT const &input_)
  433. : input(input_), was_initialized(false)
  434. {}
  435. InputT input;
  436. value_type curtok;
  437. bool was_initialized;
  438. };
  439. // Needed by compilers not implementing the resolution to DR45. For
  440. // reference, see
  441. // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
  442. friend struct Data;
  443. public:
  444. typedef
  445. typename std::iterator_traits<InputT>::difference_type
  446. difference_type;
  447. typedef
  448. typename std::iterator_traits<InputT>::pointer
  449. pointer;
  450. typedef
  451. typename std::iterator_traits<InputT>::reference
  452. reference;
  453. protected:
  454. inner()
  455. : data(0)
  456. {}
  457. inner(InputT x)
  458. : data(new Data(x))
  459. {}
  460. inner(inner const& x)
  461. : data(x.data)
  462. {}
  463. void destroy()
  464. {
  465. delete data;
  466. data = 0;
  467. }
  468. bool same_input(inner const& x) const
  469. {
  470. return data == x.data;
  471. }
  472. typedef
  473. typename std::iterator_traits<InputT>::value_type
  474. value_t;
  475. void swap(inner& x)
  476. {
  477. impl::mp_swap(data, x.data);
  478. }
  479. void ensure_initialized() const
  480. {
  481. if (data && !data->was_initialized) {
  482. data->curtok = *data->input; // get the first token
  483. data->was_initialized = true;
  484. }
  485. }
  486. public:
  487. reference get_input() const
  488. {
  489. BOOST_SPIRIT_ASSERT(NULL != data);
  490. ensure_initialized();
  491. return data->curtok;
  492. }
  493. void advance_input()
  494. {
  495. BOOST_SPIRIT_ASSERT(NULL != data);
  496. data->was_initialized = false; // should get the next token
  497. ++data->input;
  498. }
  499. bool input_at_eof() const
  500. {
  501. return !data || data->input == InputT();
  502. }
  503. private:
  504. Data *data;
  505. };
  506. };
  507. ///////////////////////////////////////////////////////////////////////////////
  508. // class lex_input
  509. // Implementation of the InputPolicy used by multi_pass
  510. // lex_input gets tokens (ints) from yylex()
  511. ///////////////////////////////////////////////////////////////////////////////
  512. class lex_input
  513. {
  514. public:
  515. template <typename InputT>
  516. class inner
  517. {
  518. public:
  519. typedef int value_type;
  520. typedef std::ptrdiff_t difference_type;
  521. typedef int* pointer;
  522. typedef int& reference;
  523. protected:
  524. inner()
  525. : curtok(new int(0))
  526. {}
  527. inner(InputT x)
  528. : curtok(new int(x))
  529. {}
  530. inner(inner const& x)
  531. : curtok(x.curtok)
  532. {}
  533. void destroy()
  534. {
  535. delete curtok;
  536. curtok = 0;
  537. }
  538. bool same_input(inner const& x) const
  539. {
  540. return curtok == x.curtok;
  541. }
  542. void swap(inner& x)
  543. {
  544. impl::mp_swap(curtok, x.curtok);
  545. }
  546. public:
  547. reference get_input() const
  548. {
  549. return *curtok;
  550. }
  551. void advance_input()
  552. {
  553. extern int yylex();
  554. *curtok = yylex();
  555. }
  556. bool input_at_eof() const
  557. {
  558. return *curtok == 0;
  559. }
  560. private:
  561. int* curtok;
  562. };
  563. };
  564. ///////////////////////////////////////////////////////////////////////////////
  565. // class functor_input
  566. // Implementation of the InputPolicy used by multi_pass
  567. // functor_input gets tokens from a functor
  568. // Note: the functor must have a typedef for result_type
  569. // It also must have a static variable of type result_type defined to
  570. // represent eof that is called eof.
  571. ///////////////////////////////////////////////////////////////////////////////
  572. class functor_input
  573. {
  574. public:
  575. template <typename FunctorT>
  576. class inner
  577. {
  578. typedef typename FunctorT::result_type result_type;
  579. public:
  580. typedef result_type value_type;
  581. typedef std::ptrdiff_t difference_type;
  582. typedef result_type* pointer;
  583. typedef result_type& reference;
  584. protected:
  585. inner()
  586. : ftor(0)
  587. , curtok(0)
  588. {}
  589. inner(FunctorT const& x)
  590. : ftor(new FunctorT(x))
  591. , curtok(new result_type((*ftor)()))
  592. {}
  593. inner(inner const& x)
  594. : ftor(x.ftor)
  595. , curtok(x.curtok)
  596. {}
  597. void destroy()
  598. {
  599. delete ftor;
  600. ftor = 0;
  601. delete curtok;
  602. curtok = 0;
  603. }
  604. bool same_input(inner const& x) const
  605. {
  606. return ftor == x.ftor;
  607. }
  608. void swap(inner& x)
  609. {
  610. impl::mp_swap(curtok, x.curtok);
  611. impl::mp_swap(ftor, x.ftor);
  612. }
  613. public:
  614. reference get_input() const
  615. {
  616. return *curtok;
  617. }
  618. void advance_input()
  619. {
  620. if (curtok) {
  621. *curtok = (*ftor)();
  622. }
  623. }
  624. bool input_at_eof() const
  625. {
  626. return !curtok || *curtok == ftor->eof;
  627. }
  628. FunctorT& get_functor() const
  629. {
  630. return *ftor;
  631. }
  632. private:
  633. FunctorT* ftor;
  634. result_type* curtok;
  635. };
  636. };
  637. } // namespace multi_pass_policies
  638. ///////////////////////////////////////////////////////////////////////////////
  639. // iterator_base_creator
  640. ///////////////////////////////////////////////////////////////////////////////
  641. namespace iterator_ { namespace impl {
  642. // Meta-function to generate a std::iterator<>-like base class for multi_pass.
  643. template <typename InputPolicyT, typename InputT>
  644. struct iterator_base_creator
  645. {
  646. typedef typename InputPolicyT::BOOST_NESTED_TEMPLATE inner<InputT> input_t;
  647. struct type {
  648. typedef std::forward_iterator_tag iterator_category;
  649. typedef typename input_t::value_type value_type;
  650. typedef typename input_t::difference_type difference_type;
  651. typedef typename input_t::pointer pointer;
  652. typedef typename input_t::reference reference;
  653. };
  654. };
  655. }}
  656. ///////////////////////////////////////////////////////////////////////////////
  657. // class template multi_pass
  658. ///////////////////////////////////////////////////////////////////////////////
  659. // The default multi_pass instantiation uses a ref-counted std_deque scheme.
  660. template
  661. <
  662. typename InputT,
  663. typename InputPolicy,
  664. typename OwnershipPolicy,
  665. typename CheckingPolicy,
  666. typename StoragePolicy
  667. >
  668. class multi_pass
  669. : public OwnershipPolicy
  670. , public CheckingPolicy
  671. , public StoragePolicy::template inner<
  672. typename InputPolicy::template inner<InputT>::value_type>
  673. , public InputPolicy::template inner<InputT>
  674. , public iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
  675. {
  676. typedef OwnershipPolicy OP;
  677. typedef CheckingPolicy CHP;
  678. typedef typename StoragePolicy::template inner<
  679. typename InputPolicy::template inner<InputT>::value_type> SP;
  680. typedef typename InputPolicy::template inner<InputT> IP;
  681. typedef typename
  682. iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
  683. IB;
  684. public:
  685. typedef typename IB::value_type value_type;
  686. typedef typename IB::difference_type difference_type;
  687. typedef typename IB::reference reference;
  688. typedef typename IB::pointer pointer;
  689. typedef InputT iterator_type;
  690. multi_pass();
  691. explicit multi_pass(InputT input);
  692. #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  693. multi_pass(int);
  694. #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  695. ~multi_pass();
  696. multi_pass(multi_pass const&);
  697. multi_pass& operator=(multi_pass const&);
  698. void swap(multi_pass& x);
  699. reference operator*() const;
  700. pointer operator->() const;
  701. multi_pass& operator++();
  702. multi_pass operator++(int);
  703. void clear_queue();
  704. bool operator==(const multi_pass& y) const;
  705. bool operator<(const multi_pass& y) const;
  706. private: // helper functions
  707. bool is_eof() const;
  708. };
  709. template
  710. <
  711. typename InputT,
  712. typename InputPolicy,
  713. typename OwnershipPolicy,
  714. typename CheckingPolicy,
  715. typename StoragePolicy
  716. >
  717. inline
  718. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  719. multi_pass()
  720. : OP()
  721. , CHP()
  722. , SP()
  723. , IP()
  724. {
  725. }
  726. template
  727. <
  728. typename InputT,
  729. typename InputPolicy,
  730. typename OwnershipPolicy,
  731. typename CheckingPolicy,
  732. typename StoragePolicy
  733. >
  734. inline
  735. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  736. multi_pass(InputT input)
  737. : OP()
  738. , CHP()
  739. , SP()
  740. , IP(input)
  741. {
  742. }
  743. #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  744. // The standard library shipped with gcc-3.1 has a bug in
  745. // bits/basic_string.tcc. It tries to use iter::iter(0) to
  746. // construct an iterator. Ironically, this happens in sanity
  747. // checking code that isn't required by the standard.
  748. // The workaround is to provide an additional constructor that
  749. // ignores its int argument and behaves like the default constructor.
  750. template
  751. <
  752. typename InputT,
  753. typename InputPolicy,
  754. typename OwnershipPolicy,
  755. typename CheckingPolicy,
  756. typename StoragePolicy
  757. >
  758. inline
  759. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  760. multi_pass(int)
  761. : OP()
  762. , CHP()
  763. , SP()
  764. , IP()
  765. {
  766. }
  767. #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  768. template
  769. <
  770. typename InputT,
  771. typename InputPolicy,
  772. typename OwnershipPolicy,
  773. typename CheckingPolicy,
  774. typename StoragePolicy
  775. >
  776. inline
  777. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  778. ~multi_pass()
  779. {
  780. if (OP::release())
  781. {
  782. CHP::destroy();
  783. SP::destroy();
  784. IP::destroy();
  785. }
  786. }
  787. template
  788. <
  789. typename InputT,
  790. typename InputPolicy,
  791. typename OwnershipPolicy,
  792. typename CheckingPolicy,
  793. typename StoragePolicy
  794. >
  795. inline
  796. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  797. multi_pass(
  798. multi_pass const& x)
  799. : OP(x)
  800. , CHP(x)
  801. , SP(x)
  802. , IP(x)
  803. {
  804. OP::clone();
  805. }
  806. template
  807. <
  808. typename InputT,
  809. typename InputPolicy,
  810. typename OwnershipPolicy,
  811. typename CheckingPolicy,
  812. typename StoragePolicy
  813. >
  814. inline
  815. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
  816. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  817. operator=(
  818. multi_pass const& x)
  819. {
  820. multi_pass temp(x);
  821. temp.swap(*this);
  822. return *this;
  823. }
  824. template
  825. <
  826. typename InputT,
  827. typename InputPolicy,
  828. typename OwnershipPolicy,
  829. typename CheckingPolicy,
  830. typename StoragePolicy
  831. >
  832. inline void
  833. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  834. swap(multi_pass& x)
  835. {
  836. OP::swap(x);
  837. CHP::swap(x);
  838. SP::swap(x);
  839. IP::swap(x);
  840. }
  841. template
  842. <
  843. typename InputT,
  844. typename InputPolicy,
  845. typename OwnershipPolicy,
  846. typename CheckingPolicy,
  847. typename StoragePolicy
  848. >
  849. inline
  850. typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  851. reference
  852. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  853. operator*() const
  854. {
  855. CHP::check_if_valid();
  856. return SP::dereference(*this);
  857. }
  858. template
  859. <
  860. typename InputT,
  861. typename InputPolicy,
  862. typename OwnershipPolicy,
  863. typename CheckingPolicy,
  864. typename StoragePolicy
  865. >
  866. inline
  867. typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  868. pointer
  869. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  870. operator->() const
  871. {
  872. return &(operator*());
  873. }
  874. template
  875. <
  876. typename InputT,
  877. typename InputPolicy,
  878. typename OwnershipPolicy,
  879. typename CheckingPolicy,
  880. typename StoragePolicy
  881. >
  882. inline
  883. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
  884. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  885. operator++()
  886. {
  887. CHP::check_if_valid();
  888. SP::increment(*this);
  889. return *this;
  890. }
  891. template
  892. <
  893. typename InputT,
  894. typename InputPolicy,
  895. typename OwnershipPolicy,
  896. typename CheckingPolicy,
  897. typename StoragePolicy
  898. >
  899. inline
  900. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>
  901. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  902. operator++(int)
  903. {
  904. multi_pass
  905. <
  906. InputT,
  907. InputPolicy,
  908. OwnershipPolicy,
  909. CheckingPolicy,
  910. StoragePolicy
  911. > tmp(*this);
  912. ++*this;
  913. return tmp;
  914. }
  915. template
  916. <
  917. typename InputT,
  918. typename InputPolicy,
  919. typename OwnershipPolicy,
  920. typename CheckingPolicy,
  921. typename StoragePolicy
  922. >
  923. inline void
  924. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  925. clear_queue()
  926. {
  927. SP::clear_queue();
  928. CHP::clear_queue();
  929. }
  930. template
  931. <
  932. typename InputT,
  933. typename InputPolicy,
  934. typename OwnershipPolicy,
  935. typename CheckingPolicy,
  936. typename StoragePolicy
  937. >
  938. inline bool
  939. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  940. is_eof() const
  941. {
  942. return SP::is_eof(*this);
  943. }
  944. ///// Comparisons
  945. template
  946. <
  947. typename InputT,
  948. typename InputPolicy,
  949. typename OwnershipPolicy,
  950. typename CheckingPolicy,
  951. typename StoragePolicy
  952. >
  953. inline bool
  954. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  955. operator==(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  956. StoragePolicy>& y) const
  957. {
  958. bool is_eof_ = SP::is_eof(*this);
  959. bool y_is_eof_ = SP::is_eof(y);
  960. if (is_eof_ && y_is_eof_)
  961. {
  962. return true; // both are EOF
  963. }
  964. else if (is_eof_ ^ y_is_eof_)
  965. {
  966. return false; // one is EOF, one isn't
  967. }
  968. else if (!IP::same_input(y))
  969. {
  970. return false;
  971. }
  972. else
  973. {
  974. return SP::equal_to(y);
  975. }
  976. }
  977. template
  978. <
  979. typename InputT,
  980. typename InputPolicy,
  981. typename OwnershipPolicy,
  982. typename CheckingPolicy,
  983. typename StoragePolicy
  984. >
  985. inline bool
  986. multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
  987. operator<(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  988. StoragePolicy>& y) const
  989. {
  990. return SP::less_than(y);
  991. }
  992. template
  993. <
  994. typename InputT,
  995. typename InputPolicy,
  996. typename OwnershipPolicy,
  997. typename CheckingPolicy,
  998. typename StoragePolicy
  999. >
  1000. inline
  1001. bool operator!=(
  1002. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1003. StoragePolicy>& x,
  1004. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1005. StoragePolicy>& y)
  1006. {
  1007. return !(x == y);
  1008. }
  1009. template
  1010. <
  1011. typename InputT,
  1012. typename InputPolicy,
  1013. typename OwnershipPolicy,
  1014. typename CheckingPolicy,
  1015. typename StoragePolicy
  1016. >
  1017. inline
  1018. bool operator>(
  1019. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1020. StoragePolicy>& x,
  1021. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1022. StoragePolicy>& y)
  1023. {
  1024. return y < x;
  1025. }
  1026. template
  1027. <
  1028. typename InputT,
  1029. typename InputPolicy,
  1030. typename OwnershipPolicy,
  1031. typename CheckingPolicy,
  1032. typename StoragePolicy
  1033. >
  1034. inline
  1035. bool operator>=(
  1036. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1037. StoragePolicy>& x,
  1038. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1039. StoragePolicy>& y)
  1040. {
  1041. return !(x < y);
  1042. }
  1043. template
  1044. <
  1045. typename InputT,
  1046. typename InputPolicy,
  1047. typename OwnershipPolicy,
  1048. typename CheckingPolicy,
  1049. typename StoragePolicy
  1050. >
  1051. inline
  1052. bool operator<=(
  1053. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1054. StoragePolicy>& x,
  1055. const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
  1056. StoragePolicy>& y)
  1057. {
  1058. return !(y < x);
  1059. }
  1060. ///// Generator function
  1061. template <typename InputT>
  1062. inline multi_pass<InputT,
  1063. multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
  1064. multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>
  1065. make_multi_pass(InputT i)
  1066. {
  1067. return multi_pass<InputT,
  1068. multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
  1069. multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>(i);
  1070. }
  1071. // this could be a template typedef, since such a thing doesn't
  1072. // exist in C++, we'll use inheritance to accomplish the same thing.
  1073. template <typename InputT, std::size_t N>
  1074. class look_ahead :
  1075. public multi_pass<
  1076. InputT,
  1077. multi_pass_policies::input_iterator,
  1078. multi_pass_policies::first_owner,
  1079. multi_pass_policies::no_check,
  1080. multi_pass_policies::fixed_size_queue<N> >
  1081. {
  1082. typedef multi_pass<
  1083. InputT,
  1084. multi_pass_policies::input_iterator,
  1085. multi_pass_policies::first_owner,
  1086. multi_pass_policies::no_check,
  1087. multi_pass_policies::fixed_size_queue<N> > base_t;
  1088. public:
  1089. look_ahead()
  1090. : base_t() {}
  1091. explicit look_ahead(InputT x)
  1092. : base_t(x) {}
  1093. look_ahead(look_ahead const& x)
  1094. : base_t(x) {}
  1095. #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  1096. look_ahead(int) // workaround for a bug in the library
  1097. : base_t() {} // shipped with gcc 3.1
  1098. #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
  1099. // default generated operators destructor and assignment operator are okay.
  1100. };
  1101. template
  1102. <
  1103. typename InputT,
  1104. typename InputPolicy,
  1105. typename OwnershipPolicy,
  1106. typename CheckingPolicy,
  1107. typename StoragePolicy
  1108. >
  1109. void swap(
  1110. multi_pass<
  1111. InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
  1112. > &x,
  1113. multi_pass<
  1114. InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
  1115. > &y)
  1116. {
  1117. x.swap(y);
  1118. }
  1119. namespace impl {
  1120. template <typename T>
  1121. inline void mp_swap(T& t1, T& t2)
  1122. {
  1123. using std::swap;
  1124. using BOOST_SPIRIT_CLASSIC_NS::swap;
  1125. swap(t1, t2);
  1126. }
  1127. }
  1128. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  1129. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  1130. #endif // BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP