...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::proto::make::impl
// In header: <boost/proto/transform/make.hpp> template<typename Expr, typename State, typename Data> struct impl : proto::transform_impl< Expr, State, Data > { // types typedef see-below result_type; // public member functions result_type operator()(typename impl::expr_param, typename impl::state_param, typename impl::data_param) const; };
impl
public
typestypedef see-below result_type;
proto::make<T>::impl<Expr, State, Data>::result_type
is
computed as follows:
If T
is an ObjectTransform of the form
Object(A0,…An)
or
Object(A0,…An ...)
,
then let O
be the return type
Object
. Otherwise, let O
be T
. The result_type
typedef is
then computed as follows:
If proto::is_transform<O>::value
is
true
, then let the result type be
boost::result_of<proto::when<_, O>(Expr, State, Data)>::type
.
Note that a substitution took place.
O
is a template like
proto::noinvoke<S<X0,…Xn> >
,
then the result type is calculated as follows:
For each i
in
[0,n]
, let
Xi'
be
boost::result_of<proto::make<Xi>(Expr, State, Data)>::type
(which evaluates this procedure recursively). Note that a substitution took place. (In this case,
Proto merely assumes that a substitution took place for the sake of compile-time efficiency. There
would be no reason to use proto::noinvoke<>
otherwise.)
The result type is
S<X0',…Xn'>
.
O
is a template like
S<X0,…Xn>
,
then the result type is calculated as follows:
For each i
in
[0,n]
, let
Xi'
be
boost::result_of<proto::make<Xi>(Expr, State, Data)>::type
(which evaluates this procedure recursively). Note whether any substitutions took place during
this operation.
If any substitutions took place in the above step and
S<X0',…Xn'>
has a nested
type
typedef, the result type is
S<X0',…Xn'>::type
.
Otherwise, the result type is
S<X0',…Xn'>
.
O
, and note that no
substitution took place.
Note that proto::when<>
is implemented
in terms of proto::call<>
and proto::make<>
, so the
above procedure is evaluated recursively.
impl
public member functionsresult_type operator()(typename impl::expr_param expr, typename impl::state_param state, typename impl::data_param data) const;
behaves as follows:
proto::make
<T>::impl<Expr,State,Data>::operator()
If T
is of the form
O(A0,…An)
, then:
If
is proto::is_aggregate
<result_type>::value
true
, then construct
and return an object that
as follows:
result_type that = {proto::when
<_
, A0>()(expr, state, data), …proto::when
<_
, An>()(expr, state, data) };
Otherwise, construct
and return an object that
as follows:
result_type that(proto::when
<_
, A0>()(expr, state, data), …proto::when
<_
, An>()(expr, state, data) );
If T
is of the form
O(A0,…An ...)
,
then let T'
be O(A0,…An-1,
,
where S
)S
is a type sequence computed from the unpacking expression An
as described in the reference for
. Then, return:
proto::pack
proto::make<T'>()(expr, state, data)
Otherwise, construct and return an object that
as follows:
result_type that = result_type();