File indexing completed on 2024-11-16 09:33:23
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
0009 #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_HPP
0010
0011 #include <boost/config.hpp>
0012 #include <boost/throw_exception.hpp>
0013 #include <deque>
0014 #include <iterator>
0015 #include <iostream>
0016 #include <algorithm> // for std::swap
0017 #include <exception> // for std::exception
0018 #include <boost/limits.hpp>
0019
0020 #include <boost/spirit/home/classic/namespace.hpp>
0021 #include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
0022 #include <boost/spirit/home/classic/iterator/fixed_size_queue.hpp>
0023
0024 #include <boost/spirit/home/classic/iterator/multi_pass_fwd.hpp>
0025
0026 namespace boost { namespace spirit {
0027
0028 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0029
0030 namespace impl {
0031 template <typename T>
0032 inline void mp_swap(T& t1, T& t2);
0033 }
0034
0035 namespace multi_pass_policies
0036 {
0037
0038
0039
0040
0041
0042
0043
0044
0045 class ref_counted
0046 {
0047 protected:
0048 ref_counted()
0049 : count(new std::size_t(1))
0050 {}
0051
0052 ref_counted(ref_counted const& x)
0053 : count(x.count)
0054 {}
0055
0056
0057
0058 void clone()
0059 {
0060 ++*count;
0061 }
0062
0063
0064
0065 bool release()
0066 {
0067 if (!--*count)
0068 {
0069 delete count;
0070 count = 0;
0071 return true;
0072 }
0073 return false;
0074 }
0075
0076 void swap(ref_counted& x)
0077 {
0078 impl::mp_swap(count, x.count);
0079 }
0080
0081 public:
0082
0083
0084
0085 bool unique() const
0086 {
0087 return *count == 1;
0088 }
0089
0090 private:
0091 std::size_t* count;
0092 };
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 class first_owner
0107 {
0108 protected:
0109 first_owner()
0110 : first(true)
0111 {}
0112
0113 first_owner(first_owner const&)
0114 : first(false)
0115 {}
0116
0117 void clone()
0118 {
0119 }
0120
0121
0122 bool release()
0123 {
0124 return first;
0125 }
0126
0127 void swap(first_owner&)
0128 {
0129
0130
0131 }
0132
0133 public:
0134 bool unique() const
0135 {
0136 return false;
0137 }
0138
0139 private:
0140 bool first;
0141 };
0142
0143
0144
0145
0146
0147
0148 class BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception
0149 {
0150 public:
0151
0152 illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
0153 ~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
0154
0155 const char*
0156 what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
0157 { return "BOOST_SPIRIT_CLASSIC_NS::illegal_backtracking"; }
0158 };
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 class buf_id_check
0169 {
0170 protected:
0171 buf_id_check()
0172 : shared_buf_id(new unsigned long(0))
0173 , buf_id(0)
0174 {}
0175
0176 buf_id_check(buf_id_check const& x)
0177 : shared_buf_id(x.shared_buf_id)
0178 , buf_id(x.buf_id)
0179 {}
0180
0181
0182 void destroy()
0183 {
0184 delete shared_buf_id;
0185 shared_buf_id = 0;
0186 }
0187
0188 void swap(buf_id_check& x)
0189 {
0190 impl::mp_swap(shared_buf_id, x.shared_buf_id);
0191 impl::mp_swap(buf_id, x.buf_id);
0192 }
0193
0194
0195 void check_if_valid() const
0196 {
0197 if (buf_id != *shared_buf_id)
0198 {
0199 boost::throw_exception(illegal_backtracking());
0200 }
0201 }
0202
0203
0204 void clear_queue()
0205 {
0206 ++*shared_buf_id;
0207 ++buf_id;
0208 }
0209
0210 private:
0211 unsigned long* shared_buf_id;
0212 unsigned long buf_id;
0213 };
0214
0215
0216
0217
0218
0219
0220 class no_check
0221 {
0222 protected:
0223 no_check() {}
0224 no_check(no_check const&) {}
0225 void destroy() {}
0226 void swap(no_check&) {}
0227 void check_if_valid() const {}
0228 void clear_queue() {}
0229 };
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 class std_deque
0241 {
0242 public:
0243
0244 template <typename ValueT>
0245 class inner
0246 {
0247 private:
0248
0249 typedef std::deque<ValueT> queue_type;
0250 queue_type* queuedElements;
0251 mutable typename queue_type::size_type queuePosition;
0252
0253 protected:
0254 inner()
0255 : queuedElements(new queue_type)
0256 , queuePosition(0)
0257 {}
0258
0259 inner(inner const& x)
0260 : queuedElements(x.queuedElements)
0261 , queuePosition(x.queuePosition)
0262 {}
0263
0264
0265 void destroy()
0266 {
0267 BOOST_SPIRIT_ASSERT(NULL != queuedElements);
0268 delete queuedElements;
0269 queuedElements = 0;
0270 }
0271
0272 void swap(inner& x)
0273 {
0274 impl::mp_swap(queuedElements, x.queuedElements);
0275 impl::mp_swap(queuePosition, x.queuePosition);
0276 }
0277
0278
0279
0280
0281 template <typename MultiPassT>
0282 static typename MultiPassT::reference dereference(MultiPassT const& mp)
0283 {
0284 if (mp.queuePosition == mp.queuedElements->size())
0285 {
0286
0287 if (mp.unique())
0288 {
0289
0290 if (mp.queuedElements->size() > 0)
0291 {
0292 mp.queuedElements->clear();
0293 mp.queuePosition = 0;
0294 }
0295 }
0296 return mp.get_input();
0297 }
0298 else
0299 {
0300 return (*mp.queuedElements)[mp.queuePosition];
0301 }
0302 }
0303
0304
0305
0306
0307 template <typename MultiPassT>
0308 static void increment(MultiPassT& mp)
0309 {
0310 if (mp.queuePosition == mp.queuedElements->size())
0311 {
0312
0313 if (mp.unique())
0314 {
0315
0316 if (mp.queuedElements->size() > 0)
0317 {
0318 mp.queuedElements->clear();
0319 mp.queuePosition = 0;
0320 }
0321 }
0322 else
0323 {
0324 mp.queuedElements->push_back(mp.get_input());
0325 ++mp.queuePosition;
0326 }
0327 mp.advance_input();
0328 }
0329 else
0330 {
0331 ++mp.queuePosition;
0332 }
0333
0334 }
0335
0336
0337 void clear_queue()
0338 {
0339 queuedElements->clear();
0340 queuePosition = 0;
0341 }
0342
0343
0344 template <typename MultiPassT>
0345 static bool is_eof(MultiPassT const& mp)
0346 {
0347 return mp.queuePosition == mp.queuedElements->size() &&
0348 mp.input_at_eof();
0349 }
0350
0351
0352 bool equal_to(inner const& x) const
0353 {
0354 return queuePosition == x.queuePosition;
0355 }
0356
0357
0358 bool less_than(inner const& x) const
0359 {
0360 return queuePosition < x.queuePosition;
0361 }
0362 };
0363
0364 };
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 template < std::size_t N>
0379 class fixed_size_queue
0380 {
0381 public:
0382
0383 template <typename ValueT>
0384 class inner
0385 {
0386 private:
0387
0388 typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<ValueT, N> queue_type;
0389 queue_type * queuedElements;
0390 mutable typename queue_type::iterator queuePosition;
0391
0392 protected:
0393 inner()
0394 : queuedElements(new queue_type)
0395 , queuePosition(queuedElements->begin())
0396 {}
0397
0398 inner(inner const& x)
0399 : queuedElements(x.queuedElements)
0400 , queuePosition(x.queuePosition)
0401 {}
0402
0403
0404 void destroy()
0405 {
0406 BOOST_SPIRIT_ASSERT(NULL != queuedElements);
0407 delete queuedElements;
0408 queuedElements = 0;
0409 }
0410
0411 void swap(inner& x)
0412 {
0413 impl::mp_swap(queuedElements, x.queuedElements);
0414 impl::mp_swap(queuePosition, x.queuePosition);
0415 }
0416
0417
0418
0419
0420 template <typename MultiPassT>
0421 static typename MultiPassT::reference dereference(MultiPassT const& mp)
0422 {
0423 if (mp.queuePosition == mp.queuedElements->end())
0424 {
0425 return mp.get_input();
0426 }
0427 else
0428 {
0429 return *mp.queuePosition;
0430 }
0431 }
0432
0433
0434
0435
0436 template <typename MultiPassT>
0437 static void increment(MultiPassT& mp)
0438 {
0439 if (mp.queuePosition == mp.queuedElements->end())
0440 {
0441
0442 if (mp.queuedElements->size() >= N)
0443 mp.queuedElements->pop_front();
0444
0445 mp.queuedElements->push_back(mp.get_input());
0446 mp.advance_input();
0447 }
0448 ++mp.queuePosition;
0449 }
0450
0451
0452 void clear_queue()
0453 {}
0454
0455
0456 template <typename MultiPassT>
0457 static bool is_eof(MultiPassT const& mp)
0458 {
0459 return mp.queuePosition == mp.queuedElements->end() &&
0460 mp.input_at_eof();
0461 }
0462
0463
0464 bool equal_to(inner const& x) const
0465 {
0466 return queuePosition == x.queuePosition;
0467 }
0468
0469
0470 bool less_than(inner const& x) const
0471 {
0472 return queuePosition < x.queuePosition;
0473 }
0474 };
0475
0476 };
0477
0478
0479
0480
0481
0482
0483
0484 class input_iterator
0485 {
0486 public:
0487
0488 template <typename InputT>
0489 class inner
0490 {
0491 private:
0492 typedef
0493 typename std::iterator_traits<InputT>::value_type
0494 result_type;
0495
0496 public:
0497 typedef result_type value_type;
0498
0499 private:
0500 struct Data {
0501 Data(InputT const &input_)
0502 : input(input_), was_initialized(false)
0503 {}
0504
0505 InputT input;
0506 value_type curtok;
0507 bool was_initialized;
0508 };
0509
0510
0511
0512
0513
0514 friend struct Data;
0515
0516 public:
0517 typedef
0518 typename std::iterator_traits<InputT>::difference_type
0519 difference_type;
0520 typedef
0521 typename std::iterator_traits<InputT>::pointer
0522 pointer;
0523 typedef
0524 typename std::iterator_traits<InputT>::reference
0525 reference;
0526
0527 protected:
0528 inner()
0529 : data(0)
0530 {}
0531
0532 inner(InputT x)
0533 : data(new Data(x))
0534 {}
0535
0536 inner(inner const& x)
0537 : data(x.data)
0538 {}
0539
0540 void destroy()
0541 {
0542 delete data;
0543 data = 0;
0544 }
0545
0546 bool same_input(inner const& x) const
0547 {
0548 return data == x.data;
0549 }
0550
0551 typedef
0552 typename std::iterator_traits<InputT>::value_type
0553 value_t;
0554 void swap(inner& x)
0555 {
0556 impl::mp_swap(data, x.data);
0557 }
0558
0559 void ensure_initialized() const
0560 {
0561 if (data && !data->was_initialized) {
0562 data->curtok = *data->input;
0563 data->was_initialized = true;
0564 }
0565 }
0566
0567 public:
0568 reference get_input() const
0569 {
0570 BOOST_SPIRIT_ASSERT(NULL != data);
0571 ensure_initialized();
0572 return data->curtok;
0573 }
0574
0575 void advance_input()
0576 {
0577 BOOST_SPIRIT_ASSERT(NULL != data);
0578 data->was_initialized = false;
0579 ++data->input;
0580 }
0581
0582 bool input_at_eof() const
0583 {
0584 return !data || data->input == InputT();
0585 }
0586
0587 private:
0588 Data *data;
0589 };
0590
0591 };
0592
0593
0594
0595
0596
0597
0598 class lex_input
0599 {
0600 public:
0601
0602 template <typename InputT>
0603 class inner
0604 {
0605 public:
0606 typedef int value_type;
0607 typedef std::ptrdiff_t difference_type;
0608 typedef int* pointer;
0609 typedef int& reference;
0610
0611 protected:
0612 inner()
0613 : curtok(new int(0))
0614 {}
0615
0616 inner(InputT x)
0617 : curtok(new int(x))
0618 {}
0619
0620 inner(inner const& x)
0621 : curtok(x.curtok)
0622 {}
0623
0624 void destroy()
0625 {
0626 delete curtok;
0627 curtok = 0;
0628 }
0629
0630 bool same_input(inner const& x) const
0631 {
0632 return curtok == x.curtok;
0633 }
0634
0635 void swap(inner& x)
0636 {
0637 impl::mp_swap(curtok, x.curtok);
0638 }
0639
0640 public:
0641 reference get_input() const
0642 {
0643 return *curtok;
0644 }
0645
0646 void advance_input()
0647 {
0648 extern int yylex();
0649 *curtok = yylex();
0650 }
0651
0652 bool input_at_eof() const
0653 {
0654 return *curtok == 0;
0655 }
0656
0657 private:
0658 int* curtok;
0659
0660 };
0661
0662 };
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672 class functor_input
0673 {
0674 public:
0675
0676 template <typename FunctorT>
0677 class inner
0678 {
0679 typedef typename FunctorT::result_type result_type;
0680 public:
0681 typedef result_type value_type;
0682 typedef std::ptrdiff_t difference_type;
0683 typedef result_type* pointer;
0684 typedef result_type& reference;
0685
0686 protected:
0687 inner()
0688 : ftor(0)
0689 , curtok(0)
0690 {}
0691
0692 inner(FunctorT const& x)
0693 : ftor(new FunctorT(x))
0694 , curtok(new result_type((*ftor)()))
0695 {}
0696
0697 inner(inner const& x)
0698 : ftor(x.ftor)
0699 , curtok(x.curtok)
0700 {}
0701
0702 void destroy()
0703 {
0704 delete ftor;
0705 ftor = 0;
0706 delete curtok;
0707 curtok = 0;
0708 }
0709
0710 bool same_input(inner const& x) const
0711 {
0712 return ftor == x.ftor;
0713 }
0714
0715 void swap(inner& x)
0716 {
0717 impl::mp_swap(curtok, x.curtok);
0718 impl::mp_swap(ftor, x.ftor);
0719 }
0720
0721 public:
0722 reference get_input() const
0723 {
0724 return *curtok;
0725 }
0726
0727 void advance_input()
0728 {
0729 if (curtok) {
0730 *curtok = (*ftor)();
0731 }
0732 }
0733
0734 bool input_at_eof() const
0735 {
0736 return !curtok || *curtok == ftor->eof;
0737 }
0738
0739 FunctorT& get_functor() const
0740 {
0741 return *ftor;
0742 }
0743
0744
0745 private:
0746 FunctorT* ftor;
0747 result_type* curtok;
0748
0749 };
0750
0751 };
0752
0753 }
0754
0755
0756
0757
0758
0759 namespace iterator_ { namespace impl {
0760
0761
0762 template <typename InputPolicyT, typename InputT>
0763 struct iterator_base_creator
0764 {
0765 typedef typename InputPolicyT::BOOST_NESTED_TEMPLATE inner<InputT> input_t;
0766
0767 struct type {
0768 typedef std::forward_iterator_tag iterator_category;
0769 typedef typename input_t::value_type value_type;
0770 typedef typename input_t::difference_type difference_type;
0771 typedef typename input_t::pointer pointer;
0772 typedef typename input_t::reference reference;
0773 };
0774 };
0775
0776 }}
0777
0778
0779
0780
0781
0782
0783 template
0784 <
0785 typename InputT,
0786 typename InputPolicy,
0787 typename OwnershipPolicy,
0788 typename CheckingPolicy,
0789 typename StoragePolicy
0790 >
0791 class multi_pass
0792 : public OwnershipPolicy
0793 , public CheckingPolicy
0794 , public StoragePolicy::template inner<
0795 typename InputPolicy::template inner<InputT>::value_type>
0796 , public InputPolicy::template inner<InputT>
0797 , public iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
0798 {
0799 typedef OwnershipPolicy OP;
0800 typedef CheckingPolicy CHP;
0801 typedef typename StoragePolicy::template inner<
0802 typename InputPolicy::template inner<InputT>::value_type> SP;
0803 typedef typename InputPolicy::template inner<InputT> IP;
0804 typedef typename
0805 iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
0806 IB;
0807
0808 public:
0809 typedef typename IB::value_type value_type;
0810 typedef typename IB::difference_type difference_type;
0811 typedef typename IB::reference reference;
0812 typedef typename IB::pointer pointer;
0813 typedef InputT iterator_type;
0814
0815 multi_pass();
0816 explicit multi_pass(InputT input);
0817
0818 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
0819 multi_pass(int);
0820 #endif
0821
0822 ~multi_pass();
0823
0824 multi_pass(multi_pass const&);
0825 multi_pass& operator=(multi_pass const&);
0826
0827 void swap(multi_pass& x);
0828
0829 reference operator*() const;
0830 pointer operator->() const;
0831 multi_pass& operator++();
0832 multi_pass operator++(int);
0833
0834 void clear_queue();
0835
0836 bool operator==(const multi_pass& y) const;
0837 bool operator<(const multi_pass& y) const;
0838
0839 private:
0840 bool is_eof() const;
0841 };
0842
0843 template
0844 <
0845 typename InputT,
0846 typename InputPolicy,
0847 typename OwnershipPolicy,
0848 typename CheckingPolicy,
0849 typename StoragePolicy
0850 >
0851 inline
0852 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0853 multi_pass()
0854 : OP()
0855 , CHP()
0856 , SP()
0857 , IP()
0858 {
0859 }
0860
0861 template
0862 <
0863 typename InputT,
0864 typename InputPolicy,
0865 typename OwnershipPolicy,
0866 typename CheckingPolicy,
0867 typename StoragePolicy
0868 >
0869 inline
0870 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0871 multi_pass(InputT input)
0872 : OP()
0873 , CHP()
0874 , SP()
0875 , IP(input)
0876 {
0877 }
0878
0879 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
0880
0881
0882
0883
0884
0885
0886 template
0887 <
0888 typename InputT,
0889 typename InputPolicy,
0890 typename OwnershipPolicy,
0891 typename CheckingPolicy,
0892 typename StoragePolicy
0893 >
0894 inline
0895 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0896 multi_pass(int)
0897 : OP()
0898 , CHP()
0899 , SP()
0900 , IP()
0901 {
0902 }
0903 #endif
0904
0905 template
0906 <
0907 typename InputT,
0908 typename InputPolicy,
0909 typename OwnershipPolicy,
0910 typename CheckingPolicy,
0911 typename StoragePolicy
0912 >
0913 inline
0914 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0915 ~multi_pass()
0916 {
0917 if (OP::release())
0918 {
0919 CHP::destroy();
0920 SP::destroy();
0921 IP::destroy();
0922 }
0923 }
0924
0925 template
0926 <
0927 typename InputT,
0928 typename InputPolicy,
0929 typename OwnershipPolicy,
0930 typename CheckingPolicy,
0931 typename StoragePolicy
0932 >
0933 inline
0934 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0935 multi_pass(
0936 multi_pass const& x)
0937 : OP(x)
0938 , CHP(x)
0939 , SP(x)
0940 , IP(x)
0941 {
0942 OP::clone();
0943 }
0944
0945 template
0946 <
0947 typename InputT,
0948 typename InputPolicy,
0949 typename OwnershipPolicy,
0950 typename CheckingPolicy,
0951 typename StoragePolicy
0952 >
0953 inline
0954 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
0955 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0956 operator=(
0957 multi_pass const& x)
0958 {
0959 multi_pass temp(x);
0960 temp.swap(*this);
0961 return *this;
0962 }
0963
0964 template
0965 <
0966 typename InputT,
0967 typename InputPolicy,
0968 typename OwnershipPolicy,
0969 typename CheckingPolicy,
0970 typename StoragePolicy
0971 >
0972 inline void
0973 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0974 swap(multi_pass& x)
0975 {
0976 OP::swap(x);
0977 CHP::swap(x);
0978 SP::swap(x);
0979 IP::swap(x);
0980 }
0981
0982 template
0983 <
0984 typename InputT,
0985 typename InputPolicy,
0986 typename OwnershipPolicy,
0987 typename CheckingPolicy,
0988 typename StoragePolicy
0989 >
0990 inline
0991 typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0992 reference
0993 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
0994 operator*() const
0995 {
0996 CHP::check_if_valid();
0997 return SP::dereference(*this);
0998 }
0999
1000 template
1001 <
1002 typename InputT,
1003 typename InputPolicy,
1004 typename OwnershipPolicy,
1005 typename CheckingPolicy,
1006 typename StoragePolicy
1007 >
1008 inline
1009 typename multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1010 pointer
1011 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1012 operator->() const
1013 {
1014 return &(operator*());
1015 }
1016
1017 template
1018 <
1019 typename InputT,
1020 typename InputPolicy,
1021 typename OwnershipPolicy,
1022 typename CheckingPolicy,
1023 typename StoragePolicy
1024 >
1025 inline
1026 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>&
1027 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1028 operator++()
1029 {
1030 CHP::check_if_valid();
1031 SP::increment(*this);
1032 return *this;
1033 }
1034
1035 template
1036 <
1037 typename InputT,
1038 typename InputPolicy,
1039 typename OwnershipPolicy,
1040 typename CheckingPolicy,
1041 typename StoragePolicy
1042 >
1043 inline
1044 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>
1045 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1046 operator++(int)
1047 {
1048 multi_pass
1049 <
1050 InputT,
1051 InputPolicy,
1052 OwnershipPolicy,
1053 CheckingPolicy,
1054 StoragePolicy
1055 > tmp(*this);
1056
1057 ++*this;
1058
1059 return tmp;
1060 }
1061
1062 template
1063 <
1064 typename InputT,
1065 typename InputPolicy,
1066 typename OwnershipPolicy,
1067 typename CheckingPolicy,
1068 typename StoragePolicy
1069 >
1070 inline void
1071 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1072 clear_queue()
1073 {
1074 SP::clear_queue();
1075 CHP::clear_queue();
1076 }
1077
1078 template
1079 <
1080 typename InputT,
1081 typename InputPolicy,
1082 typename OwnershipPolicy,
1083 typename CheckingPolicy,
1084 typename StoragePolicy
1085 >
1086 inline bool
1087 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1088 is_eof() const
1089 {
1090 return SP::is_eof(*this);
1091 }
1092
1093
1094 template
1095 <
1096 typename InputT,
1097 typename InputPolicy,
1098 typename OwnershipPolicy,
1099 typename CheckingPolicy,
1100 typename StoragePolicy
1101 >
1102 inline bool
1103 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1104 operator==(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1105 StoragePolicy>& y) const
1106 {
1107 bool is_eof_ = SP::is_eof(*this);
1108 bool y_is_eof_ = SP::is_eof(y);
1109
1110 if (is_eof_ && y_is_eof_)
1111 {
1112 return true;
1113 }
1114 else if (is_eof_ ^ y_is_eof_)
1115 {
1116 return false;
1117 }
1118 else if (!IP::same_input(y))
1119 {
1120 return false;
1121 }
1122 else
1123 {
1124 return SP::equal_to(y);
1125 }
1126 }
1127
1128 template
1129 <
1130 typename InputT,
1131 typename InputPolicy,
1132 typename OwnershipPolicy,
1133 typename CheckingPolicy,
1134 typename StoragePolicy
1135 >
1136 inline bool
1137 multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
1138 operator<(const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1139 StoragePolicy>& y) const
1140 {
1141 return SP::less_than(y);
1142 }
1143
1144 template
1145 <
1146 typename InputT,
1147 typename InputPolicy,
1148 typename OwnershipPolicy,
1149 typename CheckingPolicy,
1150 typename StoragePolicy
1151 >
1152 inline
1153 bool operator!=(
1154 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1155 StoragePolicy>& x,
1156 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1157 StoragePolicy>& y)
1158 {
1159 return !(x == y);
1160 }
1161
1162 template
1163 <
1164 typename InputT,
1165 typename InputPolicy,
1166 typename OwnershipPolicy,
1167 typename CheckingPolicy,
1168 typename StoragePolicy
1169 >
1170 inline
1171 bool operator>(
1172 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1173 StoragePolicy>& x,
1174 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1175 StoragePolicy>& y)
1176 {
1177 return y < x;
1178 }
1179
1180 template
1181 <
1182 typename InputT,
1183 typename InputPolicy,
1184 typename OwnershipPolicy,
1185 typename CheckingPolicy,
1186 typename StoragePolicy
1187 >
1188 inline
1189 bool operator>=(
1190 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1191 StoragePolicy>& x,
1192 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1193 StoragePolicy>& y)
1194 {
1195 return !(x < y);
1196 }
1197
1198 template
1199 <
1200 typename InputT,
1201 typename InputPolicy,
1202 typename OwnershipPolicy,
1203 typename CheckingPolicy,
1204 typename StoragePolicy
1205 >
1206 inline
1207 bool operator<=(
1208 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1209 StoragePolicy>& x,
1210 const multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy,
1211 StoragePolicy>& y)
1212 {
1213 return !(y < x);
1214 }
1215
1216
1217 template <typename InputT>
1218 inline multi_pass<InputT,
1219 multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
1220 multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>
1221 make_multi_pass(InputT i)
1222 {
1223 return multi_pass<InputT,
1224 multi_pass_policies::input_iterator, multi_pass_policies::ref_counted,
1225 multi_pass_policies::buf_id_check, multi_pass_policies::std_deque>(i);
1226 }
1227
1228
1229
1230
1231 template <typename InputT, std::size_t N>
1232 class look_ahead :
1233 public multi_pass<
1234 InputT,
1235 multi_pass_policies::input_iterator,
1236 multi_pass_policies::first_owner,
1237 multi_pass_policies::no_check,
1238 multi_pass_policies::fixed_size_queue<N> >
1239 {
1240 typedef multi_pass<
1241 InputT,
1242 multi_pass_policies::input_iterator,
1243 multi_pass_policies::first_owner,
1244 multi_pass_policies::no_check,
1245 multi_pass_policies::fixed_size_queue<N> > base_t;
1246 public:
1247 look_ahead()
1248 : base_t() {}
1249
1250 explicit look_ahead(InputT x)
1251 : base_t(x) {}
1252
1253 look_ahead(look_ahead const& x)
1254 : base_t(x) {}
1255
1256 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
1257 look_ahead(int)
1258 : base_t() {}
1259 #endif
1260
1261
1262 };
1263
1264 template
1265 <
1266 typename InputT,
1267 typename InputPolicy,
1268 typename OwnershipPolicy,
1269 typename CheckingPolicy,
1270 typename StoragePolicy
1271 >
1272 void swap(
1273 multi_pass<
1274 InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
1275 > &x,
1276 multi_pass<
1277 InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy
1278 > &y)
1279 {
1280 x.swap(y);
1281 }
1282
1283 namespace impl {
1284
1285 template <typename T>
1286 inline void mp_swap(T& t1, T& t2)
1287 {
1288 using std::swap;
1289 using BOOST_SPIRIT_CLASSIC_NS::swap;
1290 swap(t1, t2);
1291 }
1292 }
1293
1294 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
1295
1296 }}
1297
1298 #endif