Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:53

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004     http://spirit.sourceforge.net/
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #if !defined(BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM)
0010 #define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include<boost/config.hpp>
0017 
0018 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
0019     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
0020 #include <utility>
0021 #include <type_traits>
0022 #endif
0023 
0024 
0025 #include <boost/spirit/home/support/attributes.hpp>
0026 
0027 namespace boost { namespace phoenix
0028 {
0029     template <typename Expr>
0030     struct actor;
0031 }}
0032 
0033 namespace boost { namespace spirit { namespace traits
0034 {
0035     template <typename Component>
0036     struct action_dispatch
0037     {
0038 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
0039     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
0040         // omit function parameters without specializing for each possible
0041         // type of callable entity
0042         // many thanks to Eelis/##iso-c++ for this contribution
0043 
0044     private:
0045         // this will be used to pass around POD types which are safe
0046         // to go through the ellipsis operator (if ever used)
0047         template <typename>
0048         struct fwd_tag {};
0049 
0050         // the first parameter is a placeholder to obtain SFINAE when
0051         // doing overload resolution, the second one is the actual
0052         // forwarder, where we can apply our implementation
0053         template <typename, typename T>
0054         struct fwd_storage { typedef T type; };
0055 
0056         // gcc should accept fake<T>() but it prints a sorry, needs
0057         // a check once the bug is sorted out, use a FAKE_CALL macro for now
0058         template <typename T>
0059         T fake_call();
0060 
0061 #define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0)
0062 
0063         // the forwarders, here we could tweak the implementation of
0064         // how parameters are passed to the functions, if needed
0065         struct fwd_none
0066         {
0067             template<typename F, typename... Rest>
0068             auto operator()(F && f, Rest&&...) -> decltype(f())
0069             {
0070                 return f();
0071             }
0072         };
0073 
0074         struct fwd_attrib
0075         {
0076             template<typename F, typename A, typename... Rest>
0077             auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a))
0078             {
0079                  return f(a);
0080             }
0081         };
0082 
0083         struct fwd_attrib_context
0084         {
0085              template<typename F, typename A, typename B, typename... Rest>
0086              auto operator()(F && f, A && a, B && b, Rest&&...)
0087                 -> decltype(f(a, b))
0088              {
0089                  return f(a, b);
0090              }
0091         };
0092 
0093         struct fwd_attrib_context_pass
0094         {
0095             template<typename F, typename A, typename B, typename C
0096               , typename... Rest>
0097             auto operator()(F && f, A && a, B && b, C && c, Rest&&...)
0098                -> decltype(f(a, b, c))
0099             {
0100                 return f(a, b, c);
0101             }
0102         };
0103 
0104         // SFINAE for our calling syntax, the forwarders are stored based
0105         // on what function call gives a proper result
0106         // this code can probably be more generic once implementations are
0107         // steady
0108         template <typename F>
0109         static auto do_call(F && f, ...)
0110            -> typename fwd_storage<decltype(f()), fwd_none>::type
0111         {
0112             return {};
0113         }
0114 
0115         template <typename F, typename A>
0116         static auto do_call(F && f, fwd_tag<A>, ...)
0117            -> typename fwd_storage<decltype(f(BOOST_SPIRIT_FAKE_CALL(A)))
0118                  , fwd_attrib>::type
0119         {
0120             return {};
0121         }
0122 
0123         template <typename F, typename A, typename B>
0124         static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, ...)
0125            -> typename fwd_storage<
0126                     decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)))
0127                 , fwd_attrib_context>::type
0128         {
0129             return {};
0130         }
0131 
0132         template <typename F, typename A, typename B, typename C>
0133         static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, fwd_tag<C>, ...)
0134            -> typename fwd_storage<
0135                   decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)
0136                     , BOOST_SPIRIT_FAKE_CALL(C)))
0137                 , fwd_attrib_context_pass>::type
0138         {
0139             return {};
0140         }
0141 
0142         // this function calls the forwarder and is responsible for
0143         // stripping the tail of the parameters
0144         template <typename F, typename... A>
0145         static void caller(F && f, A && ... a)
0146         {
0147             do_call(f, fwd_tag<typename std::remove_reference<A>::type>()...)
0148                 (std::forward<F>(f), std::forward<A>(a)...);
0149         }
0150 
0151 #undef BOOST_SPIRIT_FAKE_CALL
0152 
0153     public:
0154         template <typename F, typename Attribute, typename Context>
0155         bool operator()(F const& f, Attribute& attr, Context& context)
0156         {
0157             bool pass = true;
0158             caller(f, attr, context, pass);
0159             return pass;
0160         }
0161 #else
0162         // general handler for everything not explicitly specialized below
0163         template <typename F, typename Attribute, typename Context>
0164         bool operator()(F const& f, Attribute& attr, Context& context)
0165         {
0166             bool pass = true;
0167             f(attr, context, pass);
0168             return pass;
0169         }
0170 #endif
0171 
0172         // handler for phoenix actors
0173 
0174         // If the component this action has to be invoked for is a tuple, we
0175         // wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
0176         // and pass through any fusion tuple.
0177         template <typename Eval, typename Attribute, typename Context>
0178         bool operator()(phoenix::actor<Eval> const& f
0179           , Attribute& attr, Context& context)
0180         {
0181             bool pass = true;
0182             typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
0183             f(attr_wrap, context, pass);
0184             return pass;
0185         }
0186 
0187         // specializations for plain function pointers taking different number of
0188         // arguments
0189         template <typename RT, typename A0, typename A1, typename A2
0190           , typename Attribute, typename Context>
0191         bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
0192         {
0193             bool pass = true;
0194             f(attr, context, pass);
0195             return pass;
0196         }
0197 
0198         template <typename RT, typename A0, typename A1
0199           , typename Attribute, typename Context>
0200         bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
0201         {
0202             f(attr, context);
0203             return true;
0204         }
0205 
0206         template <typename RT, typename A0, typename Attribute, typename Context>
0207         bool operator()(RT(*f)(A0), Attribute& attr, Context&)
0208         {
0209             f(attr);
0210             return true;
0211         }
0212 
0213         template <typename RT, typename Attribute, typename Context>
0214         bool operator()(RT(*f)(), Attribute&, Context&)
0215         {
0216             f();
0217             return true;
0218         }
0219     };
0220 }}}
0221 
0222 #endif