4#include "Stroika/Foundation/StroikaPreComp.h"
15#if !qStroika_Foundation_Characters_SDKUseswchar_t
17 constexpr CodeCvt<wchar_t>::Options kAllowMissing_{.fInvalidCharacterReplacement = UTFConvert::Options::kDefaultMissingReplacementCharacter};
21#if not qStroika_Foundation_Characters_SDKUseswchar_t && not qStroika_Platform_MacOS
24 bool LocaleCanEncode_ (
const locale& l,
Character c)
26 static_assert (
sizeof (wchar_t) ==
sizeof (
char32_t));
27 using CVT = codecvt<wchar_t, char, mbstate_t>;
28 wchar_t w =
static_cast<wchar_t> (c.As<
char32_t> ());
30 const wchar_t* fromNext{};
33 return use_facet<CVT> (l).out (state, &w, &w + 1, fromNext, begin (to), end (to), toNext) == CVT::ok;
37 struct LocaleCodeCvts_ {
43 LocaleCodeCvts_ MakeLocaleCodeCvts_ (
const locale& l)
45 auto toSDK = kAllowMissing_;
46 if (not LocaleCanEncode_ (l, *toSDK.fInvalidCharacterReplacement)) {
47 toSDK.fInvalidCharacterReplacement =
'?';
54 thread_local bool tLocaleCodeCvtsCacheGone_{
false};
63 if (tLocaleCodeCvtsCacheGone_) [[unlikely]] {
64 return MakeLocaleCodeCvts_ (l).*which;
67 optional<LocaleCodeCvts_> fEntry;
70 tLocaleCodeCvtsCacheGone_ =
true;
73 static thread_local Cache_ tCache_;
74 if (not tCache_.fEntry or tCache_.fEntry->fLocale != l) [[unlikely]] {
75 tCache_.fEntry.emplace (MakeLocaleCodeCvts_ (l));
79 return (*tCache_.fEntry).*which;
89#if !qStroika_Foundation_Characters_SDKUseswchar_t
90wstring Characters::SDK2Wide (span<const SDKChar> s)
92#if qStroika_Platform_MacOS
96 return GetCodeCvt_ (&LocaleCodeCvts_::fStrict).
Bytes2String<wstring> (as_bytes (s));
101#if qStroika_Platform_MacOS
102 static const CodeCvt<wchar_t> kCvt_{UnicodeExternalEncodings::eUTF8, kAllowMissing_};
105 return GetCodeCvt_ (&LocaleCodeCvts_::fAllowMissingToWide).
Bytes2String<wstring> (as_bytes (s));
115#if !qStroika_Foundation_Characters_SDKUseswchar_t
118#if qStroika_Platform_MacOS
127#if qStroika_Platform_MacOS
128 static const CodeCvt<wchar_t> kCvt_{UnicodeExternalEncodings::eUTF8, kAllowMissing_};
CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt,...
nonvirtual STRINGISH Bytes2String(span< const byte > from) const
nonvirtual BLOBISH String2Bytes(span< const CHAR_T > from) const
basic_string< SDKChar > SDKString
AllowMissingCharacterErrorsFlag