From cb269307bd46d9bfb8d378036fa3cc4dfa8d04a1 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Mon, 1 Apr 2002 07:13:32 +0000 Subject: [PATCH] mpl_v2 checkin [SVN r13330] --- include/boost/mpl/apply.hpp | 312 ++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 include/boost/mpl/apply.hpp diff --git a/include/boost/mpl/apply.hpp b/include/boost/mpl/apply.hpp new file mode 100644 index 0000000..5f39c64 --- /dev/null +++ b/include/boost/mpl/apply.hpp @@ -0,0 +1,312 @@ +//----------------------------------------------------------------------------- +// boost mpl/apply.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2000-02 +// Aleksey Gurtovoy +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appears in all copies and +// that both the copyright notice and this permission notice appear in +// supporting documentation. No representations are made about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. + +#ifndef BOOST_MPL_APPLY_HPP_INCLUDED +#define BOOST_MPL_APPLY_HPP_INCLUDED + +#include "boost/mpl/aux_/config/use_preprocessed.hpp" + +#if defined(BOOST_MPL_USE_PREPROCESSED_HEADERS) +# include "boost/mpl/aux_/preprocessed/apply.hpp" +#else + +#include "boost/mpl/placeholder.hpp" +#include "boost/mpl/limits/arity.hpp" +#include "boost/mpl/aux_/lambda_spec.hpp" +#include "boost/mpl/aux_/count_if_not.hpp" +#include "boost/mpl/aux_/arity.hpp" +#include "boost/mpl/aux_/none.hpp" +#include "boost/mpl/aux_/msvc_workarounds.hpp" +#include "boost/mpl/aux_/preprocessor/params.hpp" +#include "boost/mpl/aux_/preprocessor/default_params.hpp" +#include "boost/mpl/aux_/preprocessor/enum.hpp" +#include "boost/mpl/aux_/preprocessor/project1st.hpp" +#include "boost/mpl/aux_/config/dtp.hpp" + +#include "boost/preprocessor/arithmetic/add.hpp" +#include "boost/preprocessor/arithmetic/sub.hpp" +#include "boost/preprocessor/repeat_2nd.hpp" +#include "boost/preprocessor/repeat_3rd.hpp" +#include "boost/preprocessor/comma_if.hpp" +#include "boost/preprocessor/if.hpp" +#include "boost/preprocessor/inc.hpp" +#include "boost/config.hpp" + +namespace boost { +namespace mpl { + +// local macros, #undef-ined at the end of the header +#define AUX_APPLY_PARAMS(param) \ + BOOST_MPL_PP_PARAMS( \ + 1 \ + , BOOST_PP_INC(BOOST_MPL_METAFUNCTION_MAX_ARITY) \ + , param \ + ) \ +/**/ + +#define AUX_APPLY_DEFAULT_PARAMS(param, value) \ + BOOST_MPL_PP_DEFAULT_PARAMS( \ + 1 \ + , BOOST_PP_INC(BOOST_MPL_METAFUNCTION_MAX_ARITY) \ + , param \ + , value \ + ) \ +/**/ + +#define AUX_APPLY_N_PARAMS(i, param) \ + BOOST_MPL_PP_PARAMS(1, BOOST_PP_INC(i), param) \ +/**/ + +#define AUX_APPLY_N_PLACEHOLDERS(i) \ + BOOST_MPL_PP_ENUM(0, BOOST_PP_INC(i), BOOST_MPL_PP_PROJECT2ND, _) \ +/**/ + +#define AUX_APPLY_0_TEMPLATE_DEF(unused) \ +template< typename F > \ +struct apply0 : F \ +{ \ +}; \ +\ +template<> \ +struct apply0<_> \ +{ \ + template< typename F > struct apply \ + : F \ + { \ + }; \ +}; \ +/**/ + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +// 'apply0' workaround +template< typename F > struct apply0; +template<> struct apply0 { typedef apply0 type; }; + +#define AUX_APPLY_N_TEMPLATE_DEF(i) \ +namespace aux { \ +BOOST_MPL_AUX_MSVC_DEPENDENT_TEMPLATE_WRAPPER_DEF(msvc_apply##i, apply, i) \ +} \ +template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ +struct apply##i \ + : aux::msvc_apply##i::template result_ \ +{ \ +}; \ +\ +template<> \ +struct apply##i< AUX_APPLY_N_PLACEHOLDERS(i) > \ +{ \ + template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ + struct apply \ + : aux::msvc_apply##i::template result_ \ + { \ + }; \ +}; \ +/**/ + +#elif defined(BOOST_NO_DEFAULT_TEMPLATE_PARAMETERS_IN_NESTED_TEMPLATES) +// agurt, 10/mar/02: MWCW 8.0 "losts" default template parameters of nested +// class templates when their owner classes are passed as arguments to +// other templates; in particular, that means that 'apply#' won't work on +// the result of 'bind#<..>' expression if no special care is taken; +// whatever is below, it is supposed to workaround the problem + +#define AUX_APPLY_IMPL_N_TEMPLATE_SPEC(j,i) \ +namespace aux { \ +template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ +struct mwcw_apply##i< \ + BOOST_PP_ADD(i, j) \ + , F \ + , AUX_APPLY_N_PARAMS(i, T) \ + > \ +{ \ + typedef typename F::template apply< \ + AUX_APPLY_N_PARAMS(i, T) \ + BOOST_PP_COMMA_IF(j) \ + BOOST_MPL_PP_ENUM(0, j, BOOST_MPL_PP_PROJECT2ND, aux::none) \ + > type; \ +}; \ +} \ +/**/ + +#define AUX_APPLY_N_TEMPLATE_DEF(i) \ +namespace aux { \ +template< \ + long \ + , typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ +struct mwcw_apply##i; \ +} \ +\ +BOOST_PP_REPEAT_3RD( \ + BOOST_PP_INC(BOOST_PP_SUB(BOOST_MPL_METAFUNCTION_MAX_ARITY, i)) \ + , AUX_APPLY_IMPL_N_TEMPLATE_SPEC \ + , i \ + ) \ +\ +template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ +struct apply##i \ + : aux::mwcw_apply##i< \ + aux::arity::value \ + , F \ + , AUX_APPLY_N_PARAMS(i, T) \ + >::type \ +{ \ +}; \ +\ +template<> \ +struct apply##i< AUX_APPLY_N_PLACEHOLDERS(i) > \ +{ \ + template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ + struct apply \ + : aux::mwcw_apply##i< \ + aux::arity::value \ + , F \ + , AUX_APPLY_N_PARAMS(i, T) \ + >::type \ + { \ + }; \ +}; \ +/**/ + +#else // #elif defined(BOOST_NO_DEFAULT_TEMPLATE_PARAMETERS_IN_NESTED_TEMPLATES) + +#define AUX_APPLY_N_TEMPLATE_DEF(i) \ +template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ +struct apply##i \ + : F::template apply< \ + AUX_APPLY_N_PARAMS(i, T) \ + > \ +{ \ +}; \ +\ +template<> \ +struct apply##i< AUX_APPLY_N_PLACEHOLDERS(i) > \ +{ \ + template< \ + typename F \ + , AUX_APPLY_N_PARAMS(i, typename T) \ + > \ + struct apply \ + : F::template apply< \ + AUX_APPLY_N_PARAMS(i, T) \ + > \ + { \ + }; \ +}; \ +/**/ + +#endif // #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +namespace aux { +// to be able to define specializations +template struct apply_impl_chooser; +} + +#define AUX_APPLY_IMPL_CHOOSER_SPEC(i) \ +namespace aux { \ +template<> \ +struct apply_impl_chooser \ +{ \ + template< typename F, AUX_APPLY_PARAMS(typename T) > \ + struct result_ \ + { \ + typedef apply##i< \ + F \ + BOOST_PP_COMMA_IF(i) AUX_APPLY_N_PARAMS(i, T) \ + > type; \ + }; \ +}; \ +} \ +/**/ + +#define AUX_APPLY_TEMPLATE_DEF(i, unused) \ + BOOST_PP_IF( \ + i \ + , AUX_APPLY_N_TEMPLATE_DEF \ + , AUX_APPLY_0_TEMPLATE_DEF \ + )(i) \ + \ + BOOST_MPL_AUX_LAMBDA_TEMPLATE_SPEC( \ + BOOST_PP_INC(i) \ + , apply##i \ + ) \ + \ + AUX_APPLY_IMPL_CHOOSER_SPEC(i) \ +/**/ + + +// apply# +BOOST_PP_REPEAT_2ND( + BOOST_PP_INC(BOOST_MPL_METAFUNCTION_MAX_ARITY) + , AUX_APPLY_TEMPLATE_DEF + , unused + ) + +BOOST_MPL_AUX_COUNT_IF_NOT(apply, BOOST_MPL_METAFUNCTION_MAX_ARITY) + +#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) +// agurt, 15/jan/02: top-level 'apply' template gives an ICE on MSVC +// (for known reasons); numbered form works, though +template< + typename F + , AUX_APPLY_DEFAULT_PARAMS(typename T, aux::none) + > +struct apply + : aux::apply_impl_chooser< + aux::apply_count_if_not::value + >::template result_< F, AUX_APPLY_PARAMS(T) >::type +{ +}; + +#define BOOST_MPL_HAS_APPLY + +#endif // !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) + +#undef AUX_APPLY_TEMPLATE_DEF +#undef AUX_APPLY_N_TEMPLATE_DEF +#undef AUX_APPLY_0_TEMPLATE_DEF +#undef AUX_APPLY_IMPL_N_TEMPLATE_SPEC +#undef AUX_APPLY_N_PLACEHOLDERS +#undef AUX_APPLY_N_PARAMS +#undef AUX_APPLY_DEFAULT_PARAMS +#undef AUX_APPLY_PARAMS + +} // namespace mpl +} // namespace boost + +#endif // #if defined(BOOST_MPL_USE_PREPROCESSED_HEADERS) + +#endif // BOOST_MPL_APPLY_HPP_INCLUDED