1 /*============================================================================= 2 Copyright (c) 2001-2011 Hartmut Kaiser 3 Copyright (c) 2001-2011 Joel de Guzman 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_ATTR_JUL_23_2008_0956AM) 9 #define BOOST_SPIRIT_ATTR_JUL_23_2008_0956AM 10 11 #if defined(_MSC_VER) 12 #pragma once 13 #endif 14 15 #include <boost/mpl/bool.hpp> 16 #include <boost/spirit/home/qi/domain.hpp> 17 #include <boost/spirit/home/qi/parser.hpp> 18 #include <boost/spirit/home/qi/detail/assign_to.hpp> 19 #include <boost/spirit/home/qi/meta_compiler.hpp> 20 #include <boost/spirit/home/support/common_terminals.hpp> 21 #include <boost/spirit/home/support/handles_container.hpp> 22 #include <boost/type_traits/add_reference.hpp> 23 #include <boost/type_traits/add_const.hpp> 24 #include <boost/type_traits/remove_const.hpp> 25 26 namespace boost { namespace spirit 27 { 28 /////////////////////////////////////////////////////////////////////////// 29 // Enablers 30 /////////////////////////////////////////////////////////////////////////// 31 template <typename A0> // enables attr() 32 struct use_terminal< 33 qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > > 34 : mpl::true_ {}; 35 36 template <> // enables *lazy* attr() 37 struct use_lazy_terminal<qi::domain, tag::attr, 1> 38 : mpl::true_ {}; 39 40 }} 41 42 namespace boost { namespace spirit { namespace qi 43 { 44 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 45 using spirit::attr; 46 #endif 47 using spirit::attr_type; 48 49 template <typename Value> 50 struct attr_parser : primitive_parser<attr_parser<Value> > 51 { 52 template <typename Context, typename Iterator> 53 struct attribute : remove_const<Value> {}; 54 attr_parserboost::spirit::qi::attr_parser55 attr_parser(typename add_reference<Value>::type value) 56 : value_(value) {} 57 58 template <typename Iterator, typename Context 59 , typename Skipper, typename Attribute> parseboost::spirit::qi::attr_parser60 bool parse(Iterator& /*first*/, Iterator const& /*last*/ 61 , Context& /*context*/, Skipper const& /*skipper*/ 62 , Attribute& attr_) const 63 { 64 spirit::traits::assign_to(value_, attr_); 65 return true; // never consume any input, succeed always 66 } 67 68 template <typename Context> whatboost::spirit::qi::attr_parser69 info what(Context& /*context*/) const 70 { 71 return info("attr"); 72 } 73 74 Value value_; 75 76 // silence MSVC warning C4512: assignment operator could not be generated 77 BOOST_DELETED_FUNCTION(attr_parser& operator= (attr_parser const&)) 78 }; 79 80 /////////////////////////////////////////////////////////////////////////// 81 // Parser generators: make_xxx function (objects) 82 /////////////////////////////////////////////////////////////////////////// 83 template <typename Modifiers, typename A0> 84 struct make_primitive< 85 terminal_ex<tag::attr, fusion::vector1<A0> > 86 , Modifiers> 87 { 88 typedef typename add_const<A0>::type const_value; 89 typedef attr_parser<const_value> result_type; 90 91 template <typename Terminal> operator ()boost::spirit::qi::make_primitive92 result_type operator()(Terminal const& term, unused_type) const 93 { 94 return result_type(fusion::at_c<0>(term.args)); 95 } 96 }; 97 }}} 98 99 namespace boost { namespace spirit { namespace traits 100 { 101 /////////////////////////////////////////////////////////////////////////// 102 template <typename T, typename Attr, typename Context, typename Iterator> 103 struct handles_container<qi::attr_parser<T>, Attr, Context, Iterator> 104 : traits::is_container<Attr> {}; 105 }}} 106 107 #endif 108 109 110