Skip to content

Commit

Permalink
support platforms without wchar_t
Browse files Browse the repository at this point in the history
closes #51
  • Loading branch information
sdkrystian committed Oct 24, 2023
1 parent 175f467 commit 42bb99e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 20 deletions.
18 changes: 18 additions & 0 deletions include/boost/static_string/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,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 <cwchar> exists.
#define BOOST_STATIC_STRING_HAS_WCHAR
#elif __has_include(<cwchar>)
#define BOOST_STATIC_STRING_HAS_WCHAR
#endif
#endif

#ifdef BOOST_STATIC_STRING_HAS_WCHAR
#include <cwchar>
#endif

// Define the basic string_view type used by the library
// Conversions to and from other available string_view types
// are still defined.
Expand Down
11 changes: 10 additions & 1 deletion include/boost/static_string/static_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cwchar>
#include <functional>
#include <initializer_list>
#include <limits>
Expand All @@ -58,9 +57,11 @@ template<std::size_t N>
using static_string =
basic_static_string<N, char, std::char_traits<char>>;

#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N>
using static_wstring =
basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
#endif

template<std::size_t N>
using static_u16string =
Expand Down Expand Up @@ -555,6 +556,7 @@ to_static_string_int_impl(Integer value) noexcept
return static_string<N>(digits_begin, std::distance(digits_begin, digits_end));
}

#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N, typename Integer>
inline
static_wstring<N>
Expand All @@ -566,6 +568,7 @@ to_static_wstring_int_impl(Integer value) noexcept
digits_end, value, std::is_signed<Integer>{});
return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end));
}
#endif

BOOST_STATIC_STRING_CPP11_CONSTEXPR
inline
Expand Down Expand Up @@ -643,6 +646,7 @@ to_static_string_float_impl(long double value) noexcept
return static_string<N>(buffer);
}

#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N>
inline
static_wstring<N>
Expand Down Expand Up @@ -716,6 +720,7 @@ to_static_wstring_float_impl(long double value) noexcept
// this will not throw
return static_wstring<N>(buffer);
}
#endif

#if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -6227,6 +6232,7 @@ to_static_string(long double value) noexcept
std::numeric_limits<long double>::max_digits10 + 4>(value);
}

#ifdef BOOST_STATIC_STRING_HAS_WCHAR
/// Converts `value` to a `static_wstring`
static_wstring<std::numeric_limits<int>::digits10 + 2>
inline
Expand Down Expand Up @@ -6307,6 +6313,7 @@ to_static_wstring(long double value) noexcept
return detail::to_static_wstring_float_impl<
std::numeric_limits<long double>::max_digits10 + 4>(value);
}
#endif

//------------------------------------------------------------------------------
//
Expand Down Expand Up @@ -6347,7 +6354,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
Expand Down
91 changes: 72 additions & 19 deletions test/static_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,29 +245,52 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S

template<typename Arithmetic>
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<Arithmetic>::value)
{
const auto std_res = std::to_string(value);
return str == std_res.data();
}
else
{
if (std::is_signed<Arithmetic>::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<typename Arithmetic>
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<Arithmetic>::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<Arithmetic>::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);
}
}
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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<long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<long long>::min()));
BOOST_TEST(testTWS(std::numeric_limits<unsigned long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<unsigned long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<long double>::min()));
BOOST_TEST(testTWS(std::numeric_limits<float>::min()));

{
auto str = to_static_wstring(std::numeric_limits<float>::max());
BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') !=
Expand All @@ -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
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 42bb99e

Please sign in to comment.