From c963533f73e5da1f9e87aaadb221a5a198bd9971 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 25 Dec 2025 15:18:03 +0200 Subject: [PATCH] Make to_chars constexpr --- include/boost/uuid/detail/to_chars.hpp | 3 +- include/boost/uuid/uuid_io.hpp | 17 ++- test/Jamfile.v2 | 2 + test/test_to_chars_cx.cpp | 169 +++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 test/test_to_chars_cx.cpp diff --git a/include/boost/uuid/detail/to_chars.hpp b/include/boost/uuid/detail/to_chars.hpp index c1468af..061acfd 100644 --- a/include/boost/uuid/detail/to_chars.hpp +++ b/include/boost/uuid/detail/to_chars.hpp @@ -7,6 +7,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include +#include namespace boost { namespace uuids { @@ -41,7 +42,7 @@ constexpr char8_t const* to_chars_digits( char8_t const* ) noexcept #endif -template inline Ch* to_chars( uuid const& u, Ch* out ) noexcept +template BOOST_CXX14_CONSTEXPR inline Ch* to_chars( uuid const& u, Ch* out ) noexcept { constexpr Ch const* digits = to_chars_digits( static_cast( nullptr ) ); diff --git a/include/boost/uuid/uuid_io.hpp b/include/boost/uuid/uuid_io.hpp index f70c355..ebb058b 100644 --- a/include/boost/uuid/uuid_io.hpp +++ b/include/boost/uuid/uuid_io.hpp @@ -29,16 +29,21 @@ namespace uuids { // to_chars template -OutputIterator to_chars( uuid const& u, OutputIterator out ) +BOOST_CXX14_CONSTEXPR OutputIterator to_chars( uuid const& u, OutputIterator out ) { - char tmp[ 36 ]; + char tmp[ 36 ] = {}; detail::to_chars( u, tmp ); - return std::copy_n( tmp, 36, out ); + for( std::size_t i = 0; i < 36; ++i ) + { + *out++ = tmp[ i ]; + } + + return out; } template -inline bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept +BOOST_CXX14_CONSTEXPR inline bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept { if( last - first < 36 ) { @@ -50,7 +55,7 @@ inline bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept } template -inline Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept +BOOST_CXX14_CONSTEXPR inline Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept { BOOST_UUID_STATIC_ASSERT( N >= 37 ); @@ -63,7 +68,7 @@ inline Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept // only provided for compatibility; deprecated template BOOST_DEPRECATED( "Use Ch[37] instead of Ch[36] to allow for the null terminator" ) -inline Ch* to_chars( uuid const& u, Ch (&buffer)[ 36 ] ) noexcept +BOOST_CXX14_CONSTEXPR inline Ch* to_chars( uuid const& u, Ch (&buffer)[ 36 ] ) noexcept { detail::to_chars( u, buffer + 0 ); return buffer + 36; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index cd929ce..27ad45c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -231,6 +231,8 @@ run test_constants_cx.cpp ; run test_from_chars_cx.cpp ; run test_from_chars_cx2.cpp ; +run test_to_chars_cx.cpp ; + # 'quick' test for CI run quick.cpp ; diff --git a/test/test_to_chars_cx.cpp b/test/test_to_chars_cx.cpp new file mode 100644 index 0000000..862c192 --- /dev/null +++ b/test/test_to_chars_cx.cpp @@ -0,0 +1,169 @@ +// Copyright 2024, 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include + +using namespace boost::uuids; + +template +BOOST_CXX14_CONSTEXPR boost::array uuid_to_string( uuid const& u ) +{ + boost::array r = {{}}; + to_chars( u, r.begin(), r.end() ); + return r; +} + +int main() +{ + { + BOOST_CXX14_CONSTEXPR uuid u; + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::string const w( "00000000-0000-0000-0000-000000000000" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::wstring const w( L"00000000-0000-0000-0000-000000000000" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u16string const w( u"00000000-0000-0000-0000-000000000000" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u32string const w( U"00000000-0000-0000-0000-000000000000" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u8string const w( u8"00000000-0000-0000-0000-000000000000" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#endif + } + + { + BOOST_CXX14_CONSTEXPR uuid u = {{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }}; + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::string const w( "00010203-0405-0607-0809-0a0b0c0d0e0f" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::wstring const w( L"00010203-0405-0607-0809-0a0b0c0d0e0f" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u16string const w( u"00010203-0405-0607-0809-0a0b0c0d0e0f" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u32string const w( U"00010203-0405-0607-0809-0a0b0c0d0e0f" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u8string const w( u8"00010203-0405-0607-0809-0a0b0c0d0e0f" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#endif + } + + { + BOOST_CXX14_CONSTEXPR uuid u = {{ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }}; + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::string const w( "12345678-90ab-cdef-1234-567890abcdef" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::wstring const w( L"12345678-90ab-cdef-1234-567890abcdef" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u16string const w( u"12345678-90ab-cdef-1234-567890abcdef" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u32string const w( U"12345678-90ab-cdef-1234-567890abcdef" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + + { + BOOST_CXX14_CONSTEXPR auto v = uuid_to_string( u ); + + std::u8string const w( u8"12345678-90ab-cdef-1234-567890abcdef" ); + + BOOST_TEST_ALL_EQ( v.begin(), v.end(), w.begin(), w.end() ); + } + +#endif + } + + return boost::report_errors(); +}