Imported existing code
This commit is contained in:
261
libraries/include/boost/proto/detail/poly_function.hpp
Normal file
261
libraries/include/boost/proto/detail/poly_function.hpp
Normal file
@@ -0,0 +1,261 @@
|
||||
#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>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/poly_function.hpp>, 0))
|
||||
#include BOOST_PP_ITERATE()
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFunSig, bool IsPoly>
|
||||
struct as_mono_function_impl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFunSig>
|
||||
struct as_mono_function;
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/poly_function.hpp>, 1))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
}}} // namespace boost::proto::detail
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#elif 0 == BOOST_PP_ITERATION_FLAGS()
|
||||
|
||||
#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
|
||||
|
||||
#elif 1 == BOOST_PP_ITERATION_FLAGS()
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), true>
|
||||
{
|
||||
typedef typename PolyFun::template impl<BOOST_PP_ENUM_PARAMS(N, const A)> type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), false>
|
||||
{
|
||||
typedef PolyFun type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PolyFun, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
struct as_mono_function<PolyFun(BOOST_PP_ENUM_PARAMS(N, A))>
|
||||
: as_mono_function_impl<PolyFun(BOOST_PP_ENUM_PARAMS(N, A)), is_poly_function<PolyFun>::value>
|
||||
{};
|
||||
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user