real_policies.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  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_X3_REAL_POLICIES_APRIL_17_2006_1158PM)
  8. #define BOOST_SPIRIT_X3_REAL_POLICIES_APRIL_17_2006_1158PM
  9. #include <boost/spirit/home/x3/string/detail/string_parse.hpp>
  10. #include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
  11. namespace boost { namespace spirit { namespace x3
  12. {
  13. ///////////////////////////////////////////////////////////////////////////
  14. // Default (unsigned) real number policies
  15. ///////////////////////////////////////////////////////////////////////////
  16. template <typename T>
  17. struct ureal_policies
  18. {
  19. // trailing dot policy suggested by Gustavo Guerra
  20. static bool const allow_leading_dot = true;
  21. static bool const allow_trailing_dot = true;
  22. static bool const expect_dot = false;
  23. template <typename Iterator>
  24. static bool
  25. parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
  26. {
  27. return false;
  28. }
  29. template <typename Iterator, typename Attribute>
  30. static bool
  31. parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
  32. {
  33. return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
  34. }
  35. template <typename Iterator>
  36. static bool
  37. parse_dot(Iterator& first, Iterator const& last)
  38. {
  39. if (first == last || *first != '.')
  40. return false;
  41. ++first;
  42. return true;
  43. }
  44. template <typename Iterator, typename Attribute>
  45. static bool
  46. parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
  47. {
  48. return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
  49. }
  50. template <typename Iterator>
  51. static bool
  52. parse_exp(Iterator& first, Iterator const& last)
  53. {
  54. if (first == last || (*first != 'e' && *first != 'E'))
  55. return false;
  56. ++first;
  57. return true;
  58. }
  59. template <typename Iterator>
  60. static bool
  61. parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
  62. {
  63. return extract_int<int, 10, 1, -1>::call(first, last, attr_);
  64. }
  65. ///////////////////////////////////////////////////////////////////////
  66. // The parse_nan() and parse_inf() functions get called whenever
  67. // a number to parse does not start with a digit (after having
  68. // successfully parsed an optional sign).
  69. //
  70. // The functions should return true if a Nan or Inf has been found. In
  71. // this case the attr should be set to the matched value (NaN or
  72. // Inf). The optional sign will be automatically applied afterwards.
  73. //
  74. // The default implementation below recognizes representations of NaN
  75. // and Inf as mandated by the C99 Standard and as proposed for
  76. // inclusion into the C++0x Standard: nan, nan(...), inf and infinity
  77. // (the matching is performed case-insensitively).
  78. ///////////////////////////////////////////////////////////////////////
  79. template <typename Iterator, typename Attribute>
  80. static bool
  81. parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
  82. {
  83. if (first == last)
  84. return false; // end of input reached
  85. if (*first != 'n' && *first != 'N')
  86. return false; // not "nan"
  87. // nan[(...)] ?
  88. if (detail::string_parse("nan", "NAN", first, last, unused))
  89. {
  90. if (first != last && *first == '(')
  91. {
  92. // skip trailing (...) part
  93. Iterator i = first;
  94. while (++i != last && *i != ')')
  95. ;
  96. if (i == last)
  97. return false; // no trailing ')' found, give up
  98. first = ++i;
  99. }
  100. attr_ = std::numeric_limits<T>::quiet_NaN();
  101. return true;
  102. }
  103. return false;
  104. }
  105. template <typename Iterator, typename Attribute>
  106. static bool
  107. parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
  108. {
  109. if (first == last)
  110. return false; // end of input reached
  111. if (*first != 'i' && *first != 'I')
  112. return false; // not "inf"
  113. // inf or infinity ?
  114. if (detail::string_parse("inf", "INF", first, last, unused))
  115. {
  116. // skip allowed 'inity' part of infinity
  117. detail::string_parse("inity", "INITY", first, last, unused);
  118. attr_ = std::numeric_limits<T>::infinity();
  119. return true;
  120. }
  121. return false;
  122. }
  123. };
  124. ///////////////////////////////////////////////////////////////////////////
  125. // Default (signed) real number policies
  126. ///////////////////////////////////////////////////////////////////////////
  127. template <typename T>
  128. struct real_policies : ureal_policies<T>
  129. {
  130. template <typename Iterator>
  131. static bool
  132. parse_sign(Iterator& first, Iterator const& last)
  133. {
  134. return extract_sign(first, last);
  135. }
  136. };
  137. template <typename T>
  138. struct strict_ureal_policies : ureal_policies<T>
  139. {
  140. static bool const expect_dot = true;
  141. };
  142. template <typename T>
  143. struct strict_real_policies : real_policies<T>
  144. {
  145. static bool const expect_dot = true;
  146. };
  147. }}}
  148. #endif