Boost C++ Libraries

PrevUpHomeNext

Function Builders

function
function_facade
generator
implicit
poly
static_
variadic

Function builders build Major Function Object types, which can be used with boost::lambda::bind and boost::result_of.

Description

function is the "kernel" class template which transforms a Little Function into a Major Function Object.

Header
  • <boost/egg/function.hpp>
Synopsys
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
    // ...
};
Notation
Valid expressions

Valid expression

Semantics

function<__Lit, __Stg>

An aggregate Major Function Object type

f(a1,...,aN)

f.little().call<__Lit::apply<__Lit const, __meta_arg_list(a, __Stg)>::type>(__arg_list(a, __Stg))

f()

f.little().call<__Lit::nullary_result_type>()

Preconditions
Invariants
Example

struct little_unwrap
{
    template<class Me, class A>
    struct apply
    {
        typedef A &type; 1
    };

    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 2
    {
        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 );
}

1

A is possibly cv-qualified but not reference type.

2

Re is apply<little_unwrap const, A>::type, which is passed by Egg.

See also
Description

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.

Header
  • <boost/egg/function_facade.hpp>
Valid expressions

Valid expression

Semantics

__lit

A Major Function Object

__lit(a1,...,aN)

__lit.call<__typeof(__lit)::apply<__typeof(__lit) const, __meta_arg_list(a, __Stg)>::type>(__arg_list(a, __Stg))

__lit()

__lit.call<R0>()

Preconditions
Example

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;
};

1
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 );
}

1

plus_to<> is already Major Function Object type.

See also
Description

generator builds Object Generators.

Header
  • <boost/egg/generator.hpp>
Notation
Valid expressions

Valid expression

Semantics

generator<Lam, __Stg = __ud, Cons = __ud, R0 = __ud>::type

A POD Major Function Object type

BOOST_EGG_GENERATOR()

A braced initializer of generator<Lam, __Stg, Cons, R0>::type

g(a1,...,aN)

Cst(T)()(__fwd_arg_list(a, __Stg))

g()

Cst(__decltype_r0(R0, __mpl::apply<C(Lam)>::type())()()

__mpl::_%%M and __mpl::_

as-is

Preconditions
Invariants
[Note] Note

Lam is not instantiated while invoking __mpl::apply, so that any static assertion in generated type doesn't fail.

Deducers

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 expressions of Deducers

Valid expression

Semantics

deduce<A, As>

__mpl::apply<As, A> if the corresponding argument is passed; ill-formed otherwise.

deduce<A, As, Def>

__mpl::apply<As, A> if the corresponding argument is passed; __mpl::identity<Def> otherwise.

as_ref

boost::add_reference<__mpl::_>

as_cref

boost::add_reference< boost::add_const<__mpl::_> >

as_value

boost::remove_cv< boost::decay<__mpl::_> >

as_qualified

__mpl::identity<__mpl::_>

Example

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_ 1
{
    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 );
}

1

Boost.Tuple template arity is large, so that mpl::_x can't be used.

See also
Description

implicit adds implicit conversion support to a cast form function.

Header
  • <boost/egg/implicit.hpp>
Notation
Valid expressions

Valid expression

Semantics

implicit<Lam, __Stg = __ud>::type

A POD Major Function Object type

BOOST_EGG_IMPLICIT()

A braced initializer of implicit<Lam, __Stg>::type

To to = u(a1,...,aN);

To to = boost::implicit_cast<__typeof(to)>( fuse(F())(X_pack<__Stg>()(a1,...,aN)) );

__mpl::_%%M and __mpl::_

as-is

Preconditions
[Note] Note

These valid expressions imply that the implicit conversion is available everywhere copy-initialization is invoked. For example, you can place u in a return-statement. The last precondition comes from a bug of GCC.

Invariants
Example

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" );
}

See also
Description

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.

Header
  • <boost/egg/poly.hpp>
Notation
  • f is an object of poly<Lam,...>::type.
Valid expressions

Valid expression

Semantics

poly<Lam, __Stg = __ud, R0 = __ud>::type

A POD Major Function Object type

BOOST_EGG_POLY()

A braced initializer of poly<Lam,...>::type

f(a1,...,aN)

__mpl::apply<Lam, __meta_arg_list(a, __Stg)>::type()(__arg_list(a, __Stg))

f()

__mpl::apply<Lam>::type()()

__mpl::_%%M and __mpl::_

as-is

Preconditions
Invariants
Example

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);
}

See also
Description

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_.

[Note] Note

When indirect also is available, prefer indirect, which seems to run faster in msvc.

Header
  • <boost/egg/static.hpp>
Notation
  • u is an object of static_<Lam, __Stg>::type.
  • F is __mpl::apply<Lam, __Stg>::type.
Valid expressions

Valid expression

Semantics

static_<Lam, __Stg = __ud>::type

A POD Major Function Object type

BOOST_EGG_STATIC()

A braced initializer of static_<Lam, __Stg>::type

u(a1,...,aN)

F()(__fwd_arg_list(a, __Stg))

__mpl::_%%M, __mpl::_ and __mpl::always

as-is

Preconditions
Invariants
Example

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; 1
T_my_plus const my_plus = BOOST_EGG_STATIC();

void egg_example()
{
    BOOST_CHECK( my_apply(my_plus, 1, 2) == 3 );
}

1

T_my_plus is POD, whereas std::plus<int> is not.

See also
Description

variadic emulates Variadic functions in C++98. In fact, this is a shortcut to unfuse.

Header
  • <boost/egg/variadic.hpp>
Valid expressions

Valid expression

Semantics

variadic<__Lit, __Stg = __ud, Pack = __ud, R0 = __ud>::type

result_of_unfuse<function<__Lit, by_cref>, R0, Pack, __Stg>::type

BOOST_EGG_VARIADIC_L __lit BOOST_EGG_VARIADIC_R

A braced initializer of variadic<__typeof(__lit),...>::type

BOOST_EGG_VARIADIC(L)

BOOST_EGG_VARIADIC_L L BOOST_EGG_VARIADIC_R

variadic_poly<Lam, __Stg = __ud, Pack = __ud, R0 = __ud>::type

result_of_unfuse<poly<Lam, by_cref>::type, R0, Pack, __Stg>::type

BOOST_EGG_VARIADIC_POLY()

A braced initializer of variadic_poly<Lam,...>::type

__mpl::_%%M and __mpl::_

as-is

Invariants
  • What the corresponding semantics implies.
Example

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")) );
}

See also

PrevUpHomeNext