1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
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(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
9 #define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
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>
18 namespace boost { namespace spirit { namespace x3
20 template <typename Subject>
21 struct optional : proxy<Subject, optional<Subject>>
23 typedef proxy<Subject, optional<Subject>> base_type;
24 static bool const handles_container = true;
26 optional(Subject const& subject)
27 : base_type(subject) {}
29 using base_type::parse_subject;
31 // Attribute is a container
32 template <typename Iterator, typename Context
33 , typename RContext, typename Attribute>
34 bool parse_subject(Iterator& first, Iterator const& last
35 , Context const& context, RContext& rcontext, Attribute& attr
36 , traits::container_attribute) const
38 detail::parse_into_container(
39 this->subject, first, last, context, rcontext, attr);
43 // Attribute is an optional
44 template <typename Iterator, typename Context
45 , typename RContext, typename Attribute>
46 bool parse_subject(Iterator& first, Iterator const& last
47 , Context const& context, RContext& rcontext, Attribute& attr
48 , traits::optional_attribute) const
51 x3::traits::optional_value<Attribute>::type
54 // create a local value
55 value_type val = value_type();
57 if (this->subject.parse(first, last, context, rcontext, val))
59 // assign the parsed value into our attribute
60 x3::traits::move_to(val, attr);
66 template <typename Subject>
67 inline optional<typename extension::as_parser<Subject>::value_type>
68 operator-(Subject const& subject)
70 return { as_parser(subject) };
74 namespace boost { namespace spirit { namespace x3 { namespace traits
76 template <typename Subject, typename Context>
77 struct attribute_of<x3::optional<Subject>, Context>
79 typename attribute_of<Subject, Context>::type> {};