ALib C++ Library
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/// \ref alib_manual_modules_impludes "import/include headers".
7///
8/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
9/// Published under \ref mainpage_license "Boost Software License".
10//==================================================================================================
11#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
12# error "Symbol 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 /// \ref 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 \ref 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/// \ref 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 \alib{strings;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/// \ref 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/// - \alib{strings;compatibility::std::operator>>(std::istream&;NAString& string)} and
88/// \alib{strings;compatibility::std::operator<<(std::ostream&;const NString&)}.
89/// - For a sample, refer to the source code of \alib class \b %IniFile, method
90/// \alib{variables;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 \alib{characters;nchar},
95/// \alib{characters;wchar} exist. Those have corresponding alias type definition
96/// shortcuts \alib{IStreamLineN} and \alib{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 256 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 = 256,
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 \alib{strings;AppendableTraits} for type
146/// \alib{strings::compatibility::std;TIStreamLine}.
147/// @tparam TChar The <b>AString</b>'s \ref 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 /// \alib{strings::compatibility::std::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 \alib{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/// \alib{characters;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 #Write.
191/// "Printed" here means that it is how many characters in a <em>UTF8-enconding</em>
192/// would effectively be shown, if printed.
193/// - The type uses \alib allocators for memory management.
194///
195/// It is recommended that only short-living, local instances of this class are created.
196/// This is especially important in the case that parameter \p{TSynced} is \c true.
197/// In this mode, this type follows the
198/// \https{RAII idiom,https://en.cppreference.com/w/cpp/language/raii} just as its then
199/// available member <c>std::osyncstream</c> does.
200///
201/// \note As of 10/2025, some toolchains might not support the C++20 output stream synchronization,
202/// yet. In this case, the code compiles without using it, and the output is not synchronized
203/// and may interleave.<br>
204/// Clang's standard library \e libc++ (which can be activated with
205/// \alib with CMake variable \ref alib_manual_build_cmake_3 "ALIB_CLANG_USE_LIBCPP"),
206/// in its version \b 200100 supports class <c>std::osyncstream</c> only if the compiler
207/// flag <c>-fexperimental-library</c> is provided.
208///
209/// @tparam TChar The character type of the target <c>std::basic_ostream</c>.
210/// Defaults to \alib{nchar} (which effectively is C++ \c char).
211/// @tparam TAllocator The \alib{lang;Allocator;allocator type} to use with
212/// <c>std::osyncstream</c> (if \p{TSynced} is \c true), and with temporary
213/// character conversion buffers in case those need to exceed 4kB.<br>
214/// Defaults to \alib{lang::HeapAllocator}.
215/// @tparam TSynced Determines if the encapsulated <c>std::ostream</c> should be synchronized
216/// on writing. If so, the C++ 20 mechanism provided with
217/// \https{std::osyncstream,https://en.cppreference.com/w/cpp/io/basic_osyncstream}
218/// is used, as well as \alib's built-in mechanism provided with the global mutex
219/// \alib{threads;STD_IOSTREAMS_LOCK}.
220/// Both mechanics togoether allows syncing across C++ libraries and in
221/// respect to ouput generated with \alib, synchronization between
222/// <c>std::cout</c> and <c>std::cerr</c>.
223/// @tparam TTargetLF Determines whether non-conform line-feeds are adjusted.
224/// The default value is \alib{lang;LineFeeds;Platform}, which converts all
225/// line-feeds to the platforms' standard. Values \alib{lang;LineFeeds;Unix}
226/// and \alib{lang;LineFeeds;WindowsOS} can be used to force conversion
227/// to a different standard. Finally, \alib{lang;LineFeeds;Ignore} disables
228/// the detection and conversion of line-feed codes.
229//==================================================================================================
230template< typename TChar = nchar,
231 typename TAllocator= lang::HeapAllocator,
232 bool TSynced = false,
234requires (::std::is_same_v<TChar, char> || ::std::is_same_v<TChar, wchar_t>)
235class OStreamWriter : public lang::AllocatorMember<TAllocator> {
236 protected:
237 /// The type of the base class that stores the allocator.
239
240 public:
241 static constexpr bool Synced = TSynced; ///< Exposes template parameter \p{TSynced}.
242 using CharType = TChar; ///< Exposes template parameter \p{TChar}.
243 using AllocatorType= TAllocator; ///< Exposes template parameter \p{TAllocator}.
244 static constexpr
245 lang::LineFeeds TargetLF = TTargetLF; ///< Exposes template parameter \p{TAdjustLF}.
246
247 /// This flag may be set after construction to disable the syncing mechanics, even if
248 /// the template parameter \p{TSynced} is set. This is useful, for example, if a using code
249 /// detects recursion, which is not allowed with \c std::osyncstream and
250 /// \alib{threads;STD_IOSTREAMS_LOCK}.
251 bool DisableSync =false;
252
253 protected:
254 #if defined(__cpp_lib_syncbuf) || DOXYGEN
255 /// If unsynced, this member holds the output stream as provided with construction.
256 /// In the synced case, this stores a <c>std::basic_osyncstream</c> which wraps the given
257 /// output stream.
258 ::std::conditional_t<TSynced && !ALIB_SINGLE_THREADED,
259 ::std::basic_osyncstream< TChar,
260 ::std::char_traits<TChar>,
262 ::std::basic_ostream<TChar>& > ostream;
263 #else
264 ::std::basic_ostream<TChar>& ostream;
265 #endif
266
267 /// Implementation of overloaded methods #Write.
268 /// @param src The string to write.
269 /// @param[out] printedWidth If given, the output width of \p{src} when it was printed
270 /// is returned. (See the class description for further information.)
271 /// @tparam TSrc The character type of the source string.
272 template<typename TSrc>
273 void doWrite( const TString<TSrc>& src, integer* printedWidth ) {
274 integer lineStart= 0;
275 integer lineEnd = 0;
276 if ( printedWidth )
277 *printedWidth= 0;
278 bool done= TTargetLF != lang::LineFeeds::Ignore ? false : true;
279
280 #if !ALIB_SINGLE_THREADED && (defined(__cpp_lib_syncbuf) || DOXYGEN )
281 // create an empty owner and fill it in case that a) this object is synced, and b) the
282 // encapsulated ostream is either std::cout or std::cerr.
284 if constexpr (TSynced)
285 if ( !DisableSync
286 && ( ostream.get_wrapped() == ::std::cout.rdbuf()
287 || ostream.get_wrapped() == ::std::cerr.rdbuf() ) )
288 ioLocker.Set( &threads::STD_IOSTREAMS_LOCK );
289 #endif
290
291 for (;;) {
292 if constexpr ( TTargetLF != lang::LineFeeds::Ignore ) {
293 lineEnd= src.IndexOf('\n', lineStart);
294 if (lineEnd == -1) {
295 lineEnd= src.Length();
296 done= true;
297 } }
298 else
299 lineEnd= src.Length();
300
301 integer writeEnd= lineEnd;
302 if (src.CharAt(writeEnd - 1) == '\r' )
303 --writeEnd;
304 if (writeEnd > lineStart) {
305 if constexpr (::std::is_same_v<TChar, TSrc>) {
306 if ( printedWidth )
307 *printedWidth= TString<TChar>( src.Buffer() + lineStart, writeEnd - lineStart ).WStringLength();
308 ostream.write( src.Buffer() + lineStart, writeEnd - lineStart );
309 } else {
310
313 TString<TSrc> line(src.Buffer() + lineStart, writeEnd - lineStart);
314 converter << line;
315 ostream.write( converter.Buffer(), converter.Length() );
316 if ( printedWidth ) {
317 if constexpr (::std::is_same_v<TChar, wchar>)
318 *printedWidth= converter.Length();
319 else
320 *printedWidth= line.Length();
321 } } }
322
323 if ( done )
324 break;
325
326 // write the line feed as specified by TTargetLF
327 if constexpr ( TTargetLF == lang::LineFeeds::Unix ) {
328 if constexpr ( ::std::is_same_v<TChar, nchar> ) ostream.write( "\n", 1 );
329 else ostream.write( L"\n", 1 );
330 } else if constexpr ( TTargetLF == lang::LineFeeds::WindowsOS ) {
331 if constexpr ( ::std::is_same_v<TChar, nchar> ) ostream.write( "\r\n", 2 );
332 else ostream.write( L"\r\n", 2 );
333 }
334 lineStart= lineEnd + 1;
335 } }
336
337 public:
338 /// Constructor accepting the destination stream.
339 /// @param os The output-stream to use.
340 OStreamWriter(::std::basic_ostream<TChar> &os)
341 : ostream( os ) {}
342
343 #if !defined(__cpp_lib_syncbuf) || ALIB_SINGLE_THREADED || DOXYGEN
344 /// Constructor accepting the destination stream, as well as an allocator to use.
345 /// @param os The output-stream to use.
346 /// @param alloc The allocator to use for the internal buffers.
347 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
348 : allocBase(alloc)
349 , ostream( os ) {}
350 #else
351 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
352 requires (!TSynced)
353 : allocBase(alloc)
354 , ostream( os ) {}
355
356 OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator& alloc)
357 requires (TSynced)
358 : allocBase{alloc}
359 , ostream { os.rdbuf() , lang::StdAllocator<TChar, TAllocator>(alloc) } {}
360 #endif
361
362 /// Returns the output stream given with construction, or, if template parameter \p{TSynced}
363 /// is \c true, that output stream wrapped in a <c>std::basic_osyncstream</c>.
364 /// In the latter case, the sync-stream is destructed - and data is written - only with the
365 /// destruction of this instance.
366 /// @return The output stream of this writer.
367 ::std::ostream& GetStream() { return ostream; }
368
369 /// Writes the given narrow string to the stream.
370 ///
371 /// \note
372 /// The output parameter \p{printedWidth} returns the length of the given string, when
373 /// it was converted to wide string. This is done, even if template parameter \p{TChar}
374 /// is narrow and consequently no conversion was performed.<br>
375 /// The value is useful to callers when the "real" output width is needed, i.e., when
376 /// the output text is formatted in tabulator columns or tables.
377 /// Of course, in some locales, this might still not be the correct output width because even
378 /// uni-code characters are not guaranteed to represent exactly one printable character.
379 /// But still, this value is already a much better approximation than the length of the
380 /// given narrow string.
381 ///
382 /// @param src The string to write.
383 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
384 /// See the note above. If not given, the method might execute
385 /// slightly faster.
386 void Write( const NString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
387
388 /// See sibling method #Write( const NString& src, integer* printedWidth ).
389 /// @param src The wide string to write.
390 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
391 /// See the note above. If not given, the method might execute
392 /// slightly faster.
393 void Write( const WString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
394
395 /// See sibling method #Write( const NString& src, integer* printedWidth ).
396 /// @param src The strange string to write.
397 /// @param[out] printedWidth If given, the width if \p{src} was printed is returned.
398 /// See the note above. If not given, the method might execute
399 /// slightly faster.
400 void Write( const XString& src, integer* printedWidth= nullptr ) { doWrite(src, printedWidth); }
401
402 /// Write the given character repeatedly to the stream.
403 /// @param fillChar The character to write.
404 /// @param count The number of characters to write.
405 void Fill( const TChar fillChar, integer count ) {
406 characters::AlignedCharArray<TChar, 8*sizeof(void*)> alc( fillChar );
407 while (count >= alc.Length() ) {
408 ostream.write(alc.Buffer(), alc.Length());
409 count-= alc.Length();
410 }
411
412 if (count > 0)
413 ostream.write(alc.Buffer(), count);
414 }
415
416
417};
418
419/// @param os The output-stream to use.
420template< typename TChar = nchar,
421 typename TAllocator= lang::HeapAllocator,
422 bool TSynced = false,
424OStreamWriter(::std::basic_ostream<TChar>& os)
426
427/// C++17 Deduction Guide to construct the type \alib{strings::compatibility::std;OStreamWriter}.
428/// @param os The output-stream to use.
429/// @param allocator The allocator to use for the internal buffers.
430template< typename TChar = nchar,
431 typename TAllocator= lang::HeapAllocator,
432 bool TSynced = false,
434OStreamWriter(::std::basic_ostream<TChar>& os, TAllocator allocator)
436
437//==================================================================================================
438/// This class is a helper-class that converts narrow string data read from an object of
439/// type \c std::istream to the \alib{characters;character;default character type}.
440///
441/// \see Class \alib{strings::compatibility::std;OStreamWriter}.
442//==================================================================================================
444{
445 protected:
446 /// The string buffer used for conversion.
448
449 /// The input stream as provided with #SetStream. Will be set to the \c std::cin,
450 /// respectively \c std::win in the constructor.
452
453
454 public:
455 /// Constructor.Invokes #SetStream passing \c std::cin.
456 IStreamReader() : readOp( &::std::cin ) {}
457
458 /// Sets the input stream.
459 /// @param is Pointer to the input stream to read from to.
460 void SetStream( ::std::istream* is ) { readOp.IStream= is; }
461
462 /// Returns the input stream previously set with #SetStream.
463 /// @return The input stream set with #SetStream.
464 ::std::istream* GetStream() { return readOp.IStream; }
465
466 /// Returns \c true if the input stream signaled its end, \c false otherwise.
467 /// @return \c true if the input stream is known to be at its end, \c false otherwise.
468 bool IsEOF() { return readOp.IsEOF; }
469
470
471 /// Reads one line of text from the input stream into a narrow string.
472 /// @param target The storage buffer for the string to read. This string will be cleared
473 /// independent of the availability of input data.
474 void Read( NAString& target ) { target.Reset( readOp ); }
475
476 /// Reads one line of text from the internal input stream into a wide string.
477 /// @param target The storage buffer for the string to read. This string will be cleared
478 /// independent of the availability of input data.
479 void Read( WAString& target ) {
480 target.Reset();
481 converter.Reset( readOp );
482 target << converter;
483 }
484};
485
486}}} // namespace alib[::strings::compatibility::std]
487
488/// Type alias in namespace \b alib.
490
491/// Type alias in namespace \b alib.
493
494/// Type alias in namespace \b alib.
496
497/// Type alias in namespace \b alib.
498template< typename TChar = nchar,
499 typename TAllocator= lang::HeapAllocator,
500 bool TSynced = false,
503 TTargetLF>;
504
505/// Type alias in namespace \b alib.
507
508//##################################################################################################
509//##################################### std::ostream& operator<< ###################################
510//##################################################################################################
511#if DOXYGEN
512 namespace strings { namespace compatibility { namespace std {
513#else
514} // namespace [alib]
515#endif
516
517//==================================================================================================
518/// Copies the contents of the given \b %NString to into the \c std::ostream given as reference.
519///
520/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
521/// @param stream The ostream object to write the given String into.
522/// @param string The String to write into the given ostream.
523/// @returns The ostream to allow concatenated operations.
524//==================================================================================================
526inline std::ostream& operator<<( std::ostream& stream, const alib::NString& string ) {
527 if ( string.IsNotEmpty() )
528 stream.write( string.Buffer(), string.Length() );
529 return stream;
530}
531
532//==================================================================================================
533/// Copies the contents of the given \b %NString to into the \c std::ostream given as pointer.
534///
535/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
536/// @param stream The ostream object to write the given String into.
537/// @param string The String to write into the given ostream.
538/// @returns The ostream to allow concatenated operations.
539//==================================================================================================
541inline std::ostream* operator<<( std::ostream* stream, const alib::NString& string )
542{
543 stream->write( string.Buffer(), string.Length() );
544 return stream;
545}
546
547//==================================================================================================
548/// Copies the contents of the given \b %WString to into the \c std::ostream given as reference.
549///
550/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
551/// @param stream The ostream object to write the given String into.
552/// @param string The String to write into the given ostream.
553/// @returns The ostream to allow concatenated operations.
554//==================================================================================================
556ALIB_DLL std::ostream& operator<<( std::ostream& stream, const alib::WString& string );
557
558//==================================================================================================
559/// Copies the contents of the given \b %WString to into the \c std::ostream given as pointer.
560///
561/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
562/// @param stream The ostream object to write the given String into.
563/// @param string The String to write into the given ostream.
564/// @returns The ostream to allow concatenated operations.
565//==================================================================================================
567inline std::ostream* operator<<( std::ostream* stream, const alib::WString& string )
568{
569 (*stream) << string;
570 return stream;
571}
572
573//==================================================================================================
574/// Copies the contents of the given \b %NString to into the \c std::wostream given as reference.
575///
576/// \note
577/// This operator uses a local string buffer of 256 bytes size to convert the given narrow string
578/// to an string of \c wchar_t characters that the output stream accepts. In case that
579/// the given \p{string} is larger, a dynamic memory allocation has to be made.<br>
580/// In performance-critical code that writes larger string data, a custom conversion method,
581/// that, for example, reuses a buffer, may be appropriate.
582///
583/// <p>
584/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
585/// @param stream The ostream object to write the given String into.
586/// @param string The String to write into the given ostream.
587/// @returns The ostream to allow concatenated operations.
588//==================================================================================================
590ALIB_DLL std::wostream& operator<<( std::wostream& stream, const alib::NString& string );
591
592//==================================================================================================
593/// Copies the contents of the given \b %NString to into the \c std::wostream given as pointer.
594///
595/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
596/// \see The notes on memory efficiency, documented with operator
597/// \alib{strings::compatibility::std;operator<<(std::wostream&,const NString&)}
598/// which this operator uses inline.
599/// @param stream The ostream object to write the given String into.
600/// @param string The String to write into the given ostream.
601/// @returns The ostream to allow concatenated operations.
602//==================================================================================================
604inline std::wostream* operator<<( std::wostream* stream, const alib::NString& string )
605{
606 (*stream) << string;
607 return stream;
608}
609
610//==================================================================================================
611/// Copies the contents of the given \b %WString to into the \c std::wostream given as reference.
612///
613/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
614/// @param stream The ostream object to write the given String into.
615/// @param string The String to write into the given ostream.
616/// @returns The ostream to allow concatenated operations.
617//==================================================================================================
619inline std::wostream& operator<<( std::wostream& stream, const alib::WString& string ) {
620 if ( string.IsNotEmpty() ) {
621 #if ALIB_CHARACTERS_NATIVE_WCHAR
622 stream.write( string.Buffer(), string.Length() );
623 #else
624 alib::XLocalString<1024> converter( string );
626 stream.write( converter.Buffer(), converter.Length() );
627 #endif
628 }
629 return stream;
630}
631
632//==================================================================================================
633/// Copies the contents of the given \b %WString to into the \c std::wostream given as pointer.
634///
635/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
636/// @param stream The ostream object to write the given String into.
637/// @param string The String to write into the given ostream.
638/// @returns The ostream to allow concatenated operations.
639//==================================================================================================
641inline std::wostream* operator<<( std::wostream* stream, const alib::WString& string )
642{
643 (*stream) << string;
644 return stream;
645}
646
647//==================================================================================================
648/// Clears the given \b %NAString and extracts data from the std::istream into it. The extraction
649/// ends with either the end of the std::istream or when reading a newline character.
650///
651/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
652/// @param stream The istream object to extract data from.
653/// @param string The AString to receive data.
654/// @returns The ostream to allow concatenated operations.
655//==================================================================================================
657inline std::istream& operator>>( std::istream& stream, alib::NAString& string ) {
658 string << alib::strings::compatibility::std::TIStreamLine<alib::nchar>( &stream,
660 return stream;
661}
662
663//==================================================================================================
664/// Clears the given \b %NAString and extracts data from the std::istream into it. The extractions
665/// ends with either the end of the std::istream or when reading a newline character.
666///
667/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
668/// @param stream The istream object to extract data from.
669/// @param string The AString to receive data.
670/// @returns The ostream to allow concatenated operations.
671//==================================================================================================
673inline std::istream* operator>>( std::istream* stream, alib::NAString& string ) {
674 ALIB_ASSERT_WARNING( stream != nullptr, "STRINGS", "Given std::IStream is nullptr" )
675
676 if (stream != nullptr)
677 string << alib::strings::compatibility::std::TIStreamLine<alib::nchar>( stream,
679 return stream;
680}
681
682//==================================================================================================
683/// Clears the given \b %WAString and extracts data from the std::istream into it. The extractions
684/// ends with either the end of the std::istream or when reading a newline character.
685///
686/// \note
687/// If code selection symbol \ref ALIB_CHARACTERS_NATIVE_WCHAR evaluates to false, a local buffer
688/// is used to convert the string of \c wchar_t characters that the input stream provides.
689/// In case that the string read from the stream is larger, a dynamic memory allocation has to
690/// be made.<br>
691/// In performance-critical code that receives larger string data, a custom conversion method
692/// that, for example, reuses a buffer may be appropriate.
693///
694/// <p>
695/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
696/// @param stream The istream object to extract data from.
697/// @param string The AString to receive data.
698/// @returns The ostream to allow concatenated operations.
699//==================================================================================================
701inline std::basic_istream<wchar_t>& operator>>( std::basic_istream<wchar_t>& stream,
702 alib::WAString& string ) {
703 #if ALIB_CHARACTERS_NATIVE_WCHAR
704 string << alib::strings::compatibility::std::TIStreamLine<wchar_t>( &stream,
706 #else
707 alib::XLocalString<1024> converter;
709 converter << alib::strings::compatibility::std::TIStreamLine<wchar_t>( &stream,
711 string.Reset( converter );
712 #endif
713 return stream;
714}
715
716//==================================================================================================
717/// Clears the given \b %WAString and extracts data from the std::istream into it. The extractions
718/// ends with either the end of the std::istream or when reading a newline character.
719///
720/// \note Unlike this documentation indicates, the operator is defined in the global namespace.
721///
722/// \see The notes on memory efficiency, documented with operator
723/// \alib{strings::compatibility::std;operator>>(std::basic_istream<wchar_t>&, WAString& )}
724/// which this operator uses inline.
725/// @param stream The istream object to extract data from.
726/// @param string The AString to receive data.
727/// @returns The ostream to allow concatenated operations.
728//==================================================================================================
730inline std::basic_istream<wchar_t>* operator>>( std::basic_istream<wchar_t>* stream,
731 alib::WAString& string ) {
732 ALIB_ASSERT_WARNING ( stream != nullptr, "STRINGS", "Given std::istream is nullptr" )
733
734 if (stream != nullptr)
735 (*stream) >> string;
736 return stream;
737}
738
739
740//==================================================================================================
741/// Copies the contents of the given \ref alib_strings_assembly_ttostring "appendable type"
742/// the \c std::ostream given as reference.
743///
744/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
745///
746/// @tparam TAppendable The appendable type.
747/// @param stream The \c std::ostream object to write the given String into.
748/// @param appendable The object whose contents is to be written into the given \p{stream}.
749/// @returns The ostream to allow concatenated operations.
750//==================================================================================================
752template<typename TAppendable>
755std::ostream& operator<<( std::ostream& stream, const TAppendable& appendable ) {
758
759 if ( buf._(appendable).IsNotEmpty() )
760 stream.write( buf.Buffer(), buf.Length() );
761 return stream;
762}
763
764//==================================================================================================
765/// Copies the contents of the given \alib{strings;AppendableTraits;appendable type} the \c std::ostream
766/// given as pointer.
767///
768/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
769///
770/// @tparam TAppendable The appendable type.
771/// @param stream The \c std::ostream object to write the given String into.
772/// @param appendable The object whose contents is to be written into the given \p{stream}.
773/// @returns The ostream to allow concatenated operations.
774//==================================================================================================
776template<typename TAppendable>
779std::ostream* operator<<( std::ostream* stream, const TAppendable& appendable ) {
780 if (stream != nullptr)
781 operator<<( * stream, appendable );
782 return stream;
783}
784
785//==================================================================================================
786/// Copies the contents of the given \alib{strings;AppendableTraits;appendable type} the \c std::ostream
787/// given as reference.
788///
789/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
790///
791/// @tparam TAppendable The appendable type.
792/// @param stream The \c std::ostream object to write the given String into.
793/// @param appendable The object whose contents is to be written into the given \p{stream}.
794/// @returns The ostream to allow concatenated operations.
795//==================================================================================================
797template<typename TAppendable>
800std::wostream& operator<<( std::wostream& stream, const TAppendable& appendable ) {
801 #if ALIB_CHARACTERS_NATIVE_WCHAR
803 #else
805 #endif
807
808 if ( buf._(appendable).IsNotEmpty() )
809 stream.write( buf.Buffer(), buf.Length() );
810 return stream;
811}
812
813//==================================================================================================
814/// Copies the contents of the given \alib{strings;AppendableTraits;appendable type} the \c std::ostream
815/// given as a pointer.
816///
817/// \note Unlike this documentation indicates, this operator is defined in the global namespace.
818///
819/// @tparam TAppendable The appendable type.
820/// @tparam TAllocator The allocator type, as prototyped with \alib{lang;Allocator}.
821/// @param stream The \c std::ostream object to write the given String into.
822/// @param appendable The object whose contents is to be written into the given \p{stream}.
823/// @returns The ostream to allow concatenated operations.
824//==================================================================================================
826template<typename TAppendable, typename TAllocator>
829std::wostream* operator<<( std::wostream* stream, const TAppendable& appendable ) {
830 if (stream != nullptr)
831 operator<<( * stream, appendable );
832 return stream;
833}
834
835
836
837#if DOXYGEN
838 }} namespace APPENDABLES {
839#else
841namespace alib { namespace strings { // the real namespace
842#endif
843
844
846 ::operator()( TAString<char , lang::HeapAllocator>& target, const strings::compatibility::std::TIStreamLine<char >& reader );
847
849 ::operator()( TAString<wchar_t, lang::HeapAllocator>& target, const strings::compatibility::std::TIStreamLine<wchar_t>& reader );
850
851#if DOXYGEN
852 }} // namespace alib[::strings::APPENDABLES]
853#else
854 } // namespace alib[::strings]
855#endif
856
857} // namespace [alib]
858#include "ALib.Lang.CIMethods.H"
859
865
void Set(OwnablePointer ownable)
Definition owner.inl:103
TAString & _(const TAppendable &src)
void DbgDisableBufferReplacementWarning()
Definition tastring.inl:244
constexpr integer Length() const
Definition string.inl:316
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:815
TChar CharAt(integer idx) const
Definition string.inl:415
constexpr bool IsNotEmpty() const
Definition string.inl:369
constexpr const TChar * Buffer() const
Definition string.inl:311
integer WStringLength() const
compatibility::std::TIStreamLine< nchar > readOp
NAString converter
The string buffer used for conversion.
IStreamReader()
Constructor.Invokes SetStream passing std::cin.
void Write(const NString &src, integer *printedWidth=nullptr)
::std::conditional_t< TSynced &&!ALIB_SINGLE_THREADED, ::std::basic_osyncstream< TChar, ::std::char_traits< TChar >, lang::StdAllocator< TChar, TAllocator > >, ::std::basic_ostream< TChar > & > ostream
void Write(const XString &src, integer *printedWidth=nullptr)
OStreamWriter(::std::basic_ostream< TChar > &os)
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.
lang::AllocatorMember< TAllocator > allocBase
The type of the base class that stores the allocator.
void Fill(const TChar fillChar, integer count)
TAllocator AllocatorType
Exposes template parameter TAllocator.
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_COMMA_CALLER_PRUNED
Definition alib.inl:1025
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1067
#define ALIB_STRINGS_SUPPRESS_STD_OSTREAM_OPERATOR(TYPE)
#define ALIB_EXPORT
Definition alib.inl:497
#define ALIB_SINGLE_THREADED
Definition prepro.dox.md:22
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)
ALIB_DLL Lock STD_IOSTREAMS_LOCK
Definition locks.cpp:48
strings::TAString< wchar, lang::HeapAllocator > WAString
Type alias in namespace alib.
strings::compatibility::std::IStreamReader IStreamReader
Type alias in namespace alib.
strings::TString< xchar > XString
Type alias in namespace alib.
Definition string.inl:2204
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2198
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
strings::compatibility::std::TIStreamLine< alib::nchar > IStreamLineN
Type alias in namespace alib.
strings::TString< wchar > WString
Type alias in namespace alib.
Definition string.inl:2201
strings::compatibility::std::TIStreamLine< alib::character > IStreamLine
Type alias in namespace alib.
characters::nchar nchar
Type alias in namespace alib.
strings::TLocalString< xchar, TCapacity, lang::HeapAllocator > XLocalString
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.
strings::compatibility::std::OStreamWriter< TChar, TAllocator, TSynced, TTargetLF > OStreamWriter
Type alias in namespace alib.
strings::compatibility::std::TIStreamLine< alib::wchar > IStreamLineW
Type alias in namespace alib.
strings::TLocalString< wchar, TCapacity, lang::HeapAllocator > WLocalString
Type alias in namespace alib.
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=256, integer maxLineWidth=4096)