|
Boost-Commit : |
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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk