$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: eric_at_[hidden]
Date: 2008-05-03 02:02:14
Author: eric_niebler
Date: 2008-05-03 02:02:13 EDT (Sat, 03 May 2008)
New Revision: 45058
URL: http://svn.boost.org/trac/boost/changeset/45058
Log:
polymorphic function object builder, intended for use with new make_expr and friends
Added:
   branches/proto/v4/boost/proto/detail/poly_function.hpp   (contents, props changed)
Added: branches/proto/v4/boost/proto/detail/poly_function.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/poly_function.hpp	2008-05-03 02:02:13 EDT (Sat, 03 May 2008)
@@ -0,0 +1,209 @@
+#ifndef BOOST_PP_IS_ITERATING
+    ///////////////////////////////////////////////////////////////////////////////
+    /// \file poly_function.hpp
+    /// A wrapper that makes a tr1-style function object that handles const
+    /// and non-const refs and reference_wrapper arguments, too, and forwards
+    /// the arguments on to the specified implementation.
+    //
+    //  Copyright 2008 Eric Niebler. 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_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
+    #define BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
+
+    #include <boost/ref.hpp>
+    #include <boost/mpl/bool.hpp>
+    #include <boost/mpl/void.hpp>
+    #include <boost/mpl/eval_if.hpp>
+    #include <boost/preprocessor/cat.hpp>
+    #include <boost/preprocessor/facilities/intercept.hpp>
+    #include <boost/preprocessor/iteration/iterate.hpp>
+    #include <boost/preprocessor/repetition/enum.hpp>
+    #include <boost/preprocessor/repetition/enum_params.hpp>
+    #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+    #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+    #include <boost/proto/proto_fwd.hpp>
+
+    namespace boost { namespace proto { namespace detail
+    {
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////
+        template<typename T>
+        struct normalize_arg
+        {
+            typedef T type;
+            typedef T const &reference;
+        };
+
+        template<typename T>
+        struct normalize_arg<T &>
+        {
+            typedef T type;
+            typedef T const &reference;
+        };
+
+        template<typename T>
+        struct normalize_arg<T const &>
+        {
+            typedef T type;
+            typedef T const &reference;
+        };
+
+        template<typename T>
+        struct normalize_arg<boost::reference_wrapper<T> >
+        {
+            typedef T &type;
+            typedef T &reference;
+        };
+
+        template<typename T>
+        struct normalize_arg<boost::reference_wrapper<T> &>
+        {
+            typedef T &type;
+            typedef T &reference;
+        };
+
+        template<typename T>
+        struct normalize_arg<boost::reference_wrapper<T> const &>
+        {
+            typedef T &type;
+            typedef T &reference;
+        };
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////
+        template<typename T>
+        struct arg
+        {
+            typedef T const &type;
+
+            arg(type t)
+              : value(t)
+            {}
+            
+            operator type() const
+            {
+                return this->value;
+            }
+
+            type operator()() const
+            {
+                return *this;
+            }
+
+        private:
+            arg &operator =(arg const &);
+            type value;
+        };
+
+        template<typename T>
+        struct arg<T &>
+        {
+            typedef T &type;
+
+            arg(type t)
+              : value(t)
+            {}
+
+            operator type() const
+            {
+                return this->value;
+            }
+
+            type operator()() const
+            {
+                return *this;
+            }
+
+        private:
+            arg &operator =(arg const &);
+            type value;
+        };
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////
+        template<typename T, typename Void = void>
+        struct is_poly_function
+          : mpl::false_
+        {};
+
+        template<typename T>
+        struct is_poly_function<T, typename T::is_poly_function_base_>
+          : mpl::true_
+        {};
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////
+        struct poly_function_base
+        {
+            typedef void is_poly_function_base_;
+        };
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////
+        template<typename Derived, typename NullaryResult = void>
+        struct poly_function
+          : poly_function_base
+        {
+            template<typename Sig>
+            struct result;
+
+            template<typename This>
+            struct result<This()>
+              : Derived::template impl<>
+            {
+                typedef typename result::result_type type;
+            };
+
+            NullaryResult operator()() const
+            {
+                result<Derived const()> impl;
+                return impl();
+            }
+
+            #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/poly_function.hpp>))
+            #include BOOST_PP_ITERATE()
+        };
+
+    }}} // namespace boost::proto::detail
+
+    #endif
+
+#else
+
+    #define N BOOST_PP_ITERATION()
+
+            template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+            struct result<This(BOOST_PP_ENUM_PARAMS(N, A))>
+              : Derived::template impl<
+                    BOOST_PP_ENUM_BINARY_PARAMS(
+                        N
+                      , typename normalize_arg<A
+                      , >::type BOOST_PP_INTERCEPT
+                    )
+                >
+            {
+                typedef typename result::result_type type;
+            };
+
+            template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+            typename result<
+                Derived const(
+                    BOOST_PP_ENUM_BINARY_PARAMS(N, A, const & BOOST_PP_INTERCEPT)
+                )
+            >::type
+            operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a)) const
+            {
+                result<
+                    Derived const(
+                        BOOST_PP_ENUM_BINARY_PARAMS(N, A, const & BOOST_PP_INTERCEPT)
+                    )
+                > impl;
+
+                #define M0(Z, N, DATA)                                                              \
+                    static_cast<typename normalize_arg<BOOST_PP_CAT(A, N) const &>                  \
+                        ::reference>(BOOST_PP_CAT(a, N))
+                return impl(BOOST_PP_ENUM(N, M0, ~));
+                #undef M0
+            }
+
+    #undef N
+
+#endif