2
0
mirror of https://github.com/boostorg/uuid.git synced 2026-01-19 04:42:16 +00:00

Add to_chars for writing uuid strings without allocating

This commit is contained in:
Gudmundur Adalsteinsson
2020-08-13 21:53:12 +00:00
committed by Jim King
parent 145531fe07
commit eaa4be7b96
3 changed files with 78 additions and 9 deletions

View File

@@ -62,6 +62,7 @@
<ul>
<li><a href="#Synopsis_io">Synopsis</a></li>
<li><a href="#Stream_operators">Stream Operators</a></li>
<li><a href="#to_chars">To Chars</a></li>
<li><a href="#to_string">To String</a></li>
</ul>
<li><a href="#boost/uuid/uuid_serialize.hpp">boost/uuid/uuid_serialize.hpp</a></li>
@@ -722,6 +723,11 @@ template &lt;typename ch, typename char_traits&gt;
template &lt;typename ch, typename char_traits&gt;
std::basic_istream&lt;ch, char_traits&gt;&amp; operator&gt;&gt;(std::basic_istream&lt;ch, char_traits&gt; &amp;is, uuid &amp;u);
template&lt;class OutputIterator&gt;
OutputIterator to_chars(uuid const&amp; u, OutputIterator out);
bool to_chars(uuid const&amp; u, char* first, char* last);
std::string to_string(uuid const&amp; u);
std::wstring to_wstring(uuid const&amp; u);
@@ -757,6 +763,21 @@ boost::uuids::uuid u2 = boost::lexical_cast&lt;boost::uuids::uuid&gt;(s);
assert(u1 == u2);
</pre>
<h4><a name="to_chars">To Chars</a></h4>
<p>
The function <tt>to_chars</tt> is a fast non-allocating (and non-throwing if the
iterator does not throw) function to write a <b>uuid</b> to a string buffer.
It writes exactly 36 characters to the iterator on success (not null-terminated).
<pre>
boost::uuids::uuid u; // initialize uuid
char buf[36];
boost::uuids::to_chars(u, buf);
// OR
bool ret = boost::uuids::to_chars(u, std::begin(buf), std::end(buf));
assert(ret);
</pre>
<h4><a name="to_string">To String</a></h4>
<p>
The functions <tt>to_string</tt> and <tt>to_wstring</tt> are provided as a
@@ -845,8 +866,8 @@ mailing list provided useful comments and greatly helped to shape the library.
<p>Revised November 8, 2017</p>
<hr>
<p>© Copyright Andy Tompkins, 2006</p>
<p>© Copyright 2017 James E. King III</p>
<p>© Copyright Andy Tompkins, 2006</p>
<p>© Copyright 2017 James E. King III</p>
<p> Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="https://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a>)</p>

View File

@@ -146,23 +146,38 @@ inline wchar_t to_wchar(size_t i) {
} // namespace detail
inline std::string to_string(uuid const& u)
template<class OutputIterator>
OutputIterator to_chars(uuid const& u, OutputIterator out)
{
std::string result;
result.reserve(36);
std::size_t i=0;
for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
const size_t hi = ((*it_data) >> 4) & 0x0F;
result += detail::to_char(hi);
*out++ = detail::to_char(hi);
const size_t lo = (*it_data) & 0x0F;
result += detail::to_char(lo);
*out++ = detail::to_char(lo);
if (i == 3 || i == 5 || i == 7 || i == 9) {
result += '-';
*out++ = '-';
}
}
return out;
}
inline bool to_chars(uuid const& u, char* first, char* last)
{
if (last - first < 36) {
return false;
}
to_chars(u, first);
return true;
}
inline std::string to_string(uuid const& u)
{
std::string result(36, char());
// string::data() returns const char* before C++17
to_chars(u, &result[0]);
return result;
}

View File

@@ -147,6 +147,39 @@ int main(int, char*[])
#endif
{
char buf[36] = {};
BOOST_TEST(to_chars(u3, &buf[0], &buf[36]));
BOOST_TEST(std::string(buf, 36) == std::string("12345678-90ab-cdef-1234-567890abcdef"));
}
{
char buf[37] = {}; // will be null-terminated
BOOST_TEST(to_chars(u3, &buf[0], &buf[37]));
BOOST_TEST(std::string(buf) == std::string("12345678-90ab-cdef-1234-567890abcdef"));
}
{
char buf[35] = {};
BOOST_TEST(!to_chars(u3, &buf[0], &buf[35]));
}
{
char buf[36] = {};
char* ret = to_chars(u3, &buf[0]);
BOOST_TEST(ret == &buf[36]);
BOOST_TEST(std::string(buf, 36) == std::string("12345678-90ab-cdef-1234-567890abcdef"));
}
{
char buf[36] = {};
char* ret = to_chars(u3, buf); // decay
BOOST_TEST(ret == &buf[36]);
BOOST_TEST(std::string(buf, 36) == std::string("12345678-90ab-cdef-1234-567890abcdef"));
}
{
char buf[37] = {}; // will be null-terminated
char* ret = to_chars(u3, buf);
BOOST_TEST(ret == &buf[36]);
BOOST_TEST(std::string(buf) == std::string("12345678-90ab-cdef-1234-567890abcdef"));
}
BOOST_TEST(to_string(u1) == std::string("00000000-0000-0000-0000-000000000000"));
BOOST_TEST(to_string(u3) == std::string("12345678-90ab-cdef-1234-567890abcdef"));