mirror of
https://github.com/boostorg/fusion.git
synced 2025-07-24 09:37:14 +02:00
revises function object concepts and functional module documenation to reflect
boost::result_of-based result computation [SVN r38209]
This commit is contained in:
@ -19,7 +19,7 @@ __sequence__, introducing yet another function provides a solution:
|
||||
|
||||
invoke(f,my_sequence)
|
||||
|
||||
Alternatively it's possible to apply a simple transformation to [^f] in order
|
||||
Alternatively it is possible to apply a simple transformation to [^f] in order
|
||||
to achieve the same effect:
|
||||
|
||||
f tuple <=> ``f'`` (tuple)
|
||||
@ -66,44 +66,50 @@ returns an adapter instance for the given argument.
|
||||
|
||||
[section Concepts]
|
||||
|
||||
|
||||
[section:callable Callable Object]
|
||||
|
||||
[heading Description]
|
||||
|
||||
A pointer to a function, a pointer to member function, a pointer to member
|
||||
data, or a class type whose objects can appear immediately to the left of a
|
||||
function call operator.
|
||||
|
||||
[/ TODO: note about TR1, link to current draft]
|
||||
[heading Models]
|
||||
* function pointer types
|
||||
* member (function or data) pointer types
|
||||
* all kinds of function objects
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:poly Polymorphic Function Object]
|
||||
[section:reg_callable Regular Callable Object]
|
||||
|
||||
[heading Description]
|
||||
[heading Description]
|
||||
|
||||
A type of function object with a nested metafunction `result`. `result`
|
||||
returns the result type of calling the function object, given the argument
|
||||
types.
|
||||
A non-member-pointer __callable_obj__ type: A pointer to a function or a class
|
||||
type whose objects can appear immediately to the left of a function call operator.
|
||||
|
||||
[heading Refinement of]
|
||||
* __callable_obj__
|
||||
|
||||
[variablelist Notation
|
||||
[[`F`][A Polymorphic Function Object type]]
|
||||
[[`f`][A Polymorphic Function Object]]
|
||||
[[`T1 ...TN`][Arbitrary types]]
|
||||
[[`t1 ...tN`][Objects with types `T1 ...TN`]]
|
||||
[[`F`][A possibly const qualified Deferred Callable Object type]]
|
||||
[[`f`][An object or reference to an object of type F]]
|
||||
[[`A1 ...AN`][Argument types]]
|
||||
[[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
|
||||
]
|
||||
|
||||
[heading Expression requirements]
|
||||
|
||||
[table
|
||||
[[Expression][Return Type][Runtime Complexity]]
|
||||
[[`f(t1, ...tN)`][`F::result<T1, ...TN>::type`][Unspecified]]
|
||||
[[`f(a1, ...aN)`][Unspecified][Unspecified]]
|
||||
]
|
||||
|
||||
[heading Models]
|
||||
* all Fusion __functional_adapters__
|
||||
* function pointer types
|
||||
* all kinds of function objects
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -112,29 +118,71 @@ types.
|
||||
|
||||
[heading Description]
|
||||
|
||||
__callable_obj__ that works with __boost_result_of__ to determine the result
|
||||
of a call (such as the function objects provided by the standard library).
|
||||
__callable_obj__ types that work with __boost_result_of__ to determine the
|
||||
result of a call.
|
||||
|
||||
[heading Refinement of]
|
||||
* __callable_obj__
|
||||
|
||||
[blurb note Once C++ supports the [^decltype] keyword, all models of
|
||||
__callable_obj__ will also be models of __def_callable_obj__, because
|
||||
function objects won't need client-side support for `result_of`.
|
||||
]
|
||||
|
||||
[variablelist Notation
|
||||
[[`F`][A Deferred Callable Object type]]
|
||||
[[`T1 ...TN`][Arbitrary types]]
|
||||
[[`F`][A possibly const qualified Deferred Callable Object type]]
|
||||
[[`A1 ...AN`][Argument types]]
|
||||
[[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
|
||||
[[`T1 ...TN`][`T`i is `A`i `&` if `a`i is an __lvalue__, same as `A`i, otherwise]]
|
||||
]
|
||||
|
||||
[heading Expression requirements]
|
||||
|
||||
[table
|
||||
[[Expression][Type]]
|
||||
[[__boost_result_of_call__`< F(T1 ...TN) >::type`][Unspecified]]
|
||||
[[__boost_result_of_call__`< F(T1 ...TN) >::type`][Result of a call with `A1 ...AN`-typed arguments]]
|
||||
]
|
||||
|
||||
[heading Models]
|
||||
* __poly_func_obj__ types
|
||||
* member (function or data) pointer types
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:poly Polymorphic Function Object]
|
||||
|
||||
[heading Description]
|
||||
|
||||
A non-member-pointer __def_callable_obj__ type.
|
||||
|
||||
[heading Refinement of]
|
||||
* __reg_callable_obj__
|
||||
* __def_callable_obj__
|
||||
|
||||
[variablelist Notation
|
||||
[[`F`][A possibly const-qualified Polymorphic Function Object type]]
|
||||
[[`f`][An object or reference to an object of type F]]
|
||||
[[`A1 ...AN`][Argument types]]
|
||||
[[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
|
||||
[[`T1 ...TN`][`T`i is `A`i `&` if `a`i is an __lvalue__, same as `A`i, otherwise]]
|
||||
]
|
||||
|
||||
[heading Expression requirements]
|
||||
|
||||
[table
|
||||
[[Expression][Return Type][Runtime Complexity]]
|
||||
[[`f(a1, ...aN)`][`result_of< F(T1, ...TN) >::type`][Unspecified]]
|
||||
]
|
||||
|
||||
[heading Models]
|
||||
* function pointers
|
||||
* function objects of the Standard Library
|
||||
* all Fusion __functional_adapters__
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]
|
||||
@ -149,10 +197,6 @@ of a call (such as the function objects provided by the standard library).
|
||||
|
||||
Calls a __def_callable_obj__ with the arguments from a __sequence__.
|
||||
|
||||
The corresponding metafunction, __result_of_invoke__ does not define a
|
||||
`type` member for target functions of non-class type whose arity is not
|
||||
satisfied by the size of the sequence.
|
||||
|
||||
The first template parameter can be specialized explicitly to avoid copying
|
||||
and/or to control the const qualification of a function object.
|
||||
|
||||
@ -216,10 +260,6 @@ the result of the call expression.
|
||||
Calls a __callable_obj__ with the arguments from a __sequence__. The result
|
||||
of the call is ignored.
|
||||
|
||||
The corresponding metafunction, __result_of_invoke_procedure, does not define
|
||||
a `type` member for target functions of non-class type whose arity is not
|
||||
satisfied by the size of the sequence.
|
||||
|
||||
The first template parameter can be specialized explicitly to avoid copying
|
||||
and/or to control the const qualification of a function object.
|
||||
|
||||
@ -285,10 +325,6 @@ implemented).
|
||||
|
||||
Calls a __poly_func_obj__ with the arguments from a __sequence__.
|
||||
|
||||
The corresponding metafunction, __result_of_invoke_function_object__, does
|
||||
not define a `type` member, if the nested `result` class template of the
|
||||
target function object is empty.
|
||||
|
||||
The first template parameter can be specialized explicitly to avoid copying
|
||||
and/or to control the const qualification of a function object.
|
||||
|
||||
@ -316,7 +352,7 @@ and/or to control the const qualification of a function object.
|
||||
|
||||
[heading Expression Semantics]
|
||||
|
||||
invoke_procedure(f,s);
|
||||
invoke_function_object(f,s);
|
||||
|
||||
[*Return type]: Return type of `f` when invoked with the elements in `s` as its
|
||||
arguments.
|
||||
@ -330,11 +366,12 @@ result of the call expression.
|
||||
[heading Example]
|
||||
struct sub
|
||||
{
|
||||
template<typename T, typename _>
|
||||
struct result
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <class Self, typename T>
|
||||
struct result< Self(T,T) >
|
||||
{ typedef typename remove_reference<T>::type type; };
|
||||
|
||||
template<typename T>
|
||||
T operator()(T lhs, T rhs) const
|
||||
@ -366,9 +403,6 @@ result of the call expression.
|
||||
[heading Description]
|
||||
Returns the result type of __invoke__.
|
||||
|
||||
Empty for non-class target function types whose arity is not satisfied by
|
||||
the size of the sequence.
|
||||
|
||||
[heading Synopsis]
|
||||
namespace result_of
|
||||
{
|
||||
@ -393,9 +427,6 @@ the size of the sequence.
|
||||
[heading Description]
|
||||
Returns the result type of __invoke_procedure__.
|
||||
|
||||
Empty for non-class target function types whose arity is not satisfied by
|
||||
the size of the sequence.
|
||||
|
||||
[heading Synopsis]
|
||||
namespace result_of
|
||||
{
|
||||
@ -420,8 +451,6 @@ the size of the sequence.
|
||||
[heading Description]
|
||||
Returns the result type of __invoke_function_object__.
|
||||
|
||||
Empty if the target function's nested `result` class template is empty.
|
||||
|
||||
[heading Synopsis]
|
||||
namespace result_of
|
||||
{
|
||||
@ -459,17 +488,13 @@ An unary __poly_func_obj__ adapter template for __def_callable_obj__ target
|
||||
functions. It takes a __forward_sequence__ that contains the arguments for the
|
||||
target function.
|
||||
|
||||
The nested `result` metafunction does not define a `type` member for target
|
||||
functions of non-class type whose arity is not satisfied by the size of the
|
||||
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 for an
|
||||
(in other words, only const versions of [^operator()] can be used for a
|
||||
target function object that is const or, if the target function object
|
||||
is held by value, the adapter is const - these semantics have nothing to
|
||||
do with the const qualification of a member function, which is referring
|
||||
to the type of object pointed to by [^this] that is specified with the
|
||||
to the type of object pointed to by [^this] which is specified with the
|
||||
first element in the sequence passed to the adapter).
|
||||
|
||||
If the target function is a pointer to a class members, the corresponding
|
||||
@ -534,17 +559,15 @@ An unary __poly_func_obj__ adapter template for __callable_obj__ target
|
||||
functions. It takes a __forward_sequence__ that contains the arguments for
|
||||
the target function.
|
||||
|
||||
The result is discared and the adapter's return type is `void`. The nested
|
||||
`result` metafunction does not define a `type` member for target functions
|
||||
of non-class type whose arity is not satisfied by the size of the sequence.
|
||||
The result is discared and the adapter's return type is `void`.
|
||||
|
||||
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 for an
|
||||
(in other words, only const versions of [^operator()] can be used for a
|
||||
target function object that is const or, if the target function object
|
||||
is held by value, the adapter is const - these semantics have nothing to
|
||||
do with the const qualification of a member function, which is referring
|
||||
to the type of object pointed to by [^this] that is specified with the
|
||||
to the type of object pointed to by [^this] which is specified with the
|
||||
first element in the sequence passed to the adapter).
|
||||
|
||||
If the target function is a pointer to a members function, the corresponding
|
||||
@ -554,8 +577,8 @@ defined (Boost provides this function for [^std::auto_ptr] and
|
||||
__boost_shared_ptr_call__).
|
||||
|
||||
The target function must not be a pointer to a member object (dereferencing
|
||||
such a pointer without returning anything does not make sense, so it isn't
|
||||
implemented).
|
||||
such a pointer without returning anything does not make sense, so this case
|
||||
is not implemented).
|
||||
|
||||
[heading Header]
|
||||
#include <boost/fusion/functional/adapter/fused_procedure.hpp>
|
||||
@ -625,8 +648,6 @@ An unary __poly_func_obj__ adapter template for a __poly_func_obj__ target
|
||||
function. It takes a __forward_sequence__ that contains the arguments for the
|
||||
target function.
|
||||
|
||||
The nested `result` metafunction is inhertied from the target function.
|
||||
|
||||
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 for an
|
||||
@ -680,11 +701,12 @@ is held by value, the adapter is const).
|
||||
|
||||
struct sub
|
||||
{
|
||||
template<typename T, typename _>
|
||||
struct result
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <class Self, typename T>
|
||||
struct result< Self(T,T) >
|
||||
{ typedef typename remove_reference<T>::type type; };
|
||||
|
||||
template<typename T>
|
||||
T operator()(T lhs, T rhs) const
|
||||
@ -726,16 +748,6 @@ compile time expensive operation (see __the_forwarding_problem__ for
|
||||
details). Therefore, there are two, lightweight and more restricted variants
|
||||
of this class template, __unfused_lvalue_args__ and __unfused_rvalue_args__.]
|
||||
|
||||
The overload set of the adapter's function call operator can be restricted
|
||||
by removing the `type` member from the nested result metafunction of the
|
||||
__poly_func_obj__ (in this case the substitution-failure-is-not-an-error
|
||||
principle applies for non-nullary case and nullary calls are explicitly
|
||||
disabled by the library).
|
||||
|
||||
[caution As the nullary call operator cannot be a template it will be
|
||||
instantiated along with the class template, so it must be disabled (as
|
||||
described above) in cases where it isn't instantiable.]
|
||||
|
||||
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
|
||||
@ -782,24 +794,27 @@ object is held by value, the adapter is const).
|
||||
template <typename Function, typename T>
|
||||
class fused_bound_1st
|
||||
{
|
||||
typename traits::__deduce__<Function>::type fnc_deferred;
|
||||
typename traits::__deduce__<T>::type xxx_bound;
|
||||
typename traits::deduce<Function>::type fnc_deferred;
|
||||
typename traits::deduce<T>::type xxx_bound;
|
||||
public:
|
||||
|
||||
fused_bound_1st(Function deferred, T bound)
|
||||
: fnc_deferred(deferred), xxx_bound(bound)
|
||||
{ }
|
||||
|
||||
template <class Seq>
|
||||
struct result
|
||||
: __result_of_invoke__< Function,
|
||||
typename __result_of_push_front__<Seq, T>::type >
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <class Self, class Seq>
|
||||
struct result< Self(Seq) >
|
||||
: result_of::invoke< Function, typename result_of::push_front<
|
||||
typename remove_reference<Seq>::type, T>::type >
|
||||
{ };
|
||||
|
||||
template <class Seq>
|
||||
typename result<Seq>::type operator()(Seq const & s) const
|
||||
typename result< void(Seq) >::type operator()(Seq const & s) const
|
||||
{
|
||||
return __invoke__(fnc_deferred, push_front(s,xxx_bound));
|
||||
return invoke(fnc_deferred, push_front(s,xxx_bound));
|
||||
}
|
||||
};
|
||||
|
||||
@ -819,7 +834,7 @@ object is held by value, the adapter is const).
|
||||
void try_it()
|
||||
{
|
||||
assert(bind_1st(& test_func,3)(-2,-1) == 0);
|
||||
assert(bind_1st(__std_plus_doc__<float>(), 1)(0.5f) == 1.5f);
|
||||
assert(bind_1st(std::plus<float>(), 1)(0.5f) == 1.5f);
|
||||
}
|
||||
|
||||
[heading See also]
|
||||
@ -841,16 +856,6 @@ target function. When called, its arguments are bundled to a
|
||||
__random_access_sequence__ of references that is passed to the target function
|
||||
object. Only __lvalue__ arguments are accepted.
|
||||
|
||||
The overload set of the adapter's function call operator can be restricted
|
||||
by removing the `type` member from the nested result metafunction of the
|
||||
__poly_func_obj__ (in this case the substitution-failure-is-not-an-error
|
||||
principle applies for non-nullary calls and nullary calls are explicitly
|
||||
disabled by the library).
|
||||
|
||||
[caution As the nullary call operator cannot be a template it will be
|
||||
instantiated along with the class template, so it must be disabled (as
|
||||
described above) in cases where it isn't instantiable.]
|
||||
|
||||
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
|
||||
@ -933,16 +938,6 @@ target function. When called, its arguments are bundled to a
|
||||
__random_access_sequence__ of references that is passed to the target
|
||||
function object. All referenced objects in the sequence are const qualified.
|
||||
|
||||
The overload set of the adapter's function call operator can be restricted
|
||||
by removing the `type` member from the nested result metafunction of the
|
||||
__poly_func_obj__ (in this case the substitution-failure-is-not-an-error
|
||||
principle applies for non-nullary calls and nullary calls are explicitly
|
||||
disabled by the library).
|
||||
|
||||
[caution As the nullary call operator cannot be a template it will be
|
||||
instantiated along with the class template, so it must be disabled (as
|
||||
described above) in cases where it isn't instantiable.]
|
||||
|
||||
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
|
||||
@ -1029,16 +1024,6 @@ The call operators of the resulting function object are strictly typed
|
||||
By default, call operators with zero to N parameters are generated to,
|
||||
where N is the size of the __sequence__ that specifies the types.
|
||||
|
||||
The overload set of the adapter's function call operator can be restricted
|
||||
by removing the `type` member from the nested result metafunction of the
|
||||
__poly_func_obj__ (in this case the substitution-failure-is-not-an-error
|
||||
principle applies for non-nullary calls and nullary calls are explicitly
|
||||
disabled by the library).
|
||||
|
||||
[caution As the function call operators are not templates, they are
|
||||
instantiated along with the class template, so they must be disabled (as
|
||||
described above) in cases where they are not instantiable.]
|
||||
|
||||
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
|
||||
@ -1114,38 +1099,40 @@ signature is optimized automatically to avoid by-value parameters.]
|
||||
: tie_dest(dest)
|
||||
{ }
|
||||
|
||||
template <class Seq>
|
||||
struct result
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
typedef void result_type;
|
||||
|
||||
template <class Seq>
|
||||
void operator()(Seq const & s) const
|
||||
{
|
||||
__for_each__(__zip__(tie_dest,s), __fused__<add_assign>() );
|
||||
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 <class Seq>
|
||||
struct result
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <class Self, class Seq>
|
||||
struct result< Self(Seq) >
|
||||
{
|
||||
typedef unfused_typed<fused_parallel_adder<Seq>,
|
||||
typename mpl::transform<Seq, remove_reference<_> >::type > type;
|
||||
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<Seq>::type operator()(Seq const & tie)
|
||||
typename result< void(Seq) >::type operator()(Seq const & tie)
|
||||
{
|
||||
return typename result<Seq>::type(fused_parallel_adder<Seq>(tie));
|
||||
return typename result< void(Seq) >::type(
|
||||
fused_parallel_adder<Seq>(tie) );
|
||||
}
|
||||
};
|
||||
__unfused_lvalue_args__<fused_parallel_adder_maker> parallel_add;
|
||||
unfused_lvalue_args<fused_parallel_adder_maker> parallel_add;
|
||||
|
||||
int main()
|
||||
void try_it()
|
||||
{
|
||||
int a = 2; char b = 'X';
|
||||
// the second call is strictly typed with the types deduced from the
|
||||
@ -1154,8 +1141,6 @@ signature is optimized automatically to avoid by-value parameters.]
|
||||
parallel_add(a,b)(3);
|
||||
parallel_add(a,b)();
|
||||
assert(a == 8 && b == 'Z');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[heading See also]
|
||||
@ -1297,11 +1282,12 @@ The usual __element_conversion__ is applied to the target function.
|
||||
[heading Example]
|
||||
struct sub
|
||||
{
|
||||
template<typename T, typename _>
|
||||
struct result
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <class Self, typename T>
|
||||
struct result< Self(T,T) >
|
||||
{ typedef typename remove_reference<T>::type type; };
|
||||
|
||||
template<typename T>
|
||||
T operator()(T lhs, T rhs) const
|
||||
@ -1357,11 +1343,7 @@ The usual __element_conversion__ is applied to the target function.
|
||||
[heading Example]
|
||||
struct bottles_song
|
||||
{
|
||||
template<class Seq>
|
||||
struct result
|
||||
: mpl::if_< mpl::less< __result_of_size__<Seq>, mpl::int_<2> >,
|
||||
boost::blank, mpl::identity<void> >::type
|
||||
{ };
|
||||
typedef void result_type;
|
||||
|
||||
template<class Seq>
|
||||
void operator()(Seq & s) const
|
||||
|
Reference in New Issue
Block a user