Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions include/nfx/detail/string/StringBuilder.inl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
#include <iterator>
#include <utility>

#if !NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
# include <cstdio>
Comment thread
willson556 marked this conversation as resolved.
# include <limits>
#endif

namespace nfx::string
{
//=====================================================================
Expand Down Expand Up @@ -298,11 +303,21 @@ namespace nfx::string
{
ensureCapacity( m_size + FLOAT_MAX_CHARS );
}
#if NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
auto [ptr, ec] = std::to_chars( m_buffer + m_size, m_buffer + m_capacity, value );
if( ec == std::errc() ) NFX_STRINGBUILDER_LIKELY
{
m_size = ptr - m_buffer;
}
#else
char scratch[FLOAT_MAX_CHARS + 1];
const int written = std::snprintf( scratch, sizeof( scratch ), "%.*g",
std::numeric_limits<float>::max_digits10, static_cast<double>( value ) );
if( written > 0 )
{
return append( std::string_view{ scratch, static_cast<size_t>( written ) } );
}
#endif
return *this;
}

Expand All @@ -312,11 +327,21 @@ namespace nfx::string
{
ensureCapacity( m_size + DOUBLE_MAX_CHARS );
}
#if NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
auto [ptr, ec] = std::to_chars( m_buffer + m_size, m_buffer + m_capacity, value );
if( ec == std::errc() ) NFX_STRINGBUILDER_LIKELY
{
m_size = ptr - m_buffer;
}
#else
char scratch[DOUBLE_MAX_CHARS + 1];
const int written = std::snprintf( scratch, sizeof( scratch ), "%.*g",
std::numeric_limits<double>::max_digits10, value );
if( written > 0 )
{
return append( std::string_view{ scratch, static_cast<size_t>( written ) } );
}
#endif
return *this;
}

Expand Down Expand Up @@ -491,23 +516,43 @@ namespace nfx::string

inline StringBuilder& StringBuilder::prepend( float value )
{
#if NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
char buffer[FLOAT_MAX_CHARS];
auto [ptr, ec] = std::to_chars( buffer, buffer + FLOAT_MAX_CHARS, value );
if( ec == std::errc() ) NFX_STRINGBUILDER_LIKELY
{
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
}
#else
char buffer[FLOAT_MAX_CHARS + 1];
const int written = std::snprintf( buffer, sizeof( buffer ), "%.*g",
std::numeric_limits<float>::max_digits10, static_cast<double>( value ) );
if( written > 0 )
{
return prepend( std::string_view{ buffer, static_cast<size_t>( written ) } );
}
#endif
return *this;
}

inline StringBuilder& StringBuilder::prepend( double value )
{
#if NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
char buffer[DOUBLE_MAX_CHARS];
auto [ptr, ec] = std::to_chars( buffer, buffer + DOUBLE_MAX_CHARS, value );
if( ec == std::errc() ) NFX_STRINGBUILDER_LIKELY
{
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
}
#else
char buffer[DOUBLE_MAX_CHARS + 1];
const int written = std::snprintf( buffer, sizeof( buffer ), "%.*g",
std::numeric_limits<double>::max_digits10, value );
if( written > 0 )
{
return prepend( std::string_view{ buffer, static_cast<size_t>( written ) } );
}
#endif
return *this;
}

Expand Down
16 changes: 16 additions & 0 deletions include/nfx/string/StringBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@
# define NFX_STRINGBUILDER_UNLIKELY
#endif

/**
* @def NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS
* @brief Whether std::to_chars(float/double) is usable on this toolchain.
* @details Integer std::to_chars is universally available, but the
* floating-point overloads are not: IAR's libc++ ships them as deleted
* functions. When unavailable the float/double formatters fall back to
* std::snprintf. Define this to 0/1 before including to override.
*/
#if !defined( NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS )
# if defined( __IAR_SYSTEMS_ICC__ )
# define NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS 0
# else
# define NFX_STRINGBUILDER_HAS_FLOAT_TO_CHARS 1
# endif
#endif

namespace nfx::string
{
//=====================================================================
Expand Down
Loading