File indexing completed on 2025-12-16 10:09:16
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_KARMA_KLEENE_MAR_03_2007_0337AM)
0008 #define BOOST_SPIRIT_KARMA_KLEENE_MAR_03_2007_0337AM
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/spirit/home/karma/domain.hpp>
0015 #include <boost/spirit/home/karma/generator.hpp>
0016 #include <boost/spirit/home/karma/meta_compiler.hpp>
0017 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
0018 #include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
0019 #include <boost/spirit/home/karma/detail/get_stricttag.hpp>
0020 #include <boost/spirit/home/karma/detail/pass_container.hpp>
0021 #include <boost/spirit/home/karma/detail/fail_function.hpp>
0022 #include <boost/spirit/home/support/info.hpp>
0023 #include <boost/spirit/home/support/unused.hpp>
0024 #include <boost/spirit/home/support/container.hpp>
0025 #include <boost/spirit/home/support/handles_container.hpp>
0026 #include <boost/spirit/home/karma/detail/attributes.hpp>
0027 #include <boost/proto/operators.hpp>
0028 #include <boost/proto/tags.hpp>
0029 #include <boost/type_traits/add_const.hpp>
0030
0031 namespace boost { namespace spirit
0032 {
0033
0034
0035
0036 template <>
0037 struct use_operator<karma::domain, proto::tag::dereference>
0038 : mpl::true_ {};
0039 }}
0040
0041
0042 namespace boost { namespace spirit { namespace karma
0043 {
0044 template <typename Subject, typename Strict, typename Derived>
0045 struct base_kleene : unary_generator<Derived>
0046 {
0047 private:
0048
0049
0050
0051 template <typename F, typename Attribute>
0052 bool generate_subject(F f, Attribute const&, mpl::false_) const
0053 {
0054 bool r = !f(subject);
0055 if (!r && !f.is_at_end())
0056 f.next();
0057 return true;
0058 }
0059
0060 template <typename F, typename Attribute>
0061 bool generate_subject(F f, Attribute const&, mpl::true_) const
0062 {
0063 return !f(subject);
0064 }
0065
0066
0067
0068
0069 template <typename F>
0070 bool generate_subject(F f, unused_type, mpl::false_) const
0071 {
0072 return !f(subject);
0073 }
0074
0075
0076
0077
0078
0079
0080
0081 public:
0082 typedef Subject subject_type;
0083 typedef typename subject_type::properties properties;
0084
0085
0086
0087
0088 template <typename Context, typename Iterator>
0089 struct attribute
0090 : traits::build_std_vector<
0091 typename traits::attribute_of<Subject, Context, Iterator>::type
0092 >
0093 {};
0094
0095 base_kleene(Subject const& subject)
0096 : subject(subject) {}
0097
0098 template <
0099 typename OutputIterator, typename Context, typename Delimiter
0100 , typename Attribute>
0101 bool generate(OutputIterator& sink, Context& ctx
0102 , Delimiter const& d, Attribute const& attr) const
0103 {
0104 typedef detail::fail_function<
0105 OutputIterator, Context, Delimiter> fail_function;
0106
0107 typedef typename traits::container_iterator<
0108 typename add_const<Attribute>::type
0109 >::type iterator_type;
0110
0111 typedef
0112 typename traits::make_indirect_iterator<iterator_type>::type
0113 indirect_iterator_type;
0114 typedef detail::pass_container<
0115 fail_function, Attribute, indirect_iterator_type, mpl::false_>
0116 pass_container;
0117
0118 iterator_type it = traits::begin(attr);
0119 iterator_type end = traits::end(attr);
0120
0121 pass_container pass(fail_function(sink, ctx, d),
0122 indirect_iterator_type(it), indirect_iterator_type(end));
0123
0124
0125 while (!pass.is_at_end())
0126 {
0127 if (!generate_subject(pass, attr, Strict()))
0128 break;
0129 }
0130 return detail::sink_is_good(sink);
0131 }
0132
0133 template <typename Context>
0134 info what(Context& context) const
0135 {
0136 return info("kleene", subject.what(context));
0137 }
0138
0139 Subject subject;
0140 };
0141
0142 template <typename Subject>
0143 struct kleene
0144 : base_kleene<Subject, mpl::false_, kleene<Subject> >
0145 {
0146 typedef base_kleene<Subject, mpl::false_, kleene> base_kleene_;
0147
0148 kleene(Subject const& subject)
0149 : base_kleene_(subject) {}
0150 };
0151
0152 template <typename Subject>
0153 struct strict_kleene
0154 : base_kleene<Subject, mpl::true_, strict_kleene<Subject> >
0155 {
0156 typedef base_kleene<Subject, mpl::true_, strict_kleene> base_kleene_;
0157
0158 strict_kleene(Subject const& subject)
0159 : base_kleene_(subject) {}
0160 };
0161
0162
0163
0164
0165 namespace detail
0166 {
0167 template <typename Subject, bool strict_mode = false>
0168 struct make_kleene
0169 : make_unary_composite<Subject, kleene>
0170 {};
0171
0172 template <typename Subject>
0173 struct make_kleene<Subject, true>
0174 : make_unary_composite<Subject, strict_kleene>
0175 {};
0176 }
0177
0178 template <typename Subject, typename Modifiers>
0179 struct make_composite<proto::tag::dereference, Subject, Modifiers>
0180 : detail::make_kleene<Subject, detail::get_stricttag<Modifiers>::value>
0181 {};
0182 }}}
0183
0184 namespace boost { namespace spirit { namespace traits
0185 {
0186
0187 template <typename Subject>
0188 struct has_semantic_action<karma::kleene<Subject> >
0189 : unary_has_semantic_action<Subject> {};
0190
0191 template <typename Subject>
0192 struct has_semantic_action<karma::strict_kleene<Subject> >
0193 : unary_has_semantic_action<Subject> {};
0194
0195
0196 template <typename Subject, typename Attribute, typename Context
0197 , typename Iterator>
0198 struct handles_container<karma::kleene<Subject>, Attribute
0199 , Context, Iterator>
0200 : mpl::true_ {};
0201
0202 template <typename Subject, typename Attribute, typename Context
0203 , typename Iterator>
0204 struct handles_container<karma::strict_kleene<Subject>, Attribute
0205 , Context, Iterator>
0206 : mpl::true_ {};
0207 }}}
0208
0209 #endif