Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Click here to view the latest version of this page.
PrevUpHomeNext

unfused_typed

Description

An n-ary Polymorphic Function Object adapter template for an unary Polymorphic Function Object target function. When called, its arguments are bundled to a Random Access Sequence that is passed to the target function object.

The call operators of esulting function objects are strictly typed (in other words, non-templatized) with the types from a Sequence.

The type of the target function is allowed to be const qualified or a reference. Const qualification is preserved and propagated appropriately (in other words, only const versions of operator() can be used if the target function object is const - or, in case the target function object is held by value, the adapter is const).

/functional/adapter/unfused_typed.hpp>

Synopsis
template <class Function, class Sequence>
class unfused_typed;
Template parameters

Parameter

Description

Default

Function

A unary Polymorphic Function Object

Sequence

A Sequence

Model of

Notation

F

A possibly const qualified, unary Polymorphic Function Object type or reference type thereof

f

An object convertible to F

S

A Sequence of parameter types

UT

The type unfused_typed<F,S>

ut

An instance of UT, initialized with f

a0...aN

Arguments to ut, convertible to the types in S

Expression Semantics

Expression

Semantics

UT(f)

Creates a fused function as described above, initializes the target function with f.

UT()

Creates a fused function as described above, attempts to use F's default constructor.

ut(a0...aN)

Calls f with an instance of S (or a subsequence of S starting at the first element, if fewer arguments are given and the overload hasn't been disabled) initialized with a0...aN.

Example
struct add_assign // applies operator+=
{
    typedef void result_type; // for simplicity

    template <typename T>
    void operator()(T & lhs, T const & rhs) const
    {
        lhs += rhs;
    }
};

template <class Tie>
class fused_parallel_adder
{
    Tie tie_dest;
public:
    explicit fused_parallel_adder(Tie const & dest)
        : tie_dest(dest)
    { }

    typedef void result_type;

    template <class Seq>
    void operator()(Seq const & s) const
    {
        for_each( zip(tie_dest,s), fused<add_assign>() );
    }
};

// accepts a tie and creates a typed function object from it
struct fused_parallel_adder_maker
{
    template <typename Sig>
    struct result;

    template <class Self, class Seq>
    struct result< Self(Seq) >
    {
        typedef typename remove_reference<Seq>::type seq;

        typedef unfused_typed< fused_parallel_adder<seq>,
            typename mpl::transform<seq, remove_reference<_> >::type > type;
    };

    template <class Seq>
    typename result< void(Seq) >::type operator()(Seq const & tie)
    {
        return typename result< void(Seq) >::type(
            fused_parallel_adder<Seq>(tie) );
    }
};
unfused_lvalue_args<fused_parallel_adder_maker> parallel_add;

void try_it()
{
    int a = 2; char b = 'X';
    // the second call is strictly typed with the types deduced from the
    // first call
    parallel_add(a,b)(3,2);
    parallel_add(a,b)(3);
    parallel_add(a,b)();
    assert(a == 8 && b == 'Z');
}
See also

PrevUpHomeNext