poly_function.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 261 行
HPP
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 { 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?