[#sequence_apply]
[section sequence_apply]

[h1 Synopsis]

  template <template <class, ..., class> class T, class P1, ..., class Pn>
  struct sequence_applyn;

This is a [link parser_combinator parser combinator].

[table Arguments
  [[T] [Template class taking `n` arguments]]
  [[`P1`..`Pn`]  [[link parser parser]s]]
]

[h1 Description]

It applies the `P1` ... `Pn` [link parser parser]s on the input in order. When
all of them succeed, the result of parsing with `sequence_applyn` is the `T`
template class instantiated with the results of the `P1` ... `Pn`
[link parser parser]s. When any of the `P1` ... `Pn` [link parser parser]s
reject the input, the error is propagated.

`n` has to be in the `[1..BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE)` range.

[h1 Header]

  #include <boost/metaparse/sequence_apply.hpp>

[h1 Expression semantics]

For any `n > 0`, `p1` ... `pn` [link parser parser]s, `t` template class with
`n` `class` arguments, `s` compile-time string and `pos` source position the
following are equivalent:

  sequence_apply<t, p1, ..., pn>::apply<s, pos>::type

when [link sequence `sequence`]`<p1, ..., pn>` accepts the input:

  return_<
    t<
      mpl::at_c<0, get_result<sequence<p1,...,pn>::apply<s, pos>>::type>::type,
      ...
      mpl::at_c<n, get_result<sequence<p1,...,pn>::apply<s, pos>>::type>::type,
    >
  >::apply<s, pos>::type

when [link sequence `sequence`]`<p1, ..., pn>` rejects the input:

  sequence<p1, ..., pn>::apply<s, pos>::type
  
[h1 Example]

  #include <boost/metaparse/sequence_apply.hpp>
  #include <boost/metaparse/int_.hpp>
  #include <boost/metaparse/middle_of.hpp>
  #include <boost/metaparse/lit_c.hpp>
  #include <boost/metaparse/start.hpp>
  #include <boost/metaparse/string.hpp>
  #include <boost/metaparse/get_result.hpp>
  
  #include <boost/type_traits/is_same.hpp>
  
  using namespace boost::metaparse;
  
  template <int Real, int Imaginary>
  struct complex_c { typedef complex_c type; };

  template <class Real, class Imaginary>
  struct complex : complex_c<Real::type::value, Imaginary::type::value> {};

  typedef
    sequence_apply2<complex, int_, middle_of<lit_c<'+'>, int_, lit_c<'i'>>>
    complex_parser;
  
  static_assert(
    boost::is_same<
      complex_c<1, 2>,
      get_result<
        complex_parser::apply<BOOST_METAPARSE_STRING("1+2i"), start>
      >::type::type
    >::type::value,
    "the result of parsing should be the list of digit values"
  );

[endsect]

