summaryrefslogtreecommitdiff
path: root/boost/proto/transform/when.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/proto/transform/when.hpp')
-rw-r--r--boost/proto/transform/when.hpp59
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