|
Boost : |
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-06-15 18:02:47
Eric Niebler wrote:
> Tobias Schwinger wrote:
>> Eric Niebler wrote:
>>>>> Is the sort of thing you are looking for?
>>>>>
>>>>> fused_ctor<T> fc;
>>>>> T t = fc(sequence);
>>> Yes, that's the thing.
>> OK, but why duplicate the unpacking of the Sequence?
>>
>> All it takes is yet another adapter encapsulating a type's ctor(s) in a
>> function object to just use fusion::(invoke|fused)_function_object. E.g:
>>
> <snip>
>> Client code (at function scope):
>>
>> invoke_function_object( ctor<my_class>(), argseq );
>
>
> Yes, that's exactly it. Now, put it in Fusion so I don't have to write a
> function object with N overloads. :-)
OK, and here's some preliminary code.
Headers go to fusion/functional/adapter, the .cpp file is a test.
Thanks to Peter for making me realize things can be easy, occasionally :-).
Regards,
Tobias
/*=============================================================================
Copyright (c) 2006-2007 Tobias Schwinger
Use modification and distribution are subject to 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 !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED)
# define BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED
# include <boost/fusion/sequence/container/vector/limits.hpp>
# if !defined(BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY)
# define BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY 6
# elif BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY > FUSION_MAX_VECTOR_SIZE
# error "BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY > FUSION_MAX_VECTOR_SIZE"
# endif
# if !defined(BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY)
# define BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY 6
# elif BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE
# error "BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE"
# endif
# if !defined(BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY)
# define BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY 6
# elif BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE
# error "BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE"
# endif
# if !defined(BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY)
# define BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY 6
# elif BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY > FUSION_MAX_VECTOR_SIZE
# error "BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY > FUSION_MAX_VECTOR_SIZE"
# endif
# if !defined(BOOST_FUSION_CONSTRUCTOR_MAX_ARITY)
# define BOOST_FUSION_CONSTRUCTOR_MAX_ARITY 6
# endif
#endif
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
Use modification and distribution are subject to 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 !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_CONSTRUCTOR_HPP_INCLUDED)
#if !defined(BOOST_PP_IS_ITERATING)
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/fusion/functional/adapter/limits.hpp>
namespace boost { namespace fusion
{
template<typename T>
class constructor
{
public:
typedef T result_type;
inline T operator()() const
{
return T();
}
#define BOOST_PP_FILENAME_1 \
<boost/fusion/functional/adapter/constructor.hpp>
#define BOOST_PP_ITERATION_LIMITS \
(1, BOOST_FUSION_CONSTRUCTOR_MAX_ARITY)
#include BOOST_PP_ITERATE()
};
}}
#define BOOST_FUSION_FUNCTIONAL_ADAPTER_CONSTRUCTOR_HPP_INCLUDED
#else // defined(BOOST_PP_IS_ITERATING)
////////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
////////////////////////////////////////////////////////////////////////////////
#define N BOOST_PP_ITERATION()
template< BOOST_PP_ENUM_PARAMS(N, typename T) >
inline T operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
{
return T(BOOST_PP_ENUM_PARAMS(N, a));
}
#undef N
#endif // defined(BOOST_PP_IS_ITERATING)
#endif
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
Use modification and distribution are subject to 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).
==============================================================================*/
#include <boost/fusion/functional/adapter/constructor.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/bind.hpp>
namespace fusion = boost::fusion;
class X
{
int val_sum;
public:
X() : val_sum(0) { }
X(int a) : val_sum(a) { }
X(int a, int b) : val_sum(a + b) { }
operator int() const { return this->val_sum; }
};
class Y
{
int const & ref_a;
Y(); // undefined
public:
Y(int & a) : ref_a(a) { }
operator int() const { return this->ref_a; }
};
int main()
{
int one = 1, two = 2;
fusion::constructor<X> create_x;
BOOST_TEST(create_x() == 0);
BOOST_TEST(create_x(one) == 1);
BOOST_TEST(create_x(one,two) == 3);
fusion::constructor<Y> create_y;
BOOST_TEST(create_y(one) == 1);
BOOST_TEST(boost::bind(create_x,one,_1)(two) == 3);
BOOST_TEST(boost::bind(create_x,1,_1)(two) == 3);
return boost::report_errors();
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk