You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
219 lines
6.1 KiB
219 lines
6.1 KiB
/////////////////////////////////////////////////////////////////////////////// |
|
/// \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> |
|
|
|
#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 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_ |
|
{}; |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////// |
|
#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 |
|
|
|
|