diff options
author | Kevin Smith <git@kismith.co.uk> | 2013-01-12 18:41:34 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2013-01-13 10:36:26 (GMT) |
commit | f3bc816af1b0d61452de973963e453bf3b3f95a2 (patch) | |
tree | e895f8afa3580e6cff6f5ad2017d45bf147a17c2 /3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp | |
parent | 188fc285c6555eadd3c9d50ab8a94adcade78d89 (diff) | |
download | swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.zip swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.tar.bz2 |
Adding in the spirit Boost stuff
Change-Id: I4f127ce61667243b64081b0aa309028d5077045f
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp b/3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp new file mode 100644 index 0000000..a525ef3 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/support/meta_compiler.hpp @@ -0,0 +1,320 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + 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_META_COMPILER_OCTOBER_16_2008_1258PM +#define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_1258PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/config.hpp> +#include <boost/spirit/include/phoenix_limits.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto +#include <boost/proto/proto.hpp> +#include <boost/spirit/home/support/make_component.hpp> +#include <boost/spirit/home/support/modify.hpp> +#include <boost/spirit/home/support/detail/make_cons.hpp> +#include <boost/spirit/home/support/unused.hpp> +#include <boost/spirit/home/support/assert_msg.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/remove_reference.hpp> + +namespace boost { namespace spirit +{ + // Some defaults... + + template <typename Domain, typename Tag, typename Enable = void> + struct use_operator : mpl::false_ {}; + + template <typename Domain, typename T, typename Enable = void> + struct use_function : mpl::false_ {}; + + template <typename Domain, typename T, typename Enable = void> + struct use_directive : mpl::false_ {}; + + template <typename Domain, typename T, typename Enable /* = void */> + struct is_modifier_directive : mpl::false_ {}; + + template <typename Domain, typename T, typename Enable = void> + struct use_terminal : mpl::false_ {}; + + template <typename Domain, typename T, typename Enable /*= void*/> + struct flatten_tree : mpl::false_ {}; + + // Our meta-compiler. This is the main engine that hooks Spirit + // to the proto expression template engine. + + template <typename Domain> + struct meta_compiler + { + struct meta_grammar; + + BOOST_SPIRIT_ASSERT_MSG(( + !use_operator<Domain, proto::tag::subscript>::value + ), error_proto_tag_subscript_cannot_be_used, ()); + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400) + // this is the non-broken part for compilers properly supporting + // partial template specialization (VC7.1 does not) + struct cases + { + template <typename Tag, typename Enable = void> + struct case_ + : proto::not_<proto::_> + {}; + + /////////////////////////////////////////////////////////////////// + // terminals + /////////////////////////////////////////////////////////////////// + template <typename Enable> + struct case_<proto::tag::terminal, Enable> + : proto::when< + proto::if_<use_terminal<Domain, proto::_value>()>, + detail::make_terminal<Domain> + > + {}; + + template <typename Tag> + struct case_<Tag, typename enable_if<use_operator<Domain, Tag> >::type> + : proto::or_< + /////////////////////////////////////////////////////////////////// + // binary operators + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr<Tag, meta_grammar, meta_grammar>, + detail::make_binary<Domain, Tag, meta_grammar> + >, + /////////////////////////////////////////////////////////////////// + // unary operators + /////////////////////////////////////////////////////////////////// + proto::when<proto::unary_expr<Tag, meta_grammar>, + detail::make_unary<Domain, Tag, meta_grammar> + > + > + {}; + + template <typename Enable> + struct case_<proto::tag::subscript, Enable> + : proto::or_< + /////////////////////////////////////////////////////////////////// + // directives + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr<proto::tag::subscript + , proto::and_< + proto::terminal<proto::_> + , proto::if_<use_directive<Domain, proto::_value >()> > + , meta_grammar>, + detail::make_directive<Domain, meta_grammar> + >, + /////////////////////////////////////////////////////////////////// + // semantic actions + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr<proto::tag::subscript + , meta_grammar, proto::_>, + detail::make_action<Domain, meta_grammar> + > + > + {}; + }; +#else + // this part actually constitutes invalid C++ code, but it allows us to + // convince VC7.1 to do what we want + struct cases + { + template <typename Tag, typename Enable = void> + struct case_ + : proto::not_<proto::_> + {}; + + /////////////////////////////////////////////////////////////////// + // terminals + /////////////////////////////////////////////////////////////////// + template <> + struct case_<proto::tag::terminal> + : proto::when< + proto::if_<use_terminal<Domain, proto::_value>()>, + detail::make_terminal<Domain> + > + {}; + + template <typename Tag> + struct case_<Tag> + : proto::or_< + /////////////////////////////////////////////////////////////////// + // binary operators + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr< + typename enable_if<use_operator<Domain, Tag>, Tag>::type + , meta_grammar, meta_grammar> + , detail::make_binary<Domain, Tag, meta_grammar> + >, + /////////////////////////////////////////////////////////////////// + // unary operators + /////////////////////////////////////////////////////////////////// + proto::when<proto::unary_expr< + typename enable_if<use_operator<Domain, Tag>, Tag>::type + , meta_grammar> + , detail::make_unary<Domain, Tag, meta_grammar> + > + > + {}; + + template <> + struct case_<proto::tag::subscript> + : proto::or_< + /////////////////////////////////////////////////////////////////// + // directives + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr<proto::tag::subscript + , proto::and_< + proto::terminal<proto::_> + , proto::if_<use_directive<Domain, proto::_value >()> > + , meta_grammar>, + detail::make_directive<Domain, meta_grammar> + >, + /////////////////////////////////////////////////////////////////// + // semantic actions + /////////////////////////////////////////////////////////////////// + proto::when<proto::binary_expr<proto::tag::subscript + , meta_grammar, proto::_>, + detail::make_action<Domain, meta_grammar> + > + > + {}; + }; +#endif + + struct meta_grammar + : proto::switch_<cases> + {}; + }; + + namespace result_of + { + // Default case + template <typename Domain, typename Expr + , typename Modifiers = unused_type, typename Enable = void> + struct compile + { + typedef typename meta_compiler<Domain>::meta_grammar meta_grammar; + typedef typename meta_grammar:: + template result<meta_grammar(Expr, mpl::void_, Modifiers)>::type + type; + }; + + // If Expr is not a proto expression, make it a terminal + template <typename Domain, typename Expr, typename Modifiers> + struct compile<Domain, Expr, Modifiers, + typename disable_if<proto::is_expr<Expr> >::type> + : compile<Domain, typename proto::terminal<Expr>::type, Modifiers> {}; + } + + namespace traits + { + // Check if Expr matches the domain's grammar + template <typename Domain, typename Expr> + struct matches : + proto::matches< + typename proto::result_of::as_expr< + typename remove_reference<Expr>::type>::type, + typename meta_compiler<Domain>::meta_grammar + > + { + }; + } + + namespace detail + { + template <typename Domain> + struct compiler + { + // Default case + template <typename Expr, typename Modifiers> + static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type + compile(Expr const& expr, Modifiers modifiers, mpl::true_) + { + typename meta_compiler<Domain>::meta_grammar compiler; + return compiler(expr, mpl::void_(), modifiers); + } + + // If Expr is not a proto expression, make it a terminal + template <typename Expr, typename Modifiers> + static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type + compile(Expr const& expr, Modifiers modifiers, mpl::false_) + { + typename meta_compiler<Domain>::meta_grammar compiler; + typedef typename detail::as_meta_element<Expr>::type expr_; + typename proto::terminal<expr_>::type term = {expr}; + return compiler(term, mpl::void_(), modifiers); + } + }; + } + + template <typename Domain, typename Expr> + inline typename result_of::compile<Domain, Expr, unused_type>::type + compile(Expr const& expr) + { + typedef typename proto::is_expr<Expr>::type is_expr; + return detail::compiler<Domain>::compile(expr, unused, is_expr()); + } + + template <typename Domain, typename Expr, typename Modifiers> + inline typename result_of::compile<Domain, Expr, Modifiers>::type + compile(Expr const& expr, Modifiers modifiers) + { + typedef typename proto::is_expr<Expr>::type is_expr; + return detail::compiler<Domain>::compile(expr, modifiers, is_expr()); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Elements, template <typename Subject> class generator> + struct make_unary_composite + { + typedef typename + fusion::result_of::value_at_c<Elements, 0>::type + element_type; + typedef generator<element_type> result_type; + result_type operator()(Elements const& elements, unused_type) const + { + return result_type(fusion::at_c<0>(elements)); + } + }; + + template <typename Elements, template <typename Left, typename Right> class generator> + struct make_binary_composite + { + typedef typename + fusion::result_of::value_at_c<Elements, 0>::type + left_type; + typedef typename + fusion::result_of::value_at_c<Elements, 1>::type + right_type; + typedef generator<left_type, right_type> result_type; + + result_type operator()(Elements const& elements, unused_type) const + { + return result_type( + fusion::at_c<0>(elements) + , fusion::at_c<1>(elements) + ); + } + }; + + template <typename Elements, template <typename Elements_> class generator> + struct make_nary_composite + { + typedef generator<Elements> result_type; + result_type operator()(Elements const& elements, unused_type) const + { + return result_type(elements); + } + }; + +}} + +#endif |