Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file poly_function.hpp Chris@16: /// A wrapper that makes a tr1-style function object that handles const Chris@16: /// and non-const refs and reference_wrapper arguments, too, and forwards Chris@16: /// the arguments on to the specified implementation. Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02 Chris@16: #define BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: # pragma warning(push) Chris@16: # pragma warning(disable: 4181) // const applied to reference type Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace proto { namespace detail Chris@16: { Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct normalize_arg Chris@16: { Chris@16: typedef typename mpl::if_c::value, T &, T>::type type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg Chris@16: { Chris@16: typedef typename mpl::if_c::value, T const &, T>::type type; Chris@16: typedef T const &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg Chris@16: { Chris@16: typedef typename mpl::if_c::value, T &, T>::type type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg Chris@16: { Chris@16: typedef typename mpl::if_c::value, T const &, T>::type type; Chris@16: typedef T const &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg > Chris@16: { Chris@16: typedef T &type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg const> Chris@16: { Chris@16: typedef T &type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg &> Chris@16: { Chris@16: typedef T &type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalize_arg const &> Chris@16: { Chris@16: typedef T &type; Chris@16: typedef T &reference; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct arg Chris@16: { Chris@16: typedef T const &type; Chris@16: Chris@16: arg(type t) Chris@16: : value(t) Chris@16: {} Chris@16: Chris@16: operator type() const Chris@16: { Chris@16: return this->value; Chris@16: } Chris@16: Chris@16: type operator()() const Chris@16: { Chris@16: return this->value; Chris@16: } Chris@16: Chris@16: private: Chris@16: arg &operator =(arg const &); Chris@16: type value; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct arg Chris@16: { Chris@16: typedef T &type; Chris@16: Chris@16: arg(type t) Chris@16: : value(t) Chris@16: {} Chris@16: Chris@16: operator type() const Chris@16: { Chris@16: return this->value; Chris@16: } Chris@16: Chris@16: type operator()() const Chris@16: { Chris@16: return this->value; Chris@16: } Chris@16: Chris@16: private: Chris@16: arg &operator =(arg const &); Chris@16: type value; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_poly_function Chris@16: : mpl::false_ Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct is_poly_function Chris@16: : mpl::true_ Chris@16: {}; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: #define BOOST_PROTO_POLY_FUNCTION() \ Chris@16: typedef void is_poly_function_base_; \ Chris@16: /**/ Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: struct poly_function_base Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: BOOST_PROTO_POLY_FUNCTION() Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct poly_function Chris@16: : poly_function_base Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : Derived::template impl<> Chris@16: { Chris@16: typedef typename result::result_type type; Chris@16: }; Chris@16: Chris@16: NullaryResult operator()() const Chris@16: { Chris@16: result impl; Chris@16: return impl(); Chris@16: } Chris@16: Chris@16: #include Chris@16: }; Chris@16: Chris@16: template Chris@16: struct wrap_t; Chris@16: Chris@16: typedef char poly_function_t; Chris@16: typedef char (&mono_function_t)[2]; Chris@16: typedef char (&unknown_function_t)[3]; Chris@16: Chris@16: template poly_function_t test_poly_function(T *, wrap_t * = 0); Chris@16: template mono_function_t test_poly_function(T *, wrap_t * = 0); Chris@16: template unknown_function_t test_poly_function(T *, ...); Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template(0,0))> > Chris@16: struct poly_function_traits Chris@16: { Chris@16: typedef typename Fun::template result::type result_type; Chris@16: typedef Fun function_type; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct poly_function_traits > Chris@16: { Chris@16: typedef typename Fun::result_type result_type; Chris@16: typedef Fun function_type; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct as_mono_function_impl; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct as_mono_function; Chris@16: Chris@16: #include Chris@16: Chris@16: }}} // namespace boost::proto::detail Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: # pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif Chris@16: