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