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
+