/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Copyright (c) 2014 Thomas Bernard Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP #define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP #include #include namespace boost { namespace spirit { namespace x3 { namespace detail { template struct exact_count // handles repeat(exact)[p] { typedef T type; bool got_max(T i) const { return i >= exact_value; } bool got_min(T i) const { return i >= exact_value; } T const exact_value; }; template struct finite_count // handles repeat(min, max)[p] { typedef T type; bool got_max(T i) const { return i >= max_value; } bool got_min(T i) const { return i >= min_value; } T const min_value; T const max_value; }; template struct infinite_count // handles repeat(min, inf)[p] { typedef T type; bool got_max(T /*i*/) const { return false; } bool got_min(T i) const { return i >= min_value; } T const min_value; }; }}}} namespace boost { namespace spirit { namespace x3 { template struct repeat_directive : unary_parser> { typedef unary_parser> base_type; static bool const is_pass_through_unary = true; static bool const handles_container = true; constexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_) : base_type(subject) , repeat_limit(repeat_limit_) {} template bool parse( Iterator& first, Iterator const& last , Context const& context, RContext& rcontext, Attribute& attr) const { Iterator local_iterator = first; typename RepeatCountLimit::type i{}; for (/**/; !repeat_limit.got_min(i); ++i) { if (!detail::parse_into_container( this->subject, local_iterator, last, context, rcontext, attr)) return false; } first = local_iterator; // parse some more up to the maximum specified for (/**/; !repeat_limit.got_max(i); ++i) { if (!detail::parse_into_container( this->subject, first, last, context, rcontext, attr)) break; } return true; } RepeatCountLimit repeat_limit; }; // Infinite loop tag type struct inf_type {}; constexpr inf_type inf = inf_type(); struct repeat_gen { template constexpr auto operator[](Subject const& subject) const { return *as_parser(subject); } template struct repeat_gen_lvl1 { constexpr repeat_gen_lvl1(T&& repeat_limit_) : repeat_limit(repeat_limit_) {} template constexpr repeat_directive< typename extension::as_parser::value_type, T> operator[](Subject const& subject) const { return { as_parser(subject),repeat_limit }; } T repeat_limit; }; template constexpr repeat_gen_lvl1> operator()(T const exact) const { return { detail::exact_count{exact} }; } template constexpr repeat_gen_lvl1> operator()(T const min_val, T const max_val) const { return { detail::finite_count{min_val,max_val} }; } template constexpr repeat_gen_lvl1> operator()(T const min_val, inf_type const &) const { return { detail::infinite_count{min_val} }; } }; constexpr auto repeat = repeat_gen{}; }}} namespace boost { namespace spirit { namespace x3 { namespace traits { template struct attribute_of, Context> : build_container::type> {}; }}}} #endif