attr.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Hartmut Kaiser
  3. Copyright (c) 2001-2011 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #if !defined(BOOST_SPIRIT_ATTR_JUL_23_2008_0956AM)
  8. #define BOOST_SPIRIT_ATTR_JUL_23_2008_0956AM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/mpl/bool.hpp>
  13. #include <boost/spirit/home/qi/domain.hpp>
  14. #include <boost/spirit/home/qi/parser.hpp>
  15. #include <boost/spirit/home/qi/detail/assign_to.hpp>
  16. #include <boost/spirit/home/qi/meta_compiler.hpp>
  17. #include <boost/spirit/home/support/common_terminals.hpp>
  18. #include <boost/spirit/home/support/handles_container.hpp>
  19. #include <boost/type_traits/add_reference.hpp>
  20. #include <boost/type_traits/add_const.hpp>
  21. #include <boost/type_traits/remove_const.hpp>
  22. namespace boost { namespace spirit
  23. {
  24. ///////////////////////////////////////////////////////////////////////////
  25. // Enablers
  26. ///////////////////////////////////////////////////////////////////////////
  27. template <typename A0> // enables attr()
  28. struct use_terminal<
  29. qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > >
  30. : mpl::true_ {};
  31. template <> // enables *lazy* attr()
  32. struct use_lazy_terminal<qi::domain, tag::attr, 1>
  33. : mpl::true_ {};
  34. }}
  35. namespace boost { namespace spirit { namespace qi
  36. {
  37. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  38. using spirit::attr;
  39. #endif
  40. using spirit::attr_type;
  41. template <typename Value>
  42. struct attr_parser : primitive_parser<attr_parser<Value> >
  43. {
  44. template <typename Context, typename Iterator>
  45. struct attribute : remove_const<Value> {};
  46. attr_parser(typename add_reference<Value>::type value)
  47. : value_(value) {}
  48. template <typename Iterator, typename Context
  49. , typename Skipper, typename Attribute>
  50. bool parse(Iterator& /*first*/, Iterator const& /*last*/
  51. , Context& /*context*/, Skipper const& /*skipper*/
  52. , Attribute& attr_) const
  53. {
  54. spirit::traits::assign_to(value_, attr_);
  55. return true; // never consume any input, succeed always
  56. }
  57. template <typename Context>
  58. info what(Context& /*context*/) const
  59. {
  60. return info("attr");
  61. }
  62. Value value_;
  63. // silence MSVC warning C4512: assignment operator could not be generated
  64. BOOST_DELETED_FUNCTION(attr_parser& operator= (attr_parser const&))
  65. };
  66. ///////////////////////////////////////////////////////////////////////////
  67. // Parser generators: make_xxx function (objects)
  68. ///////////////////////////////////////////////////////////////////////////
  69. template <typename Modifiers, typename A0>
  70. struct make_primitive<
  71. terminal_ex<tag::attr, fusion::vector1<A0> >
  72. , Modifiers>
  73. {
  74. typedef typename add_const<A0>::type const_value;
  75. typedef attr_parser<const_value> result_type;
  76. template <typename Terminal>
  77. result_type operator()(Terminal const& term, unused_type) const
  78. {
  79. return result_type(fusion::at_c<0>(term.args));
  80. }
  81. };
  82. }}}
  83. namespace boost { namespace spirit { namespace traits
  84. {
  85. ///////////////////////////////////////////////////////////////////////////
  86. template <typename T, typename Attr, typename Context, typename Iterator>
  87. struct handles_container<qi::attr_parser<T>, Attr, Context, Iterator>
  88. : traits::is_container<Attr> {};
  89. }}}
  90. #endif