File indexing completed on 2025-01-19 09:47:51
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
0009 #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
0010
0011 #include <boost/config.hpp>
0012 #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
0013 #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
0014 #include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
0015 #include <boost/limits.hpp>
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/core/invoke_swap.hpp>
0018 #include <boost/utility/base_from_member.hpp>
0019
0020 namespace boost { namespace spirit
0021 {
0022
0023
0024
0025 template<typename T, typename Policies>
0026 class multi_pass
0027 : private boost::base_from_member<
0028 typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
0029 , public Policies::BOOST_NESTED_TEMPLATE unique<T>
0030 {
0031 private:
0032
0033 typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T>
0034 policies_base_type;
0035 typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T>
0036 shared_data_type;
0037
0038 typedef boost::base_from_member<shared_data_type*> member_base;
0039
0040
0041
0042 typedef typename policies_base_type::input_policy iterator_type;
0043
0044 public:
0045
0046 typedef std::forward_iterator_tag iterator_category;
0047 typedef typename iterator_type::value_type value_type;
0048 typedef typename iterator_type::difference_type difference_type;
0049 typedef typename iterator_type::distance_type distance_type;
0050 typedef typename iterator_type::reference reference;
0051 typedef typename iterator_type::pointer pointer;
0052
0053 multi_pass() : member_base(static_cast<shared_data_type*>(0)) {}
0054
0055 explicit multi_pass(T& input)
0056 : member_base(new shared_data_type(input)), policies_base_type(input) {}
0057
0058 explicit multi_pass(T const& input)
0059 : member_base(new shared_data_type(input)), policies_base_type(input) {}
0060
0061 multi_pass(multi_pass const& x)
0062 : member_base(x.member), policies_base_type(x)
0063 {
0064 policies_base_type::clone(*this);
0065 }
0066
0067 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
0068
0069
0070
0071
0072
0073
0074 multi_pass(int) : member_base(static_cast<shared_data_type*>(0)) {}
0075 #endif
0076
0077 ~multi_pass()
0078 {
0079 if (policies_base_type::release(*this)) {
0080 policies_base_type::destroy(*this);
0081 delete this->member;
0082 }
0083 }
0084
0085 multi_pass& operator=(multi_pass const& x)
0086 {
0087 if (this != &x) {
0088 multi_pass temp(x);
0089 temp.swap(*this);
0090 }
0091 return *this;
0092 }
0093
0094 void swap(multi_pass& x)
0095 {
0096 boost::core::invoke_swap(this->member, x.member);
0097 this->policies_base_type::swap(x);
0098 }
0099
0100 reference operator*() const
0101 {
0102 policies_base_type::docheck(*this);
0103 return policies_base_type::dereference(*this);
0104 }
0105 pointer operator->() const
0106 {
0107 return &(operator*());
0108 }
0109
0110 multi_pass& operator++()
0111 {
0112 policies_base_type::docheck(*this);
0113 policies_base_type::increment(*this);
0114 return *this;
0115 }
0116 multi_pass operator++(int)
0117 {
0118 multi_pass tmp(*this);
0119 ++*this;
0120 return tmp;
0121 }
0122
0123 void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode =
0124 traits::clear_mode::clear_if_enabled)
0125 {
0126 if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
0127 policies_base_type::clear_queue(*this);
0128 }
0129 bool inhibit_clear_queue() const
0130 {
0131 return this->member->inhibit_clear_queue_;
0132 }
0133 void inhibit_clear_queue(bool flag)
0134 {
0135 this->member->inhibit_clear_queue_ = flag;
0136 }
0137
0138 bool operator==(multi_pass const& y) const
0139 {
0140 if (is_eof())
0141 return y.is_eof();
0142 if (y.is_eof())
0143 return false;
0144
0145 return policies_base_type::equal_to(*this, y);
0146 }
0147 bool operator<(multi_pass const& y) const
0148 {
0149 return policies_base_type::less_than(*this, y);
0150 }
0151
0152 bool operator!=(multi_pass const& y) const
0153 {
0154 return !(*this == y);
0155 }
0156 bool operator>(multi_pass const& y) const
0157 {
0158 return y < *this;
0159 }
0160 bool operator>=(multi_pass const& y) const
0161 {
0162 return !(*this < y);
0163 }
0164 bool operator<=(multi_pass const& y) const
0165 {
0166 return !(y < *this);
0167 }
0168
0169
0170 shared_data_type* shared() const { return this->member; }
0171
0172 private:
0173 bool is_eof() const
0174 {
0175 return (0 == this->member) || policies_base_type::is_eof(*this);
0176 }
0177 };
0178
0179
0180
0181
0182 template <typename Policies, typename T>
0183 inline multi_pass<T, Policies>
0184 make_multi_pass(T& i)
0185 {
0186 return multi_pass<T, Policies>(i);
0187 }
0188 template <typename Policies, typename T>
0189 inline multi_pass<T, Policies>
0190 make_multi_pass(T const& i)
0191 {
0192 return multi_pass<T, Policies>(i);
0193 }
0194
0195
0196 template <typename T>
0197 inline multi_pass<T>
0198 make_default_multi_pass(T& i)
0199 {
0200 return multi_pass<T>(i);
0201 }
0202 template <typename T>
0203 inline multi_pass<T>
0204 make_default_multi_pass(T const& i)
0205 {
0206 return multi_pass<T>(i);
0207 }
0208
0209
0210 template <typename T, typename Policies>
0211 inline void
0212 swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
0213 {
0214 x.swap(y);
0215 }
0216
0217
0218
0219
0220 namespace traits
0221 {
0222 template <typename T, typename Policies>
0223 void clear_queue(multi_pass<T, Policies>& mp
0224 , BOOST_SCOPED_ENUM(traits::clear_mode) mode)
0225 {
0226 mp.clear_queue(mode);
0227 }
0228
0229 template <typename T, typename Policies>
0230 void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
0231 {
0232 mp.inhibit_clear_queue(flag);
0233 }
0234
0235 template <typename T, typename Policies>
0236 bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
0237 {
0238 return mp.inhibit_clear_queue();
0239 }
0240 }
0241
0242 }}
0243
0244 #endif
0245
0246