| Home | Libraries | People | FAQ | More

## Struct template impl

boost::proto::make::impl

## Synopsis

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

## Description

### `impl` public types

1. typedef 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.

   - If `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'>` .

   - If `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'>` .

   - Otherwise, the result type is `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 functions

1.     result_type operator()(typename impl::expr_param expr,
                              typename impl::state_param state,
                              typename impl::data_param data) const;

   ``proto::make`<T>::impl<Expr,State,Data>::operator()` behaves as follows:

   - If `T` is of the form `O(A0,…An)`, then:

     - If ``proto::is_aggregate`<result_type>::value` is `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, `S`)`, where `S` is a type sequence computed from the unpacking expression `An` as described in the reference for ``proto::pack``. Then, return:

         proto::make<T'>()(expr, state, data)

   - Otherwise, construct and return an object `that` as follows:

         result_type that = result_type();