zhangmeng
2021-07-02 056f71f24cefaf88f2a93714c6678c03ed5f1e0e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*=============================================================================
    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