$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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();
}