diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9217227d..1757fe2d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+Version 40
+
+* Add to_static_string
+
+--------------------------------------------------------------------------------
+
Version 39
Beast versions are now identified by a single integer which
diff --git a/doc/quickref.xml b/doc/quickref.xml
index fc11461e..c006e14e 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -183,6 +183,7 @@
prepare_buffer
prepare_buffers
system_category
+ to_static_string
Macros
diff --git a/include/beast/core/detail/static_string.hpp b/include/beast/core/detail/static_string.hpp
index dbd92df1..a3e8b516 100644
--- a/include/beast/core/detail/static_string.hpp
+++ b/include/beast/core/detail/static_string.hpp
@@ -58,6 +58,16 @@ lexicographical_compare(
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(
+ bytes * 2.41) + 1;
+}
+
} // detail
} // beast
diff --git a/include/beast/core/impl/static_string.ipp b/include/beast/core/impl/static_string.ipp
index 4eec94fd..786eb516 100644
--- a/include/beast/core/impl/static_string.ipp
+++ b/include/beast/core/impl/static_string.ipp
@@ -450,6 +450,18 @@ copy(CharT* dest, size_type count, size_type pos) const ->
return str.size();
}
+template
+void
+static_string::
+resize(std::size_t n)
+{
+ if(n > max_size())
+ throw detail::make_exception(
+ "n > max_size()", __FILE__, __LINE__);
+ n_ = n;
+ term();
+}
+
template
void
static_string::
@@ -518,6 +530,76 @@ assign_char(CharT ch, std::false_type) ->
"max_size() == 0", __FILE__, __LINE__);
}
+namespace detail {
+
+template
+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
+static_string
+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 s;
+ s.resize(p - buf);
+ auto d = &s[0];
+ while(p > buf)
+ *d++ = *--p;
+ return s;
+}
+
+} // detail
+
+template
+static_string
+to_static_string(Integer x)
+{
+ static_assert(
+ std::is_integral::value,
+ "Integral requirements not met");
+ return detail::to_static_string(
+ x, std::integral_constant::value>{});
+}
+
} // beast
#endif
diff --git a/include/beast/core/static_string.hpp b/include/beast/core/static_string.hpp
index 1bd359e5..0f340acf 100644
--- a/include/beast/core/static_string.hpp
+++ b/include/beast/core/static_string.hpp
@@ -31,6 +31,8 @@ namespace beast {
imposes a natural small upper limit on the size of a value.
@note The stored string is always null-terminated.
+
+ @see @ref to_static_string
*/
template<
std::size_t N,
@@ -783,13 +785,10 @@ public:
/** Changes the number of characters stored.
If the resulting string is larger, the new
- characters are initialized to zero.
+ characters are uninitialized.
*/
void
- resize(std::size_t n)
- {
- resize(n, 0);
- }
+ resize(std::size_t n);
/** Changes the number of characters stored.
@@ -1098,6 +1097,23 @@ operator<<(std::basic_ostream& os,
beast::basic_string_view>(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
+static_string
+to_static_string(Integer x);
+
} // beast
#include
diff --git a/test/core/static_string.cpp b/test/core/static_string.cpp
index ade4d50e..227b2e72 100644
--- a/test/core/static_string.cpp
+++ b/test/core/static_string.cpp
@@ -1433,7 +1433,29 @@ public:
pass();
}
- void run() override
+ void
+ testToStaticString()
+ {
+ BEAST_EXPECT(to_static_string(0) == "0");
+ BEAST_EXPECT(to_static_string(1) == "1");
+ BEAST_EXPECT(to_static_string(0xffff) == "65535");
+ BEAST_EXPECT(to_static_string(0x10000) == "65536");
+ BEAST_EXPECT(to_static_string(0xffffffff) == "4294967295");
+
+ BEAST_EXPECT(to_static_string(-1) == "-1");
+ BEAST_EXPECT(to_static_string(-65535) == "-65535");
+ BEAST_EXPECT(to_static_string(-65536) == "-65536");
+ BEAST_EXPECT(to_static_string(-4294967295ll) == "-4294967295");
+
+ BEAST_EXPECT(to_static_string(0) == "0");
+ BEAST_EXPECT(to_static_string(1) == "1");
+ BEAST_EXPECT(to_static_string(0xffff) == "65535");
+ BEAST_EXPECT(to_static_string(0x10000) == "65536");
+ BEAST_EXPECT(to_static_string(0xffffffff) == "4294967295");
+ }
+
+ void
+ run() override
{
testConstruct();
testAssign();
@@ -1445,6 +1467,7 @@ public:
testSwap();
testGeneral();
+ testToStaticString();
}
};