Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/phoenix/statement/switch.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/phoenix/statement/switch.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,300 @@ +/*============================================================================== + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2010 Thomas Heller + + 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_PHOENIX_STATEMENT_SWITCH_HPP +#define BOOST_PHOENIX_STATEMENT_SWITCH_HPP + +#include <boost/phoenix/core/limits.hpp> +#include <boost/fusion/iterator/advance.hpp> +#include <boost/phoenix/core/call.hpp> +#include <boost/phoenix/core/expression.hpp> +#include <boost/phoenix/core/meta_grammar.hpp> +#include <boost/phoenix/core/is_nullary.hpp> +#include <boost/phoenix/support/iterate.hpp> +#include <boost/proto/make_expr.hpp> +#include <boost/proto/fusion.hpp> + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4065) // switch statement contains 'default' but no 'case' labels +#endif + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(phoenix)(switch_case) + , (proto::terminal<proto::_>) + (meta_grammar) +) + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(phoenix)(switch_default_case) + , (meta_grammar) +) + +namespace boost { namespace phoenix +{ + namespace detail + { + struct switch_case_grammar; + struct switch_case_with_default_grammar; + struct switch_grammar + : proto::or_< + proto::when< + detail::switch_case_grammar + , mpl::false_() + > + , proto::when< + detail::switch_case_with_default_grammar + , mpl::true_() + > + > + {}; + } + + namespace detail + { + struct switch_case_is_nullary + : proto::or_< + proto::when< + proto::comma< + switch_case_is_nullary + , proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case> + > + , mpl::and_< + switch_case_is_nullary( + proto::_child_c<0> + , proto::_state + ) + , switch_case_is_nullary( + proto::_child_c<1> + , proto::_state + ) + >() + > + , proto::when< + proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case> + , evaluator(proto::_child_c<0>, proto::_state) + > + > + {}; + + struct switch_case_grammar + : proto::or_< + proto::comma<switch_case_grammar, phoenix::rule::switch_case> + , proto::when<phoenix::rule::switch_case, proto::_> + > + {}; + + struct switch_case_with_default_grammar + : proto::or_< + proto::comma<switch_case_grammar, phoenix::rule::switch_default_case> + , proto::when<phoenix::rule::switch_default_case, proto::_> + > + {}; + + struct switch_size + : proto::or_< + proto::when< + proto::comma<switch_size, proto::_> + , mpl::next<switch_size(proto::_left)>() + > + , proto::when<proto::_, mpl::int_<1>()> + > + {}; + } +}} + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(phoenix)(switch_) + , (meta_grammar) // Cond + (detail::switch_grammar) // Cases +) + +namespace boost { namespace phoenix { + + template <typename Dummy> + struct is_nullary::when<rule::switch_, Dummy> + : proto::and_< + evaluator(proto::_child_c<0>, _context) + , detail::switch_case_is_nullary(proto::_child_c<1>, _context) + > + {}; + + struct switch_eval + { + typedef void result_type; + + template <typename Context> + result_type + operator()(Context const &) const + { + } + + template <typename Cond, typename Cases, typename Context> + result_type + operator()(Cond const & cond, Cases const & cases, Context const & ctx) const + { + this->evaluate( + ctx + , cond + , cases + , typename detail::switch_size::impl<Cases, int, proto::empty_env>::result_type() + , typename detail::switch_grammar::impl<Cases, int, proto::empty_env>::result_type() + ); + } + + private: + template <typename Context, typename Cond, typename Cases> + result_type + evaluate( + Context const & ctx + , Cond const & cond + , Cases const & cases + , mpl::int_<1> + , mpl::false_ + ) const + { + typedef + typename proto::result_of::value< + typename proto::result_of::child_c< + Cases + , 0 + >::type + >::type + case_label; + + switch(boost::phoenix::eval(cond, ctx)) + { + case case_label::value: + boost::phoenix::eval(proto::child_c<1>(cases), ctx); + } + } + + template <typename Context, typename Cond, typename Cases> + result_type + evaluate( + Context const & ctx + , Cond const & cond + , Cases const & cases + , mpl::int_<1> + , mpl::true_ + ) const + { + switch(boost::phoenix::eval(cond, ctx)) + { + default: + boost::phoenix::eval(proto::child_c<0>(cases), ctx); + } + } + + // Bring in the evaluation functions + #include <boost/phoenix/statement/detail/switch.hpp> + }; + + template <typename Dummy> + struct default_actions::when<rule::switch_, Dummy> + : call<switch_eval> + {}; + + template <int N, typename A> + inline + typename proto::result_of::make_expr< + tag::switch_case + , proto::basic_default_domain + , mpl::int_<N> + , A + >::type const + case_(A const & a) + { + return + proto::make_expr< + tag::switch_case + , proto::basic_default_domain + >( + mpl::int_<N>() + , a + ); + } + + template <typename A> + inline + typename proto::result_of::make_expr< + tag::switch_default_case + , proto::basic_default_domain + , A + >::type const + default_(A const& a) + { + return + proto::make_expr< + tag::switch_default_case + , proto::basic_default_domain + >(a); + } + + template <typename Cond> + struct switch_gen + { + switch_gen(Cond const& cond) : cond(cond) {} + + template <typename Cases> + typename expression::switch_< + Cond + , Cases + >::type + operator[](Cases const& cases) const + { + return + this->generate( + cases + , proto::matches<Cases, detail::switch_grammar>() + ); + } + + private: + Cond const& cond; + + template <typename Cases> + typename expression::switch_< + Cond + , Cases + >::type + generate(Cases const & cases, mpl::true_) const + { + return expression::switch_<Cond, Cases>::make(cond, cases); + } + + template <typename Cases> + typename expression::switch_< + Cond + , Cases + >::type + generate(Cases const &, mpl::false_) const + { + BOOST_MPL_ASSERT_MSG( + false + , INVALID_SWITCH_CASE_STATEMENT + , (Cases) + ); + } + }; + + template <typename Cond> + inline + switch_gen<Cond> const + switch_(Cond const& cond) + { + return switch_gen<Cond>(cond); + } + +}} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif +