Add to_static_string:

This function converts integers to their decimal
representation as a static string.

In addition, static_string::resize no longer initializes
characters if the new size is larger.
This commit is contained in:
Vinnie Falco
2017-05-07 18:40:22 -07:00
parent 8a49eed947
commit 4edd797611
6 changed files with 144 additions and 6 deletions

View File

@@ -1,3 +1,9 @@
Version 40
* Add to_static_string
--------------------------------------------------------------------------------
Version 39 Version 39
Beast versions are now identified by a single integer which Beast versions are now identified by a single integer which

View File

@@ -183,6 +183,7 @@
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member> <member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member> <member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
<member><link linkend="beast.ref.system_category">system_category</link></member> <member><link linkend="beast.ref.system_category">system_category</link></member>
<member><link linkend="beast.ref.to_static_string">to_static_string</link></member>
</simplelist> </simplelist>
<bridgehead renderas="sect3">Macros</bridgehead> <bridgehead renderas="sect3">Macros</bridgehead>
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">

View File

@@ -58,6 +58,16 @@ lexicographical_compare(
s1.data(), s1.size(), s2.data(), s2.size()); s1.data(), s1.size(), s2.data(), s2.size());
} }
// Maximum number of characters in the decimal
// representation of a binary number
inline
std::size_t constexpr
max_digits(std::size_t bytes)
{
return static_cast<std::size_t>(
bytes * 2.41) + 1;
}
} // detail } // detail
} // beast } // beast

View File

@@ -450,6 +450,18 @@ copy(CharT* dest, size_type count, size_type pos) const ->
return str.size(); return str.size();
} }
template<std::size_t N, class CharT, class Traits>
void
static_string<N, CharT, Traits>::
resize(std::size_t n)
{
if(n > max_size())
throw detail::make_exception<std::length_error>(
"n > max_size()", __FILE__, __LINE__);
n_ = n;
term();
}
template<std::size_t N, class CharT, class Traits> template<std::size_t N, class CharT, class Traits>
void void
static_string<N, CharT, Traits>:: static_string<N, CharT, Traits>::
@@ -518,6 +530,76 @@ assign_char(CharT ch, std::false_type) ->
"max_size() == 0", __FILE__, __LINE__); "max_size() == 0", __FILE__, __LINE__);
} }
namespace detail {
template<class Integer>
static_string<1+max_digits(sizeof(Integer))>
to_static_string(Integer x, std::true_type)
{
if(x == 0)
return {'0'};
static_string<1 + detail::max_digits(
sizeof(Integer))> s;
if(x < 0)
{
x = -x;
char buf[max_digits(sizeof(x))];
char* p = buf;
for(;x > 0; x /= 10)
*p++ = "0123456789"[x % 10];
s.resize(1 + p - buf);
s[0] = '-';
auto d = &s[1];
while(p > buf)
*d++ = *--p;
}
else
{
char buf[max_digits(sizeof(x))];
char* p = buf;
for(;x > 0; x /= 10)
*p++ = "0123456789"[x % 10];
s.resize(p - buf);
auto d = &s[0];
while(p > buf)
*d++ = *--p;
}
return s;
}
template<class Integer>
static_string<max_digits(sizeof(Integer))>
to_static_string(Integer x, std::false_type)
{
if(x == 0)
return {'0'};
char buf[max_digits(sizeof(x))];
char* p = buf;
for(;x > 0; x /= 10)
*p++ = "0123456789"[x % 10];
static_string<detail::max_digits(
sizeof(Integer))> s;
s.resize(p - buf);
auto d = &s[0];
while(p > buf)
*d++ = *--p;
return s;
}
} // detail
template<class Integer>
static_string<detail::max_digits(sizeof(Integer))>
to_static_string(Integer x)
{
static_assert(
std::is_integral<Integer>::value,
"Integral requirements not met");
return detail::to_static_string(
x, std::integral_constant<bool,
std::is_signed<Integer>::value>{});
}
} // beast } // beast
#endif #endif

View File

@@ -31,6 +31,8 @@ namespace beast {
imposes a natural small upper limit on the size of a value. imposes a natural small upper limit on the size of a value.
@note The stored string is always null-terminated. @note The stored string is always null-terminated.
@see @ref to_static_string
*/ */
template< template<
std::size_t N, std::size_t N,
@@ -783,13 +785,10 @@ public:
/** Changes the number of characters stored. /** Changes the number of characters stored.
If the resulting string is larger, the new If the resulting string is larger, the new
characters are initialized to zero. characters are uninitialized.
*/ */
void void
resize(std::size_t n) resize(std::size_t n);
{
resize(n, 0);
}
/** Changes the number of characters stored. /** Changes the number of characters stored.
@@ -1098,6 +1097,23 @@ operator<<(std::basic_ostream<CharT, Traits>& os,
beast::basic_string_view<CharT, Traits>>(str); beast::basic_string_view<CharT, Traits>>(str);
} }
//
// Numeric conversions
//
/** Returns a static string representing an integer as a decimal.
@param x The signed or unsigned integer to convert.
This must be an integral type.
@return A @ref static_string with an implementation defined
maximum size large enough to hold the longest possible decimal
representation of any integer of the given type.
*/
template<class Integer>
static_string<detail::max_digits(sizeof(Integer))>
to_static_string(Integer x);
} // beast } // beast
#include <beast/core/impl/static_string.ipp> #include <beast/core/impl/static_string.ipp>

View File

@@ -1433,7 +1433,29 @@ public:
pass(); pass();
} }
void run() override void
testToStaticString()
{
BEAST_EXPECT(to_static_string<long>(0) == "0");
BEAST_EXPECT(to_static_string<long>(1) == "1");
BEAST_EXPECT(to_static_string<long>(0xffff) == "65535");
BEAST_EXPECT(to_static_string<long>(0x10000) == "65536");
BEAST_EXPECT(to_static_string<long long>(0xffffffff) == "4294967295");
BEAST_EXPECT(to_static_string<long>(-1) == "-1");
BEAST_EXPECT(to_static_string<long>(-65535) == "-65535");
BEAST_EXPECT(to_static_string<long>(-65536) == "-65536");
BEAST_EXPECT(to_static_string<long long>(-4294967295ll) == "-4294967295");
BEAST_EXPECT(to_static_string<unsigned long>(0) == "0");
BEAST_EXPECT(to_static_string<unsigned long>(1) == "1");
BEAST_EXPECT(to_static_string<unsigned long>(0xffff) == "65535");
BEAST_EXPECT(to_static_string<unsigned long>(0x10000) == "65536");
BEAST_EXPECT(to_static_string<unsigned long>(0xffffffff) == "4294967295");
}
void
run() override
{ {
testConstruct(); testConstruct();
testAssign(); testAssign();
@@ -1445,6 +1467,7 @@ public:
testSwap(); testSwap();
testGeneral(); testGeneral();
testToStaticString();
} }
}; };