Boost logo

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