![]() |
Function builders build Major
Function Object types, which can be used with boost::lambda::bind and
boost::result_of.
function is the "kernel"
class template which transforms a Little
Function into a Major
Function Object.
<boost/egg/function.hpp>
template<class Little, class Stg = __ud>
struct function
{
typedef Little little_type;
typedef Stg strategy_type;
Little lit; // exposition only
Little const & little() const { return lit; }
// unspecified
// ...
};
|
Valid expression |
Semantics |
|---|---|
|
An aggregate Major Function Object type |
|
|
|
|
|
|
|
function<__Lit, __Stg>
is POD if and only if __Lit is POD.
function<__Lit, __Stg>
is Default
Constructible if and only if __Lit is Default
Constructible.
function<__Lit, __Stg>
is Copy Assignable
if and only if __Lit is Copy
Assignable.
struct little_unwrap { template<class Me, class A> struct apply { typedef A &type;}; template<class Me, class T> struct apply< Me, boost::reference_wrapper<T> > { typedef T &type; }; template<class Me, class T> struct apply< Me, boost::reference_wrapper<T> const > { typedef T &type; }; template<class Re, class A> Re call(A &a) const
{ return a; } }; typedef function<little_unwrap> T_unwrap; T_unwrap const unwrap = {{}}; void egg_example() { int i = 1; BOOST_CHECK( &(unwrap(i)) == &i ); BOOST_CHECK( &(unwrap(boost::ref(i))) == &i ); }
|
|
|
|
function_facade creates a
new Major Function
Object type using "CRTP". Though a type built from function_facade can't be POD,
it can have non-default constructors. This can be regarded as a port of
callable to Egg.
<boost/egg/function_facade.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
template<class T> struct plus_to : function_facade< plus_to<T> > { template<class Me, class A> struct apply { typedef T type; }; template<class Re, class A> Re call(A &a) const { return m_x + a; } explicit plus_to(T x) : m_x(x) {} private: T m_x; };template<class T> plus_to<T> make_plus_to(T x) { return plus_to<T>(x); } void egg_example() { BOOST_CHECK( make_plus_to(1)(3) == 4 ); }
|
|
generator builds Object
Generators.
<boost/egg/generator.hpp>C(Lam)
is
Lam
with no nested type
if Lam is an MPL
Placeholder Expression.
Lam itself otherwise.
g is an object of generator<Lam, __Stg,
Cons,
R0>::type.
T is __mpl::apply<C(Lam), __meta_arg_list(a, __Stg)>::type.
Cst(U) is
__mpl::apply<X_construct<__mpl::_1, __mpl::_2>, U, __Stg>::type if Cons
is __ud,
__mpl::apply<Cons, U,
__Stg>::type
otherwise.
|
Valid expression |
Semantics |
|---|---|
|
A POD Major Function Object type |
|
|
|
A braced initializer of |
|
|
|
|
|
|
|
as-is |
Lam is an (possibly cv-qualified)
MPL
Lambda Expression.
g with
static storage duration is statically initialized
if initialized using BOOST_EGG_GENERATOR().
g is Default
Constructible and Copy
Assignable.
![]() |
Note |
|---|---|
|
Some basic and useful MPL Metafunction Class types are provided for better error messages. You can place any elaborate MPL Lambda Expression in generating type, though.
|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef generator< std::pair< deduce<boost::mpl::_1, as_value>, deduce<boost::mpl::_2, as_value> > >::type T_make_pair; T_make_pair const make_pair = BOOST_EGG_GENERATOR(); struct tuple_{ template<class T1, class T2> struct apply { typedef boost::tuples::tuple<T1 &, T2 &> type; }; }; generator<tuple_>::type const my_pack = BOOST_EGG_GENERATOR(); void egg_example() { BOOST_CHECK( make_pair(10, std::string("generator")) == std::make_pair(10, std::string("generator")) ); int ten = 10; BOOST_CHECK( &(boost::get<1>(my_pack('a', ten))) == &ten ); }
|
Boost.Tuple
template arity is large, so that |
implicit adds implicit conversion
support to a cast form function.
<boost/egg/implicit.hpp>|
Valid expression |
Semantics |
|---|---|
|
A POD Major Function Object type |
|
|
|
A braced initializer of |
|
|
|
|
as-is |
F is a Polymorphic
Function Object type.
boost::is_convertible<unspecified,
__typeof(to)>::value == false.
u is not placed in a default
argument list.
![]() |
Note |
|---|---|
These valid expressions imply that the implicit conversion is available
everywhere copy-initialization is invoked. For example,
you can place |
u with
static storage duration is statically initialized
if initialized using BOOST_EGG_IMPLICIT().
u is Default
Constructible and Copy
Assignable.
template<class To> struct X_lexical_cast { typedef To result_type; template<class From> To operator()(From from) const { return boost::lexical_cast<To>(from); } }; implicit< X_lexical_cast<boost::mpl::_> >::type const lexical = BOOST_EGG_IMPLICIT(); void egg_example() { std::string str = lexical(20); BOOST_CHECK( str == "20" ); }
poly is a port of detail::function family which is secretly contained
in Boost.Accumulators. Though poly
can't build "stateful" function, you can access nested typedefs
from operator()
body. When you want to build a stateless Function
Object, poly is the
coolest builder.
<boost/egg/poly.hpp>f is an object of poly<Lam,...>::type.
|
Valid expression |
Semantics |
|---|---|
|
A POD Major Function Object type |
|
|
|
A braced initializer of |
|
|
|
|
|
|
|
as-is |
1 <=
N &&
N <=
BOOST_MPL_LIMIT_METAFUNCTION_ARITY,
which has a default value 5.
__mpl::apply<Lam, __meta_arg_list(a, __Stg)>::type::result_type is a valid expression such
that it is the same as __decltype(__mpl::apply<Lam, __meta_arg_list(a, __Stg)>::type()(__arg_list(a,
__Stg))).
R0 is use_nullary_result, __mpl::apply<Lam>::type::result_type is a valid expression such
that it is the same as __decltype(__mpl::apply<Lam>::type()()).
f with
static storage duration is statically initialized
if initialized using BOOST_EGG_POLY().
f is Default
Constructible and Copy
Assignable.
template<class F, class X> struct mono_twice { typedef typename result_of_<F(typename result_of_<F(X &)>::type)>::type result_type; result_type operator()(F &f, X &x) const { return f(f(x)); } }; typedef poly< mono_twice<boost::mpl::_, boost::mpl::_> >::type T_twice; T_twice const twice = BOOST_EGG_POLY(); int increment(int i) { return i + 1; } void egg_example() { BOOST_CHECK(twice(&increment, 3) == 5); }
static_ builds a POD
Function Object
from a Default
Constructible one. Note that Egg's Function
Object class templates which begin with X_
are not guaranteed to be statically initialized without
static_.
<boost/egg/static.hpp>|
Valid expression |
Semantics |
|---|---|
|
A POD Major Function Object type |
|
|
|
A braced initializer of |
|
|
|
|
as-is |
F is a Polymorphic
Function Object type.
u with
static storage duration is statically initialized
if initialized using BOOST_EGG_STATIC().
u is Default
Constructible and Copy
Assignable.
typedef static_<X_apply<boost::mpl::_1>, by_cref>::type T_my_apply; T_my_apply const my_apply = BOOST_EGG_STATIC(); typedef static_< boost::mpl::always< std::plus<int> > >::type T_my_plus;T_my_plus const my_plus = BOOST_EGG_STATIC(); void egg_example() { BOOST_CHECK( my_apply(my_plus, 1, 2) == 3 ); }
variadic emulates Variadic functions
in C++98. In fact, this is a shortcut to unfuse.
<boost/egg/variadic.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A braced initializer of |
|
as-is |
template<class Args> struct mono_vplus { typedef typename boost::remove_cv< typename boost::remove_reference< typename Args::head_type >::type >::type result_type; result_type operator()(Args &args) const { return boost::fusion::accumulate( args.get_tail(), boost::get<0>(args), bll::_2 + bll::_1 ); } }; typedef variadic_poly< mono_vplus<boost::mpl::_1> >::type T_vplus; T_vplus const vplus = BOOST_EGG_VARIADIC_POLY(); void egg_example() { using std::string; BOOST_CHECK( boost::lexical_cast<string>(vplus(5, 6, 7)) == vplus(string("1"), string("8")) ); }