diff options
Diffstat (limited to 'boost/proto/transform/when.hpp')
-rw-r--r-- | boost/proto/transform/when.hpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/boost/proto/transform/when.hpp b/boost/proto/transform/when.hpp index 4bbb8a7aa8..bd4cb9fa6a 100644 --- a/boost/proto/transform/when.hpp +++ b/boost/proto/transform/when.hpp @@ -22,8 +22,63 @@ #include <boost/proto/transform/make.hpp> #include <boost/proto/transform/impl.hpp> +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma warning(push) +# pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined +#endif + namespace boost { namespace proto { + namespace detail + { + template<typename Grammar, typename R, typename Fun> + struct when_impl + : transform<when<Grammar, Fun> > + { + typedef Grammar first; + typedef Fun second; + typedef typename Grammar::proto_grammar proto_grammar; + + // Note: do not evaluate is_callable<R> in this scope. + // R may be an incomplete type at this point. + + template<typename Expr, typename State, typename Data> + struct impl : transform_impl<Expr, State, Data> + { + // OK to evaluate is_callable<R> here. R should be compete by now. + typedef + typename mpl::if_c< + is_callable<R>::value + , proto::call<Fun> // "R" is a function to call + , proto::make<Fun> // "R" is an object to construct + >::type + which; + + typedef typename which::template impl<Expr, State, Data>::result_type result_type; + + /// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with + /// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on + /// whether <tt>is_callable\<R\>::value</tt> is \c true or + /// \c false. + /// + /// \param e The current expression + /// \param s The current state + /// \param d An arbitrary data + /// \pre <tt>matches\<Expr, Grammar\>::value</tt> is \c true + /// \return <tt>which()(e, s, d)</tt> + BOOST_FORCEINLINE + result_type operator ()( + typename impl::expr_param e + , typename impl::state_param s + , typename impl::data_param d + ) const + { + return typename which::template impl<Expr, State, Data>()(e, s, d); + } + }; + }; + } + /// \brief A grammar element and a PrimitiveTransform that associates /// a transform with the grammar. /// @@ -194,4 +249,8 @@ namespace boost { namespace proto }} // namespace boost::proto +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma warning(pop) +#endif + #endif |