A Function Adaptor is a higher-order function that takes a "base" Function Object and returns an "adapted" Function Object. A Function Adaptor provides, if possible, two interfaces: A normal higher-order Function Object, and an MPL Metafunction with a corresponding macro for static initialization. An adapted non-local Function Object with static storage duration is statically initialized if the "base" Function Object type is POD and the expression passed to the macro is a constant expression. Also, Function Adaptors don't modify Default Constructible and Copy Assignable-ness of base Function Object unless otherwise specified.
Important | |
---|---|
If a macro argument is not guaranteed to contain no commas and recursions,
you must use |
The ambi
family helps you
to make Ambi Function
Object.
<boost/egg/ambi.hpp>
Valid expression |
Semantics |
---|---|
An Ambi Major Function Object type |
|
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
N <=
__MAX_PACK_ARITY
-1
.
__PFo
d =
init;
is a valid expression.
__Bytag
is by_value
, __typeof
(aI)
is Copy Constructible.
struct base_my_plus { typedef int result_type; int operator()(int x, int y) const { return x + y; } }; result_of_ambi1<base_my_plus>::type const my_plus = BOOST_EGG_AMBI({}); void egg_example() { BOOST_CHECK( my_plus(1, 2) == 3 ); BOOST_CHECK( ( 1|my_plus(2) ) == 3 ); std::plus<int> std_plus; BOOST_CHECK( ambi1(std_plus)(1, 2) == 3 ); BOOST_CHECK( ( 1|ambi1(std_plus)(2) ) == 3 ); }
compose
is a Function Adaptor
for function composition.
<boost/egg/compose.hpp>
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
0 <=
N &&
N <=
__MAX_PACK_ARITY
.
__PFo
1 d1 = init1;
is a valid expression.
__PFo
2 d2 = init2;
is a valid expression.
__decltype_r0
(R0, d1(d2()))
is a valid expression which specifies
the nullary return type.
Important | |
---|---|
The last precondition means that |
int increment(int i) { return i + 1; } int decrement(int i) { return i - 1; } void egg_example() { using namespace infix; int r = (&increment ^compose^ &decrement ^compose^ &increment)(3); BOOST_CHECK( r == 4 ); }
The curry
family turn Function Objects
into curried ones.
<boost/egg/curry.hpp>
fc(d)
is
an object of result_of_curry%%N<__typeof
(d)>::type
initialized by d
.
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
|
|
N
is the arity of __PFo
such that 2 <=
N &&
N <=
BOOST_EGG_MAX_ARITY
.
__PFo
d =
init;
is a valid expression.
I
such that 1 <= I &&
I <=
N-1
, __typeof
(aI)
is
Copy Constructible.
Note | |
---|---|
Arguments except for the last one are captured by-copy. When you need to
capture by-reference, pass arguments using |
struct base_my_minus { typedef int result_type; int operator()(int x, int y) const { return x - y; } }; result_of_curry2<base_my_minus>::type const curried_minus = BOOST_EGG_CURRY2({}); void egg_example() { BOOST_CHECK( curried_minus(4)(9) == -5 ); BOOST_CHECK( curry2(base_my_minus())(4)(9) == -5 ); }
uncurry
reverses curry
.
<boost/egg/uncurry.hpp>
Valid expression |
Semantics |
---|---|
A Major Function Object type |
|
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
2 <=
N &&
N <=
BOOST_EGG_MAX_ARITY
.
__PFo
d =
init;
is a valid expression.
void egg_example() { std::plus<int> std_plus; BOOST_CHECK( uncurry(curry2(std_plus))(4, 9) == 13 ); }
fix
is Fixed
point combinator, which enables you to write recursive functions
on the fly.
<boost/egg/fix.hpp>
Valid expression |
Semantics |
---|---|
|
|
|
Static
|
Note | |
---|---|
|
void egg_example() { using bll::_1; using bll::_2; int r = fix2( bll::ret<int>( // \(f,a) -> a == 0 ? 1 : a * f(a-1) bll::if_then_else_return( _2 == 0, 1, _2 * lazy(_1)(_2 - 1) ) ) ) (5); BOOST_CHECK(r == 5*4*3*2*1); }
fuse
converts a Function
Object into a unary Function
Object which takes a Fusion
Forward Sequence.
<boost/egg/fuse.hpp>
fc(d)
is
an object of result_of_fuse<__typeof
(d)>::type
initialized by d
.
t_
is __fwd_arg_list
(t, by_perfect)
.
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
|
|
1 <=
N &&
N <=
__MAX_PACK_ARITY
.
__PFo
d =
init;
is a valid expression.
int unfused_plus(int i, int j, int k) { return i + j + k; } void egg_example() { BOOST_CHECK( 1+2+3 == fuse(&unfused_plus)(boost::make_tuple(1,2,3)) ); }
unfuse
reverses fuse
.
<boost/egg/unfuse.hpp>
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
__PFo
d =
init;
is a valid expression.
__decltype_r0
(R0, d(pack_())
is a valid expression which specifies
the nullary return type.
Pack
isn't __ud
,
__mpl
::apply<Pack, by_ref>::type
is a valid expression.
struct fused_print { typedef void result_type; template<class Args> void operator()(Args const &args) const { boost::fusion::for_each(args, std::cout << bll::_1); } }; result_of_unfuse<fused_print>::type const print = BOOST_EGG_UNFUSE({}); void egg_example() { print(1, '2', "34"); }
indirect
takes a pointer-like
object then calls it after dereferencing.
<boost/egg/indirect.hpp>
Valid expression |
Semantics |
---|---|
A Major Function Object type |
|
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
boost::pointee<Pco>::type
is Polymorphic
Function Object type.
Pco p
= init;
is a valid expression.
result_of_indirect<Pco,...>::type
is POD if and
only if Pco
is POD.
typedef result_of_pipable< result_of_indirect<T_pipable const *>::type >::type T_pipi; T_pipi const pipi = BOOST_EGG_PIPABLE_L BOOST_EGG_INDIRECT(&pipable) BOOST_EGG_PIPABLE_R; struct counter : private boost::noncopyable { typedef void result_type; template<class T> void operator()(T const &) { m_count += 1; } int m_count; counter() : m_count(0) {} }; void egg_example() { std::plus<int> plus; BOOST_CHECK( (1|pipable(plus)(3)) == 1+3 ); BOOST_CHECK( (1|(plus|pipi)(3)) == 1+3 ); counter c; int a[] = {1,2,3}; std::for_each(a, a+3, indirect(&c)); BOOST_CHECK(c.m_count == 3); }
Make |
|
|
|
A macro invocation
must be sandwiched using |
|
|
Boost.Phoenix is able to make a lambda expression
without a "bind function". lazy
turns a bindable Function
Object into such one which can be used with Boost.Lambda.
<boost/egg/lazy.hpp>
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
Polymorphic
|
|
A Major Function Object type |
|
|
|
|
F f
= init;
is a valid expression.
result_of_lazy<F, Bind>::type
is POD if and only if F
is POD.
Tip | |
---|---|
When you provide a |
struct base_my_plus { typedef int result_type; int operator()(int x, int y) const { return x + y; } }; result_of_lazy<base_my_plus>::type const my_Plus = BOOST_EGG_LAZY({}); void egg_example() { using bll::_1; using bll::_2; BOOST_CHECK( my_Plus(_1, 3)(bll::make_const(2)) == 5 ); int two = 2, four = 4; BOOST_CHECK( my_Plus(my_Plus(_1, 3), my_Plus(_2, _1)) (two, four) == (2+3)+(4+2) ); }
memoize
stores the result
of function for later reuse.
<boost/egg/memoize.hpp>
fixed
is an unspecified
unary Function Object
which represents __pfo
itself.
Valid expression |
Semantics |
---|---|
|
|
|
|
memoize(__pfo
)
must always be called with the same type
arguments.
__typeof
(a1)
is Copy Assignable,
Copy Constructible
and Equality
Comparable.
__decltype
(memoize(__pfo
)(a1))
is Copy Constructible.
struct T_fib { typedef int result_type; template<class Fixed> int operator()(Fixed f, int x) const { return x <= 1 ? 1 : f(x-1) + f(x-2); } int operator()(int x) const { return (*this)(*this, x); } }; T_fib const fib = {}; void egg_example() { BOOST_CHECK( fib(30) == 1346269 ); BOOST_CHECK( memoize(fib)(30) == 1346269 ); }
mono
turns a Function
Object into a "monomorphic" one which contains no templates.
<boost/egg/mono.hpp>
fc(f)
is
an object of result_of_mono<__typeof
(f), Sig>::type
initialized by f
.
N
is an arity of Sig
.
R
is a return type of
Sig
.
ParamOf(Sig, I)
is
an imaginary operator which returns an I
th
parameter type of Sig
.
bI
is boost::implicit_cast<ParamOf(Sig, I)>(aI)
.
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
|
A Major Function Object type |
|
|
|
|
Fun
is a Function
Object type.
Sig
is a function
type.
Fun f
= init;
is a valid expression.
R
is __ud
, Fun
is a Polymorphic
Function Object type; R
specifies a return type of Fun
,
otherwise.
result_of_mono<Fun,...>::type
is POD if and
only if Fun
is POD.
result_of_mono<Fun,...>::type
is Adaptable
if and only if N
is 1
or 2
.
void egg_example() { BOOST_CHECK( std::not1( egg::mono<bool(int const&)>(bll::_1 != 12) ) (12) ); BOOST_CHECK( std::bind1st( egg::mono<boost::use_default(int const&, int const&)>(bll::_1 == bll::_2), 12 ) (12) ); }
nestN
is generalization of
curryN
and lazy
,
which enables you to write nested lambda expressions. N
represents nesting level of lambda expression.
<boost/egg/nest.hpp>
bll_bind
is an imaginary
Function Object
behaving as if it were boost::lambda::bind
.
wrap_ref_
is an imaginary
Function Object
behaving as if it were boost::ref
.
unwrap_ref_
is an imaginary
Function Object
which extracts a wrapped reference from boost::reference_wrapper
.
bind_
is bll_bind
if Bind
is __ud
,
Bind()
otherwise.
protect_
is boost::lambda::protect
if Protect
is __ud
,
Protect()
otherwise.
LAZY(N)
is:
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
Polymorphic
|
|
|
|
A Major Function Object type |
|
Polymorphic
|
|
Static
|
|
A Major Function Object type |
|
Polymorphic
|
|
Static
|
|
using-declarations of |
0 <=
N &&
N <=
BOOST_EGG_MAX_ARITY
.
0 <=
M &&
M <=
N-1
.
Important | |
---|---|
For capturing by-reference in nested lambda expressions, |
int & second(int, int &j, int, int) { return j; } void egg_example() { using bll::_1; using bll::_2; std::plus<int> plus; std::minus<int> minus; int i6 = 6, i1 = 1, i3 = 3, i9 = 9; // Lv: 0 1 2 3 // \x -> (\y -> (\(z,w) -> foo(y,w,z,x)))) BOOST_CHECK( nest3(foo)(_1_(_1), _2_(_2), _2_(_1), _0_(_1)) (i3)(i6)(i1,i9) == foo(6,9,1,3) ); // \x -> apply(\y -> minus(x,y), plus(x,3)) BOOST_CHECK( nest1(apply)(nest2(minus)(_0_(_1), _1_(_1)), nest1(plus)(_0_(_1), 3)) (i9) == minus(9, plus(9,3)) ); int w = 7; // \x -> (\y -> (\z -> second(y,w,z,x)))) BOOST_CHECK( boost::addressof( nest3(second)(_1_(_1), ref3(w), _2_(_1), _0_(_1)) (i1)(i1)(i1) ) == boost::addressof(w) ); }
|
|
By the definition, |
|
Captures |
perfect
performs "perfect
forwarding".
<boost/egg/perfect.hpp>
fc(d)
is
an object of result_of_perfect<__typeof
(d)>::type
initialized by d
.
Valid expression |
Semantics |
---|---|
|
A Major Function Object type |
|
A braced initializer of |
|
|
|
|
|
|
__PFo
d =
init;
is a valid expression.
struct imperfect { template<class FunCall> struct result; template<class Fun, class A> struct result<Fun(A &)> { typedef A &type; }; template<class A> A & operator()(A &a) const { return a; } }; void egg_example() { BOOST_CHECK( perfect(imperfect())(3) == 3 ); }
pipable
adapts Function
Object into Pipable
Function Object.
<boost/egg/pipable.hpp>
Valid expression |
Semantics |
---|---|
|
A Pipable Major Function Object type |
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
0 <=
N &&
N+1 <= BOOST_EGG_MAX_LINEAR_ARITY
.
N+1 <= __MAX_PACK_ARITY
.
__PFo
d =
init;
is a valid expression.
__bytag_at
(__Stg
, N,
I)
is by_value
, __typeof
(aI)
is Copy Constructible.
Tip | |
---|---|
When you provide a Pipable
Function Object, its "base" function also should be provided
with a consistent naming convention, so that your clients can use it with
|
struct weird_mult { typedef int result_type; int operator()(int x) const { return x * x; } int operator()(int x, int y) const { return x * y; } int operator()(int x, int y, int z) const { return x * y * z; } }; result_of_pipable<weird_mult>::type const mult = BOOST_EGG_PIPABLE({}); void egg_example() { BOOST_CHECK( ( 2|mult ) == 2 * 2 ); BOOST_CHECK( ( 2|mult() ) == 2 * 2 ); BOOST_CHECK( ( 2|mult(3)|mult(4) ) == 2 * 3 * 4 ); BOOST_CHECK( ( 2|mult(3, 4) ) == 2 * 3 * 4 ); BOOST_CHECK( ( mult|=2 ) == 2 * 2 ); BOOST_CHECK( ( mult()|=2 ) == 2 * 2 ); BOOST_CHECK( ( mult|=mult|=2) == (2 * 2) * (2 * 2) ); BOOST_CHECK( ( mult(3)|=2 ) == 2 * 3 ); BOOST_CHECK( ( mult(3, 4)|= 2 ) == 2 * 3 * 4 ); }
A Boost.Lambda
Function Object
is neither Default
Constructible nor Copy
Assignable. An iterator holding such a Function
Object can't conform to even Input
Iterator. regular
converts it into comfortable one for iterators.
<boost/egg/regular.hpp>
Valid expression |
Semantics |
---|---|
|
A Major Function Object which is Default Constructible and Copy Assignable. |
|
|
void egg_example() { int a1[6] = {1,2,3,4,5,6}; int a2[3] = {2,4,6}; BOOST_CHECK( std::equal(a2, a2+3, boost::make_filter_iterator(regular(bll::_1 % 2 == 0), a1, a1+6) ) ); }
return_
just calls Function Object,
possibly with a modified return type.
<boost/egg/return.hpp>
Valid expression |
Semantics |
---|---|
A Major Function Object type |
|
|
A braced initializer of |
|
|
|
|
A Major Function Object type |
|
|
|
|
|
Fun
is a Function
Object type.
Fun
is a Polymorphic
Function Object type if R
is __ud
.
Fun f
= init;
is a valid expression.
result_of_return<Fun,...>::type
is POD if and
only if Fun
is POD.
void egg_example() { BOOST_CHECK( egg::return_<std::string>(bll::_1)("string").size() == 6 ); }
tagged
makes a new distinct
Function Object
type. This emulates support for strong typedefs.
<boost/egg/tagged.hpp>
Valid expression |
Semantics |
---|---|
A Major Function Object type |
|
|
A braced initializer of |
|
|
|
|
|
|
|
|
Tag
is any (possibly incomplete)
type.
__PFo
d =
init;
is a valid expression.
struct tag1; struct tag2; typedef result_of_tagged<std::multiplies<int>, tag1>::type my_mult1; typedef result_of_tagged<std::multiplies<int>, tag2>::type my_mult2; void egg_example() { BOOST_CHECK( my_mult1()(3, 5) == my_mult2()(3, 5) ); BOOST_STATIC_ASSERT(( !boost::is_same<my_mult1, my_mult2>::value )); BOOST_STATIC_ASSERT(( is_tagged_with<my_mult1, tag1>::value )); }