as.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Copyright (c) 2010 Bryce Lelbach
  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. #ifndef BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP
  9. #define BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/spirit/home/qi/meta_compiler.hpp>
  14. #include <boost/spirit/home/qi/skip_over.hpp>
  15. #include <boost/spirit/home/qi/parser.hpp>
  16. #include <boost/spirit/home/qi/detail/assign_to.hpp>
  17. #include <boost/spirit/home/support/unused.hpp>
  18. #include <boost/spirit/home/support/info.hpp>
  19. #include <boost/spirit/home/support/common_terminals.hpp>
  20. #include <boost/spirit/home/support/unused.hpp>
  21. #include <boost/spirit/home/support/has_semantic_action.hpp>
  22. #include <boost/spirit/home/support/handles_container.hpp>
  23. #include <boost/spirit/home/support/assert_msg.hpp>
  24. #include <boost/spirit/home/support/container.hpp>
  25. namespace boost { namespace spirit { namespace qi
  26. {
  27. template <typename T>
  28. struct as
  29. : stateful_tag_type<T, tag::as>
  30. {
  31. //~ BOOST_SPIRIT_ASSERT_MSG(
  32. //~ (traits::is_container<T>::type::value),
  33. //~ error_type_must_be_a_container,
  34. //~ (T));
  35. };
  36. }}}
  37. namespace boost { namespace spirit
  38. {
  39. ///////////////////////////////////////////////////////////////////////////
  40. // Enablers
  41. ///////////////////////////////////////////////////////////////////////////
  42. // enables as_string[...]
  43. template <>
  44. struct use_directive<qi::domain, tag::as_string>
  45. : mpl::true_ {};
  46. // enables as_wstring[...]
  47. template <>
  48. struct use_directive<qi::domain, tag::as_wstring>
  49. : mpl::true_ {};
  50. // enables as<T>[...]
  51. template <typename T>
  52. struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
  53. : mpl::true_
  54. {};
  55. }}
  56. namespace boost { namespace spirit { namespace qi
  57. {
  58. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  59. using spirit::as_string;
  60. using spirit::as_wstring;
  61. #endif
  62. using spirit::as_string_type;
  63. using spirit::as_wstring_type;
  64. template <typename Subject, typename T>
  65. struct as_directive : unary_parser<as_directive<Subject, T> >
  66. {
  67. typedef Subject subject_type;
  68. as_directive(Subject const& subject_)
  69. : subject(subject_) {}
  70. template <typename Context, typename Iterator>
  71. struct attribute
  72. {
  73. typedef T type;
  74. };
  75. template <typename Iterator, typename Context
  76. , typename Skipper, typename Attribute>
  77. bool parse(Iterator& first, Iterator const& last
  78. , Context& context, Skipper const& skipper, Attribute& attr_) const
  79. {
  80. Iterator i = first;
  81. T as_attr;
  82. if (subject.parse(i, last, context, skipper, as_attr))
  83. {
  84. spirit::traits::assign_to(as_attr, attr_);
  85. first = i;
  86. return true;
  87. }
  88. return false;
  89. }
  90. template <typename Iterator, typename Context, typename Skipper>
  91. bool parse(Iterator& first, Iterator const& last
  92. , Context& context, Skipper const& skipper, T& attr_) const
  93. {
  94. Iterator i = first;
  95. if (subject.parse(i, last, context, skipper, attr_))
  96. {
  97. first = i;
  98. return true;
  99. }
  100. return false;
  101. }
  102. template <typename Context>
  103. info what(Context& context) const
  104. {
  105. return info("as", subject.what(context));
  106. }
  107. Subject subject;
  108. };
  109. ///////////////////////////////////////////////////////////////////////////
  110. // Parser generators: make_xxx function (objects)
  111. ///////////////////////////////////////////////////////////////////////////
  112. template <typename Subject, typename Modifiers>
  113. struct make_directive<tag::as_string, Subject, Modifiers>
  114. {
  115. typedef as_directive<Subject, std::string> result_type;
  116. result_type operator()(unused_type, Subject const& subject
  117. , unused_type) const
  118. {
  119. return result_type(subject);
  120. }
  121. };
  122. template <typename Subject, typename Modifiers>
  123. struct make_directive<tag::as_wstring, Subject, Modifiers>
  124. {
  125. typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
  126. result_type operator()(unused_type, Subject const& subject
  127. , unused_type) const
  128. {
  129. return result_type(subject);
  130. }
  131. };
  132. template <typename T, typename Subject, typename Modifiers>
  133. struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
  134. {
  135. typedef as_directive<Subject, T> result_type;
  136. result_type operator()(unused_type, Subject const& subject
  137. , unused_type) const
  138. {
  139. return result_type(subject);
  140. }
  141. };
  142. }}}
  143. namespace boost { namespace spirit { namespace traits
  144. {
  145. ///////////////////////////////////////////////////////////////////////////
  146. template <typename Subject, typename T>
  147. struct has_semantic_action<qi::as_directive<Subject, T> >
  148. : unary_has_semantic_action<Subject> {};
  149. ///////////////////////////////////////////////////////////////////////////
  150. template <typename Subject, typename T, typename Attribute
  151. , typename Context, typename Iterator>
  152. struct handles_container<qi::as_directive<Subject, T>, Attribute
  153. , Context, Iterator>
  154. : mpl::false_ {};
  155. }}}
  156. #endif