BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlb_printmethods.h
Go to the documentation of this file.
1/// @file bdlb_printmethods.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_printmethods.h -*-C++-*-
8#ifndef INCLUDED_BDLB_PRINTMETHODS
9#define INCLUDED_BDLB_PRINTMETHODS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_printmethods bdlb_printmethods
15/// @brief Provide methods for uniform printing of value-semantic types.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_printmethods
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_printmethods-purpose"> Purpose</a>
25/// * <a href="#bdlb_printmethods-classes"> Classes </a>
26/// * <a href="#bdlb_printmethods-description"> Description </a>
27/// * <a href="#bdlb_printmethods-traits-affecting-printing"> Traits Affecting Printing </a>
28/// * <a href="#bdlb_printmethods-effect-of-bdlb-typetraithasprintmethod-trait"> Effect of bdlb::TypeTraitHasPrintMethod Trait </a>
29/// * <a href="#bdlb_printmethods-effect-of-bslalg-hasstliterators-trait"> Effect of bslalg::HasStlIterators Trait </a>
30/// * <a href="#bdlb_printmethods-effect-of-bslmf-ispair-trait"> Effect of bslmf::IsPair Trait </a>
31/// * <a href="#bdlb_printmethods-usage"> Usage </a>
32/// * <a href="#bdlb_printmethods-example-1-supplying-a-print-method-for-a-parameterized-class"> Example 1: Supplying a print Method for a Parameterized Class </a>
33///
34/// # Purpose {#bdlb_printmethods-purpose}
35/// Provide methods for uniform printing of value-semantic types.
36///
37/// # Classes {#bdlb_printmethods-classes}
38///
39/// - bdlb::PrintMethods: templates for uniform printing of value-semantic types
40/// - bdlb::HasPrintMethod: trait indicating existence of `print` method
41/// - bdlb::TypeTraitHasPrintMethod: old-style version of `bdlb::HasPrintMethod`
42///
43/// @see bslalg_nestedtraitdeclaration
44///
45/// # Description {#bdlb_printmethods-description}
46/// This component provides a namespace for print utilities that
47/// support uniform `ostream` printing across all printable types, including
48/// template types and containers. The `bdlb::PrintMethods` namespace enables
49/// clients to output the value of any printable object according to the
50/// standard BDE `print` protocol. If the parameterized `TYPE` does not provide
51/// a `print` method, `TYPE::operator<<` is used. Availability of a `print`
52/// method is determined by testing for the `bdlb::HasPrintMethod` and
53/// `bdlb::TypeTraitHasPrintMethod` traits.
54///
55/// ## Traits Affecting Printing {#bdlb_printmethods-traits-affecting-printing}
56///
57///
58/// By default, `bdlb::PrintMethods::print` uses the `<<` stream output operator
59/// to print a value. This formats the entire output on one line, suppressing
60/// all indentation. A class can override this behavior by declaring certain
61/// traits related to printing. This component detects these traits and invokes
62/// an appropriate print operation. The following lists the traits recognized
63/// by this component:
64/// @code
65/// bdlb::HasPrintMethod ( highest precedence )
66/// bslalg::HasStlIterators
67/// bslmf::IsPair ( lowest precedence )
68/// @endcode
69/// Since a class may declare multiple traits (see the component-level
70/// documentation of @ref bslalg_nestedtraitdeclaration for information about
71/// declaring traits), the relative precedence of the traits is shown above.
72/// The next sub-sections describe these traits and their effects on printing.
73///
74/// ### Effect of bdlb::TypeTraitHasPrintMethod Trait {#bdlb_printmethods-effect-of-bdlb-typetraithasprintmethod-trait}
75///
76///
77/// If a class `X` declares the `bdlb::TypeTraitHasPrintMethod` trait, then it
78/// must provide a `print` method with the following signature:
79/// @code
80/// bsl::ostream& print(bsl::ostream& stream,
81/// int level = 0,
82/// int spacesPerLevel = 4) const;
83/// @endcode
84/// To output an `X` object with this trait declared, the
85/// `bdlb::PrintMethods::print` method simply forwards to this method. This
86/// means that the print operation is completely defined by the class. Ideally,
87/// it should behave according to the standard BDE `print` protocol that is
88/// documented as follows:
89/// @code
90/// Format this object to the specified output `stream` at the (absolute value
91/// of) the optionally specified indentation `level` and return a reference to
92/// `stream`. If `level` is specified, optionally specify `spacesPerLevel`,
93/// the number of spaces per indentation level for this and all of its nested
94/// objects. If `level` is negative, suppress indentation of the first line.
95/// If `spacesPerLevel` is negative, format the entire output on one line,
96/// suppressing all but the initial indentation (as governed by `level`). If
97/// `stream` is not valid on entry, this operation has no effect.
98/// @endcode
99///
100/// ### Effect of bslalg::HasStlIterators Trait {#bdlb_printmethods-effect-of-bslalg-hasstliterators-trait}
101///
102///
103/// If a class `X` declares the `bslalg::HasStlIterators` trait, then it must
104/// provide access to iterators using the standard STL protocol. The BDE
105/// implementation of STL declares this trait for all STL container types that
106/// have STL iterators. Other containers that provide STL iterators should
107/// declare this trait to get correct printing behavior.
108///
109/// When an `X` object with this trait is printed using
110/// `bdlb::PrintMethods::print`, the contents of the object is traversed via an
111/// iterator and the output is formatted according to the standard BDE `print`
112/// protocol, as documented above. Additionally, an opening `[` character is
113/// prepended at the beginning of the output and a closing `]` character is
114/// appended at the end of the output. Each iterated element is printed using
115/// its own print method, and with an indentation level one higher than that of
116/// the container.
117///
118/// ### Effect of bslmf::IsPair Trait {#bdlb_printmethods-effect-of-bslmf-ispair-trait}
119///
120///
121/// If a class `X` declares the `bslmf::IsPair` trait, then the class must
122/// contain two `public` data members named `first` and `second`. The BDE
123/// implementation of STL declares this trait for the `bsl::pair` `struct`.
124/// Other classes that have `public` `first` and `second` data members may
125/// declare this trait to get printing behavior similar to that of `bsl::pair`.
126///
127/// When an `X` object with this trait is printed using
128/// `bdlb::PrintMethods::print`, its output is formatted based on the standard
129/// BDE `print` protocol, as documented above. Additionally, an opening `[`
130/// character is prepended at the beginning of the output and a closing `]`
131/// character is appended at the end of the output. The `first` and `second`
132/// elements are printed using their own `print` methods, and with an
133/// indentation level one higher than that of the pair object.
134///
135/// ## Usage {#bdlb_printmethods-usage}
136///
137///
138/// This section illustrates intended use of this component.
139///
140/// ### Example 1: Supplying a print Method for a Parameterized Class {#bdlb_printmethods-example-1-supplying-a-print-method-for-a-parameterized-class}
141///
142///
143/// Suppose we must create a value-semantic class that holds an object of
144/// parameterized `TYPE` and, per BDE convention for VSTs, provides a `print`
145/// method that shows the value in some human-readable format.
146///
147/// First, we define the wrapper class:
148/// @code
149/// /// An example wrapper class for a `TYPE` object.
150/// template <class TYPE>
151/// class MyWrapper {
152///
153/// // PRIVATE DATA MEMBERS
154/// TYPE d_obj; // wrapped object
155///
156/// public:
157/// // TRAITS
158/// BSLMF_NESTED_TRAIT_DECLARATION(MyWrapper, bdlb::HasPrintMethod);
159///
160/// // CREATORS
161/// MyWrapper(): d_obj() {};
162/// MyWrapper(const TYPE& value) : d_obj(value) { }
163/// // ... other constructors and destructor ...
164///
165/// // MANIPULATORS
166/// // ... assignment operator, etc. ...
167///
168/// // ACCESSORS
169///
170/// /// Format the contained `TYPE` to the specified output `stream` at
171/// /// the (absolute value of) the optionally specified indentation
172/// /// `level` and return a reference to `stream`. If `level` is
173/// /// specified, optionally specify `spacesPerLevel`, the number of
174/// /// spaces per indentation level for this and all of its nested
175/// /// objects. If `level` is negative, suppress indentation of the
176/// /// first line. If `spacesPerLevel` is negative, format the entire
177/// /// output on one line, suppressing all but the initial indentation
178/// /// (as governed by `level`). If `stream` is not valid on entry,
179/// /// this operation has no effect.
180/// bsl::ostream& print(bsl::ostream& stream,
181/// int level = 0,
182/// int spacesPerLevel = 4) const;
183/// };
184/// @endcode
185/// Now, we implement the `print` method of `MyWrapper` using the
186/// `bdlb::PrintMethods` utility. Doing so gives us a method that produces
187/// results both when `TYPE` defines a `print` method and when it does not. In
188/// the latter case `TYPE::operator<<` is used.
189/// @code
190/// template <class TYPE>
191/// bsl::ostream& MyWrapper<TYPE>::print(bsl::ostream& stream,
192/// int level,
193/// int spacesPerLevel) const
194/// {
195/// return bdlb::PrintMethods::print(stream, d_obj, level, spacesPerLevel);
196/// }
197/// @endcode
198/// Finally, we exercise our `MyWrapper` class using several representative
199/// types, starting with `MyDate` (not shown) a class that implements a `print`
200/// method.
201/// @code
202/// static void usingMyWrapper()
203/// {
204/// BSLMF_ASSERT(bdlb::HasPrintMethod<MyDate>::value);
205///
206/// MyDate myDate;
207/// MyWrapper<MyDate> myWrapperForMyDate(myDate);
208///
209/// BSLMF_ASSERT(!bdlb::HasPrintMethod<int>::value);
210///
211/// bsl::ostringstream oss1;
212/// myWrapperForMyDate.print(oss1); // No problem expected since
213/// // `bsls::TimeInterval` has a `print`
214/// // method.
215/// assert("01JAN0001\n" == oss1.str());
216/// @endcode
217/// Using an `int` type shows how `bdlb::PrintMethods::print` transparently
218/// handles types that do not provide `print` methods:
219/// @code
220/// int myInt = 123;
221/// MyWrapper<int> myWrapperForInt(myInt);
222///
223/// bsl::ostringstream oss2;
224/// myWrapperForInt.print(oss2); // `int` has no `print` method.
225/// // Problem?
226/// assert("123\n" == oss2.str()); // No problem!
227/// @endcode
228/// Lastly, since `MyWrapper` itself is a type that implements `print` -- and
229/// sets the `bdlb::TypeTraitHasPrintMethod` trait -- one instance of the
230/// `MyWrapper` type can be wrapped by another.
231/// @code
232/// BSLMF_ASSERT(bdlb::HasPrintMethod<MyWrapper<int> >::value);
233///
234/// MyWrapper<MyWrapper<int> > myWrappedWrapper;
235///
236/// bsl::ostringstream oss3;
237/// myWrappedWrapper.print(oss3);
238/// assert("0\n" == oss3.str());
239/// }
240/// @endcode
241/// See the @ref bslmf_nestedtraitdeclaration component for more information
242/// about declaring traits for user-defined classes.
243/// @}
244/** @} */
245/** @} */
246
247/** @addtogroup bdl
248 * @{
249 */
250/** @addtogroup bdlb
251 * @{
252 */
253/** @addtogroup bdlb_printmethods
254 * @{
255 */
256
257#include <bdlscm_version.h>
258
259#include <bdlb_print.h>
260
262
263#include <bslmf_ispair.h>
265#include <bslmf_selecttrait.h>
266
267#include <bsls_libraryfeatures.h>
268
269#include <bsl_iomanip.h>
270#include <bsl_ostream.h>
271#include <bsl_vector.h>
272
273#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
275#include <bslalg_typetraitpair.h>
276#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
277
278#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
279#include <optional>
280#include <variant>
281#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
282
283namespace bsl {
284
285template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
286class basic_string;
287
288} // close namespace bsl
289
290
291namespace bdlb {
292
293 // =====================
294 // struct HasPrintMethod
295 // =====================
296
297/// A class, `TYPE`, should specialize this trait to derive from `true_type`
298/// if it has a `print` method with the following signature:
299/// @code
300/// bsl::ostream& print(bsl::ostream& stream,
301/// int level = 0,
302/// int spacesPerLevel = 4) const;
303/// @endcode
304template <class TYPE>
306 bslmf::DetectNestedTrait<TYPE, HasPrintMethod>::type {
307};
308
309 // ==============================
310 // struct TypeTraitHasPrintMethod
311 // ==============================
312
313/// A class should declare this trait if it has a `print` method with the
314/// following signature:
315/// @code
316/// bsl::ostream& print(bsl::ostream& stream,
317/// int level = 0,
318/// int spacesPerLevel = 4) const;
319/// @endcode
320///
321/// See @ref bdlb_printmethods
323
324 /// This class template ties the `bdlb::TypeTraitHasPrintMethod` trait
325 /// tag to the `bdlb::HasPrintMethod` trait metafunction.
326 template <class TYPE>
328 bslmf::NestedTraitDeclaration<TYPE, HasPrintMethod>
329 {
330 };
331
332 template <class TYPE>
333 struct Metafunction : HasPrintMethod<TYPE>::type { };
334};
335
336 // ======================
337 // namespace PrintMethods
338 // ======================
339
340/// This `namespace` contains parameterized `print` methods having the
341/// standard BDE signature for such methods.
342namespace PrintMethods {
343
344/// Format the specified `object` to the specified output `stream` at the
345/// (absolute value of) the optionally specified indentation `level` and
346/// return a reference to `stream`. If `level` is specified, optionally
347/// specify `spacesPerLevel`, the number of spaces per indentation level for
348/// this and all of its nested objects. If `level` is negative, suppress
349/// indentation of the first line. If `spacesPerLevel` is negative, format
350/// the entire output on one line, suppressing all but the initial
351/// indentation (as governed by `level`). If `stream` is not valid on
352/// entry, this operation has no effect.
353template <class TYPE>
354bsl::ostream& print(bsl::ostream& stream,
355 const TYPE& object,
356 int level = 0,
357 int spacesPerLevel = 4);
358bsl::ostream& print(bsl::ostream& stream,
359 char object,
360 int level = 0,
361 int spacesPerLevel = 4);
362bsl::ostream& print(bsl::ostream& stream,
363 unsigned char object,
364 int level = 0,
365 int spacesPerLevel = 4);
366
367/// Format the specified `object` to the specified output `stream` at the
368/// (absolute value of) the optionally specified indentation `level` and return a reference to stream.
369///
370/// \note Note that output will be formatted on one
371/// line. If `stream` is not valid on entry, this operation has no effect.
372template <class CHAR_T, class CHAR_TRAITS_T, class ALLOC>
373bsl::ostream& print(bsl::ostream& stream,
374 const bsl::basic_string<CHAR_T,
375 CHAR_TRAITS_T,
376 ALLOC>& object,
377 int level = 0,
378 int spacesPerLevel = 4);
379
380/// Format the specified `object` to the specified output `stream` at the
381/// (absolute value of) the optionally specified indentation `level` and return a reference to stream.
382///
383/// \note Note that output will be formatted on one
384/// line. Also note that non-printable characters in `object` will be
385/// printed using their hexadecimal representation. If `stream` is not
386/// valid on entry, this operation has no effect.
387template <class ALLOC>
388bsl::ostream& print(bsl::ostream& stream,
389 const bsl::vector<char, ALLOC>& object,
390 int level = 0,
391 int spacesPerLevel = 4);
392
393#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
394
395/// Format the specified `object` to the specified output `stream` at the
396/// (absolute value of) the optionally specified indentation `level` and
397/// return a reference to `stream`. If `level` is specified, optionally
398/// specify `spacesPerLevel`, the number of spaces per indentation level for
399/// this and all of its nested objects. If `level` is negative, suppress
400/// indentation of the first line. If `spacesPerLevel` is negative, format
401/// the entire output on one line, suppressing all but the initial
402/// indentation (as governed by `level`). If `stream` is not valid on
403/// entry, this operation has no effect. A descriptive, human-readable
404/// message, indented according to `level` and `spacesPerLevel`, is output
405/// for objects having no value (i.e., `false == object.has_value()`).
406template <class TYPE>
407bsl::ostream& print(bsl::ostream& stream,
408 const std::optional<TYPE>& object,
409 int level = 0,
410 int spacesPerLevel = 4);
411
412/// Format the specified `object` to the specified output `stream` at the
413/// (absolute value of) the optionally specified indentation `level` and
414/// return a reference to `stream`. If `level` is specified, optionally
415/// specify `spacesPerLevel`, the number of spaces per indentation level for
416/// this and all of its nested objects. If `level` is negative, suppress
417/// indentation of the first line. If `spacesPerLevel` is negative, format
418/// the entire output on one line, suppressing all but the initial
419/// indentation (as governed by `level`). If `stream` is not valid on
420/// entry, this operation has no effect. A descriptive, human-readable
421/// message, indented according to `level` and `spacesPerLevel`, is output for objects holding the value of type `std::monostate`.
422///
423/// \note Note that a
424/// `std::variant` object can hold the `std::monostate` value only if its
425/// template parameters explicitly mention the `std::monostate` type.
426template <class ... TYPE>
427bsl::ostream& print(bsl::ostream& stream,
428 const std::variant<TYPE ...>& object,
429 int level = 0,
430 int spacesPerLevel = 4);
431
432/// Format the specified `object` to the specified output `stream` at the
433/// (absolute value of) the optionally specified indentation `level` and
434/// return a reference to `stream`. If `level` is specified, optionally
435/// specify `spacesPerLevel`, the number of spaces per indentation level for
436/// this and all of its nested objects. If `level` is negative, suppress
437/// indentation of the first line. If `spacesPerLevel` is negative, format
438/// the entire output on one line, suppressing all but the initial
439/// indentation (as governed by `level`). If `stream` is not valid on
440/// entry, this operation has no effect. As all objects of this type have
441/// the same value, `object` is *ignored* and a descriptive, human-readable
442/// message is output for all objects of this type.
443bsl::ostream& print(bsl::ostream& stream,
444 const std::monostate& object,
445 int level = 0,
446 int spacesPerLevel = 4);
447
448#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
449
450} // close namespace PrintMethods
451} // close package namespace
452
453// ============================================================================
454// INLINE DEFINITIONS
455// ============================================================================
456
457namespace bdlb {
458
459 // --------------------------------------------
460 // struct bdlb::PrintMethods_Imp<TYPE, SELECTOR>
461 // --------------------------------------------
462
463template <class TYPE, class SELECTOR>
465
466/// Component-private `struct`. Do not use outside of this component. This
467/// `struct` provides a `print` function that prints objects of
468/// parameterized `TYPE` that do not declare any of the traits recognized by
469/// this component.
470template <class TYPE>
471struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<> > {
472
473 // CLASS METHODS
474
475 /// Print the specified `object` to the specified `stream` using its `<<` output stream operator.
476 ///
477 /// \note Note that a compiler error will result
478 /// if the specified `TYPE` does not have a `<<` output stream operator.
479 static bsl::ostream& print(bsl::ostream& stream,
480 const TYPE& object,
481 int level,
482 int spacesPerLevel);
483};
484
485 // ----------------------------------------------------
486 // struct PrintMethods_Imp<TYPE, HasPrintMethod<TYPE> >
487 // ----------------------------------------------------
488
489/// Component-private `struct`. Do not use outside of this component. This
490/// `struct` provides a `print` function that prints objects of the
491/// parameterized `TYPE` that are associated with the `HasPrintMethod`
492/// trait.
493template <class TYPE>
494struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<HasPrintMethod> >
495{
496
497 // CLASS METHODS
498 static bsl::ostream& print(bsl::ostream& stream,
499 const TYPE& object,
500 int level,
501 int spacesPerLevel);
502};
503
504 // -------------------------------------------------------------
505 // struct PrintMethods_Imp<TYPE, bslalg::HasStlIterators<TYPE> >
506 // -------------------------------------------------------------
507
508/// Component-private `struct`. Do not use outside of this component. This
509/// `struct` provides a `print` function that prints objects of the
510/// parameterized `TYPE` that have the `bslalg::HasStlIterators` trait
511/// declared.
512template <class TYPE>
513struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<bslalg::HasStlIterators> >
514{
515
516 // CLASS METHODS
517 static bsl::ostream& print(bsl::ostream& stream,
518 const TYPE& object,
519 int level,
520 int spacesPerLevel);
521};
522
523 // ---------------------------------------------------
524 // struct PrintMethods_Imp<TYPE, bslmf::IsPair<TYPE> >
525 // ---------------------------------------------------
526
527/// Component-private `struct`. Do not use outside of this component. This
528/// `struct` provides a `print` function that prints objects of
529/// parameterized `TYPE` that declare the `bslmf::IsPair` trait.
530template <class TYPE>
531struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<bslmf::IsPair> >
532{
533
534 // CLASS METHODS
535 static bsl::ostream& print(bsl::ostream& stream,
536 const TYPE& object,
537 int level,
538 int spacesPerLevel);
539};
540
541// ============================================================================
542// TEMPLATE AND INLINE FUNCTION DEFINITIONS
543// ============================================================================
544
545 // ---------------------------------------
546 // struct PrintMethods_Imp<TYPE, SELECTOR>
547 // ---------------------------------------
548
549// CLASS METHODS
550template <class TYPE>
552 bsl::ostream& stream,
553 const TYPE& object,
554 int level,
555 int spacesPerLevel)
556{
557 if (stream.bad()) {
558 return stream; // RETURN
559 }
560
561 Print::indent(stream, level, spacesPerLevel);
562
563 // A compilation error indicating the next line of code implies the `TYPE`
564 // parameter does not have the `<<` output stream operator.
565
566 stream << object;
567
568 if (0 <= spacesPerLevel) {
569 stream << '\n';
570 }
571
572 return stream;
573}
574
575 // ----------------------------------------------------
576 // struct PrintMethods_Imp<TYPE, HasPrintMethod<TYPE> >
577 // ----------------------------------------------------
578
579// CLASS METHODS
580template <class TYPE>
581inline
583 print(bsl::ostream& stream,
584 const TYPE& object,
585 int level,
586 int spacesPerLevel)
587{
588 // A compilation error indicating the next line of code implies the 'TYPE'
589 // parameter does not have a 'print' method with the expected signature.
590
591 return object.print(stream, level, spacesPerLevel);
592}
593
594 // -------------------------------------------------------------
595 // struct PrintMethods_Imp<TYPE, bslalg::HasStlIterators<TYPE> >
596 // -------------------------------------------------------------
597
598// CLASS METHODS
599template <class TYPE>
600bsl::ostream& PrintMethods_Imp<TYPE,
602 >::print(bsl::ostream& stream,
603 const TYPE& object,
604 int level,
605 int spacesPerLevel)
606{
607 if (stream.bad()) {
608 return stream; // RETURN
609 }
610
611 Print::indent(stream, level, spacesPerLevel);
612
613 // A compilation error indicating the next line of code implies the 'TYPE'
614 // parameter does not have STL-compliant iterators.
615
616 typedef typename TYPE::const_iterator Iterator;
617
618 if (0 <= spacesPerLevel) {
619 // Multi-line output.
620
621 if (level < 0) {
622 level = -level;
623 }
624
625 stream << "[\n";
626
627 const int levelPlus1 = level + 1;
628
629 for (Iterator it = object.begin(); it != object.end(); ++it) {
630 PrintMethods::print(stream,
631 *it,
632 levelPlus1,
633 spacesPerLevel);
634 }
635
636 Print::indent(stream, level, spacesPerLevel);
637
638 stream << "]\n";
639 }
640 else {
641 // Output on a single line and suppress any further indentation.
642
643 stream << "[ ";
644
645 for (Iterator it = object.begin(); it != object.end(); ++it) {
646 PrintMethods::print(stream, *it, 0, -1);
647 stream << ' ';
648 }
649
650 stream << ']';
651 }
652
653 return stream << bsl::flush;
654}
655
656 // ---------------------------------------------------
657 // struct PrintMethods_Imp<TYPE, bslmf::IsPair<TYPE> >
658 // ---------------------------------------------------
659
660// CLASS METHODS
661template <class TYPE>
663 print(bsl::ostream& stream,
664 const TYPE& object,
665 int level,
666 int spacesPerLevel)
667{
668 if (stream.bad()) {
669 return stream; // RETURN
670 }
671
672 Print::indent(stream, level, spacesPerLevel);
673
674 if (0 <= spacesPerLevel) {
675 // Multi-line output.
676
677 if (level < 0) {
678 level = -level;
679 }
680
681 stream << "[\n";
682
683 const int levelPlus1 = level + 1;
684
685 // A compilation error indicating the next line of code implies the
686 // 'TYPE' parameter is not a pair.
687
688 PrintMethods::print(stream,
689 object.first,
690 levelPlus1,
691 spacesPerLevel);
692 PrintMethods::print(stream,
693 object.second,
694 levelPlus1,
695 spacesPerLevel);
696
697 Print::indent(stream, level, spacesPerLevel);
698
699 stream << "]\n";
700 }
701 else {
702 // Output on a single line and suppress any further indentation.
703
704 stream << "[ ";
705
706 // A compilation error indicating the next line of code implies the
707 // 'TYPE' parameter is not a pair.
708
709 PrintMethods::print(stream, object.first, 0, -1);
710 stream << ' ';
711
712 PrintMethods::print(stream, object.second, 0, -1);
713 stream << " ]";
714 }
715
716 return stream << bsl::flush;
717}
718
719 // ----------------------
720 // namespace PrintMethods
721 // ----------------------
722
723// CLASS METHODS
724template <class TYPE>
725bsl::ostream& PrintMethods::print(bsl::ostream& stream,
726 const TYPE& object,
727 int level,
728 int spacesPerLevel)
729{
730 typedef typename bslmf::SelectTrait<TYPE,
733 bslmf::IsPair>::Type BdlbSelector;
734
736 object,
737 level,
738 spacesPerLevel);
739}
740
741template <class CHAR_T, class CHAR_TRAITS_T, class ALLOC>
743 bsl::ostream& stream,
745 int level,
746 int spacesPerLevel)
747{
749 bslmf::SelectTraitCase<> >::print(stream,
750 object,
751 level,
752 spacesPerLevel);
753}
754
755template <class ALLOC>
756bsl::ostream&
757PrintMethods::print(bsl::ostream& stream,
758 const bsl::vector<char, ALLOC>& object,
759 int level,
760 int spacesPerLevel)
761{
762 if (stream.bad()) {
763 return stream; // RETURN
764 }
765
766 Print::indent(stream, level, spacesPerLevel);
767
768 stream << "\"";
769
770 const int len = static_cast<int>(object.size());
771
772 if (0 < len) {
773 Print::printString(stream, &object[0], len, false);
774 }
775
776 stream << "\"";
777
778 if (0 <= spacesPerLevel) {
779 stream << '\n';
780 }
781
782 return stream;
783}
784
785#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
786
787template <class TYPE>
788bsl::ostream&
789PrintMethods::print(bsl::ostream& stream,
790 const std::optional<TYPE>& object,
791 int level,
792 int spacesPerLevel)
793{
794
795 if (object.has_value()) {
796 return PrintMethods::print(stream,
797 object.value(),
798 level,
799 spacesPerLevel); // RETURN
800
801 } else {
802 return PrintMethods::print(stream,
803 "EMPTY",
804 level,
805 spacesPerLevel); // RETURN
806 }
807}
808
809template <class ... TYPE>
810bsl::ostream&
811PrintMethods::print(bsl::ostream& stream,
812 const std::variant<TYPE ...>& object,
813 int level,
814 int spacesPerLevel)
815{
816 const auto lambda = [&](const auto& x) -> bsl::ostream& {
817 return PrintMethods::print(stream,
818 x,
819 level,
820 spacesPerLevel);
821 };
822 return std::visit(lambda, object);
823}
824
825inline
826bsl::ostream&
827PrintMethods::print(bsl::ostream& stream,
828 const std::monostate& ,
829 int level,
830 int spacesPerLevel)
831{
832 return PrintMethods::print(stream,
833 "MONOSTATE",
834 level,
835 spacesPerLevel); // RETURN
836}
837#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
838
839} // close package namespace
840
841
842#endif
843
844// ----------------------------------------------------------------------------
845// Copyright 2015 Bloomberg Finance L.P.
846//
847// Licensed under the Apache License, Version 2.0 (the "License");
848// you may not use this file except in compliance with the License.
849// You may obtain a copy of the License at
850//
851// http://www.apache.org/licenses/LICENSE-2.0
852//
853// Unless required by applicable law or agreed to in writing, software
854// distributed under the License is distributed on an "AS IS" BASIS,
855// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
856// See the License for the specific language governing permissions and
857// limitations under the License.
858// ----------------------------- END-OF-FILE ----------------------------------
859
860/** @} */
861/** @} */
862/** @} */
Definition bslstl_string.h:1252
Definition bslstl_vector.h:1120
Definition bslmf_nestedtraitdeclaration.h:214
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:725
Definition bdlb_algorithmworkaroundutil.h:74
Definition bdlat_valuetypefunctions.h:939
Definition bdlbb_blob.h:579
Definition bdlb_printmethods.h:306
Definition bdlb_printmethods.h:464
static bsl::ostream & indent(bsl::ostream &stream, int level, int spacesPerLevel=4)
static bsl::ostream & printString(bsl::ostream &stream, const char *string, int length, bool escapeBackSlash=false)
Definition bdlb_printmethods.h:333
Definition bdlb_printmethods.h:322
Definition bslalg_hasstliterators.h:99
Definition bslmf_detectnestedtrait.h:467
Definition bslmf_ispair.h:88
Definition bslmf_selecttrait.h:438
Definition bslmf_selecttrait.h:524