diff -r 000000000000 -r bde4ae8d615e os/ossrv/ossrv_pub/boost_apis/boost/spirit/dynamic/switch.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/spirit/dynamic/switch.hpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,255 @@ +/*============================================================================= + Copyright (c) 2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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/core/config.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/spirit/core/parser.hpp> +#include <boost/spirit/core/composite/epsilon.hpp> +#include <boost/spirit/dynamic/impl/switch.ipp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +/////////////////////////////////////////////////////////////////////////////// +// +// 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(); + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif // BOOST_SPIRIT_SWITCH_HPP