Contains definition of the ``proto::make<>`` and ``proto::protect<>`` transforms.

A type annotation in an ObjectTransform which instructs Proto not to look for a nested `::type` within `T` after type substitution.

ObjectTransforms are evaluated by ``proto::make<>``, which finds all nested transforms and replaces them with the result of their applications. If any substitutions are performed, the result is first assumed to be a metafunction to be applied; that is, Proto checks to see if the result has a nested `::type` typedef. If it does, that becomes the result. The purpose of `proto::noinvoke<>` is to prevent Proto from looking for a nested `::type` typedef in these situations.

Example:

    struct Test
      : proto::when<
            _
          , proto::noinvoke<
                // This remove_pointer invocation is bloked by noinvoke
                boost::remove_pointer<
                    // This add_pointer invocation is *not* blocked by noinvoke
                    boost::add_pointer<_>
                >
            >()
        >
    {};

    void test_noinvoke()
    {
        typedef proto::terminal<int>::type Int;

        BOOST_MPL_ASSERT((
            boost::is_same<
                boost::result_of<Test(Int)>::type
              , boost::remove_pointer<Int *>
            >
        ));

        Int i = {42};
        boost::remove_pointer<Int *> t = Test()(i);
    }

proto::transform
< protect<PrimitiveTransform> >
A PrimitiveTransform which prevents another PrimitiveTransform from being applied in an ObjectTransform.

When building higher order transforms with ``proto::make<>`` or ``proto::lazy<>`` , you sometimes would like to build types that are parameterized with Proto transforms. In such lambda-style transforms, Proto will unhelpfully find all nested transforms and apply them, even if you don't want them to be applied. Consider the following transform, which will replace the `proto::_` in `Bar<proto::_>()` with `proto::terminal<int>::type`:

    template<typename T>
    struct Bar
    {};

    struct Foo :
      proto::when<proto::_, Bar<proto::_>() >
    {};

    proto::terminal<int>::type i = {0};

    int main() {
      Foo()(i);
      std::cout << typeid(Foo()(i)).name() << std::endl;
    }

If you actually wanted to default-construct an object of type `Bar<proto::_>`, you would have to protect the `_` to prevent it from being applied. You can use `proto::protect<>` as follows:

    // OK: replace anything with Bar<_>()
    struct Foo :
      proto::when<proto::_, Bar<proto::protect<proto::_> >() >
    {};

PrimitiveTransform
proto::transform
< make<T> >
A PrimitiveTransform that computes a type by evaluating any nested transforms and then constructs an object of that type.

The purpose of `proto::make<>` is to annotate a transform as an ObjectTransform so that ``proto::when<>`` knows how to apply it.

For the full description of the behavior of the ``proto::make<>`` transform, see the documentation for the nested ``proto::make::impl<>`` class template.

proto::transform_impl
< Expr, State, Data >
see-below

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

result_type `typename impl::expr_param` `typename impl::state_param` `typename impl::data_param`

``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();