/*============================================================================= 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 <boost/spirit/home/x3/core/parser.hpp> #include <boost/spirit/home/x3/operator/kleene.hpp> namespace boost { namespace spirit { namespace x3 { namespace detail { template <typename T> 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 <typename T> 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 <typename T> 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<typename Subject, typename RepeatCountLimit> struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> { typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> 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<typename Iterator, typename Context , typename RContext, typename Attribute> 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<typename Subject> constexpr auto operator[](Subject const& subject) const { return *as_parser(subject); } template <typename T> struct repeat_gen_lvl1 { constexpr repeat_gen_lvl1(T&& repeat_limit_) : repeat_limit(repeat_limit_) {} template<typename Subject> constexpr repeat_directive< typename extension::as_parser<Subject>::value_type, T> operator[](Subject const& subject) const { return { as_parser(subject),repeat_limit }; } T repeat_limit; }; template <typename T> constexpr repeat_gen_lvl1<detail::exact_count<T>> operator()(T const exact) const { return { detail::exact_count<T>{exact} }; } template <typename T> constexpr repeat_gen_lvl1<detail::finite_count<T>> operator()(T const min_val, T const max_val) const { return { detail::finite_count<T>{min_val,max_val} }; } template <typename T> constexpr repeat_gen_lvl1<detail::infinite_count<T>> operator()(T const min_val, inf_type const &) const { return { detail::infinite_count<T>{min_val} }; } }; constexpr auto repeat = repeat_gen{}; }}} namespace boost { namespace spirit { namespace x3 { namespace traits { template <typename Subject, typename RepeatCountLimit, typename Context> struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context> : build_container<typename attribute_of<Subject, Context>::type> {}; }}}} #endif