File indexing completed on 2025-07-02 08:16:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
0019 #define BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
0020
0021 #include <boost/config.hpp>
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 # pragma once
0024 #endif
0025
0026 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
0027 #define BOOST_LCAST_NO_WCHAR_T
0028 #endif
0029
0030 #include <boost/limits.hpp>
0031 #include <boost/detail/workaround.hpp>
0032 #include <boost/core/cmath.hpp>
0033 #include <cstddef>
0034 #include <cstring>
0035
0036 #include <boost/lexical_cast/detail/lcast_char_constants.hpp>
0037
0038 namespace boost {
0039 namespace detail
0040 {
0041 template <class CharT>
0042 bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) noexcept {
0043 for( unsigned int i=0; i < len; ++i ) {
0044 if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
0045 }
0046
0047 return true;
0048 }
0049
0050
0051 template <class CharT, class T>
0052 inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
0053 , const CharT* lc_NAN, const CharT* lc_nan
0054 , const CharT* lc_INFINITY, const CharT* lc_infinity
0055 , const CharT opening_brace, const CharT closing_brace) noexcept
0056 {
0057 if (begin == end) return false;
0058 const CharT minus = lcast_char_constants<CharT>::minus;
0059 const CharT plus = lcast_char_constants<CharT>::plus;
0060 const int inifinity_size = 8;
0061
0062
0063 bool const has_minus = (*begin == minus);
0064 if (has_minus || *begin == plus) {
0065 ++ begin;
0066 }
0067
0068 if (end - begin < 3) return false;
0069 if (lc_iequal(begin, lc_nan, lc_NAN, 3)) {
0070 begin += 3;
0071 if (end != begin) {
0072
0073
0074 if (end - begin < 2) return false;
0075 -- end;
0076 if (*begin != opening_brace || *end != closing_brace) return false;
0077 }
0078
0079 if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
0080 else value = boost::core::copysign(std::numeric_limits<T>::quiet_NaN(), static_cast<T>(-1));
0081 return true;
0082 } else if (
0083 (
0084 end - begin == 3
0085 && lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
0086 )
0087 ||
0088 (
0089 end - begin == inifinity_size
0090 && lc_iequal(begin, lc_infinity, lc_INFINITY, inifinity_size)
0091 )
0092 )
0093 {
0094 if( !has_minus ) value = std::numeric_limits<T>::infinity();
0095 else value = -std::numeric_limits<T>::infinity();
0096 return true;
0097 }
0098
0099 return false;
0100 }
0101
0102 template <class CharT, class T>
0103 const CharT* get_inf_nan_impl(T value
0104 , const CharT* lc_nan
0105 , const CharT* lc_minus_nan
0106 , const CharT* lc_infinity
0107 , const CharT* lc_minus_infinity) noexcept
0108 {
0109 if (boost::core::isnan(value)) {
0110 if (boost::core::signbit(value)) {
0111 return lc_minus_nan;
0112 }
0113 return lc_nan;
0114 } else if (boost::core::isinf(value)) {
0115 if (boost::core::signbit(value)) {
0116 return lc_minus_infinity;
0117 }
0118 return lc_infinity;
0119 }
0120
0121 return nullptr;
0122 }
0123
0124
0125 #ifndef BOOST_LCAST_NO_WCHAR_T
0126 template <class T>
0127 bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) noexcept {
0128 return parse_inf_nan_impl(begin, end, value
0129 , L"NAN", L"nan"
0130 , L"INFINITY", L"infinity"
0131 , L'(', L')');
0132 }
0133
0134 template <class T>
0135 const wchar_t* get_inf_nan(T value, wchar_t) noexcept {
0136 return detail::get_inf_nan_impl(value, L"nan", L"-nan", L"inf", L"-inf");
0137 }
0138
0139 #endif
0140 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0141 template <class T>
0142 bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) noexcept {
0143 return parse_inf_nan_impl(begin, end, value
0144 , u"NAN", u"nan"
0145 , u"INFINITY", u"infinity"
0146 , u'(', u')');
0147 }
0148
0149 template <class T>
0150 const char16_t* get_inf_nan(T value, char16_t) noexcept {
0151 return detail::get_inf_nan_impl(value, u"nan", u"-nan", u"inf", u"-inf");
0152 }
0153 #endif
0154 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0155 template <class T>
0156 bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) noexcept {
0157 return parse_inf_nan_impl(begin, end, value
0158 , U"NAN", U"nan"
0159 , U"INFINITY", U"infinity"
0160 , U'(', U')');
0161 }
0162
0163 template <class T>
0164 const char32_t* get_inf_nan(T value, char32_t) noexcept {
0165 return detail::get_inf_nan_impl(value, U"nan", U"-nan", U"inf", U"-inf");
0166 }
0167 #endif
0168
0169 template <class CharT, class T>
0170 bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) noexcept {
0171 return parse_inf_nan_impl(begin, end, value
0172 , "NAN", "nan"
0173 , "INFINITY", "infinity"
0174 , '(', ')');
0175 }
0176
0177 template <class T>
0178 const char* get_inf_nan(T value, char) noexcept {
0179 return detail::get_inf_nan_impl(value, "nan", "-nan", "inf", "-inf");
0180 }
0181 }
0182 }
0183
0184 #undef BOOST_LCAST_NO_WCHAR_T
0185
0186 #endif
0187