| Home | Libraries | People | FAQ | More

#### 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

- Polymorphic Function Object
- Deferred Callable Object

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

- `unfused_generic`
- `unfused_lvalue_args`
- `unfused_rvalue_args`
- `deduce`
- `deduce_sequence`