| 3774 | typename... Ts, |
| 3775 | int... Is> |
| 3776 | void call_impl( |
| 3777 | Iter & first, |
| 3778 | Sentinel last, |
| 3779 | Context const & context, |
| 3780 | SkipParser const & skip, |
| 3781 | detail::flags flags, |
| 3782 | bool & success, |
| 3783 | tuple<Ts...> & retval, |
| 3784 | std::integer_sequence<int, Is...>) const |
| 3785 | { |
| 3786 | std::array<bool, sizeof...(Ts)> used_parsers = {{}}; |
| 3787 | |
| 3788 | // Use "parser" to fill in attribute "x", unless "parser" has |
| 3789 | // previously been used. |
| 3790 | auto parse_into = [&](int i, auto const & parser, auto & x) { |
| 3791 | if (used_parsers[i]) |
| 3792 | return false; |
| 3793 | detail::skip(first, last, skip, flags); |
| 3794 | parser.call(first, last, context, skip, flags, success, x); |
| 3795 | if (success) { |
| 3796 | used_parsers[i] = true; |
| 3797 | return true; |
| 3798 | } |
| 3799 | success = true; |
| 3800 | return false; |
| 3801 | }; |
| 3802 | // Use one of the previously-unused parsers to parse one |
| 3803 | // alternative. |
| 3804 | bool first_iteration = true; |
| 3805 | auto parsed_one = [&](auto) { |
| 3806 | if constexpr (!detail::is_nope_v<DelimiterParser>) { |
| 3807 | if (!first_iteration) { |
| 3808 | detail::skip(first, last, skip, flags); |
| 3809 | bool local_success = true; |
| 3810 | delimiter_parser_.call( |
| 3811 | first, last, context, skip, flags, local_success); |
| 3812 | if (!local_success) |
| 3813 | return false; |
| 3814 | } |
| 3815 | first_iteration = false; |
| 3816 | } |
| 3817 | return ( |
| 3818 | parse_into( |
| 3819 | Is, |
| 3820 | parser::get(parsers_, llong<Is>{}), |
| 3821 | parser::get(retval, llong<Is>{})) || |
| 3822 | ...); |
| 3823 | }; |
| 3824 | success = (parsed_one(Is) && ...); |
| 3825 | |
| 3826 | if (!success) |
| 3827 | retval = tuple<Ts...>{}; |
| 3828 | } |
| 3829 | |
| 3830 | #ifndef BOOST_PARSER_DOXYGEN |
| 3831 | |