Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:13

0001 // Copyright Kevlin Henney, 2000-2005.
0002 // Copyright Alexander Nasonov, 2006-2010.
0003 // Copyright Antony Polukhin, 2011-2023.
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // what:  lexical_cast custom keyword cast
0010 // who:   contributed by Kevlin Henney,
0011 //        enhanced with contributions from Terje Slettebo,
0012 //        with additional fixes and suggestions from Gennaro Prota,
0013 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
0014 //        Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
0015 //        Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
0016 // when:  November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
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         /* Returns true and sets the correct value if found NaN or Inf. */
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; // == sizeof("infinity") - 1
0061 
0062             /* Parsing +/- */
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                     /* It is 'nan(...)' or some bad input*/
0073 
0074                     if (end - begin < 2) return false; // bad input
0075                     -- end;
0076                     if (*begin != opening_brace || *end != closing_brace) return false; // bad input
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                 ( /* 'INF' or 'inf' */
0084                   end - begin == 3      // 3 == sizeof('inf') - 1
0085                   && lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
0086                 )
0087                 ||
0088                 ( /* 'INFINITY' or 'infinity' */
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         bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value
0104                          , const CharT* lc_nan
0105                          , const CharT* lc_infinity) noexcept
0106         {
0107             const CharT minus = lcast_char_constants<CharT>::minus;
0108             if (boost::core::isnan(value)) {
0109                 if (boost::core::signbit(value)) {
0110                     *begin = minus;
0111                     ++ begin;
0112                 }
0113 
0114                 std::memcpy(begin, lc_nan, 3 * sizeof(CharT));
0115                 end = begin + 3;
0116                 return true;
0117             } else if (boost::core::isinf(value)) {
0118                 if (boost::core::signbit(value)) {
0119                     *begin = minus;
0120                     ++ begin;
0121                 }
0122 
0123                 std::memcpy(begin, lc_infinity, 3 * sizeof(CharT));
0124                 end = begin + 3;
0125                 return true;
0126             }
0127 
0128             return false;
0129         }
0130 
0131 
0132 #ifndef BOOST_LCAST_NO_WCHAR_T
0133         template <class T>
0134         bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) noexcept {
0135             return parse_inf_nan_impl(begin, end, value
0136                                , L"NAN", L"nan"
0137                                , L"INFINITY", L"infinity"
0138                                , L'(', L')');
0139         }
0140 
0141         template <class T>
0142         bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) noexcept {
0143             return put_inf_nan_impl(begin, end, value, L"nan", L"infinity");
0144         }
0145 
0146 #endif
0147 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0148         template <class T>
0149         bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) noexcept {
0150             return parse_inf_nan_impl(begin, end, value
0151                                , u"NAN", u"nan"
0152                                , u"INFINITY", u"infinity"
0153                                , u'(', u')');
0154         }
0155 
0156         template <class T>
0157         bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) noexcept {
0158             return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
0159         }
0160 #endif
0161 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0162         template <class T>
0163         bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) noexcept {
0164             return parse_inf_nan_impl(begin, end, value
0165                                , U"NAN", U"nan"
0166                                , U"INFINITY", U"infinity"
0167                                , U'(', U')');
0168         }
0169 
0170         template <class T>
0171         bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) noexcept {
0172             return put_inf_nan_impl(begin, end, value, U"nan", U"infinity");
0173         }
0174 #endif
0175 
0176         template <class CharT, class T>
0177         bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) noexcept {
0178             return parse_inf_nan_impl(begin, end, value
0179                                , "NAN", "nan"
0180                                , "INFINITY", "infinity"
0181                                , '(', ')');
0182         }
0183 
0184         template <class CharT, class T>
0185         bool put_inf_nan(CharT* begin, CharT*& end, const T& value) noexcept {
0186             return put_inf_nan_impl(begin, end, value, "nan", "infinity");
0187         }
0188     }
0189 } // namespace boost
0190 
0191 #undef BOOST_LCAST_NO_WCHAR_T
0192 
0193 #endif // BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
0194