Convert sf::Utf<T> template into 3 namespaces

This commit is contained in:
Chris Thrasher 2024-07-19 11:58:28 -06:00
parent c8c8673259
commit 1107c29c3a
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C
2 changed files with 710 additions and 728 deletions

View File

@ -44,17 +44,12 @@ template <class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, OutputIt dFirst); OutputIt copy(InputIt first, InputIt last, OutputIt dFirst);
} }
template <unsigned int N>
class Utf;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-8 /// \brief UTF-8 string conversion functions
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <> namespace Utf8
class Utf<8>
{ {
public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decode a single UTF-8 character /// \brief Decode a single UTF-8 character
/// ///
@ -70,7 +65,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0); In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Encode a single UTF-8 character /// \brief Encode a single UTF-8 character
@ -86,7 +81,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
static Out encode(std::uint32_t input, Out output, std::uint8_t replacement = 0); Out encode(std::uint32_t input, Out output, std::uint8_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Advance to the next UTF-8 character /// \brief Advance to the next UTF-8 character
@ -101,7 +96,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In next(In begin, In end); In next(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Count the number of characters of a UTF-8 sequence /// \brief Count the number of characters of a UTF-8 sequence
@ -117,7 +112,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static std::size_t count(In begin, In end); std::size_t count(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an ANSI characters range to UTF-8 /// \brief Convert an ANSI characters range to UTF-8
@ -134,7 +129,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {}); Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a wide characters range to UTF-8 /// \brief Convert a wide characters range to UTF-8
@ -147,7 +142,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromWide(In begin, In end, Out output); Out fromWide(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8 /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
@ -160,7 +155,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromLatin1(In begin, In end, Out output); Out fromLatin1(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-8 characters range to ANSI characters /// \brief Convert an UTF-8 characters range to ANSI characters
@ -178,7 +173,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {}); Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-8 characters range to wide characters /// \brief Convert an UTF-8 characters range to wide characters
@ -192,7 +187,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toWide(In begin, In end, Out output, wchar_t replacement = 0); Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
@ -206,7 +201,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toLatin1(In begin, In end, Out output, char replacement = 0); Out toLatin1(In begin, In end, Out output, char replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-8 characters range to UTF-8 /// \brief Convert a UTF-8 characters range to UTF-8
@ -224,7 +219,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf8(In begin, In end, Out output); Out toUtf8(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-8 characters range to UTF-16 /// \brief Convert a UTF-8 characters range to UTF-16
@ -237,7 +232,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf16(In begin, In end, Out output); Out toUtf16(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-8 characters range to UTF-32 /// \brief Convert a UTF-8 characters range to UTF-32
@ -250,17 +245,15 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf32(In begin, In end, Out output); Out toUtf32(In begin, In end, Out output);
}; } // namespace Utf8
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-16 /// \brief UTF-16 string conversion functions
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <> namespace Utf16
class Utf<16>
{ {
public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decode a single UTF-16 character /// \brief Decode a single UTF-16 character
/// ///
@ -276,7 +269,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0); In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Encode a single UTF-16 character /// \brief Encode a single UTF-16 character
@ -292,7 +285,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
static Out encode(std::uint32_t input, Out output, std::uint16_t replacement = 0); Out encode(std::uint32_t input, Out output, std::uint16_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Advance to the next UTF-16 character /// \brief Advance to the next UTF-16 character
@ -307,7 +300,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In next(In begin, In end); In next(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Count the number of characters of a UTF-16 sequence /// \brief Count the number of characters of a UTF-16 sequence
@ -323,7 +316,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static std::size_t count(In begin, In end); std::size_t count(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an ANSI characters range to UTF-16 /// \brief Convert an ANSI characters range to UTF-16
@ -340,7 +333,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {}); Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a wide characters range to UTF-16 /// \brief Convert a wide characters range to UTF-16
@ -353,7 +346,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromWide(In begin, In end, Out output); Out fromWide(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16 /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
@ -366,7 +359,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromLatin1(In begin, In end, Out output); Out fromLatin1(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-16 characters range to ANSI characters /// \brief Convert an UTF-16 characters range to ANSI characters
@ -384,7 +377,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {}); Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-16 characters range to wide characters /// \brief Convert an UTF-16 characters range to wide characters
@ -398,7 +391,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toWide(In begin, In end, Out output, wchar_t replacement = 0); Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
@ -412,7 +405,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toLatin1(In begin, In end, Out output, char replacement = 0); Out toLatin1(In begin, In end, Out output, char replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-16 characters range to UTF-8 /// \brief Convert a UTF-16 characters range to UTF-8
@ -425,7 +418,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf8(In begin, In end, Out output); Out toUtf8(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-16 characters range to UTF-16 /// \brief Convert a UTF-16 characters range to UTF-16
@ -443,7 +436,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf16(In begin, In end, Out output); Out toUtf16(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-16 characters range to UTF-32 /// \brief Convert a UTF-16 characters range to UTF-32
@ -456,17 +449,15 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf32(In begin, In end, Out output); Out toUtf32(In begin, In end, Out output);
}; }; // namespace Utf16
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-32 /// \brief UTF-32 string conversion functions
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <> namespace Utf32
class Utf<32>
{ {
public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decode a single UTF-32 character /// \brief Decode a single UTF-32 character
/// ///
@ -483,7 +474,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0); In decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Encode a single UTF-32 character /// \brief Encode a single UTF-32 character
@ -500,7 +491,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
static Out encode(std::uint32_t input, Out output, std::uint32_t replacement = 0); Out encode(std::uint32_t input, Out output, std::uint32_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Advance to the next UTF-32 character /// \brief Advance to the next UTF-32 character
@ -515,7 +506,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static In next(In begin, In end); In next(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Count the number of characters of a UTF-32 sequence /// \brief Count the number of characters of a UTF-32 sequence
@ -530,7 +521,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static std::size_t count(In begin, In end); std::size_t count(In begin, In end);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an ANSI characters range to UTF-32 /// \brief Convert an ANSI characters range to UTF-32
@ -547,7 +538,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {}); Out fromAnsi(In begin, In end, Out output, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a wide characters range to UTF-32 /// \brief Convert a wide characters range to UTF-32
@ -560,7 +551,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromWide(In begin, In end, Out output); Out fromWide(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32 /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
@ -573,7 +564,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out fromLatin1(In begin, In end, Out output); Out fromLatin1(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-32 characters range to ANSI characters /// \brief Convert an UTF-32 characters range to ANSI characters
@ -591,7 +582,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {}); Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-32 characters range to wide characters /// \brief Convert an UTF-32 characters range to wide characters
@ -605,7 +596,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toWide(In begin, In end, Out output, wchar_t replacement = 0); Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
@ -619,7 +610,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toLatin1(In begin, In end, Out output, char replacement = 0); Out toLatin1(In begin, In end, Out output, char replacement = 0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-32 characters range to UTF-8 /// \brief Convert a UTF-32 characters range to UTF-8
@ -632,7 +623,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf8(In begin, In end, Out output); Out toUtf8(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-32 characters range to UTF-16 /// \brief Convert a UTF-32 characters range to UTF-16
@ -645,7 +636,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf16(In begin, In end, Out output); Out toUtf16(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a UTF-32 characters range to UTF-32 /// \brief Convert a UTF-32 characters range to UTF-32
@ -663,7 +654,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
static Out toUtf32(In begin, In end, Out output); Out toUtf32(In begin, In end, Out output);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decode a single ANSI character to UTF-32 /// \brief Decode a single ANSI character to UTF-32
@ -679,7 +670,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static std::uint32_t decodeAnsi(In input, const std::locale& locale = {}); std::uint32_t decodeAnsi(In input, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decode a single wide character to UTF-32 /// \brief Decode a single wide character to UTF-32
@ -694,7 +685,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
static std::uint32_t decodeWide(In input); std::uint32_t decodeWide(In input);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Encode a single UTF-32 character to ANSI /// \brief Encode a single UTF-32 character to ANSI
@ -712,7 +703,7 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
static Out encodeAnsi(std::uint32_t codepoint, Out output, char replacement = 0, const std::locale& locale = {}); Out encodeAnsi(std::uint32_t codepoint, Out output, char replacement = 0, const std::locale& locale = {});
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Encode a single UTF-32 character to wide /// \brief Encode a single UTF-32 character to wide
@ -729,13 +720,8 @@ public:
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
static Out encodeWide(std::uint32_t codepoint, Out output, wchar_t replacement = 0); Out encodeWide(std::uint32_t codepoint, Out output, wchar_t replacement = 0);
}; }; // namespace Utf32
// Make type aliases to get rid of the template syntax
using Utf8 = Utf<8>;
using Utf16 = Utf<16>;
using Utf32 = Utf<32>;
} // namespace sf } // namespace sf
@ -743,22 +729,18 @@ using Utf32 = Utf<32>;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \class sf::Utf /// \namespace sf::Utf8
/// \namespace sf::Utf16
/// \namespace sf::Utf32
/// \ingroup system /// \ingroup system
/// ///
/// Utility class providing generic functions for UTF conversions. /// Utility class providing generic functions for UTF conversions.
/// ///
/// sf::Utf is a low-level, generic interface for counting, iterating, /// This is a low-level, generic interface for counting, iterating,
/// encoding and decoding Unicode characters and strings. It is able /// encoding and decoding Unicode characters and strings. It is able
/// to handle ANSI, wide, latin-1, UTF-8, UTF-16 and UTF-32 encodings. /// to handle ANSI, wide, latin-1, UTF-8, UTF-16 and UTF-32 encodings.
/// ///
/// sf::Utf<X> functions are all static, these classes are not meant to /// All the functions are template, so that you can use any character
/// be instantiated. All the functions are template, so that you /// or string type for a given encoding.
/// can use any character / string type for a given encoding.
///
/// It has 3 specializations:
/// \li sf::Utf<8> (with sf::Utf8 type alias)
/// \li sf::Utf<16> (with sf::Utf16 type alias)
/// \li sf::Utf<32> (with sf::Utf32 type alias)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -52,7 +52,7 @@ OutputIt priv::copy(InputIt first, InputIt last, OutputIt dFirst)
} }
template <typename In> template <typename In>
In Utf<8>::decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement) In Utf8::decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement)
{ {
// clang-format off // clang-format off
// Some useful precomputed data // Some useful precomputed data
@ -107,7 +107,7 @@ In Utf<8>::decode(In begin, In end, std::uint32_t& output, std::uint32_t replace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
Out Utf<8>::encode(std::uint32_t input, Out output, std::uint8_t replacement) Out Utf8::encode(std::uint32_t input, Out output, std::uint8_t replacement)
{ {
// Some useful precomputed data // Some useful precomputed data
static constexpr std::array<std::uint8_t, 7> firstBytes = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; static constexpr std::array<std::uint8_t, 7> firstBytes = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
@ -156,7 +156,7 @@ Out Utf<8>::encode(std::uint32_t input, Out output, std::uint8_t replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
In Utf<8>::next(In begin, In end) In Utf8::next(In begin, In end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
return decode(begin, end, codepoint); return decode(begin, end, codepoint);
@ -165,7 +165,7 @@ In Utf<8>::next(In begin, In end)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
std::size_t Utf<8>::count(In begin, In end) std::size_t Utf8::count(In begin, In end)
{ {
std::size_t length = 0; std::size_t length = 0;
while (begin < end) while (begin < end)
@ -180,11 +180,11 @@ std::size_t Utf<8>::count(In begin, In end)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::fromAnsi(In begin, In end, Out output, const std::locale& locale) Out Utf8::fromAnsi(In begin, In end, Out output, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
{ {
const std::uint32_t codepoint = Utf<32>::decodeAnsi(*begin++, locale); const std::uint32_t codepoint = Utf32::decodeAnsi(*begin++, locale);
output = encode(codepoint, output); output = encode(codepoint, output);
} }
@ -194,11 +194,11 @@ Out Utf<8>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::fromWide(In begin, In end, Out output) Out Utf8::fromWide(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = Utf<32>::decodeWide(*begin++); std::uint32_t codepoint = Utf32::decodeWide(*begin++);
output = encode(codepoint, output); output = encode(codepoint, output);
} }
@ -208,7 +208,7 @@ Out Utf<8>::fromWide(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::fromLatin1(In begin, In end, Out output) Out Utf8::fromLatin1(In begin, In end, Out output)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -221,13 +221,13 @@ Out Utf<8>::fromLatin1(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) Out Utf8::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<32>::encodeAnsi(codepoint, output, replacement, locale); output = Utf32::encodeAnsi(codepoint, output, replacement, locale);
} }
return output; return output;
@ -236,13 +236,13 @@ Out Utf<8>::toAnsi(In begin, In end, Out output, char replacement, const std::lo
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toWide(In begin, In end, Out output, wchar_t replacement) Out Utf8::toWide(In begin, In end, Out output, wchar_t replacement)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<32>::encodeWide(codepoint, output, replacement); output = Utf32::encodeWide(codepoint, output, replacement);
} }
return output; return output;
@ -251,7 +251,7 @@ Out Utf<8>::toWide(In begin, In end, Out output, wchar_t replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toLatin1(In begin, In end, Out output, char replacement) Out Utf8::toLatin1(In begin, In end, Out output, char replacement)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -268,7 +268,7 @@ Out Utf<8>::toLatin1(In begin, In end, Out output, char replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toUtf8(In begin, In end, Out output) Out Utf8::toUtf8(In begin, In end, Out output)
{ {
return priv::copy(begin, end, output); return priv::copy(begin, end, output);
} }
@ -276,13 +276,13 @@ Out Utf<8>::toUtf8(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toUtf16(In begin, In end, Out output) Out Utf8::toUtf16(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<16>::encode(codepoint, output); output = Utf16::encode(codepoint, output);
} }
return output; return output;
@ -291,7 +291,7 @@ Out Utf<8>::toUtf16(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<8>::toUtf32(In begin, In end, Out output) Out Utf8::toUtf32(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
@ -306,7 +306,7 @@ Out Utf<8>::toUtf32(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
In Utf<16>::decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement) In Utf16::decode(In begin, In end, std::uint32_t& output, std::uint32_t replacement)
{ {
const std::uint16_t first = *begin++; const std::uint16_t first = *begin++;
@ -346,7 +346,7 @@ In Utf<16>::decode(In begin, In end, std::uint32_t& output, std::uint32_t replac
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
Out Utf<16>::encode(std::uint32_t input, Out output, std::uint16_t replacement) Out Utf16::encode(std::uint32_t input, Out output, std::uint16_t replacement)
{ {
if (input <= 0xFFFF) if (input <= 0xFFFF)
{ {
@ -383,7 +383,7 @@ Out Utf<16>::encode(std::uint32_t input, Out output, std::uint16_t replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
In Utf<16>::next(In begin, In end) In Utf16::next(In begin, In end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
return decode(begin, end, codepoint); return decode(begin, end, codepoint);
@ -392,7 +392,7 @@ In Utf<16>::next(In begin, In end)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
std::size_t Utf<16>::count(In begin, In end) std::size_t Utf16::count(In begin, In end)
{ {
std::size_t length = 0; std::size_t length = 0;
while (begin < end) while (begin < end)
@ -407,11 +407,11 @@ std::size_t Utf<16>::count(In begin, In end)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::fromAnsi(In begin, In end, Out output, const std::locale& locale) Out Utf16::fromAnsi(In begin, In end, Out output, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = Utf<32>::decodeAnsi(*begin++, locale); std::uint32_t codepoint = Utf32::decodeAnsi(*begin++, locale);
output = encode(codepoint, output); output = encode(codepoint, output);
} }
@ -421,11 +421,11 @@ Out Utf<16>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::fromWide(In begin, In end, Out output) Out Utf16::fromWide(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = Utf<32>::decodeWide(*begin++); std::uint32_t codepoint = Utf32::decodeWide(*begin++);
output = encode(codepoint, output); output = encode(codepoint, output);
} }
@ -435,7 +435,7 @@ Out Utf<16>::fromWide(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::fromLatin1(In begin, In end, Out output) Out Utf16::fromLatin1(In begin, In end, Out output)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -445,13 +445,13 @@ Out Utf<16>::fromLatin1(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) Out Utf16::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<32>::encodeAnsi(codepoint, output, replacement, locale); output = Utf32::encodeAnsi(codepoint, output, replacement, locale);
} }
return output; return output;
@ -460,13 +460,13 @@ Out Utf<16>::toAnsi(In begin, In end, Out output, char replacement, const std::l
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toWide(In begin, In end, Out output, wchar_t replacement) Out Utf16::toWide(In begin, In end, Out output, wchar_t replacement)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<32>::encodeWide(codepoint, output, replacement); output = Utf32::encodeWide(codepoint, output, replacement);
} }
return output; return output;
@ -475,7 +475,7 @@ Out Utf<16>::toWide(In begin, In end, Out output, wchar_t replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toLatin1(In begin, In end, Out output, char replacement) Out Utf16::toLatin1(In begin, In end, Out output, char replacement)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -491,13 +491,13 @@ Out Utf<16>::toLatin1(In begin, In end, Out output, char replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toUtf8(In begin, In end, Out output) Out Utf16::toUtf8(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
std::uint32_t codepoint = 0; std::uint32_t codepoint = 0;
begin = decode(begin, end, codepoint); begin = decode(begin, end, codepoint);
output = Utf<8>::encode(codepoint, output); output = Utf8::encode(codepoint, output);
} }
return output; return output;
@ -506,7 +506,7 @@ Out Utf<16>::toUtf8(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toUtf16(In begin, In end, Out output) Out Utf16::toUtf16(In begin, In end, Out output)
{ {
return priv::copy(begin, end, output); return priv::copy(begin, end, output);
} }
@ -514,7 +514,7 @@ Out Utf<16>::toUtf16(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<16>::toUtf32(In begin, In end, Out output) Out Utf16::toUtf32(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
{ {
@ -529,7 +529,7 @@ Out Utf<16>::toUtf32(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
In Utf<32>::decode(In begin, In /*end*/, std::uint32_t& output, std::uint32_t /*replacement*/) In Utf32::decode(In begin, In /*end*/, std::uint32_t& output, std::uint32_t /*replacement*/)
{ {
output = *begin++; output = *begin++;
return begin; return begin;
@ -538,7 +538,7 @@ In Utf<32>::decode(In begin, In /*end*/, std::uint32_t& output, std::uint32_t /*
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
Out Utf<32>::encode(std::uint32_t input, Out output, std::uint32_t /*replacement*/) Out Utf32::encode(std::uint32_t input, Out output, std::uint32_t /*replacement*/)
{ {
*output++ = input; *output++ = input;
return output; return output;
@ -547,7 +547,7 @@ Out Utf<32>::encode(std::uint32_t input, Out output, std::uint32_t /*replacement
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
In Utf<32>::next(In begin, In /*end*/) In Utf32::next(In begin, In /*end*/)
{ {
return ++begin; return ++begin;
} }
@ -555,7 +555,7 @@ In Utf<32>::next(In begin, In /*end*/)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
std::size_t Utf<32>::count(In begin, In end) std::size_t Utf32::count(In begin, In end)
{ {
return begin - end; return begin - end;
} }
@ -563,7 +563,7 @@ std::size_t Utf<32>::count(In begin, In end)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::fromAnsi(In begin, In end, Out output, const std::locale& locale) Out Utf32::fromAnsi(In begin, In end, Out output, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
*output++ = decodeAnsi(*begin++, locale); *output++ = decodeAnsi(*begin++, locale);
@ -574,7 +574,7 @@ Out Utf<32>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::fromWide(In begin, In end, Out output) Out Utf32::fromWide(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
*output++ = decodeWide(*begin++); *output++ = decodeWide(*begin++);
@ -585,7 +585,7 @@ Out Utf<32>::fromWide(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::fromLatin1(In begin, In end, Out output) Out Utf32::fromLatin1(In begin, In end, Out output)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -595,7 +595,7 @@ Out Utf<32>::fromLatin1(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) Out Utf32::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
{ {
while (begin < end) while (begin < end)
output = encodeAnsi(*begin++, output, replacement, locale); output = encodeAnsi(*begin++, output, replacement, locale);
@ -606,7 +606,7 @@ Out Utf<32>::toAnsi(In begin, In end, Out output, char replacement, const std::l
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toWide(In begin, In end, Out output, wchar_t replacement) Out Utf32::toWide(In begin, In end, Out output, wchar_t replacement)
{ {
while (begin < end) while (begin < end)
output = encodeWide(*begin++, output, replacement); output = encodeWide(*begin++, output, replacement);
@ -617,7 +617,7 @@ Out Utf<32>::toWide(In begin, In end, Out output, wchar_t replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toLatin1(In begin, In end, Out output, char replacement) Out Utf32::toLatin1(In begin, In end, Out output, char replacement)
{ {
// Latin-1 is directly compatible with Unicode encodings, // Latin-1 is directly compatible with Unicode encodings,
// and can thus be treated as (a sub-range of) UTF-32 // and can thus be treated as (a sub-range of) UTF-32
@ -633,20 +633,20 @@ Out Utf<32>::toLatin1(In begin, In end, Out output, char replacement)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toUtf8(In begin, In end, Out output) Out Utf32::toUtf8(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
output = Utf<8>::encode(*begin++, output); output = Utf8::encode(*begin++, output);
return output; return output;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toUtf16(In begin, In end, Out output) Out Utf32::toUtf16(In begin, In end, Out output)
{ {
while (begin < end) while (begin < end)
output = Utf<16>::encode(*begin++, output); output = Utf16::encode(*begin++, output);
return output; return output;
} }
@ -654,7 +654,7 @@ Out Utf<32>::toUtf16(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In, typename Out> template <typename In, typename Out>
Out Utf<32>::toUtf32(In begin, In end, Out output) Out Utf32::toUtf32(In begin, In end, Out output)
{ {
return priv::copy(begin, end, output); return priv::copy(begin, end, output);
} }
@ -662,7 +662,7 @@ Out Utf<32>::toUtf32(In begin, In end, Out output)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
std::uint32_t Utf<32>::decodeAnsi(In input, [[maybe_unused]] const std::locale& locale) std::uint32_t Utf32::decodeAnsi(In input, [[maybe_unused]] const std::locale& locale)
{ {
// Get the facet of the locale which deals with character conversion // Get the facet of the locale which deals with character conversion
const auto& facet = std::use_facet<std::ctype<wchar_t>>(locale); const auto& facet = std::use_facet<std::ctype<wchar_t>>(locale);
@ -674,7 +674,7 @@ std::uint32_t Utf<32>::decodeAnsi(In input, [[maybe_unused]] const std::locale&
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename In> template <typename In>
std::uint32_t Utf<32>::decodeWide(In input) std::uint32_t Utf32::decodeWide(In input)
{ {
// The encoding of wide characters is not well defined and is left to the system; // The encoding of wide characters is not well defined and is left to the system;
// however we can safely assume that it is UCS-2 on Windows and // however we can safely assume that it is UCS-2 on Windows and
@ -688,7 +688,7 @@ std::uint32_t Utf<32>::decodeWide(In input)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
Out Utf<32>::encodeAnsi(std::uint32_t codepoint, Out output, char replacement, [[maybe_unused]] const std::locale& locale) Out Utf32::encodeAnsi(std::uint32_t codepoint, Out output, char replacement, [[maybe_unused]] const std::locale& locale)
{ {
// Get the facet of the locale which deals with character conversion // Get the facet of the locale which deals with character conversion
const auto& facet = std::use_facet<std::ctype<wchar_t>>(locale); const auto& facet = std::use_facet<std::ctype<wchar_t>>(locale);
@ -702,7 +702,7 @@ Out Utf<32>::encodeAnsi(std::uint32_t codepoint, Out output, char replacement, [
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename Out> template <typename Out>
Out Utf<32>::encodeWide(std::uint32_t codepoint, Out output, wchar_t replacement) Out Utf32::encodeWide(std::uint32_t codepoint, Out output, wchar_t replacement)
{ {
// The encoding of wide characters is not well defined and is left to the system; // The encoding of wide characters is not well defined and is left to the system;
// however we can safely assume that it is UCS-2 on Windows and // however we can safely assume that it is UCS-2 on Windows and