⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 switch.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
字号:
/*=============================================================================    Copyright (c) 2003 Hartmut Kaiser    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_SWITCH_HPP#define BOOST_SPIRIT_SWITCH_HPP///////////////////////////////////////////////////////////////////////////////////  The default_p parser generator template uses the following magic number//  as the corresponding case label value inside the generated switch()//  statements. If this number conflicts with your code, please pick a//  different one./////////////////////////////////////////////////////////////////////////////////#if !defined(BOOST_SPIRIT_DEFAULTCASE_MAGIC)#define BOOST_SPIRIT_DEFAULTCASE_MAGIC 0x15F97A7#endif///////////////////////////////////////////////////////////////////////////////////  Spirit predefined maximum number of possible case_p/default_p case branch//  parsers./////////////////////////////////////////////////////////////////////////////////#if !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 3#endif // !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)///////////////////////////////////////////////////////////////////////////////#include <boost/static_assert.hpp>/////////////////////////////////////////////////////////////////////////////////// Ensure   BOOST_SPIRIT_SELECT_LIMIT > 0/////////////////////////////////////////////////////////////////////////////////BOOST_STATIC_ASSERT(BOOST_SPIRIT_SWITCH_CASE_LIMIT > 0);#include <boost/spirit/home/classic/namespace.hpp>#include <boost/spirit/home/classic/core/config.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/spirit/home/classic/core/parser.hpp>#include <boost/spirit/home/classic/core/composite/epsilon.hpp>#include <boost/spirit/home/classic/dynamic/impl/switch.ipp>///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN///////////////////////////////////////////////////////////////////////////////////  The switch_parser allows to build switch like parsing constructs, which//  will have much better perfomance as comparable straight solutions.////  Input stream driven syntax:////      switch_p//      [//          case_p<'a'>//              (...parser to use, if the next character is 'a'...),//          case_p<'b'>//              (...parser to use, if the next character is 'b'...),//          default_p//              (...parser to use, if nothing was matched before...)//      ]////  General syntax:////      switch_p(...lazy expression returning the switch condition value...)//      [//          case_p<1>//              (...parser to use, if the switch condition value is 1...),//          case_p<2>//              (...parser to use, if the switch condition value is 2...),//          default_p//              (...parser to use, if nothing was matched before...)//      ]////  The maximum number of possible case_p branches is defined by the p constant//  BOOST_SPIRIT_SWITCH_CASE_LIMIT (this value defaults to 3 if not otherwise//  defined)./////////////////////////////////////////////////////////////////////////////////template <typename CaseT, typename CondT = impl::get_next_token_cond>struct switch_parser:   public unary<CaseT, parser<switch_parser<CaseT, CondT> > >{    typedef switch_parser<CaseT, CondT>     self_t;    typedef unary_parser_category           parser_category_t;    typedef unary<CaseT, parser<self_t> >   base_t;    switch_parser(CaseT const &case_)    :   base_t(case_), cond(CondT())    {}    switch_parser(CaseT const &case_, CondT const &cond_)    :   base_t(case_), cond(cond_)    {}    template <typename ScannerT>    struct result    {        typedef typename match_result<ScannerT, nil_t>::type type;    };    template <typename ScannerT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scan) const    {        return this->subject().parse(scan,            impl::make_cond_functor<CondT>::do_(cond));    }    CondT cond;};///////////////////////////////////////////////////////////////////////////////template <typename CondT>struct switch_cond_parser{    switch_cond_parser(CondT const &cond_)    :   cond(cond_)    {}    template <typename ParserT>    switch_parser<ParserT, CondT>    operator[](parser<ParserT> const &p) const    {        return switch_parser<ParserT, CondT>(p.derived(), cond);    }    CondT const &cond;};///////////////////////////////////////////////////////////////////////////////template <int N, typename ParserT, bool IsDefault>struct case_parser:   public unary<ParserT, parser<case_parser<N, ParserT, IsDefault> > >{    typedef case_parser<N, ParserT, IsDefault> self_t;    typedef unary_parser_category               parser_category_t;    typedef unary<ParserT, parser<self_t> >     base_t;    typedef typename base_t::subject_t          self_subject_t;    BOOST_STATIC_CONSTANT(int, value = N);    BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);    BOOST_STATIC_CONSTANT(bool, is_simple = true);    BOOST_STATIC_CONSTANT(bool, is_epsilon = (        is_default && boost::is_same<self_subject_t, epsilon_parser>::value    ));    case_parser(parser<ParserT> const &p)    :   base_t(p.derived())    {}    template <typename ScannerT>    struct result    {        typedef typename match_result<ScannerT, nil_t>::type type;    };    template <typename ScannerT, typename CondT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scan, CondT const &cond) const    {        typedef impl::default_case<self_t> default_t;        if (!scan.at_end()) {            typedef impl::default_delegate_parse<                value, is_default, default_t::value> default_parse_t;            typename ScannerT::iterator_t const save(scan.first);            return default_parse_t::parse(cond(scan), *this,                *this, scan, save);        }        return default_t::is_epsilon ? scan.empty_match() : scan.no_match();    }    template <int N1, typename ParserT1, bool IsDefault1>    impl::compound_case_parser<        self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1    >    operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const    {        //  If the following compile time assertion fires, you've probably used        //  more than one default_p case inside the switch_p parser construct.        BOOST_STATIC_ASSERT(!is_default || !IsDefault1);        typedef case_parser<N1, ParserT1, IsDefault1> right_t;        return impl::compound_case_parser<self_t, right_t, IsDefault1>(*this, p);    }};///////////////////////////////////////////////////////////////////////////////struct switch_parser_gen {//  This generates a switch parser, which is driven by the condition value//  returned by the lazy parameter expression 'cond'. This may be a parser,//  which result is used or a phoenix actor, which will be dereferenced to//  obtain the switch condition value.    template <typename CondT>    switch_cond_parser<CondT>    operator()(CondT const &cond) const    {        return switch_cond_parser<CondT>(cond);    }//  This generates a switch parser, which is driven by the next character/token//  found in the input stream.    template <typename CaseT>    switch_parser<CaseT>    operator[](parser<CaseT> const &p) const    {        return switch_parser<CaseT>(p.derived());    }};switch_parser_gen const switch_p = switch_parser_gen();///////////////////////////////////////////////////////////////////////////////template <int N, typename ParserT>inline case_parser<N, ParserT, false>case_p(parser<ParserT> const &p){    return case_parser<N, ParserT, false>(p);}///////////////////////////////////////////////////////////////////////////////struct default_parser_gen:   public case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>{    default_parser_gen()    :   case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>            (epsilon_p)    {}    template <typename ParserT>    case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>    operator()(parser<ParserT> const &p) const    {        return case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>(p);    }};default_parser_gen const default_p = default_parser_gen();///////////////////////////////////////////////////////////////////////////////BOOST_SPIRIT_CLASSIC_NAMESPACE_END}}  // namespace BOOST_SPIRIT_CLASSIC_NS#endif // BOOST_SPIRIT_SWITCH_HPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -