ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
stdiostream.mpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of the \aliblong.
4/// With supporting legacy or module builds, .mpp-files are either recognized by the build-system
5/// as C++20 Module interface files, or are included by the
6/// #"alib_manual_modules_impludes;import/include headers".
7///
8/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
9/// Published under #"mainpage_license".
10//==================================================================================================
11#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
12# error "Configuration MACRO ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
13#endif
14#if ALIB_C20_MODULES
15 module;
16#endif
17//========================================= Global Fragment ========================================
19
20#include <variant>
21#include <string>
22#include <string_view>
23#include <iostream>
24#include <syncstream>
25
26//============================================== Module ============================================
27#if ALIB_C20_MODULES
28 /// This is a <em><b>C++ Module</b></em> of the \aliblong.
29 /// Due to the dual-compile option (either as C++20 Modules or using legacy C++ inclusion),
30 /// the C++20 Module names are not of further interest or use.<br>
31 /// In general, the names equal the names of the header files listed in the chapter
32 /// #"alib_manual_modules_impludes" of the \alib User Manual.
33 ///
34 /// @see The documentation of the <em><b>"ALib Module"</b></em> given with the corresponding
35 /// Programmer's Manual \alib_strings.
36 export module ALib.Strings.StdIOStream;
37 import ALib.Lang;
38# if ALIB_STRINGS
39 import ALib.Strings;
40# endif
41#else
42# include "ALib.Lang.H"
43# include "ALib.Strings.H"
44#endif
45
46//============================================= Exports ============================================
48ALIB_EXPORT namespace alib { namespace strings { namespace compatibility { namespace std {
49
50//==================================================================================================
51/// This template type may be specialized to suppress ambiguities for types \p{T} which
52/// - have <c>std::operator<<(ostream, const T&)</c> defined, \b and
53/// - are #"alib_strings_assembly_ttostring;appendable" to \alib strings.
54///
55/// \note
56/// The ambiguity occurs due to the definition of <c>std::operator<<</c> for all appendable
57/// types.
58///
59/// If a specialization of this template struct exists that inherits <c>std::true_type</c>,
60/// the compiler will not choose the \alib implementation of the operator, which resolves the
61/// ambiguity.
62///
63/// \see
64/// Specialization might be done with macro
65/// #"ALIB_STRINGS_SUPPRESS_STD_OSTREAM_OPERATOR".
66///
67/// @tparam T The appendable type to suppress
68//==================================================================================================
69template<typename T> struct SuppressStdOStreamOpTraits : ::std::false_type {};
70
71//==================================================================================================
72/// Parameter class used to append to objects of type #"TAString;AString", which
73/// invokes the method of the according specialization of template struct
74/// <b>AppendableTraits<TIStreamLine,TChar,HeapAllocator></b>.<br>
75/// This then reads a line of text from the encapsulated \b std::istream and appends that line to
76/// the target \b %AString.
77///
78/// This class can be created 'inline', similar to, for example,
79/// #"alib_strings_assembly_ttostring_builtin;special types appendable to" class \b AString.
80/// But in the common cases, where a series of lines are to be read from a \b std::istream, a local
81/// object of this type should be created.
82/// In the case of a reading-loop, it is efficient to place it outside such a loop.
83///
84/// Field #"IsEOF" can be used to detect the end of the input stream.
85///
86/// \see
87/// - #"compatibility::std::operator>>(std::istream&, alib::NAString&)" and
88/// #"std::operator<<(std::ostream&, const alib::NString&)".
89/// - For a sample, refer to the source code of \alib class \b %IniFile, method
90/// #"IniFile::Read;*".
91///
92///
93/// @tparam TChar The character type of the input stream as well as the receiving string.<br>
94/// Specializations for character types #"characters::nchar",
95/// #"characters::wchar" exist. Those have corresponding alias type definition
96/// shortcuts #"IStreamLineN" and #"IStreamLineW" in namespace #"alib".
97//==================================================================================================
98template<typename TChar>
100{
101 /// The input stream to read from.
102 ::std::basic_istream<TChar>* IStream;
103
104 /// If \c CurrentData::KEEP, the target \c %AString is not cleared before the read operation.
106
107 /// The number of characters that the buffer is increased while reading parts of the line.
109
110 /// The maximum length of a single line to be read. Longer lines get truncated.
112
113 /// Indicates if the end of the input stream was detected with the last read operation.
114 /// If so, a next read operation will not change the string (or clear it, if #"TargetData" is
115 /// \c false
116 bool IsEOF = false;
117
118 /// Constructor.
119 ///
120 /// @param istream The input stream to read from.
121 /// @param targetData If \c CurrentData::Keep, the target \c %AString is not cleared
122 /// before the read operation is performed.
123 /// Defaults to \c CurrentData::Clear.
124 /// @param bufferSize The number of characters that the buffer is increased while reading
125 /// parts of the line. Defaults to 4096 characters.
126 /// @param maxLineWidth The maximum length of a single line to be read. Longer lines
127 /// get truncated. Defaults to 4096 characters.
128 TIStreamLine( ::std::basic_istream<TChar>* istream,
130 integer bufferSize = 4096,
131 integer maxLineWidth = 4096 )
132 : IStream (istream),
133 TargetData (targetData),
134 BufferSize (bufferSize),
135 MaxLineWidth(maxLineWidth) {}
136};
137
138
139}} // namespace alib::strings[::compatibility::std]
140
141#if DOXYGEN
142 namespace APPENDABLES {
143#endif
144
145/// Specialization of the type trait #"strings::AppendableTraits;*" for type
146/// #"std::TIStreamLine".
147/// @tparam TChar The <b>AString</b>'s #"alib_characters_chars;character type".
148template<typename TChar> struct AppendableTraits<compatibility::std::TIStreamLine<TChar>, TChar, lang::HeapAllocator>
149{
150 /// Reads a line from a text file and appends the contents to \p{target}.
151 /// If the end of the input stream was reached, field
152 /// #"TIStreamLine;IsEOF" of parameter \p{reader} will be set
153 /// to \c true, which indicates that the next read operation would fail if it was performed.
154 ///
155 /// \note
156 /// For setting field <em>IsEOF</em> the object will be cast to a non-constant reference.
157 /// See functor #"strings::AppendableTraits;*" for an explanation why it is OK to do so.
158 ///
159 /// @param target The AString object to read into.
160 /// @param reader The object holding the \b std::istream and some parameters.
163};
164
165#if DOXYGEN
166}
167#endif
168
169
170namespace compatibility { namespace std {
171
172//==================================================================================================
173/// This class writes \alib_strings into instances of
174/// <c>std::basic_ostream<TChar></c>. The features of this type are:
175/// - Supports writing into narrow and wide output streams (<c>std::ostream</c> and
176/// <c>std::wostream</c>). The character width is controlled with the template parameter \p{TChar}.
177/// - Accepts \alib strings of all three character widths (narrow, wide, and
178/// #"ch xchar;strange" strings).
179/// - The template parameter \p{TSynced} allows syncing the output in multithreaded applications
180/// to avoid interleaving of output.
181/// For this, the C++ 20 mechanism provided with type
182/// \https{std::osyncstream,https://en.cppreference.com/w/cpp/io/basic_osyncstream} is used.
183/// This allows syncing across C++ libraries that rely on the same standard.<br>
184/// If syncing is enabled, output is emitted to the stream only at the moment that the
185/// corresponding instance of this class is destructed.
186/// - Optionally, this type converts non-conform newline sequences to the desired coding.
187/// For example, if the given strings contain WindowsOS newline codes <c>"\r\n"</c>, on GNU/Linux
188/// platforms, just <c>"\n"</c> may be written. This feature is controlled by the template
189/// parameter \p{TTargetLF}.
190/// - The type counts the number of printed characters with its overloaded method
191/// #".Write(const NString&)".
192/// "Printed" here means that it is how many characters in a <em>UTF8-enconding</em>
193/// would effectively be shown, if printed.
194/// - The type uses \alib allocators for memory management.
195///
196/// It is recommended that only short-living, local instances of this class are created.
197/// This is especially important in the case that parameter \p{TSynced} is \c true.
198/// In this mode, this type follows the
199/// \https{RAII idiom,https://en.cppreference.com/w/cpp/language/raii} just as its then
200/// available member <c>std::osyncstream</c> does.
201///
202/// \note As of 10/2025, some toolchains might not support the C++20 output stream synchronization,
203/// yet. In this case, the code compiles without using it, and the output is not synchronized
204/// and may interleave.<br>
205/// Clang's standard library \e libc++ (which can be activated with
206/// \alib with CMake variable #"alib_manual_build_cmake_3;ALIB_CLANG_USE_LIBCPP"),
207/// in its version \b 200100 supports class <c>std::osyncstream</c> only if the compiler
208/// flag <c>-fexperimental-library</c> is provided.
209///
210/// @tparam TChar The character type of the target <c>std::basic_ostream</c>.
211/// Defaults to #"characters::nchar" (which effectively is C++ \c char).
212/// @tparam TAllocator The #"lang::Allocator;allocator type" to use with
213/// <c>std::osyncstream</c> (if \p{TSynced} is \c true), and with temporary
214/// character conversion buffers in case those need to exceed 4kB.<br>
215/// Defaults to #"HeapAllocator".
216/// @tparam TSynced Determines if the encapsulated <c>std::ostream</c> should be synchronized
217/// on writing. If so, the C++ 20 mechanism provided with
218/// \https{std::osyncstream,https://en.cppreference.com/w/cpp/io/basic_osyncstream}
219/// is used, as well as \alib's built-in mechanism provided with the global mutex
220/// #"STD_IOSTREAMS_LOCK".
221/// Both mechanics togoether allows syncing across C++ libraries and in
222/// respect to ouput generated with \alib, synchronization between
223/// <c>std::cout</c> and <c>std::cerr</c>.
224/// @tparam TTargetLF Determines whether non-conform line-feeds are adjusted.
225/// The default value is #"LineFeeds;Platform", which converts all
226/// line-feeds to the platforms' standard. Values #"LineFeeds;Unix"
227/// and #"LineFeeds;WindowsOS" can be used to force conversion
228/// to a different standard. Finally, #"LineFeeds;Ignore" disables
229/// the detection and conversion of line-feed codes.
230//==================================================================================================
231template< typename TChar = nchar,
232 typename TAllocator= lang::HeapAllocator,
233 bool TSynced = false,
235requires (::std::is_same_v<TChar, char> || ::std::is_same_v<TChar, wchar_t>)
236class OStreamWriter : public lang::AllocatorMember<TAllocator> {
237 protected:
238 /// The type of the base class that stores the allocator.
240
241 public:
242 static constexpr bool Synced = TSynced; ///< Exposes template parameter \p{TSynced}.
243 using CharType = TChar; ///< Exposes template parameter \p{TChar}.
244 using AllocatorType= TAllocator; ///< Exposes template parameter \p{TAllocator}.
245 static constexpr
246 lang::LineFeeds TargetLF = TTargetLF; ///< Exposes template parameter \p{TAdjustLF}.
247
248 /// This flag may be set after construction to disable the syncing mechanics, even if
249 /// the template parameter \p{TSynced} is set. This is useful, for example, if a using code
250 /// detects recursion, which is not allowed with \c std::osyncstream and
251 /// #"STD_IOSTREAMS_LOCK".
252 bool DisableSync =false;
253
254 protected:
255 #if defined(__cpp_lib_syncbuf) || DOXYGEN
256 /// If unsynced, this member holds the output stream as provided with construction.
257 /// In the synced case, this stores a <c>std::basic_osyncstream</c> which wraps the given
258 /// output stream.
259 ::std::conditional_t<TSynced && !ALIB_SINGLE_THREADED,
260 ::std::basic_osyncstream< TChar,
261 ::std::char_traits<TChar>,
263 ::std::basic_ostream<TChar>& > ostream;
264 #else
265 ::std::basic_ostream<TChar>& ostream;
266 #endif
267
268 /// Implementation of overloaded methods #".Write(const NString&)".
269 /// @param src The string to write.
270 /// @param[out] printedWidth If given, the output width of \p{src} when it was printed
271 /// is returned. (See the class description for further information.)
272 /// @tparam TSrc The character type of the source string.
273 template<typename TSrc>
274 void doWrite( const TString<TSrc>& src, integer* printedWidth ) {
275 integer lineStart= 0;
276 integer lineEnd = 0;
277 if ( printedWidth )
278 *printedWidth= 0;
279 bool done= TTargetLF != lang::LineFeeds::Ignore ? false : true;
280
281 #if !ALIB_SINGLE_THREADED && (defined(__cpp_lib_syncbuf) || DOXYGEN )
282 // create an empty owner and fill it in case that a) this object is synced, and b) the
283 // encapsulated ostream is either std::cout or std::cerr.
285 if constexpr (TSynced)
286 if ( !DisableSync
287 && ( ostream.get_wrapped() == ::std::cout.rdbuf()
288 || ostream.get_wrapped() == ::std::cerr.rdbuf() ) )
289 ioLocker.Set( &threads::STD_IOSTREAMS_LOCK );
290 #endif
291
292 for (;;) {
293 if constexpr ( TTargetLF != lang::LineFeeds::Ignore ) {
294 lineEnd= src.IndexOf('\n', lineStart);
295 if (lineEnd == -1) {
296 lineEnd= src.Length();
297 done= true;
298 } }
299 else
300 lineEnd= src.Length();
301
302 integer writeEnd= lineEnd;
303 if (src.CharAt(writeEnd - 1) == '\r' )
304 --writeEnd;
305 if (writeEnd > lineStart) {
306 if constexpr (::std::is_same_v<TChar, TSrc>) {
307 if ( printedWidth )
308 *printedWidth= TString<TChar>( src.Buffer() + lineStart, writeEnd - lineStart ).WStringLength();
309 ostream.write( src.Buffer() + lineStart, writeEnd - lineStart );
310 } else {
311
314 TString<TSrc> line(src.Buffer() + lineStart, writeEnd - lineStart);
315 converter << line;
316 ostream.write( converter.Buffer(), converter.Length() );
317 if ( printedWidth ) {
318 if constexpr (::std::is_same_v<TChar, wchar>)
319 *printedWidth= converter.Length();
320 else
321 *printedWidth= line.Length();
322 } } }
323
324 if ( done )
325 break;
326
327 // write the line feed as specified by TTargetLF
328 if constexpr ( TTargetLF == lang::LineFeeds::Unix ) {
329 if constexpr ( ::std::is_same_v<TChar, nchar> ) ostream.write( "\n", 1 );
330 else ostream.write( L"\n", 1 );
331 } else if constexpr ( TTargetLF == lang::LineFeeds::WindowsOS ) {
332 if constexpr ( ::std::is_same_v<TChar, nchar> ) ostream.write( "\r\n", 2 );
333 else ostream.write( L"\r\n", 2 );
334 }
335 lineStart= lineEnd + 1;
336 } }
337
338 public:
339 /// Constructor accepting the destination stream.
340 /// @param os The output-stream to use.
341 OStreamWriter(::std::basic_ostream<TChar> &os)
342 : ostream( os ) {}
343
344 #if !defined(__cpp_lib_syncbuf) || ALIB_SINGLE_THREADED || DOXYGEN
345 /// Constructor accepting the destination stream, as well as an allocator to use.
346 /// @param os The output-stream to use.
347 /// @param alloc The allocator to use for the internal buffers.
348 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
349 : allocBase(alloc)
350 , ostream( os ) {}
351 #else
352 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
353 requires (!TSynced)
354 : allocBase(alloc)
355 , ostream( os ) {}
356
357 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
358 requires (TSynced)
359 : allocBase{alloc}
360 , ostream { os.rdbuf() , lang::StdAllocator<TChar, TAllocator>(alloc) } {}
361 #endif
362
363 /// Returns the output stream given with construction, or, if template parameter \p{TSynced}
364 /// is \c true, that output stream wrapped in a <c>std::basic_osyncstream</c>.
365 /// In the latter case, the sync-stream is destructed - and data is written - only with the
366 /// destruction of this instance.
367 /// @return The output stream of this writer.
368 ::std::ostream& GetStream() { return ostream; }
369
370 /// Writes the given narrow string to the stream.
371 ///
372 /// \note
373 /// The output parameter \p{printedWidth} returns the length of the given string, when
374 /// it was converted to wide string. This is done, even if template parameter \p{TChar}
375 /// is narrow and consequently no conversion was performed.<br>
376 /// The value is useful to callers when the "real" output width is needed, i.e., when
377 /// the output text is formatted in tabulator columns or tables.
378 /// Of course, in some locales, this might still not be the correct output width because even
379 /// uni-code characters are not guaranteed to represent exactly one printable character.
380 /// But still, this value is already a much better approximation than the length of the
381 /// given narrow string.
382 ///
383 /// @param src The string to write.
384 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
385 /// See the note above. If not given, the method might execute
386 /// slightly faster.
387 void Write( const NString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
388
389 /// See sibling method #"Write(const NString& src, integer* printedWidth)".
390 /// @param src The wide string to write.
391 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
392 /// See the note above. If not given, the method might execute
393 /// slightly faster.
394 void Write( const WString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
395
396 /// See sibling method #"Write(const NString& src, integer* printedWidth)".
397 /// @param src The strange string to write.
398 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
399 /// See the note above. If not given, the method might execute
400 /// slightly faster.
401 void Write( const XString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
402
403 /// Write the given character repeatedly to the stream.
404 /// @param fillChar The character to write.
405 /// @param count The number of characters to write.
406 void Fill( const TChar fillChar, integer count ) {
407 characters::AlignedCharArray<TChar, 8*sizeof(void*)> alc( fillChar );
408 while (count >= alc.Length() ) {
409 ostream.write(alc.Buffer(), alc.Length());
410 count-= alc.Length();
411 }
412
413 if (count > 0)
414 ostream.write(alc.Buffer(), count);
415 }
416
417
418};
419
420/// @param os The output-stream to use.
421template< typename TChar = nchar,
422 typename TAllocator= lang::HeapAllocator,
423 bool TSynced = false,
425OStreamWriter(::std::basic_ostream<TChar>& os)
427
428/// C++17 Deduction Guide to construct the type #"std::OStreamWriter".
429/// @param os The output-stream to use.
430/// @param allocator The allocator to use for the internal buffers.
431template< typename TChar = nchar,
432 typename TAllocator= lang::HeapAllocator,
433 bool TSynced = false,
435OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator allocator)
437
438//==================================================================================================
439/// This class is a helper-class that converts narrow string data read from an object of
440/// type \c std::istream to the #"characters::character;default character type".
441///
442/// \see Class #"std::OStreamWriter".
443//==================================================================================================
445{
446 protected:
447 /// The string buffer used for conversion.
449
450 /// The input stream as provided with #"SetStream". Will be set to the \c std::cin,
451 /// respectively \c std::win in the constructor.
453
454
455 public:
456 /// Constructor.Invokes #SetStream passing \c std::cin.
457 /// @param bufferSize The number of characters that the buffer is increased while reading
458 /// parts of the line. Defaults to 4096 characters.
459 /// @param maxLineWidth The maximum length of a single line to be read. Longer lines
460 /// get truncated. Defaults to 4096 characters.
461 IStreamReader( integer bufferSize= 4096, integer maxLineWidth = 4096 )
462 : readOp( &::std::cin, lang::CurrentData::Clear, bufferSize, maxLineWidth )
463 {}
464
465 /// Sets the input stream.
466 /// @param is Pointer to the input stream to read from to.
467 void SetStream( ::std::istream* is ) { readOp.IStream= is; }
468
469 /// Returns the input stream previously set with #SetStream.
470 /// @return The input stream set with #SetStream.
471 ::std::istream* GetStream() { return readOp.IStream; }
472
473 /// Returns \c true if the input stream signaled its end, \c false otherwise.
474 /// @return \c true if the input stream is known to be at its end, \c false otherwise.
475 bool IsEOF() { return readOp.IsEOF; }
476
477
478 /// Reads one line of text from the input stream into a narrow string.
479 /// @param target The storage buffer for the string to read. This string will be cleared
480 /// independent of the availability of input data.
481 void Read( NAString& target ) { target.Reset( readOp ); }
482
483 /// Reads one line of text from the internal input stream into a wide string.
484 /// @param target The storage buffer for the string to read. This string will be cleared
485 /// independent of the availability of input data.
486 void Read( WAString& target ) {
487 target.Reset();
488 converter.Reset( readOp );
489 target << converter;
490 }
491};
492
493}}} // namespace alib[::strings::compatibility::std]
494
495/// Type alias in namespace \b alib.
497
498/// Type alias in namespace \b alib.
500
501/// Type alias in namespace \b alib.
503
504/// Type alias in namespace \b alib.
505template< typename TChar = nchar,
506 typename TAllocator= lang::HeapAllocator,
507 bool TSynced = false,
510 TTargetLF>;
511
512/// Type alias in namespace \b alib.
514
515//##################################################################################################
516//##################################### std::ostream& operator<< ###################################
517//##################################################################################################
518#if DOXYGEN
519 namespace strings { namespace compatibility { namespace std {
520#else
521} // namespace [alib]
522#endif
523
524//==================================================================================================
525/// Copies the contents of the given \b %NString to into the \c std::ostream given as reference.
526///
527/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
528/// @param stream The ostream object to write the given String into.
529/// @param string The String to write into the given ostream.
530/// @returns The ostream to allow concatenated operations.
531//==================================================================================================
533inline std::ostream& operator<<( std::ostream& stream, const alib::NString& string ) {
534 if ( string.IsNotEmpty() )
535 stream.write( string.Buffer(), string.Length() );
536 return stream;
537}
538
539//==================================================================================================
540/// Copies the contents of the given \b %NString to into the \c std::ostream given as pointer.
541///
542/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
543/// @param stream The ostream object to write the given String into.
544/// @param string The String to write into the given ostream.
545/// @returns The ostream to allow concatenated operations.
546//==================================================================================================
548inline std::ostream* operator<<( std::ostream* stream, const alib::NString& string )
549{
550 stream->write( string.Buffer(), string.Length() );
551 return stream;
552}
553
554//==================================================================================================
555/// Copies the contents of the given \b %WString to into the \c std::ostream given as reference.
556///
557/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
558/// @param stream The ostream object to write the given String into.
559/// @param string The String to write into the given ostream.
560/// @returns The ostream to allow concatenated operations.
561//==================================================================================================
563ALIB_DLL std::ostream& operator<<( std::ostream& stream, const alib::WString& string );
564
565//==================================================================================================
566/// Copies the contents of the given \b %WString to into the \c std::ostream given as pointer.
567///
568/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
569/// @param stream The ostream object to write the given String into.
570/// @param string The String to write into the given ostream.
571/// @returns The ostream to allow concatenated operations.
572//==================================================================================================
574inline std::ostream* operator<<( std::ostream* stream, const alib::WString& string )
575{
576 (*stream) << string;
577 return stream;
578}
579
580//==================================================================================================
581/// Copies the contents of the given \b %NString to into the \c std::wostream given as reference.
582///
583/// \note
584/// This operator uses a local string buffer of 256 bytes size to convert the given narrow string
585/// to an string of \c wchar_t characters that the output stream accepts. In case that
586/// the given \p{string} is larger, a dynamic memory allocation has to be made.<br>
587/// In performance-critical code that writes larger string data, a custom conversion method,
588/// that, for example, reuses a buffer, may be appropriate.
589///
590/// <p>
591/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
592/// @param stream The ostream object to write the given String into.
593/// @param string The String to write into the given ostream.
594/// @returns The ostream to allow concatenated operations.
595//==================================================================================================
597ALIB_DLL std::wostream& operator<<( std::wostream& stream, const alib::NString& string );
598
599//==================================================================================================
600/// Copies the contents of the given \b %NString to into the \c std::wostream given as pointer.
601///
602/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
603/// \see The notes on memory efficiency, documented with operator
604/// #"operator<<(std::wostream&,const alib::NString&)"
605/// which this operator uses inline.
606/// @param stream The ostream object to write the given String into.
607/// @param string The String to write into the given ostream.
608/// @returns The ostream to allow concatenated operations.
609//==================================================================================================
611inline std::wostream* operator<<( std::wostream* stream, const alib::NString& string )
612{
613 (*stream) << string;
614 return stream;
615}
616
617//==================================================================================================
618/// Copies the contents of the given \b %WString to into the \c std::wostream given as reference.
619///
620/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
621/// @param stream The ostream object to write the given String into.
622/// @param string The String to write into the given ostream.
623/// @returns The ostream to allow concatenated operations.
624//==================================================================================================
626inline std::wostream& operator<<( std::wostream& stream, const alib::WString& string ) {
627 if ( string.IsNotEmpty() ) {
628 #if ALIB_CHARACTERS_NATIVE_WCHAR
629 stream.write( string.Buffer(), string.Length() );
630 #else
631 alib::XLocalString<1024> converter( string );
633 stream.write( converter.Buffer(), converter.Length() );
634 #endif
635 }
636 return stream;
637}
638
639//==================================================================================================
640/// Copies the contents of the given \b %WString to into the \c std::wostream given as pointer.
641///
642/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
643/// @param stream The ostream object to write the given String into.
644/// @param string The String to write into the given ostream.
645/// @returns The ostream to allow concatenated operations.
646//==================================================================================================
648inline std::wostream* operator<<( std::wostream* stream, const alib::WString& string )
649{
650 (*stream) << string;
651 return stream;
652}
653
654//==================================================================================================
655/// Clears the given \b %NAString and extracts data from the std::istream into it. The extraction
656/// ends with either the end of the std::istream or when reading a newline character.
657///
658/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
659/// @param stream The istream object to extract data from.
660/// @param string The AString to receive data.
661/// @returns The ostream to allow concatenated operations.
662//==================================================================================================
664inline std::istream& operator>>( std::istream& stream, alib::NAString& string ) {
665 string << alib::strings::compatibility::std::TIStreamLine<alib::nchar>( &stream,
667 return stream;
668}
669
670//==================================================================================================
671/// Clears the given \b %NAString and extracts data from the std::istream into it. The extractions
672/// ends with either the end of the std::istream or when reading a newline character.
673///
674/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
675/// @param stream The istream object to extract data from.
676/// @param string The AString to receive data.
677/// @returns The ostream to allow concatenated operations.
678//==================================================================================================
680inline std::istream* operator>>( std::istream* stream, alib::NAString& string ) {
681 ALIB_ASSERT_WARNING( stream != nullptr, "STRINGS", "Given std::IStream is nullptr" )
682
683 if (stream != nullptr)
684 string << alib::strings::compatibility::std::TIStreamLine<alib::nchar>( stream,
686 return stream;
687}
688
689//==================================================================================================
690/// Clears the given \b %WAString and extracts data from the std::istream into it. The extractions
691/// ends with either the end of the std::istream or when reading a newline character.
692///
693/// \note
694/// If code selection macro #"ALIB_CHARACTERS_NATIVE_WCHAR" evaluates to false, a local buffer
695/// is used to convert the string of \c wchar_t characters that the input stream provides.
696/// In case that the string read from the stream is larger, a dynamic memory allocation has to
697/// be made.<br>
698/// In performance-critical code that receives larger string data, a custom conversion method
699/// that, for example, reuses a buffer may be appropriate.
700///
701/// <p>
702/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
703/// @param stream The istream object to extract data from.
704/// @param string The AString to receive data.
705/// @returns The ostream to allow concatenated operations.
706//==================================================================================================
708inline std::basic_istream<wchar_t>& operator>>( std::basic_istream<wchar_t>& stream,
709 alib::WAString& string ) {
710 #if ALIB_CHARACTERS_NATIVE_WCHAR
711 string << alib::strings::compatibility::std::TIStreamLine<wchar_t>( &stream,
713 #else
714 alib::XLocalString<1024> converter;
716 converter << alib::strings::compatibility::std::TIStreamLine<wchar_t>( &stream,
718 string.Reset( converter );
719 #endif
720 return stream;
721}
722
723//==================================================================================================
724/// Clears the given \b %WAString and extracts data from the std::istream into it. The extractions
725/// ends with either the end of the std::istream or when reading a newline character.
726///
727/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
728///
729/// \see The notes on memory efficiency, documented with operator
730/// #"operator>>(std::basic_istream<wchar_t>&, alib::WAString& )"
731/// which this operator uses inline.
732/// @param stream The istream object to extract data from.
733/// @param string The AString to receive data.
734/// @returns The ostream to allow concatenated operations.
735//==================================================================================================
737inline std::basic_istream<wchar_t>* operator>>( std::basic_istream<wchar_t>* stream,
738 alib::WAString& string ) {
739 ALIB_ASSERT_WARNING ( stream != nullptr, "STRINGS", "Given std::istream is nullptr" )
740
741 if (stream != nullptr)
742 (*stream) >> string;
743 return stream;
744}
745
746
747//==================================================================================================
748/// Copies the contents of the given #"alib_strings_assembly_ttostring;appendable type"
749/// the \c std::ostream given as reference.
750///
751/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
752///
753/// @tparam TAppendable The appendable type.
754/// @param stream The \c std::ostream object to write the given String into.
755/// @param appendable The object whose contents is to be written into the given \p{stream}.
756/// @returns The ostream to allow concatenated operations.
757//==================================================================================================
759template<typename TAppendable>
762std::ostream& operator<<( std::ostream& stream, const TAppendable& appendable ) {
765
766 if ( buf._(appendable).IsNotEmpty() )
767 stream.write( buf.Buffer(), buf.Length() );
768 return stream;
769}
770
771//==================================================================================================
772/// Copies the contents of the given #"AppendableTraits;appendable type" the \c std::ostream
773/// given as pointer.
774///
775/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
776///
777/// @tparam TAppendable The appendable type.
778/// @param stream The \c std::ostream object to write the given String into.
779/// @param appendable The object whose contents is to be written into the given \p{stream}.
780/// @returns The ostream to allow concatenated operations.
781//==================================================================================================
783template<typename TAppendable>
786std::ostream* operator<<( std::ostream* stream, const TAppendable& appendable ) {
787 if (stream != nullptr)
788 operator<<( * stream, appendable );
789 return stream;
790}
791
792//==================================================================================================
793/// Copies the contents of the given #"AppendableTraits;appendable type" the \c std::ostream
794/// given as reference.
795///
796/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
797///
798/// @tparam TAppendable The appendable type.
799/// @param stream The \c std::ostream object to write the given String into.
800/// @param appendable The object whose contents is to be written into the given \p{stream}.
801/// @returns The ostream to allow concatenated operations.
802//==================================================================================================
804template<typename TAppendable>
807std::wostream& operator<<( std::wostream& stream, const TAppendable& appendable ) {
808 #if ALIB_CHARACTERS_NATIVE_WCHAR
810 #else
812 #endif
814
815 if ( buf._(appendable).IsNotEmpty() )
816 stream.write( buf.Buffer(), buf.Length() );
817 return stream;
818}
819
820//==================================================================================================
821/// Copies the contents of the given #"AppendableTraits;appendable type" the \c std::ostream
822/// given as a pointer.
823///
824/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
825///
826/// @tparam TAppendable The appendable type.
827/// @tparam TAllocator The allocator type, as prototyped with class #"lang::Allocator".
828/// @param stream The \c std::ostream object to write the given String into.
829/// @param appendable The object whose contents is to be written into the given \p{stream}.
830/// @returns The ostream to allow concatenated operations.
831//==================================================================================================
833template<typename TAppendable, typename TAllocator>
836std::wostream* operator<<( std::wostream* stream, const TAppendable& appendable ) {
837 if (stream != nullptr)
838 operator<<( * stream, appendable );
839 return stream;
840}
841
842
843
844#if DOXYGEN
845 }} namespace APPENDABLES {
846#else
848namespace alib { namespace strings { // the real namespace
849#endif
850
851
853 ::operator()( TAString<char , lang::HeapAllocator>& target, const strings::compatibility::std::TIStreamLine<char >& reader );
854
856 ::operator()( TAString<wchar_t, lang::HeapAllocator>& target, const strings::compatibility::std::TIStreamLine<wchar_t>& reader );
857
858#if DOXYGEN
859 }} // namespace alib[::strings::APPENDABLES]
860#else
861 } // namespace alib[::strings]
862#endif
863
864} // namespace [alib]
865#include "ALib.Lang.CIMethods.H"
866
872
#define ALIB_DLL
Definition alib.inl:573
#define ALIB_COMMA_CALLER_PRUNED
Definition alib.inl:1103
#define ALIB_SINGLE_THREADED
Definition alib.inl:40
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1145
#define ALIB_EXPORT
Definition alib.inl:562
void Set(OwnablePointer ownable)
Definition owner.inl:103
TAString & _(const TAppendable &src)
void DbgDisableBufferReplacementWarning()
Definition tastring.inl:241
constexpr integer Length() const
Definition string.inl:304
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:803
TChar CharAt(integer idx) const
Definition string.inl:403
constexpr bool IsNotEmpty() const
Definition string.inl:357
constexpr const TChar * Buffer() const
Definition string.inl:299
integer WStringLength() const
IStreamReader(integer bufferSize=4096, integer maxLineWidth=4096)
compatibility::std::TIStreamLine< nchar > readOp
NAString converter
The string buffer used for conversion.
::std::conditional_t< TSynced &&!0, ::std::basic_osyncstream< TChar, ::std::char_traits< TChar >, lang::StdAllocator< TChar, TAllocator > >, ::std::basic_ostream< TChar > & > ostream
void Write(const NString &src, integer *printedWidth=nullptr)
void Write(const XString &src, integer *printedWidth=nullptr)
OStreamWriter(::std::basic_ostream< TChar > &os)
lang::AllocatorMember< TAllocator > allocBase
The type of the base class that stores the allocator.
void Write(const WString &src, integer *printedWidth=nullptr)
OStreamWriter(::std::basic_ostream< TChar > &os, TAllocator &alloc)
void doWrite(const TString< TSrc > &src, integer *printedWidth)
TChar CharType
Exposes template parameter TChar.
void Fill(const TChar fillChar, integer count)
TAllocator AllocatorType
Exposes template parameter TAllocator.
LineFeeds
Denotes line-feed encoding sequences "\n" and "\r\n".
@ WindowsOS
WindowsOS style line-feeds "\r\n".
@ Platform
Platform specific. Equals to either 'Unix' or 'WindowsOS'.
@ Unix
Unix-style line-feeds "\n".
@ Ignore
Same as 'None'.
@ Keep
Chooses not no clear existing data.
@ Clear
Chooses to clear existing data.
ALIB_EXPORT std::istream & operator>>(std::istream &stream, alib::NAString &string)
ALIB_EXPORT std::ostream & operator<<(std::ostream &stream, const alib::NString &string)
Lock STD_IOSTREAMS_LOCK
Definition locks.cpp:48
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2181
strings::compatibility::std::IStreamReader IStreamReader
Type alias in namespace alib.
strings::TString< wchar > WString
Type alias in namespace alib.
Definition string.inl:2184
strings::compatibility::std::TIStreamLine< alib::wchar > IStreamLineW
Type alias in namespace alib.
strings::TLocalString< wchar, TCapacity, lang::HeapAllocator > WLocalString
Type alias in namespace alib.
strings::TString< xchar > XString
Type alias in namespace alib.
Definition string.inl:2187
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::compatibility::std::TIStreamLine< alib::character > IStreamLine
Type alias in namespace alib.
strings::TLocalString< xchar, TCapacity, lang::HeapAllocator > XLocalString
Type alias in namespace alib.
characters::nchar nchar
Type alias in namespace alib.
strings::compatibility::std::TIStreamLine< alib::nchar > IStreamLineN
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for #"TLocalString;TLocalString<nchar,256>".
strings::TAString< wchar, lang::HeapAllocator > WAString
Type alias in namespace alib.
strings::compatibility::std::OStreamWriter< TChar, TAllocator, TSynced, TTargetLF > OStreamWriter
Type alias in namespace alib.
#define ALIB_STRINGS_SUPPRESS_STD_OSTREAM_OPERATOR(TYPE)
TAllocator & GetAllocator() const noexcept
void operator()(TAString< TChar, lang::HeapAllocator > &target, const compatibility::std::TIStreamLine< TChar > &reader)
TIStreamLine(::std::basic_istream< TChar > *istream, lang::CurrentData targetData=lang::CurrentData::Clear, integer bufferSize=4096, integer maxLineWidth=4096)