File indexing completed on 2025-01-19 09:47:46
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_SPIRIT_QI_OPERATOR_OPTIONAL_HPP
0009 #define BOOST_SPIRIT_QI_OPERATOR_OPTIONAL_HPP
0010
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014
0015 #include <boost/spirit/home/support/unused.hpp>
0016 #include <boost/spirit/home/qi/detail/attributes.hpp>
0017 #include <boost/spirit/home/support/has_semantic_action.hpp>
0018 #include <boost/spirit/home/support/handles_container.hpp>
0019 #include <boost/spirit/home/support/info.hpp>
0020 #include <boost/spirit/home/support/container.hpp>
0021 #include <boost/spirit/home/qi/parser.hpp>
0022 #include <boost/spirit/home/qi/meta_compiler.hpp>
0023 #include <boost/spirit/home/qi/detail/assign_to.hpp>
0024 #include <boost/optional.hpp>
0025 #include <boost/proto/operators.hpp>
0026 #include <boost/proto/tags.hpp>
0027 #include <vector>
0028
0029 namespace boost { namespace spirit
0030 {
0031
0032
0033
0034 template <>
0035 struct use_operator<qi::domain, proto::tag::negate>
0036 : mpl::true_ {};
0037 }}
0038
0039 namespace boost { namespace spirit { namespace qi
0040 {
0041 template <typename Subject>
0042 struct optional : unary_parser<optional<Subject> >
0043 {
0044 typedef Subject subject_type;
0045
0046 template <typename Context, typename Iterator>
0047 struct attribute
0048 {
0049
0050
0051
0052 typedef typename
0053 traits::build_optional<
0054 typename traits::
0055 attribute_of<Subject, Context, Iterator>::type
0056 >::type
0057 type;
0058 };
0059
0060 optional(Subject const& subject_)
0061 : subject(subject_) {}
0062
0063 template <typename Iterator, typename Context
0064 , typename Skipper, typename Attribute>
0065 bool parse_impl(Iterator& first, Iterator const& last
0066 , Context& context, Skipper const& skipper
0067 , Attribute& attr_, mpl::false_) const
0068 {
0069
0070 typename spirit::result_of::optional_value<Attribute>::type val =
0071 typename spirit::result_of::optional_value<Attribute>::type();
0072
0073 if (subject.parse(first, last, context, skipper, val))
0074 {
0075
0076 spirit::traits::assign_to(val, attr_);
0077 }
0078 return true;
0079 }
0080
0081 template <typename Iterator, typename Context
0082 , typename Skipper, typename Attribute>
0083 bool parse_impl(Iterator& first, Iterator const& last
0084 , Context& context, Skipper const& skipper
0085 , Attribute& attr_, mpl::true_) const
0086 {
0087 subject.parse(first, last, context, skipper, attr_);
0088 return true;
0089 }
0090
0091 template <typename Iterator, typename Context
0092 , typename Skipper, typename Attribute>
0093 bool parse(Iterator& first, Iterator const& last
0094 , Context& context, Skipper const& skipper
0095 , Attribute& attr_) const
0096 {
0097 typedef typename spirit::result_of::optional_value<Attribute>::type
0098 attribute_type;
0099
0100 return parse_impl(first, last, context, skipper, attr_
0101 , traits::is_container<attribute_type>());
0102 }
0103
0104 template <typename Context>
0105 info what(Context& context) const
0106 {
0107 return info("optional", subject.what(context));
0108 }
0109
0110 Subject subject;
0111 };
0112
0113
0114
0115
0116 template <typename Elements, typename Modifiers>
0117 struct make_composite<proto::tag::negate, Elements, Modifiers>
0118 : make_unary_composite<Elements, optional>
0119 {};
0120 }}}
0121
0122 namespace boost { namespace spirit { namespace traits
0123 {
0124
0125 template <typename Subject>
0126 struct has_semantic_action<qi::optional<Subject> >
0127 : unary_has_semantic_action<Subject> {};
0128
0129
0130 template <typename Subject, typename Attribute, typename Context
0131 , typename Iterator>
0132 struct handles_container<qi::optional<Subject>, Attribute
0133 , Context, Iterator>
0134 : mpl::true_ {};
0135 }}}
0136
0137 #endif