as.hpp 5.7 KB

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