From ab0f8f749a24cd018f149deb5d64a546bd87680b Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Tue, 24 Oct 2023 11:09:29 -0400 Subject: [PATCH] support platforms without wchar_t closes #51 --- include/boost/static_string/config.hpp | 18 ++++ include/boost/static_string/static_string.hpp | 11 ++- test/static_string.cpp | 91 +++++++++++++++---- 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 2217fe8..7ccb71d 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -228,6 +228,24 @@ defined(BOOST_STATIC_STRING_CPP14) #define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR #endif +#ifndef BOOST_STATIC_STRING_STANDALONE +#if ! defined(BOOST_NO_CWCHAR) && ! defined(BOOST_NO_SWPRINTF) +#define BOOST_STATIC_STRING_HAS_WCHAR +#endif +#else +#ifndef __has_include +// If we don't have __has_include in standalone, +// we will assume that exists. +#define BOOST_STATIC_STRING_HAS_WCHAR +#elif __has_include() +#define BOOST_STATIC_STRING_HAS_WCHAR +#endif +#endif + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR +#include +#endif + // Define the basic string_view type used by the library // Conversions to and from other available string_view types // are still defined. diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index b899d54..12b044b 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -58,9 +57,11 @@ template using static_string = basic_static_string>; +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template using static_wstring = basic_static_string>; +#endif template using static_u16string = @@ -550,6 +551,7 @@ to_static_string_int_impl(Integer value) noexcept return static_string(digits_begin, std::distance(digits_begin, digits_end)); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template inline static_wstring @@ -561,6 +563,7 @@ to_static_wstring_int_impl(Integer value) noexcept digits_end, value, std::is_signed{}); return static_wstring(digits_begin, std::distance(digits_begin, digits_end)); } +#endif BOOST_STATIC_STRING_CPP11_CONSTEXPR inline @@ -638,6 +641,7 @@ to_static_string_float_impl(long double value) noexcept return static_string(buffer); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR template inline static_wstring @@ -711,6 +715,7 @@ to_static_wstring_float_impl(long double value) noexcept // this will not throw return static_wstring(buffer); } +#endif #if defined(__GNUC__) && __GNUC__ >= 7 #pragma GCC diagnostic pop @@ -6202,6 +6207,7 @@ to_static_string(long double value) noexcept std::numeric_limits::max_digits10 + 4>(value); } +#ifdef BOOST_STATIC_STRING_HAS_WCHAR /// Converts `value` to a `static_wstring` static_wstring::digits10 + 2> inline @@ -6282,6 +6288,7 @@ to_static_wstring(long double value) noexcept return detail::to_static_wstring_float_impl< std::numeric_limits::max_digits10 + 4>(value); } +#endif //------------------------------------------------------------------------------ // @@ -6322,7 +6329,9 @@ hash_value( //------------------------------------------------------------------------------ using static_strings::static_string; +#ifdef BOOST_STATIC_STRING_HAS_WCHAR using static_strings::static_wstring; +#endif using static_strings::static_u16string; using static_strings::static_u32string; } // boost diff --git a/test/static_string.cpp b/test/static_string.cpp index c818975..7541c0b 100644 --- a/test/static_string.cpp +++ b/test/static_string.cpp @@ -245,29 +245,52 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S template bool -testTS(Arithmetic value, const char* str_expected = "", const wchar_t* wstr_expected = L"", bool test_expected = false) +testTS(Arithmetic value, const char* str_expected = "", bool test_expected = false) { const auto str = to_static_string(value); - const auto wstr = to_static_wstring(value); if (std::is_floating_point::value) { const auto std_res = std::to_string(value); + return str == std_res.data(); + } + else + { + if (std::is_signed::value) + { + return + Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && + (! test_expected || str == str_expected); + } + else + { + return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && + (! test_expected || str == str_expected); + } + } +} + +template +bool +testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected = false) +{ + const auto wstr = to_static_wstring(value); + if (std::is_floating_point::value) + { const auto wstd_res = std::to_wstring(value); - return str == std_res.data() && wstr == wstd_res.data(); + return wstr == wstd_res.data(); } else { if (std::is_signed::value) { - return Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && + return Arithmetic(std::wcstoll(wstr.begin(), nullptr, 10)) == value && - (test_expected ? str == str_expected && wstr == wstr_expected : true); + (! test_expected || wstr == wstr_expected); } else { - return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && - Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && - (test_expected ? str == str_expected && wstr == wstr_expected : true); + return Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && + (! test_expected || wstr == wstr_expected); } } } @@ -3913,16 +3936,16 @@ testGeneral() void testToStaticString() { - BOOST_TEST(testTS(0, "0", L"0", true)); - BOOST_TEST(testTS(0u, "0", L"0", true)); - BOOST_TEST(testTS(0xffff, "65535", L"65535", true)); - BOOST_TEST(testTS(0x10000, "65536", L"65536", true)); - BOOST_TEST(testTS(0xffffffff, "4294967295", L"4294967295", true)); - BOOST_TEST(testTS(-65535, "-65535", L"-65535", true)); - BOOST_TEST(testTS(-65536, "-65536", L"-65536", true)); - BOOST_TEST(testTS(-4294967295ll, "-4294967295", L"-4294967295", true)); - BOOST_TEST(testTS(1, "1", L"1", true)); - BOOST_TEST(testTS(-1, "-1", L"-1", true)); + BOOST_TEST(testTS(0, "0", true)); + BOOST_TEST(testTS(0u, "0", true)); + BOOST_TEST(testTS(0xffff, "65535", true)); + BOOST_TEST(testTS(0x10000, "65536", true)); + BOOST_TEST(testTS(0xffffffff, "4294967295", true)); + BOOST_TEST(testTS(-65535, "-65535", true)); + BOOST_TEST(testTS(-65536, "-65536", true)); + BOOST_TEST(testTS(-4294967295ll, "-4294967295", true)); + BOOST_TEST(testTS(1, "1", true)); + BOOST_TEST(testTS(-1, "-1", true)); BOOST_TEST(testTS(0.1)); BOOST_TEST(testTS(0.0000001)); BOOST_TEST(testTS(-0.0000001)); @@ -3956,6 +3979,35 @@ testToStaticString() BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != static_string<0>::npos || str == "infinity" || str == "inf"); } + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR + + BOOST_TEST(testTWS(0, L"0", true)); + BOOST_TEST(testTWS(0u, L"0", true)); + BOOST_TEST(testTWS(0xffff, L"65535", true)); + BOOST_TEST(testTWS(0x10000, L"65536", true)); + BOOST_TEST(testTWS(0xffffffff, L"4294967295", true)); + BOOST_TEST(testTWS(-65535, L"-65535", true)); + BOOST_TEST(testTWS(-65536, L"-65536", true)); + BOOST_TEST(testTWS(-4294967295ll, L"-4294967295", true)); + BOOST_TEST(testTWS(1, L"1", true)); + BOOST_TEST(testTWS(-1, L"-1", true)); + BOOST_TEST(testTWS(0.1)); + BOOST_TEST(testTWS(0.0000001)); + BOOST_TEST(testTWS(-0.0000001)); + BOOST_TEST(testTWS(-0.1)); + BOOST_TEST(testTWS(1234567890.0001)); + BOOST_TEST(testTWS(1.123456789012345)); + BOOST_TEST(testTWS(-1234567890.1234)); + BOOST_TEST(testTWS(-1.123456789012345)); + + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::max())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + BOOST_TEST(testTWS(std::numeric_limits::min())); + { auto str = to_static_wstring(std::numeric_limits::max()); BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != @@ -3971,6 +4023,7 @@ testToStaticString() BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != static_string<0>::npos || str == L"infinity" || str == L"inf"); } +#endif } // done @@ -6007,7 +6060,7 @@ testFind() void testReplace() { - // replace(size_type pos1, size_type n1, const charT* s, size_type n2); + // replace(size_type pos1, size_type n1, const charT* s, size_type n2); { static_string<20> fs1 = "helloworld"; BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld");