real_policies.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. //
  68. // - a number to parse does not start with a digit (after having
  69. // successfully parsed an optional sign)
  70. //
  71. // or
  72. //
  73. // - after a floating point number of the value 1 (having no
  74. // exponential part and a fractional part value of 0) has been
  75. // parsed.
  76. //
  77. // The first call allows to recognize representations of NaN or Inf
  78. // starting with a non-digit character (such as NaN, Inf, QNaN etc.).
  79. //
  80. // The second call allows to recognize representation formats starting
  81. // with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
  82. //
  83. // The functions should return true if a Nan or Inf has been found. In
  84. // this case the attr should be set to the matched value (NaN or
  85. // Inf). The optional sign will be automatically applied afterwards.
  86. //
  87. // The default implementation below recognizes representations of NaN
  88. // and Inf as mandated by the C99 Standard and as proposed for
  89. // inclusion into the C++0x Standard: nan, nan(...), inf and infinity
  90. // (the matching is performed case-insensitively).
  91. ///////////////////////////////////////////////////////////////////////
  92. template <typename Iterator, typename Attribute>
  93. static bool
  94. parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
  95. {
  96. if (first == last)
  97. return false; // end of input reached
  98. if (*first != 'n' && *first != 'N')
  99. return false; // not "nan"
  100. // nan[(...)] ?
  101. if (detail::string_parse("nan", "NAN", first, last, unused))
  102. {
  103. if (first != last && *first == '(')
  104. {
  105. // skip trailing (...) part
  106. Iterator i = first;
  107. while (++i != last && *i != ')')
  108. ;
  109. if (i == last)
  110. return false; // no trailing ')' found, give up
  111. first = ++i;
  112. }
  113. attr_ = std::numeric_limits<T>::quiet_NaN();
  114. return true;
  115. }
  116. return false;
  117. }
  118. template <typename Iterator, typename Attribute>
  119. static bool
  120. parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
  121. {
  122. if (first == last)
  123. return false; // end of input reached
  124. if (*first != 'i' && *first != 'I')
  125. return false; // not "inf"
  126. // inf or infinity ?
  127. if (detail::string_parse("inf", "INF", first, last, unused))
  128. {
  129. // skip allowed 'inity' part of infinity
  130. detail::string_parse("inity", "INITY", first, last, unused);
  131. attr_ = std::numeric_limits<T>::infinity();
  132. return true;
  133. }
  134. return false;
  135. }
  136. };
  137. ///////////////////////////////////////////////////////////////////////////
  138. // Default (signed) real number policies
  139. ///////////////////////////////////////////////////////////////////////////
  140. template <typename T>
  141. struct real_policies : ureal_policies<T>
  142. {
  143. template <typename Iterator>
  144. static bool
  145. parse_sign(Iterator& first, Iterator const& last)
  146. {
  147. return extract_sign(first, last);
  148. }
  149. };
  150. template <typename T>
  151. struct strict_ureal_policies : ureal_policies<T>
  152. {
  153. static bool const expect_dot = true;
  154. };
  155. template <typename T>
  156. struct strict_real_policies : real_policies<T>
  157. {
  158. static bool const expect_dot = true;
  159. };
  160. }}}
  161. #endif