Files
boost_fusion/include/boost/fusion/sequence/utility/unpack_args.hpp

172 lines
5.4 KiB
C++
Raw Normal View History

//
// Copyright (c) 2005, 2006 João Abecasis
//
// 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)
//
#if !BOOST_PP_IS_ITERATING
# if !defined(BOOST_FUSION_SEQUENCE_UTILITY_UNPACK_ARGS_HPP_INCLUDED)
# define BOOST_FUSION_SEQUENCE_UTILITY_UNPACK_ARGS_HPP_INCLUDED
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/utility/result_of.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/add_pointer.hpp>
# include <boost/type_traits/is_function.hpp>
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/fusion/sequence/intrinsic/begin.hpp>
# include <boost/fusion/sequence/intrinsic/size.hpp>
# include <boost/fusion/iterator/next.hpp>
# include <boost/fusion/iterator/deref.hpp>
# include <boost/fusion/sequence/utility/limits.hpp>
namespace boost { namespace fusion
{
namespace detail
{
2006-09-22 00:41:24 +00:00
template <class F>
struct unpack_args_impl_helper
{
typedef typename remove_cv<F>::type f_nocv;
typedef
typename mpl::eval_if<
is_pointer<f_nocv>,
mpl::identity<f_nocv>,
mpl::eval_if<
is_function<f_nocv>,
add_pointer<f_nocv>,
mpl::identity<F>
>
>::type
type;
};
template <
class F,
class Sequence,
2006-09-22 00:41:24 +00:00
class F_ = typename unpack_args_impl_helper<F>::type,
class Size = mpl::int_<result_of::size<Sequence>::value>
>
struct unpack_args_impl;
template <class F, class Sequence, class F_>
struct unpack_args_impl<F, Sequence, F_, mpl::int_<0> >
{
typedef typename boost::result_of<F_()>::type type;
static type call(F & f, Sequence &)
{
return f();
}
};
# define BOOST_FUSION_next_iterator(z, n, data) \
typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
BOOST_PP_CAT(I, BOOST_PP_INC(n));
# define BOOST_FUSION_deref_iterator(z, n, data) \
typedef typename fusion::result_of::deref<BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
>::type BOOST_PP_CAT(T, BOOST_PP_INC(n));
# define BOOST_FUSION_next_call_iterator(z, n, data) \
BOOST_PP_CAT(I, BOOST_PP_INC(n)) BOOST_PP_CAT(i, BOOST_PP_INC(n)) \
= fusion::next(BOOST_PP_CAT(i, n));
# define BOOST_FUSION_n BOOST_PP_ITERATION()
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, FUSION_MAX_UNPACK_ARG_SIZE, \
<boost/fusion/sequence/utility/unpack_args.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_FUSION_next_iterator
# undef BOOST_FUSION_deref_iterator
# undef BOOST_FUSION_next_call_iterator
# undef BOOST_FUSION_n
# undef BOOST_PP_ITERATION_PARAMS_1
} // namespace detail
namespace result_of
{
template <class F, class Sequence>
struct unpack_args
: detail::unpack_args_impl<F, Sequence>
{
};
} // namespace result_of
template <class F, class Sequence>
inline typename result_of::unpack_args<F, Sequence>::type
unpack_args(F & f, Sequence & seq)
{
return result_of::unpack_args<F, Sequence>::call(f, seq);
}
template <class F, class Sequence>
inline typename result_of::unpack_args<F const, Sequence>::type
unpack_args(F const & f, Sequence & seq)
{
return result_of::unpack_args<F const, Sequence>::call(f, seq);
}
template <class F, class Sequence>
inline typename result_of::unpack_args<F, Sequence const>::type
unpack_args(F & f, Sequence const & seq)
{
return result_of::unpack_args<F, Sequence const>::call(f, seq);
}
template <class F, class Sequence>
inline typename result_of::unpack_args<F const, Sequence const>::type
unpack_args(F const & f, Sequence const & seq)
{
return result_of::unpack_args<F const, Sequence const>::call(f, seq);
}
}} // namespace boost::fusion
# endif // include guard
#else // BOOST_PP_IS_ITERATING
template <class F, class Sequence, class F_>
struct unpack_args_impl<F, Sequence, F_, mpl::int_<BOOST_FUSION_n> >
{
typedef typename fusion::result_of::begin<Sequence>::type I0;
typedef typename fusion::result_of::deref<I0>::type T0;
BOOST_PP_REPEAT(BOOST_FUSION_n, BOOST_FUSION_next_iterator, ~)
BOOST_PP_REPEAT(BOOST_FUSION_n, BOOST_FUSION_deref_iterator, ~)
typedef typename boost::result_of<
F_( BOOST_PP_ENUM_PARAMS(BOOST_FUSION_n, T) )
>::type type;
static type call(F & f, Sequence & seq)
{
I0 i0 = fusion::begin(seq);
BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_FUSION_n), BOOST_FUSION_next_call_iterator, ~)
return f( BOOST_PP_ENUM_PARAMS(BOOST_FUSION_n, *i) );
}
};
#endif // BOOST_PP_IS_ITERATING