File indexing completed on 2025-12-16 10:09:16
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_SPIRIT_KARMA_OPERATOR_LIST_HPP
0008 #define BOOST_SPIRIT_KARMA_OPERATOR_LIST_HPP
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
0030 namespace boost { namespace spirit
0031 {
0032
0033
0034
0035 template <>
0036 struct use_operator<karma::domain, proto::tag::modulus>
0037 : mpl::true_ {};
0038 }}
0039
0040
0041 namespace boost { namespace spirit { namespace karma
0042 {
0043 template <typename Left, typename Right, typename Strict, typename Derived>
0044 struct base_list : binary_generator<Derived>
0045 {
0046 private:
0047
0048
0049 template <typename F, typename Attribute>
0050 bool generate_left(F f, Attribute const&, mpl::false_) const
0051 {
0052
0053
0054 while (!f.is_at_end())
0055 {
0056 bool r = !f(left);
0057 if (r)
0058 return true;
0059 if (!f.is_at_end())
0060 f.next();
0061 }
0062 return false;
0063 }
0064
0065 template <typename F, typename Attribute>
0066 bool generate_left(F f, Attribute const&, mpl::true_) const
0067 {
0068 return !f(left);
0069 }
0070
0071
0072
0073
0074 template <typename F>
0075 bool generate_left(F f, unused_type, mpl::false_) const
0076 {
0077 return !f(left);
0078 }
0079
0080 public:
0081 typedef Left left_type;
0082 typedef Right right_type;
0083
0084 typedef mpl::int_<
0085 left_type::properties::value
0086 | right_type::properties::value
0087 | generator_properties::buffering
0088 | generator_properties::counting
0089 > properties;
0090
0091
0092
0093
0094 template <typename Context, typename Iterator>
0095 struct attribute
0096 : traits::build_std_vector<
0097 typename traits::attribute_of<Left, Context, Iterator>::type>
0098 {};
0099
0100 base_list(Left const& left, Right const& right)
0101 : left(left), right(right)
0102 {}
0103
0104 template <
0105 typename OutputIterator, typename Context, typename Delimiter
0106 , typename Attribute>
0107 bool generate(OutputIterator& sink, Context& ctx
0108 , Delimiter const& d, Attribute const& attr) const
0109 {
0110 typedef detail::fail_function<
0111 OutputIterator, Context, Delimiter
0112 > fail_function;
0113
0114 typedef typename traits::container_iterator<
0115 typename add_const<Attribute>::type
0116 >::type iterator_type;
0117
0118 typedef
0119 typename traits::make_indirect_iterator<iterator_type>::type
0120 indirect_iterator_type;
0121 typedef detail::pass_container<
0122 fail_function, Attribute, indirect_iterator_type, mpl::false_>
0123 pass_container;
0124
0125 iterator_type it = traits::begin(attr);
0126 iterator_type end = traits::end(attr);
0127
0128 pass_container pass(fail_function(sink, ctx, d),
0129 indirect_iterator_type(it), indirect_iterator_type(end));
0130
0131 if (generate_left(pass, attr, Strict()))
0132 {
0133 while (!pass.is_at_end())
0134 {
0135
0136 detail::enable_buffering<OutputIterator> buffering(sink);
0137 {
0138 detail::disable_counting<OutputIterator> nocounting(sink);
0139
0140 if (!right.generate(sink, ctx, d, unused))
0141 return false;
0142
0143 if (!generate_left(pass, attr, Strict()))
0144 break;
0145 }
0146 buffering.buffer_copy();
0147 }
0148 return detail::sink_is_good(sink);
0149 }
0150 return false;
0151 }
0152
0153 template <typename Context>
0154 info what(Context& context) const
0155 {
0156 return info("list",
0157 std::make_pair(left.what(context), right.what(context)));
0158 }
0159
0160 Left left;
0161 Right right;
0162 };
0163
0164 template <typename Left, typename Right>
0165 struct list
0166 : base_list<Left, Right, mpl::false_, list<Left, Right> >
0167 {
0168 typedef base_list<Left, Right, mpl::false_, list> base_list_;
0169
0170 list(Left const& left, Right const& right)
0171 : base_list_(left, right) {}
0172 };
0173
0174 template <typename Left, typename Right>
0175 struct strict_list
0176 : base_list<Left, Right, mpl::true_, strict_list<Left, Right> >
0177 {
0178 typedef base_list<Left, Right, mpl::true_, strict_list> base_list_;
0179
0180 strict_list (Left const& left, Right const& right)
0181 : base_list_(left, right) {}
0182 };
0183
0184
0185
0186
0187 namespace detail
0188 {
0189 template <typename Subject, bool strict_mode = false>
0190 struct make_list
0191 : make_binary_composite<Subject, list>
0192 {};
0193
0194 template <typename Subject>
0195 struct make_list<Subject, true>
0196 : make_binary_composite<Subject, strict_list>
0197 {};
0198 }
0199
0200 template <typename Subject, typename Modifiers>
0201 struct make_composite<proto::tag::modulus, Subject, Modifiers>
0202 : detail::make_list<Subject, detail::get_stricttag<Modifiers>::value>
0203 {};
0204 }}}
0205
0206 namespace boost { namespace spirit { namespace traits
0207 {
0208
0209 template <typename Left, typename Right>
0210 struct has_semantic_action<karma::list<Left, Right> >
0211 : binary_has_semantic_action<Left, Right> {};
0212
0213 template <typename Left, typename Right>
0214 struct has_semantic_action<karma::strict_list<Left, Right> >
0215 : binary_has_semantic_action<Left, Right> {};
0216
0217
0218 template <typename Left, typename Right, typename Attribute
0219 , typename Context, typename Iterator>
0220 struct handles_container<karma::list<Left, Right>, Attribute
0221 , Context, Iterator>
0222 : mpl::true_ {};
0223
0224 template <typename Left, typename Right, typename Attribute
0225 , typename Context, typename Iterator>
0226 struct handles_container<karma::strict_list<Left, Right>, Attribute
0227 , Context, Iterator>
0228 : mpl::true_ {};
0229 }}}
0230
0231 #endif