Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:46

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // Enablers
0033     ///////////////////////////////////////////////////////////////////////////
0034     template <>
0035     struct use_operator<qi::domain, proto::tag::negate> // enables -p
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             // Build a boost::optional from the subject's attribute. Note
0050             // that boost::optional may return unused_type if the
0051             // subject's attribute is an unused_type.
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             // create a local value if Attribute is not unused_type
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                 // assign the parsed value into our attribute
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     // Parser generators: make_xxx function (objects)
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