235 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			235 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								/// \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/size_t.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>
							 | 
						||
| 
								 | 
							
								#include <boost/proto/detail/is_noncopyable.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _MSC_VER
							 | 
						||
| 
								 | 
							
								# pragma warning(push)
							 | 
						||
| 
								 | 
							
								# pragma warning(disable: 4181) // const applied to reference type
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace proto { namespace detail
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    template<typename T>
							 | 
						||
| 
								 | 
							
								    struct normalize_arg
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
							 | 
						||
| 
								 | 
							
								        typedef T &reference;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T>
							 | 
						||
| 
								 | 
							
								    struct normalize_arg<T const>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type type;
							 | 
						||
| 
								 | 
							
								        typedef T const &reference;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T>
							 | 
						||
| 
								 | 
							
								    struct normalize_arg<T &>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
							 | 
						||
| 
								 | 
							
								        typedef T &reference;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T>
							 | 
						||
| 
								 | 
							
								    struct normalize_arg<T const &>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type 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> const>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        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->value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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->value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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_
							 | 
						||
| 
								 | 
							
								    {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    #define BOOST_PROTO_POLY_FUNCTION()                                                             \
							 | 
						||
| 
								 | 
							
								        typedef void is_poly_function_base_;                                                        \
							 | 
						||
| 
								 | 
							
								        /**/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    struct poly_function_base
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /// INTERNAL ONLY
							 | 
						||
| 
								 | 
							
								        BOOST_PROTO_POLY_FUNCTION()
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    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();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        #include <boost/proto/detail/poly_function_funop.hpp>
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T>
							 | 
						||
| 
								 | 
							
								    struct wrap_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    typedef char poly_function_t;
							 | 
						||
| 
								 | 
							
								    typedef char (&mono_function_t)[2];
							 | 
						||
| 
								 | 
							
								    typedef char (&unknown_function_t)[3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T> poly_function_t test_poly_function(T *, wrap_t<typename T::is_poly_function_base_> * = 0);
							 | 
						||
| 
								 | 
							
								    template<typename T> mono_function_t test_poly_function(T *, wrap_t<typename T::result_type> * = 0);
							 | 
						||
| 
								 | 
							
								    template<typename T> unknown_function_t test_poly_function(T *, ...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    template<typename Fun, typename Sig, typename Switch = mpl::size_t<sizeof(test_poly_function<Fun>(0,0))> >
							 | 
						||
| 
								 | 
							
								    struct poly_function_traits
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename Fun::template result<Sig>::type result_type;
							 | 
						||
| 
								 | 
							
								        typedef Fun function_type;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    template<typename Fun, typename Sig>
							 | 
						||
| 
								 | 
							
								    struct poly_function_traits<Fun, Sig, mpl::size_t<sizeof(mono_function_t)> >
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename Fun::result_type result_type;
							 | 
						||
| 
								 | 
							
								        typedef Fun function_type;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    template<typename PolyFunSig, bool IsPolyFunction>
							 | 
						||
| 
								 | 
							
								    struct as_mono_function_impl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								    template<typename PolyFunSig>
							 | 
						||
| 
								 | 
							
								    struct as_mono_function;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    #include <boost/proto/detail/poly_function_traits.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}}} // namespace boost::proto::detail
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _MSC_VER
							 | 
						||
| 
								 | 
							
								# pragma warning(pop)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 |