Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
CodeCvt.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Characters_CodeCvt_h_
5#define _Stroika_Foundation_Characters_CodeCvt_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <bit>
10#include <locale>
11#include <optional>
12#include <span>
13#include <variant>
14
19
20/**
21 * \file
22 * Simple wrapper on std::codecvt, abstracting commonalities between std::codecvt and UTFConvert, to map characters (UNICODE) <--> bytes
23 */
24
26
27 using namespace std;
28
29 class String; // forward declare to reference without deadly embrace
30
31 namespace Private_ {
32 template <typename>
33 inline constexpr bool IsStdCodeCvt_ = false;
34 template <class _Elem, class _Byte, class _Statype>
35 inline constexpr bool IsStdCodeCvt_<const std::codecvt_byname<_Elem, _Byte, _Statype>*> = true; // @todo NOT CLEAR WHY THIS IS NEEDED???
36 template <class _Elem, class _Byte, class _Statype>
37 inline constexpr bool IsStdCodeCvt_<const std::codecvt<_Elem, _Byte, _Statype>*> = true;
38 }
39
40 /**
41 * Is std::codecvt or subclass of std::codecvt (such as codecvt_byname).
42 */
43 template <typename STD_CODECVT_T>
44 concept IStdCodeCVT = Private_::IsStdCodeCvt_<const STD_CODECVT_T*>;
45 DISABLE_COMPILER_MSC_WARNING_START (4996) // https://cplusplus.github.io/LWG/issue3767 DEPRECATED
46 static_assert (IStdCodeCVT<std::codecvt<char16_t, char8_t, std::mbstate_t>>);
47 static_assert (IStdCodeCVT<std::codecvt<char32_t, char8_t, std::mbstate_t>>);
48 DISABLE_COMPILER_MSC_WARNING_END (4996)
49 static_assert (IStdCodeCVT<std::codecvt<wchar_t, char, std::mbstate_t>>);
50 static_assert (IStdCodeCVT<std::codecvt_byname<wchar_t, char, std::mbstate_t>>);
51
52 /**
53 * \brief CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt, as well as UTFConvert etc, to map between span<bytes> and a span<UNICODE code-point>
54 *
55 * Note, UTFConvert is probably a slightly better API, and better designed, and faster. HOWEVER, it ONLY converts to/from UNICODE. std::codecvt can convert to/from
56 * any locale code page, and is is more general.
57 *
58 * Use the CodeCvt<> API when your code conversions may involve non UNICODE byte representations.
59 *
60 * Note that this class - like codecvt - can be used to 'page' over an input, and incrementally convert it (though how it does this
61 * differs from codecvt - not maintaining a partial state - but instead adjusting the amount consumed from the input to reflect
62 * full-character conversions).
63 *
64 * \note - if encountering invalid data in the input (invalid characters) - this will 'THROW' and not just fill in special bogus replacement
65 * characters.
66 *
67 * \note - the BINARY format character is OPAQUE given this API (you get/set bytes). The CHAR_T in the template argument
68 * refers to the 'CHARACTER' format you map to/from binary format (so typically wchar_t, or char32_t maybe).
69 *
70 * Enhancements over std::codecvt:
71 * o this is a span<> based API
72 * o You can subclass IRep (to provide your own CodeCvt implementation) and copy CodeCvt objects.
73 * (unless I'm missing something, you can do one or the other with std::codecvt, but not both)
74 * o Simpler backend virtual API, so easier to create your own compliant CodeCvt object.
75 * o CodeCvt leverages these two things via UTFConvert (which uses different library backends to do
76 * the UTF code conversion, hopefully enuf faster to make up for the virtual call overhead this
77 * class introduces).
78 * o Don't support 'partial' conversion.
79 * If there is insufficient space in the target buffer, this is an ASSERTION error - UNSUPPORTED.
80 * ALL 'srcSpan' CHARACTER data MUST be consumed/converted (for byte data; we allow
81 * only a single partial character at the end for Bytes2Characters takes ptr to span and updates span
82 * to reflect remaining bytes).
83 * o Dont bother templating output byte type (std::covert supports all the useless
84 * ones but misses the most useful, at least for fileIO, binary IO)
85 * o Don't support mbstate_t. Its opaque, and a PITA. And redundant.
86 * o lots of templated combinations (codecvt) dont make sense and dont work and there is no hint/validation
87 * clarity about which you can use/make sense and which you cannot with std::codecvt. Hopefully
88 * this class will make more sense.
89 * It can be used to convert (abstract API) between ANY combination of 'target hidden in implementation'
90 * and exposed CHAR_T characters (reading or writing). DEFAULT CTORS only provide the combinations
91 * supported by stdc++ (and a little more). To get other combinations, you must use subclass.
92 * o 'equivalent code-point types automatically supported (e.g wchar_t == char16 or char32, and
93 * Character==char32_t).
94 * o No explicit 'external_type' exposed. Just bytes go in and out vs (CHAR_T) UNICODE characters.
95 * This erasure of the 'encoding' type from the CodeCvt<CHAR_T> allows it to be used generically
96 * where its hidden in the 'rep' what kind of encoding is used.
97 *
98 * Difference:
99 * o Maybe enhancement, maybe step back:
100 * Must call ComputeTargetCharacterBufferSize/ComputeTargetByteBufferSize and provide
101 * an output buffer large enuf. This way, can NEVER get get partial conversion due to lack of output buffer space (which simplfies alot
102 * within this API). NOTE - large enuf doesn't necessarily mean as large as ComputeTargetCharacterBufferSize/ComputeTargetByteBufferSize would say, as those
103 * provide safe estimate. If you know for special reasons, you can use a smaller size, but the call must always FIT - no 'targetExhausted' exceptions thrown.
104 * o no 'noconv' error code (better in that simpler, but worse in that forces throw on bad characters)
105 *
106 * Enhancements over UTFConvert:
107 * o UTFConvert only supports UNICODE <-> UNICODE translations, even if in different
108 * UNICODE encodings. This API supports UNICODE <-> any arbitrary output binary format.
109 * o So in particular, it supports translating between UNICODE characters and locale encodings (e.g. SHIFT_JIS, or whatever).
110 *
111 * And:
112 * o All the existing codecvt objects (which map to/from UNICODE) can easily be wrapped in a CodeCvt
113 *
114 * CodeCvt as smart Ptr class, and an 'abstract class' (IRep) in that only for some CHAR_T types
115 * can it be instantiated directly (the ones std c++ supports, char_16_t, char32_t, and wchar_t with locale).
116 */
117 template <IUNICODECanAlwaysConvertTo CHAR_T = Character>
118 class CodeCvt {
119 public:
120 using intern_type = CHAR_T; // what codecvt calls the (internal/CHAR_T) character type
121
122 public:
123 struct IRep;
124
125 public:
126 /**
127 */
128 struct Options {
129 /**
130 * NOTE - do as New not CTOR, so can still construct Options using designated initializers.
131 */
132 template <qCompilerAndStdLib_ConstraintDiffersInTemplateRedeclaration_BWA (IUNICODECanAlwaysConvertTo) FROM_CHAR_T_OPTIONS>
133 static constexpr inline Options New (typename CodeCvt<FROM_CHAR_T_OPTIONS>::Options o);
134
135 /**
136 * if fInvalidCharacterReplacement is nullopt (the default) - conversion APIs throw on invalid characters, and
137 * otherwise use the value provided in fInvalidCharacterReplacement as the replacement for invalid characters.
138 *
139 * The replacement need not be representable in the byte encoding (e.g. U+FFFD in the "C" locale). Decoding
140 * (bytes to characters) always uses it; encoding uses it only if it can be encoded, and otherwise throws on an
141 * invalid character, as if no replacement had been given.
142 *
143 * Note - CodeCvt allows the Character to be comprised of multiple CHAR_T characters potentially.
144 */
145 optional<Character> fInvalidCharacterReplacement;
146 };
147
148 public:
149 /**
150 * Default CTOR:
151 * Produces the fastest available CodeCvt(), between the templated UNICODE code-point
152 * and UTF-8 (as the binary format).
153 *
154 * CodeCvt (const locale& l):
155 * Produces a CodeCvt which maps (back and forth) between bytes in the 'locale' character set, and
156 * UNICODE Characters.
157 *
158 * CodeCvt (const string& localeName):
159 * Is equivalent to mkFromStdCodeCvt<...> (std::codecvt_byname {localeName}) - so it can throw if no such locale name
160 *
161 * CodeCvt (span<const byte>* guessFormatFrom)
162 * the initial part of the span data (up to kMaxBOMSize bytes) are examined and used to select the CodeCvt to create (else default CodeCvt created).
163 * If a BOM is found, guessFormatFrom is adjusted to skip it.
164 *
165 * CodeCvt (CodePage):
166 * Can throw if the code page is not recognized. NOTE - CodePage is a Windows concept, and though many code pages
167 * are provided portable (@todo list) - many more are not, and will fail on non-windows, and succeed only on windows.
168 * The (Windows) code pages which are always (portably) provided include:
169 * WellKnownCodePages::kANSI
170 * WellKnownCodePages::kMAC
171 * WellKnownCodePages::PC, // IBM PC code page 437
172 * WellKnownCodePages::PCA, // IBM PC code page 850, used by IBM Personal System/2
173 * WellKnownCodePages::kGreek,
174 * WellKnownCodePages::kTurkish,
175 * WellKnownCodePages::kHebrew,
176 * WellKnownCodePages::kArabic,
177 * WellKnownCodePages::kUNICODE_WIDE, // Standard UNICODE for MS-Windows
178 * WellKnownCodePages::kUNICODE_WIDE_BIGENDIAN,
179 * WellKnownCodePages::UTF8
180 *
181 * To use (wrap) existing std::codecvt<A,B,C> class:
182 * Quirky, because classes not generally directly instantiable, so instead specify CLASS as template param
183 * and ARGS to CTOR.
184 * CodeCvt<CHAR_T,std::codecvt<CHAR_T, BINARY_T, MBSTATE_T>> {args to that class}
185 * Note works with subclasses of std::codecvt like std::codecvt_byname
186 *
187 * To get OTHER conversions, say between char16_t, and char32_t (combines/chains CodeCvt's):
188 * CodeCvt<CHAR_T>{UnicodeExternalEncodings} - Uses UTFConvert, along with any needed byte swapping
189 * CodeCvt<CHAR_T>{const CodeCvt<OTHER_CHAR_T> basedOn} - Use this to combine CodeCvt's (helpful for locale one)
190 *
191 * \par Example Usage:
192 * \code
193 * CodeCvt cc{"en_US.UTF8"};
194 * constexpr char8_t someRandomText[] = u8"hello mom";
195 * span<const byte> someRandomTextBinarySpan = as_bytes (span<const char8_t> {someRandomText, Characters::CString::Length (someRandomText)});
196 * StackBuffer<Character> buf{cc.ComputeTargetCharacterBufferSize (someRandomTextBinarySpan)};
197 * auto b = cc.Bytes2Characters (&someRandomTextBinarySpan, span{buf});
198 * EXPECT_TRUE (someRandomTextBinarySpan.size () == 0); // ALL CONSUMED
199 * EXPECT_TRUE (b.size () == 9 and b[0] == 'h');
200 * \endcode
201 *
202 * \par Example Usage:
203 * \code
204 * // codeCvt Between UTF16 Characters And UTF8BinaryFormat, best/fastest way
205 * CodeCvt<char16_t> codeCvt1{};
206 *
207 * // codeCvt Between UTF16 Characters And UTF8BinaryFormat using std::codecvt<char16_t, char8_t, std::mbstate_t>
208 * CodeCvt<char16_t> codeCvt2 = CodeCvt<char16_t>::mkFromStdCodeCvt<std::codecvt<char16_t, char8_t, std::mbstate_t>> ();
209 *
210 * // codeCvt Between UTF16 Characters using codecvt_byname
211 * CodeCvt<char16_t> codeCvt3 = CodeCvt<char16_t,std::codecvt_byname>>{locale{"en_US.UTF8"}};
212 *
213 * // or equivalently
214 * CodeCvt<char16_t> codeCvt4{"en_US.UTF8"};
215 * \endcode
216 *
217 *
218 * @todo - ASSURE THESE 'locale-names' always work:
219 * (case insensitive equals)
220 * utf-8
221 * ISO-8859-1
222 */
223 CodeCvt (const Options& options = Options{});
224 CodeCvt (const CodeCvt& src) = default;
225 CodeCvt (CodeCvt&& src) = default;
226 CodeCvt (const locale& l, const Options& options = Options{});
227 CodeCvt (const Charset& charset, const Options& options = Options{});
228 CodeCvt (UnicodeExternalEncodings e, const Options& options = Options{});
229 CodeCvt (span<const byte>* guessFormatFrom, const optional<CodeCvt>& useElse = nullopt, const Options& options = Options{});
230 CodeCvt (CodePage e, const Options& options = Options{});
231 template <IUNICODECanAlwaysConvertTo INTERMEDIATE_CHAR_T>
232 CodeCvt (const CodeCvt<INTERMEDIATE_CHAR_T>& basedOn);
233 CodeCvt (const shared_ptr<IRep>& rep);
234
235 public:
236 /**
237 * Note, though logically this should be a CodeCvt constructor, since you cannot directly construct
238 * the STD_CODECVT, it cannot be passed by argument to the constructor. And so their
239 * appears no way to deduce or specify those constructor template arguments. But that can be done
240 * explicitly with a static function, and that is what we do with mkFromStdCodeCvt.
241 *
242 * \note - everything else has options last argument, but since we use ... parameter pack, options must be first here.
243 */
244 template <IStdCodeCVT STD_CODECVT, typename... ARGS>
245 static CodeCvt mkFromStdCodeCvt (const Options& options = {}, ARGS... args)
246 requires (same_as<CHAR_T, typename STD_CODECVT::intern_type>);
247
248 public:
249 /**
250 * \brief The encoding the platform takes text to be in where nothing says otherwise: on Windows, the ANSI code page
251 * (GetACP - the system's "language for non-Unicode programs"); elsewhere, the environment's locale (LANG), or
252 * UTF-8 where that names none ("C", "POSIX", or not set)
253 *
254 * For text a program other than this one may have written - @see Streams::BinaryToText::ByteOrderMarkOr. Not the
255 * program's global C++ locale (locale{}), which is "C" until something calls locale::global.
256 */
257 static CodeCvt PlatformDefault (const Options& options = Options{});
258
259 public:
260 nonvirtual CodeCvt& operator= (const CodeCvt& rhs) = default;
261 nonvirtual CodeCvt& operator= (CodeCvt&& rhs) = default;
262
263 public:
264 /**
265 */
266 nonvirtual Options GetOptions () const;
267
268 public:
269 /**
270 * \brief convert span byte (external serialized format) parameters to characters (like std::codecvt<>::in () - but with spans, and simpler api)
271 *
272 * Convert bytes 'from' to characters 'to'.
273 *
274 * Arguments:
275 * o span<byte> from - initially all of which will be converted or an exception thrown (only if data corrupt/unconvertable) (updated to point to bytes which form part of a single additional character)
276 * o span<CHAR_T> to - buffer to have data converted 'into'
277 * NOTE - all we require is that the result fit into 'to'. But we offer a quick way to compute a buffer 'large enough' - (call ComputeTargetCharacterBufferSize).
278 * But (a more expensive) way is to call Bytes2Characters/1 and that will tell you exactly how many needed.
279 * Returns:
280 * subspan of 'to', with converted characters.
281 * Throws on failure (corrupt source content).
282 * And '*from' updated to reflect any remaining bytes that are part of the next character.
283 *
284 * Source bytes must begin on a valid character boundary (unlike codecvt - no mbstate).
285 * If the input buffer ends with any incomplete characters, *from will refer to those characters
286 * on function completion.
287 *
288 * The overload taking pointer to from returns the amount left. The overload taking span<> - not pointer -
289 * throws if not all consumed.
290 *
291 * The caller typically will wish to save those, and resubmit their BytesToCharacter call
292 * with a new buffer, starting with those (but there is no requirement to do so).
293 *
294 * No state is maintained. ALL the input is converted expect possibly a few bytes at the end of the input
295 * which constitute a partial character.
296 *
297 * This implies that given a 'lead byte' as argument to Bytes2Characters, this function can return
298 * an EMPTY span, and that would not be an error (so no throw).
299 *
300 * \note we use the name 'Bytes' - because its suggestive of meaning, and in every case I'm aware of
301 * the target type will be char, or char8_t, or byte. But its certainly not guaranteed to be serialized
302 * to byte, and the codecvt API calls this extern_type
303 *
304 * /2 overload \pre to.size () >= min(Bytes2Characters(*from), ComputeTargetCharacterBufferSize (*from)) on input.
305 * span<const byte>* \post from->size () very small on return (at most partial character)
306 *
307 * \see also Bytes2String for similar function, but operating on strings
308 */
309 nonvirtual size_t Bytes2Characters (span<const byte> from) const;
310 nonvirtual span<CHAR_T> Bytes2Characters (span<const byte>* from, span<CHAR_T> to) const;
311 nonvirtual span<CHAR_T> Bytes2Characters (span<const byte> from, span<CHAR_T> to) const;
312
313 public:
314 /*
315 * \brief convert span<character> parameter to a span of bytes (like std::codecvt<>::out () - but with spans, and otherwise simpler API)
316 *
317 * Convert characters 'from' to bytes 'to'.
318 *
319 * Arguments:
320 * o span<character> from - all of which will be converted or an exception thrown (only if data corrupt/unconvertable).
321 * o OPTIONAL span<byte> to - buffer to have data converted 'into', which MUST be large enuf (call ComputeTargetByteBufferSize)
322 * o span<span> to - buffer to have data converted 'into'
323 * NOTE - all we require is that the result fit into 'to'. BUt we offer a quick way to compute a buffer 'large enough' - (call ComputeTargetByteBufferSize).
324 * But (a more expensive) way is to call Characters2Bytes/1 and that will tell you exactly how many needed.
325 *
326 * Returns:
327 * (sub)subspan of 'to', (if provided)with characters converted to appropriate span of bytes.
328 * Else returns number of bytes it would have been converted to /1 overload).
329 * Throws on failure.
330 *
331 * No state is maintained. ALL the input is converted to all the output, on character
332 * boundaries.
333 *
334 * \note we use the name 'Bytes' - because its suggestive of meaning, and in most cases
335 * the target type will be char, or char8_t, or byte. But its certainly not guaranteed to be serialized
336 * to byte, and the codecvt API calls this extern_type
337 *
338 * /2 overload \pre to.size () >= min(ComputeTargetByteBufferSize (from),Characters2Bytes(from)) on input.
339 *
340 * \see also String2Bytes for similar function, but operating on strings
341 */
342 nonvirtual size_t Characters2Bytes (span<const CHAR_T> from) const;
343 nonvirtual span<byte> Characters2Bytes (span<const CHAR_T> from, span<byte> to) const;
344
345 public:
346 /*
347 * \brief Compute the size of 'to' span to use in call to Bytes2Characters
348 *
349 * \note this may guess a size too large, but will always guess a size large enuf
350 * In the case of the size_t overload, its obviously a worst-case guess
351 */
352 nonvirtual size_t ComputeTargetCharacterBufferSize (span<const byte> src) const;
353 nonvirtual size_t ComputeTargetCharacterBufferSize (size_t srcSize) const;
354
355 public:
356 /*
357 * \brief Compute the size of 'to' span to use in call to Characters2Bytes
358 *
359 * \note this may guess a size too large, but will always guess a size large enuf
360 * In the case of the size_t overload, its obviously a worst-case guess
361 */
362 nonvirtual size_t ComputeTargetByteBufferSize (span<const CHAR_T> src) const;
363 nonvirtual size_t ComputeTargetByteBufferSize (size_t srcSize) const;
364
365 public:
366 /**
367 * Convert a span of bytes (in a coding defined by the constructor to CodeCvt) to a 'string' like object - anything constructible from a 'span' of characters (e.g. String or wstring)
368 *
369 * NOTE - when converting Bytes2String, the String must be encoded using CHAR_T characters.
370 * The binary rep - can be anything - of course.
371 *
372 * \par Example Usage
373 * \code
374 * span<const byte> bytes = from_somewhere;
375 * static const CodeCvt<wchar_t> kCvt_{UnicodeExternalEncodings::eUTF8};
376 * wstring result = kCvt_.Bytes2String<wstring> (bytes);
377 * \endcode
378 *
379 * \par Example Usage
380 * \code
381 * span<const byte> bytes = from_somewhere;
382 * wstring result = CodeCvt<wchar_t>{locale{}}.Bytes2String<wstring> (bytes);
383 * \endcode
384 */
385 template <constructible_from<const CHAR_T*, const CHAR_T*> STRINGISH>
386 nonvirtual STRINGISH Bytes2String (span<const byte> from) const;
387
388 public:
389 /**
390 * Convert a span of characters ('string') to a BLOB-like object - anything constructible from a 'span' of bytes; note that container of a span of bytes maybe 'string' (special case).
391 *
392 * NOTE - when converting String2Bytes, the String must be encoded using CHAR_T characters.
393 * The binary rep - can be anything - of course.
394 *
395 * \par Example Usage
396 * \code
397 * span<const wchar_t> s = from_somewhere;
398 * static const CodeCvt<wchar_t> kCvt_{UnicodeExternalEncodings::eUTF8};
399 * string utf8String = kCvt_.String2Bytes<string> (s);
400 * \endcode
401 *
402 * \par Example Usage
403 * \code
404 * span<const wchar_t> s = from_somewhere;
405 * Memory::BLOB localeFormatRenderingOfUnicodeInputAsLocaleFormatByteStream = CodeCvt<wchar_t>{locale{}}.String2Bytes<Memory::BLOB> (s);
406 * \endcode
407 *
408 * \par Example Usage
409 * \code
410 * span<const wchar_t> s = from_somewhere;
411 * string localeFormatRenderingOfUnicodeInputAsLocaleFormatByteStream = CodeCvt<wchar_t>{locale{}}.String2Bytes<string> (s);
412 * \endcode
413 */
414 template <constructible_from<const byte*, const byte*> BLOBISH>
415 nonvirtual BLOBISH String2Bytes (span<const CHAR_T> from) const;
416
417 private:
418 shared_ptr<IRep> fRep_;
419
420#if qCompilerAndStdLib_template_second_concept_Buggy
421 private:
422 template <typename SERIALIZED_CHAR_T>
423 struct UTFConvertRep_;
424
425 private:
426 struct Latin1ConvertRep_;
427
428 private:
429 template <typename SERIALIZED_CHAR_T>
430 struct UTFConvertSwappedRep_;
431
432 private:
433 template <typename INTERMEDIATE_CHAR_T>
434 struct UTF2UTFRep_;
435#else
436 private:
437 template <IUNICODECanAlwaysConvertTo SERIALIZED_CHAR_T>
438 struct UTFConvertRep_;
439
440 private:
441 struct Latin1ConvertRep_;
442
443 private:
444 template <IUNICODECanAlwaysConvertTo SERIALIZED_CHAR_T>
445 struct UTFConvertSwappedRep_;
446
447 private:
448 template <IUNICODECanAlwaysConvertTo INTERMEDIATE_CHAR_T>
449 struct UTF2UTFRep_;
450#endif
451
452 private:
453 // requires CHAR_T = typename STD_CODE_CVT_T::intern_type
454 template <typename STD_CODE_CVT_T>
455 struct CodeCvt_WrapStdCodeCvt_;
456 };
457
458 template <IUNICODECanAlwaysConvertTo CHAR_T>
459 struct CodeCvt<CHAR_T>::IRep {
460 virtual ~IRep () = default;
461 virtual Options GetOptions () const = 0;
462 virtual span<CHAR_T> Bytes2Characters (span<const byte>* from, span<CHAR_T> to) const = 0;
463 virtual span<byte> Characters2Bytes (span<const CHAR_T> from, span<byte> to) const = 0;
464 virtual size_t ComputeTargetCharacterBufferSize (variant<span<const byte>, size_t> src) const = 0;
465 virtual size_t ComputeTargetByteBufferSize (variant<span<const CHAR_T>, size_t> src) const = 0;
466
467 protected:
468 // handy utility for subclasses / requires calls
469 nonvirtual size_t _Bytes2Characters (span<const byte> from) const;
470 nonvirtual size_t _Characters2Bytes (span<const CHAR_T> from) const;
471 };
472
473}
474
475/*
476 ********************************************************************************
477 ***************************** Implementation Details ***************************
478 ********************************************************************************
479 */
480#include "CodeCvt.inl"
481
482#endif /*_Stroika_Foundation_Characters_CodeCvt_h_*/
CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt,...
Definition CodeCvt.h:118
static CodeCvt mkFromStdCodeCvt(const Options &options={}, ARGS... args)
nonvirtual STRINGISH Bytes2String(span< const byte > from) const
nonvirtual size_t Bytes2Characters(span< const byte > from) const
convert span byte (external serialized format) parameters to characters (like std::codecvt<>::in () -...
Definition CodeCvt.inl:779
nonvirtual BLOBISH String2Bytes(span< const CHAR_T > from) const
UNICODE string can be always be converted into array of this type.
Definition Character.h:132
UnicodeExternalEncodings
list of external UNICODE character encodings, for file IO (eDEFAULT = eUTF8)
Definition UTFConvert.h:31
STL namespace.