Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // static.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005
0010 
0011 // MS compatible compilers support #pragma once
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015 
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/xpressive/detail/detail_fwd.hpp>
0018 #include <boost/xpressive/detail/core/state.hpp>
0019 #include <boost/xpressive/detail/core/linker.hpp>
0020 #include <boost/xpressive/detail/core/peeker.hpp>
0021 #include <boost/xpressive/detail/static/placeholders.hpp>
0022 #include <boost/xpressive/detail/utility/width.hpp>
0023 
0024 // Random thoughts:
0025 // - must support indirect repeat counts {$n,$m}
0026 // - add ws to eat whitespace (make *ws illegal)
0027 // - a{n,m}    -> repeat<n,m>(a)
0028 // - a{$n,$m}  -> repeat(n,m)(a)
0029 // - add nil to match nothing
0030 // - instead of s1, s2, etc., how about s[1], s[2], etc.? Needlessly verbose?
0031 
0032 namespace boost { namespace xpressive { namespace detail
0033 {
0034 
0035 ///////////////////////////////////////////////////////////////////////////////
0036 // stacked_xpression
0037 //
0038 template<typename Top, typename Next>
0039 struct stacked_xpression
0040   : Next
0041 {
0042     // match
0043     //  delegates to Next
0044     template<typename BidiIter>
0045     bool match(match_state<BidiIter> &state) const
0046     {
0047         return static_cast<Next const *>(this)->
0048             BOOST_NESTED_TEMPLATE push_match<Top>(state);
0049     }
0050 
0051     // top_match
0052     //   jump back to the xpression on top of the xpression stack,
0053     //   and keep the xpression on the stack.
0054     template<typename BidiIter>
0055     static bool top_match(match_state<BidiIter> &state, void const *top)
0056     {
0057         return static_cast<Top const *>(top)->
0058             BOOST_NESTED_TEMPLATE push_match<Top>(state);
0059     }
0060 
0061     // pop_match
0062     //   jump back to the xpression on top of the xpression stack,
0063     //   pop the xpression off the stack.
0064     template<typename BidiIter>
0065     static bool pop_match(match_state<BidiIter> &state, void const *top)
0066     {
0067         return static_cast<Top const *>(top)->match(state);
0068     }
0069 
0070     // skip_match
0071     //   pop the xpression off the top of the stack and ignore it; call
0072     //   match on next.
0073     template<typename BidiIter>
0074     bool skip_match(match_state<BidiIter> &state) const
0075     {
0076         // could be static_xpression::skip_impl or stacked_xpression::skip_impl
0077         // depending on if there is 1 or more than 1 xpression on the
0078         // xpression stack
0079         return Top::skip_impl(*static_cast<Next const *>(this), state);
0080     }
0081 
0082 //protected:
0083 
0084     // skip_impl
0085     //   implementation of skip_match.
0086     template<typename That, typename BidiIter>
0087     static bool skip_impl(That const &that, match_state<BidiIter> &state)
0088     {
0089         return that.BOOST_NESTED_TEMPLATE push_match<Top>(state);
0090     }
0091 };
0092 
0093 ///////////////////////////////////////////////////////////////////////////////
0094 // stacked_xpression_cast
0095 //
0096 template<typename Top, typename Next>
0097 inline stacked_xpression<Top, Next> const &stacked_xpression_cast(Next const &next)
0098 {
0099     // NOTE: this is a little white lie. The "next" object doesn't really have
0100     // the type to which we're casting it. It is harmless, though. We are only using
0101     // the cast to decorate the next object with type information. It is done
0102     // this way to save stack space.
0103     BOOST_MPL_ASSERT_RELATION(sizeof(stacked_xpression<Top, Next>), ==, sizeof(Next));
0104     return *static_cast<stacked_xpression<Top, Next> const *>(&next);
0105 }
0106 
0107 ///////////////////////////////////////////////////////////////////////////////
0108 // static_xpression
0109 //
0110 template<typename Matcher, typename Next>
0111 struct static_xpression
0112   : Matcher
0113 {
0114     Next next_;
0115 
0116     BOOST_STATIC_CONSTANT(bool, pure = Matcher::pure && Next::pure);
0117     BOOST_STATIC_CONSTANT(
0118         std::size_t
0119       , width =
0120             Matcher::width != unknown_width::value && Next::width != unknown_width::value
0121           ? Matcher::width + Next::width
0122           : unknown_width::value
0123     );
0124 
0125     static_xpression(Matcher const &matcher = Matcher(), Next const &next = Next())
0126       : Matcher(matcher)
0127       , next_(next)
0128     {
0129     }
0130 
0131     // match
0132     //  delegates to the Matcher
0133     template<typename BidiIter>
0134     bool match(match_state<BidiIter> &state) const
0135     {
0136         return this->Matcher::match(state, this->next_);
0137     }
0138 
0139     // push_match
0140     //   call match on this, but also push "Top" onto the xpression
0141     //   stack so we know what we are jumping back to later.
0142     template<typename Top, typename BidiIter>
0143     bool push_match(match_state<BidiIter> &state) const
0144     {
0145         return this->Matcher::match(state, stacked_xpression_cast<Top>(this->next_));
0146     }
0147 
0148     // skip_impl
0149     //   implementation of skip_match, called from stacked_xpression::skip_match
0150     template<typename That, typename BidiIter>
0151     static bool skip_impl(That const &that, match_state<BidiIter> &state)
0152     {
0153         return that.match(state);
0154     }
0155 
0156     // for linking a compiled regular xpression
0157     template<typename Char>
0158     void link(xpression_linker<Char> &linker) const
0159     {
0160         linker.accept(*static_cast<Matcher const *>(this), &this->next_);
0161         this->next_.link(linker);
0162     }
0163 
0164     // for building a lead-follow
0165     template<typename Char>
0166     void peek(xpression_peeker<Char> &peeker) const
0167     {
0168         this->peek_next_(peeker.accept(*static_cast<Matcher const *>(this)), peeker);
0169     }
0170 
0171     // for getting xpression width
0172     detail::width get_width() const
0173     {
0174         return this->get_width_(mpl::size_t<width>());
0175     }
0176 
0177 private:
0178 
0179     static_xpression &operator =(static_xpression const &);
0180 
0181     template<typename Char>
0182     void peek_next_(mpl::true_, xpression_peeker<Char> &peeker) const
0183     {
0184         this->next_.peek(peeker);
0185     }
0186 
0187     template<typename Char>
0188     void peek_next_(mpl::false_, xpression_peeker<Char> &) const
0189     {
0190         // no-op
0191     }
0192 
0193     template<std::size_t Width>
0194     detail::width get_width_(mpl::size_t<Width>) const
0195     {
0196         return Width;
0197     }
0198 
0199     detail::width get_width_(unknown_width) const
0200     {
0201         // Should only be called in contexts where the width is
0202         // known to be fixed.
0203         return this->Matcher::get_width() + this->next_.get_width();
0204     }
0205 };
0206 
0207 ///////////////////////////////////////////////////////////////////////////////
0208 // make_static
0209 //
0210 template<typename Matcher>
0211 inline static_xpression<Matcher> const
0212 make_static(Matcher const &matcher)
0213 {
0214     return static_xpression<Matcher>(matcher);
0215 }
0216 
0217 template<typename Matcher, typename Next>
0218 inline static_xpression<Matcher, Next> const
0219 make_static(Matcher const &matcher, Next const &next)
0220 {
0221     return static_xpression<Matcher, Next>(matcher, next);
0222 }
0223 
0224 ///////////////////////////////////////////////////////////////////////////////
0225 // no_next
0226 //
0227 struct no_next
0228 {
0229     BOOST_STATIC_CONSTANT(std::size_t, width = 0);
0230     BOOST_STATIC_CONSTANT(bool, pure = true);
0231 
0232     template<typename Char>
0233     void link(xpression_linker<Char> &) const
0234     {
0235     }
0236 
0237     template<typename Char>
0238     void peek(xpression_peeker<Char> &peeker) const
0239     {
0240         peeker.fail();
0241     }
0242 
0243     detail::width get_width() const
0244     {
0245         return 0;
0246     }
0247 };
0248 
0249 ///////////////////////////////////////////////////////////////////////////////
0250 // get_mark_number
0251 //
0252 inline int get_mark_number(basic_mark_tag const &mark)
0253 {
0254     return proto::value(mark).mark_number_;
0255 }
0256 
0257 }}} // namespace boost::xpressive::detail
0258 
0259 #endif