scanner_value_type_tests.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*=============================================================================
  2. Copyright (c) 2005 Jordan DeLong
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. // Some tests of parsing on value_t's that aren't char or wchar_t.
  9. //
  10. // Part of what this is testing is that BOOST_SPIRIT_DEBUG doesn't
  11. // break when the scanner::value_t is some sort of non-char.
  12. #define SPIRIT_DEBUG_NODE
  13. #include <boost/spirit/include/classic_core.hpp>
  14. #include <boost/static_assert.hpp>
  15. #include <boost/type_traits/is_same.hpp>
  16. #include <deque>
  17. #include <iostream>
  18. namespace sp = BOOST_SPIRIT_CLASSIC_NS;
  19. namespace {
  20. struct grammar : sp::grammar<grammar> {
  21. template<class Scanner>
  22. struct definition {
  23. definition(grammar const&)
  24. {
  25. foo
  26. = sp::alpha_p
  27. | sp::alnum_p
  28. | sp::cntrl_p
  29. | sp::print_p
  30. | sp::blank_p
  31. | sp::digit_p
  32. | sp::graph_p
  33. | sp::lower_p
  34. | sp::upper_p
  35. | sp::xdigit_p
  36. | sp::punct_p
  37. ;
  38. }
  39. sp::rule<Scanner> foo;
  40. sp::rule<Scanner> const&
  41. start() const
  42. {
  43. return foo;
  44. }
  45. };
  46. };
  47. struct non_pod {
  48. non_pod() : value('1') {}
  49. char value;
  50. bool operator==(non_pod const& o) const { return value == o.value; }
  51. };
  52. BOOST_ATTRIBUTE_UNUSED
  53. std::ostream&
  54. operator<<(std::ostream& out, non_pod const& x)
  55. {
  56. out << x.value;
  57. return out;
  58. }
  59. template<class T>
  60. struct convertable_non_pod : non_pod {
  61. operator T() { return value; }
  62. };
  63. struct nonpod_gram : sp::grammar<nonpod_gram> {
  64. template<class Scanner>
  65. struct definition {
  66. definition(nonpod_gram const&)
  67. {
  68. foo = sp::ch_p(typename Scanner::value_t());
  69. }
  70. sp::rule<Scanner> foo;
  71. sp::rule<Scanner> const&
  72. start() const
  73. {
  74. return foo;
  75. }
  76. };
  77. };
  78. template<class Grammar, class ValueType>
  79. void
  80. test_type()
  81. {
  82. typedef std::deque<ValueType> container;
  83. typedef typename container::iterator iterator;
  84. typedef sp::scanner<iterator> scanner;
  85. container blah;
  86. blah.push_back(typename container::value_type());
  87. blah.push_back(typename container::value_type());
  88. iterator first = blah.begin();
  89. iterator last = blah.end();
  90. scanner scan(first, last);
  91. // Make sure this actually tries what we think it tries.
  92. BOOST_STATIC_ASSERT((
  93. boost::is_same<typename scanner::value_t, ValueType>::value
  94. ));
  95. Grammar().parse(scan);
  96. }
  97. }
  98. int
  99. main()
  100. {
  101. // Make sure isfoo() style functions work for integral types.
  102. test_type<grammar, char>();
  103. test_type<grammar, unsigned char>();
  104. test_type<grammar, wchar_t>();
  105. test_type<grammar, int>();
  106. test_type<grammar, long>();
  107. test_type<grammar, short>();
  108. test_type<grammar, bool>();
  109. // Non-POD's should work with things like alpha_p as long as we
  110. // can turn them into a type that can do isalpha().
  111. test_type<grammar, convertable_non_pod<char> >();
  112. test_type<grammar, convertable_non_pod<wchar_t> >();
  113. test_type<grammar, convertable_non_pod<int> >();
  114. // BOOST_SPIRIT_DEBUG should work with grammars that parse
  115. // non-POD's even if they can't do things like isalpha().
  116. test_type<nonpod_gram, non_pod>();
  117. }