From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- src/others/irrlicht-1.8.1/include/fast_atof.h | 364 ++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/include/fast_atof.h (limited to 'src/others/irrlicht-1.8.1/include/fast_atof.h') diff --git a/src/others/irrlicht-1.8.1/include/fast_atof.h b/src/others/irrlicht-1.8.1/include/fast_atof.h new file mode 100644 index 0000000..7d4917a --- /dev/null +++ b/src/others/irrlicht-1.8.1/include/fast_atof.h @@ -0,0 +1,364 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __FAST_ATOF_H_INCLUDED__ +#define __FAST_ATOF_H_INCLUDED__ + +#include "irrMath.h" +#include "irrString.h" + +namespace irr +{ +namespace core +{ + //! Selection of characters which count as decimal point in fast_atof + // TODO: This should probably also be used in irr::core::string, but the float-to-string code + // used there has to be rewritten first. + IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS; + +// we write [17] here instead of [] to work around a swig bug +const float fast_atof_table[17] = { + 0.f, + 0.1f, + 0.01f, + 0.001f, + 0.0001f, + 0.00001f, + 0.000001f, + 0.0000001f, + 0.00000001f, + 0.000000001f, + 0.0000000001f, + 0.00000000001f, + 0.000000000001f, + 0.0000000000001f, + 0.00000000000001f, + 0.000000000000001f, + 0.0000000000000001f +}; + +//! Convert a simple string of base 10 digits into an unsigned 32 bit integer. +/** \param[in] in: The string of digits to convert. No leading chars are + allowed, only digits 0 to 9. Parsing stops at the first non-digit. + \param[out] out: (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul10(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + bool overflow=false; + u32 unsignedValue = 0; + while ( ( *in >= '0') && ( *in <= '9' )) + { + const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' ); + if (tmp (u32)INT_MAX) + { + if (negative) + return (s32)INT_MIN; + else + return (s32)INT_MAX; + } + else + { + if (negative) + return -((s32)unsignedValue); + else + return (s32)unsignedValue; + } +} + +//! Convert a hex-encoded character to an unsigned integer. +/** \param[in] in The digit to convert. Only digits 0 to 9 and chars A-F,a-f + will be considered. + \return The unsigned integer value of the digit. 0xffffffff if the input is + not hex +*/ +inline u32 ctoul16(char in) +{ + if (in >= '0' && in <= '9') + return in - '0'; + else if (in >= 'a' && in <= 'f') + return 10u + in - 'a'; + else if (in >= 'A' && in <= 'F') + return 10u + in - 'A'; + else + return 0xffffffff; +} + +//! Convert a simple string of base 16 digits into an unsigned 32 bit integer. +/** \param[in] in: The string of digits to convert. No leading chars are + allowed, only digits 0 to 9 and chars A-F,a-f are allowed. Parsing stops + at the first illegal char. + \param[out] out: (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul16(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + bool overflow=false; + u32 unsignedValue = 0; + while (true) + { + u32 tmp = 0; + if ((*in >= '0') && (*in <= '9')) + tmp = (unsignedValue << 4u) + (*in - '0'); + else if ((*in >= 'A') && (*in <= 'F')) + tmp = (unsignedValue << 4u) + (*in - 'A') + 10; + else if ((*in >= 'a') && (*in <= 'f')) + tmp = (unsignedValue << 4u) + (*in - 'a') + 10; + else + break; + if (tmp= '0') && (*in <= '7')) + tmp = (unsignedValue << 3u) + (*in - '0'); + else + break; + if (tmp= '0') && ( *in <= '9' ) ) + { + // If it looks like we're going to overflow, bail out + // now and start using floating point. + if (intValue >= MAX_SAFE_U32_VALUE) + break; + + intValue = (intValue * 10) + (*in - '0'); + ++in; + } + + f32 floatValue = (f32)intValue; + + // If there are any digits left to parse, then we need to use + // floating point arithmetic from here. + while ( ( *in >= '0') && ( *in <= '9' ) ) + { + floatValue = (floatValue * 10.f) + (f32)(*in - '0'); + ++in; + if (floatValue > FLT_MAX) // Just give up. + break; + } + + if (out) + *out = in; + + return floatValue; +} + +//! Provides a fast function for converting a string into a float. +/** This is not guaranteed to be as accurate as atof(), but is + approximately 6 to 8 times as fast. + \param[in] in The string to convert. + \param[out] result The resultant float will be written here. + \return Pointer to the first character in the string that wasn't used + to create the float value. +*/ +inline const char* fast_atof_move(const char* in, f32& result) +{ + // Please run the regression test when making any modifications to this function. + + result = 0.f; + if (!in) + return 0; + + const bool negative = ('-' == *in); + if (negative || ('+'==*in)) + ++in; + + f32 value = strtof10(in, &in); + + if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 ) + { + const char* afterDecimal = ++in; + const f32 decimal = strtof10(in, &afterDecimal); + value += decimal * fast_atof_table[afterDecimal - in]; + in = afterDecimal; + } + + if ('e' == *in || 'E' == *in) + { + ++in; + // Assume that the exponent is a whole number. + // strtol10() will deal with both + and - signs, + // but calculate as f32 to prevent overflow at FLT_MAX + value *= powf(10.f, (f32)strtol10(in, &in)); + } + + result = negative?-value:value; + return in; +} + +//! Convert a string to a floating point number +/** \param floatAsString The string to convert. + \param out Optional pointer to the first character in the string that + wasn't used to create the float value. + \result Float value parsed from the input string +*/ +inline float fast_atof(const char* floatAsString, const char** out=0) +{ + float ret; + if (out) + *out=fast_atof_move(floatAsString, ret); + else + fast_atof_move(floatAsString, ret); + return ret; +} + +} // end namespace core +} // end namespace irr + +#endif + -- cgit v1.1