• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3     Copyright (c) 2001-2011 Hartmut Kaiser
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_X3_OPTIONAL_MARCH_23_2007_1117PM)
9 #define BOOST_SPIRIT_X3_OPTIONAL_MARCH_23_2007_1117PM
10 
11 #include <boost/spirit/home/x3/core/proxy.hpp>
12 #include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
13 #include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
14 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
15 #include <boost/spirit/home/x3/support/traits/optional_traits.hpp>
16 #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
17 
18 namespace boost { namespace spirit { namespace x3
19 {
20     template <typename Subject>
21     struct optional : proxy<Subject, optional<Subject>>
22     {
23         typedef proxy<Subject, optional<Subject>> base_type;
24         static bool const handles_container = true;
25 
optionalboost::spirit::x3::optional26         constexpr optional(Subject const& subject)
27           : base_type(subject) {}
28 
29         using base_type::parse_subject;
30 
31         // Attribute is a container
32         template <typename Iterator, typename Context
33           , typename RContext, typename Attribute>
parse_subjectboost::spirit::x3::optional34         bool parse_subject(Iterator& first, Iterator const& last
35           , Context const& context, RContext& rcontext, Attribute& attr
36           , traits::container_attribute) const
37         {
38             detail::parse_into_container(
39                 this->subject, first, last, context, rcontext, attr);
40             return true;
41         }
42 
43         // Attribute is an optional
44         template <typename Iterator, typename Context
45           , typename RContext, typename Attribute>
parse_subjectboost::spirit::x3::optional46         bool parse_subject(Iterator& first, Iterator const& last
47           , Context const& context, RContext& rcontext, Attribute& attr
48           , traits::optional_attribute) const
49         {
50             typedef typename
51                 x3::traits::optional_value<Attribute>::type
52             value_type;
53 
54             // create a local value
55             value_type val{};
56 
57             if (this->subject.parse(first, last, context, rcontext, val))
58             {
59                 // assign the parsed value into our attribute
60                 x3::traits::move_to(val, attr);
61             }
62             return true;
63         }
64     };
65 
66     template <typename Subject>
67     constexpr optional<typename extension::as_parser<Subject>::value_type>
operator -(Subject const & subject)68     operator-(Subject const& subject)
69     {
70         return { as_parser(subject) };
71     }
72 }}}
73 
74 namespace boost { namespace spirit { namespace x3 { namespace traits
75 {
76     template <typename Subject, typename Context>
77     struct attribute_of<x3::optional<Subject>, Context>
78         : build_optional<
79             typename attribute_of<Subject, Context>::type> {};
80 }}}}
81 
82 #endif
83