BDE 4.14.0 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
321
322 /// This class template ties the `bdlb::TypeTraitHasPrintMethod` trait
323 /// tag to the `bdlb::HasPrintMethod` trait metafunction.
324 template <class TYPE>
326 bslmf::NestedTraitDeclaration<TYPE, HasPrintMethod>
327 {
328 };
329
330 template <class TYPE>
331 struct Metafunction : HasPrintMethod<TYPE>::type { };
332};
333
334 // ======================
335 // namespace PrintMethods
336 // ======================
337
338/// This `namespace` contains parameterized `print` methods having the
339/// standard BDE signature for such methods.
340namespace PrintMethods {
341
342/// Format the specified `object` to the specified output `stream` at the
343/// (absolute value of) the optionally specified indentation `level` and
344/// return a reference to `stream`. If `level` is specified, optionally
345/// specify `spacesPerLevel`, the number of spaces per indentation level for
346/// this and all of its nested objects. If `level` is negative, suppress
347/// indentation of the first line. If `spacesPerLevel` is negative, format
348/// the entire output on one line, suppressing all but the initial
349/// indentation (as governed by `level`). If `stream` is not valid on
350/// entry, this operation has no effect.
351template <class TYPE>
352bsl::ostream& print(bsl::ostream& stream,
353 const TYPE& object,
354 int level = 0,
355 int spacesPerLevel = 4);
356bsl::ostream& print(bsl::ostream& stream,
357 char object,
358 int level = 0,
359 int spacesPerLevel = 4);
360bsl::ostream& print(bsl::ostream& stream,
361 unsigned char object,
362 int level = 0,
363 int spacesPerLevel = 4);
364
365/// Format the specified `object` to the specified output `stream` at the
366/// (absolute value of) the optionally specified indentation `level` and
367/// return a reference to stream. Note that output will be formatted on one
368/// line. If `stream` is not valid on entry, this operation has no effect.
369template <class CHAR_T, class CHAR_TRAITS_T, class ALLOC>
370bsl::ostream& print(bsl::ostream& stream,
371 const bsl::basic_string<CHAR_T,
372 CHAR_TRAITS_T,
373 ALLOC>& object,
374 int level = 0,
375 int spacesPerLevel = 4);
376
377/// Format the specified `object` to the specified output `stream` at the
378/// (absolute value of) the optionally specified indentation `level` and
379/// return a reference to stream. Note that output will be formatted on one
380/// line. Also note that non-printable characters in `object` will be
381/// printed using their hexadecimal representation. If `stream` is not
382/// valid on entry, this operation has no effect.
383template <class ALLOC>
384bsl::ostream& print(bsl::ostream& stream,
385 const bsl::vector<char, ALLOC>& object,
386 int level = 0,
387 int spacesPerLevel = 4);
388
389#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
390
391/// Format the specified `object` to the specified output `stream` at the
392/// (absolute value of) the optionally specified indentation `level` and
393/// return a reference to `stream`. If `level` is specified, optionally
394/// specify `spacesPerLevel`, the number of spaces per indentation level for
395/// this and all of its nested objects. If `level` is negative, suppress
396/// indentation of the first line. If `spacesPerLevel` is negative, format
397/// the entire output on one line, suppressing all but the initial
398/// indentation (as governed by `level`). If `stream` is not valid on
399/// entry, this operation has no effect. A descriptive, human-readable
400/// message, indented according to `level` and `spacesPerLevel`, is output
401/// for objects having no value (i.e., `false == object.has_value()`).
402template <class TYPE>
403bsl::ostream& print(bsl::ostream& stream,
404 const std::optional<TYPE>& object,
405 int level = 0,
406 int spacesPerLevel = 4);
407
408/// Format the specified `object` to the specified output `stream` at the
409/// (absolute value of) the optionally specified indentation `level` and
410/// return a reference to `stream`. If `level` is specified, optionally
411/// specify `spacesPerLevel`, the number of spaces per indentation level for
412/// this and all of its nested objects. If `level` is negative, suppress
413/// indentation of the first line. If `spacesPerLevel` is negative, format
414/// the entire output on one line, suppressing all but the initial
415/// indentation (as governed by `level`). If `stream` is not valid on
416/// entry, this operation has no effect. A descriptive, human-readable
417/// message, indented according to `level` and `spacesPerLevel`, is output
418/// for objects holding the value of type `std::monostate`. Note that a
419/// `std::variant` object can hold the `std::monostate` value only if its
420/// template parameters explicitly mention the `std::monostate` type.
421template <class ... TYPE>
422bsl::ostream& print(bsl::ostream& stream,
423 const std::variant<TYPE ...>& object,
424 int level = 0,
425 int spacesPerLevel = 4);
426
427/// Format the specified `object` to the specified output `stream` at the
428/// (absolute value of) the optionally specified indentation `level` and
429/// return a reference to `stream`. If `level` is specified, optionally
430/// specify `spacesPerLevel`, the number of spaces per indentation level for
431/// this and all of its nested objects. If `level` is negative, suppress
432/// indentation of the first line. If `spacesPerLevel` is negative, format
433/// the entire output on one line, suppressing all but the initial
434/// indentation (as governed by `level`). If `stream` is not valid on
435/// entry, this operation has no effect. As all objects of this type have
436/// the same value, `object` is *ignored* and a descriptive, human-readable
437/// message is output for all objects of this type.
438bsl::ostream& print(bsl::ostream& stream,
439 const std::monostate& object,
440 int level = 0,
441 int spacesPerLevel = 4);
442
443#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
444
445} // close namespace PrintMethods
446} // close package namespace
447
448// ============================================================================
449// INLINE DEFINITIONS
450// ============================================================================
451
452namespace bdlb {
453
454 // --------------------------------------------
455 // struct bdlb::PrintMethods_Imp<TYPE, SELECTOR>
456 // --------------------------------------------
457
458template <class TYPE, class SELECTOR>
460
461/// Component-private `struct`. Do not use outside of this component. This
462/// `struct` provides a `print` function that prints objects of
463/// parameterized `TYPE` that do not declare any of the traits recognized by
464/// this component.
465template <class TYPE>
466struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<> > {
467
468 // CLASS METHODS
469
470 /// Print the specified `object` to the specified `stream` using its
471 /// `<<` output stream operator. Note that a compiler error will result
472 /// if the specified `TYPE` does not have a `<<` output stream operator.
473 static bsl::ostream& print(bsl::ostream& stream,
474 const TYPE& object,
475 int level,
476 int spacesPerLevel);
477};
478
479 // ----------------------------------------------------
480 // struct PrintMethods_Imp<TYPE, HasPrintMethod<TYPE> >
481 // ----------------------------------------------------
482
483/// Component-private `struct`. Do not use outside of this component. This
484/// `struct` provides a `print` function that prints objects of the
485/// parameterized `TYPE` that are associated with the `HasPrintMethod`
486/// trait.
487template <class TYPE>
488struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<HasPrintMethod> >
489{
490
491 // CLASS METHODS
492 static bsl::ostream& print(bsl::ostream& stream,
493 const TYPE& object,
494 int level,
495 int spacesPerLevel);
496};
497
498 // -------------------------------------------------------------
499 // struct PrintMethods_Imp<TYPE, bslalg::HasStlIterators<TYPE> >
500 // -------------------------------------------------------------
501
502/// Component-private `struct`. Do not use outside of this component. This
503/// `struct` provides a `print` function that prints objects of the
504/// parameterized `TYPE` that have the `bslalg::HasStlIterators` trait
505/// declared.
506template <class TYPE>
507struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<bslalg::HasStlIterators> >
508{
509
510 // CLASS METHODS
511 static bsl::ostream& print(bsl::ostream& stream,
512 const TYPE& object,
513 int level,
514 int spacesPerLevel);
515};
516
517 // ---------------------------------------------------
518 // struct PrintMethods_Imp<TYPE, bslmf::IsPair<TYPE> >
519 // ---------------------------------------------------
520
521/// Component-private `struct`. Do not use outside of this component. This
522/// `struct` provides a `print` function that prints objects of
523/// parameterized `TYPE` that declare the `bslmf::IsPair` trait.
524template <class TYPE>
525struct PrintMethods_Imp<TYPE, bslmf::SelectTraitCase<bslmf::IsPair> >
526{
527
528 // CLASS METHODS
529 static bsl::ostream& print(bsl::ostream& stream,
530 const TYPE& object,
531 int level,
532 int spacesPerLevel);
533};
534
535// ============================================================================
536// TEMPLATE AND INLINE FUNCTION DEFINITIONS
537// ============================================================================
538
539 // ---------------------------------------
540 // struct PrintMethods_Imp<TYPE, SELECTOR>
541 // ---------------------------------------
542
543// CLASS METHODS
544template <class TYPE>
546 bsl::ostream& stream,
547 const TYPE& object,
548 int level,
549 int spacesPerLevel)
550{
551 if (stream.bad()) {
552 return stream; // RETURN
553 }
554
555 Print::indent(stream, level, spacesPerLevel);
556
557 // A compilation error indicating the next line of code implies the `TYPE`
558 // parameter does not have the `<<` output stream operator.
559
560 stream << object;
561
562 if (0 <= spacesPerLevel) {
563 stream << '\n';
564 }
565
566 return stream;
567}
568
569 // ----------------------------------------------------
570 // struct PrintMethods_Imp<TYPE, HasPrintMethod<TYPE> >
571 // ----------------------------------------------------
572
573// CLASS METHODS
574template <class TYPE>
575inline
577 print(bsl::ostream& stream,
578 const TYPE& object,
579 int level,
580 int spacesPerLevel)
581{
582 // A compilation error indicating the next line of code implies the 'TYPE'
583 // parameter does not have a 'print' method with the expected signature.
584
585 return object.print(stream, level, spacesPerLevel);
586}
587
588 // -------------------------------------------------------------
589 // struct PrintMethods_Imp<TYPE, bslalg::HasStlIterators<TYPE> >
590 // -------------------------------------------------------------
591
592// CLASS METHODS
593template <class TYPE>
594bsl::ostream& PrintMethods_Imp<TYPE,
596 >::print(bsl::ostream& stream,
597 const TYPE& object,
598 int level,
599 int spacesPerLevel)
600{
601 if (stream.bad()) {
602 return stream; // RETURN
603 }
604
605 Print::indent(stream, level, spacesPerLevel);
606
607 // A compilation error indicating the next line of code implies the 'TYPE'
608 // parameter does not have STL-compliant iterators.
609
610 typedef typename TYPE::const_iterator Iterator;
611
612 if (0 <= spacesPerLevel) {
613 // Multi-line output.
614
615 if (level < 0) {
616 level = -level;
617 }
618
619 stream << "[\n";
620
621 const int levelPlus1 = level + 1;
622
623 for (Iterator it = object.begin(); it != object.end(); ++it) {
624 PrintMethods::print(stream,
625 *it,
626 levelPlus1,
627 spacesPerLevel);
628 }
629
630 Print::indent(stream, level, spacesPerLevel);
631
632 stream << "]\n";
633 }
634 else {
635 // Output on a single line and suppress any further indentation.
636
637 stream << "[ ";
638
639 for (Iterator it = object.begin(); it != object.end(); ++it) {
640 PrintMethods::print(stream, *it, 0, -1);
641 stream << ' ';
642 }
643
644 stream << ']';
645 }
646
647 return stream << bsl::flush;
648}
649
650 // ---------------------------------------------------
651 // struct PrintMethods_Imp<TYPE, bslmf::IsPair<TYPE> >
652 // ---------------------------------------------------
653
654// CLASS METHODS
655template <class TYPE>
657 print(bsl::ostream& stream,
658 const TYPE& object,
659 int level,
660 int spacesPerLevel)
661{
662 if (stream.bad()) {
663 return stream; // RETURN
664 }
665
666 Print::indent(stream, level, spacesPerLevel);
667
668 if (0 <= spacesPerLevel) {
669 // Multi-line output.
670
671 if (level < 0) {
672 level = -level;
673 }
674
675 stream << "[\n";
676
677 const int levelPlus1 = level + 1;
678
679 // A compilation error indicating the next line of code implies the
680 // 'TYPE' parameter is not a pair.
681
682 PrintMethods::print(stream,
683 object.first,
684 levelPlus1,
685 spacesPerLevel);
686 PrintMethods::print(stream,
687 object.second,
688 levelPlus1,
689 spacesPerLevel);
690
691 Print::indent(stream, level, spacesPerLevel);
692
693 stream << "]\n";
694 }
695 else {
696 // Output on a single line and suppress any further indentation.
697
698 stream << "[ ";
699
700 // A compilation error indicating the next line of code implies the
701 // 'TYPE' parameter is not a pair.
702
703 PrintMethods::print(stream, object.first, 0, -1);
704 stream << ' ';
705
706 PrintMethods::print(stream, object.second, 0, -1);
707 stream << " ]";
708 }
709
710 return stream << bsl::flush;
711}
712
713 // ----------------------
714 // namespace PrintMethods
715 // ----------------------
716
717// CLASS METHODS
718template <class TYPE>
719bsl::ostream& PrintMethods::print(bsl::ostream& stream,
720 const TYPE& object,
721 int level,
722 int spacesPerLevel)
723{
724 typedef typename bslmf::SelectTrait<TYPE,
727 bslmf::IsPair>::Type BdlbSelector;
728
730 object,
731 level,
732 spacesPerLevel);
733}
734
735template <class CHAR_T, class CHAR_TRAITS_T, class ALLOC>
737 bsl::ostream& stream,
739 int level,
740 int spacesPerLevel)
741{
743 bslmf::SelectTraitCase<> >::print(stream,
744 object,
745 level,
746 spacesPerLevel);
747}
748
749template <class ALLOC>
750bsl::ostream&
751PrintMethods::print(bsl::ostream& stream,
752 const bsl::vector<char, ALLOC>& object,
753 int level,
754 int spacesPerLevel)
755{
756 if (stream.bad()) {
757 return stream; // RETURN
758 }
759
760 Print::indent(stream, level, spacesPerLevel);
761
762 stream << "\"";
763
764 const int len = static_cast<int>(object.size());
765
766 if (0 < len) {
767 Print::printString(stream, &object[0], len, false);
768 }
769
770 stream << "\"";
771
772 if (0 <= spacesPerLevel) {
773 stream << '\n';
774 }
775
776 return stream;
777}
778
779#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
780
781template <class TYPE>
782bsl::ostream&
783PrintMethods::print(bsl::ostream& stream,
784 const std::optional<TYPE>& object,
785 int level,
786 int spacesPerLevel)
787{
788
789 if (object.has_value()) {
790 return PrintMethods::print(stream,
791 object.value(),
792 level,
793 spacesPerLevel); // RETURN
794
795 } else {
796 return PrintMethods::print(stream,
797 "EMPTY",
798 level,
799 spacesPerLevel); // RETURN
800 }
801}
802
803template <class ... TYPE>
804bsl::ostream&
805PrintMethods::print(bsl::ostream& stream,
806 const std::variant<TYPE ...>& object,
807 int level,
808 int spacesPerLevel)
809{
810 const auto lambda = [&](const auto& x) -> bsl::ostream& {
811 return PrintMethods::print(stream,
812 x,
813 level,
814 spacesPerLevel);
815 };
816 return std::visit(lambda, object);
817}
818
819inline
820bsl::ostream&
821PrintMethods::print(bsl::ostream& stream,
822 const std::monostate& ,
823 int level,
824 int spacesPerLevel)
825{
826 return PrintMethods::print(stream,
827 "MONOSTATE",
828 level,
829 spacesPerLevel); // RETURN
830}
831#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
832
833} // close package namespace
834
835
836#endif
837
838// ----------------------------------------------------------------------------
839// Copyright 2015 Bloomberg Finance L.P.
840//
841// Licensed under the Apache License, Version 2.0 (the "License");
842// you may not use this file except in compliance with the License.
843// You may obtain a copy of the License at
844//
845// http://www.apache.org/licenses/LICENSE-2.0
846//
847// Unless required by applicable law or agreed to in writing, software
848// distributed under the License is distributed on an "AS IS" BASIS,
849// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
850// See the License for the specific language governing permissions and
851// limitations under the License.
852// ----------------------------- END-OF-FILE ----------------------------------
853
854/** @} */
855/** @} */
856/** @} */
Definition bslstl_string.h:1281
Definition bslstl_vector.h:1025
Definition bslmf_nestedtraitdeclaration.h:214
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:719
Definition bdlb_algorithmworkaroundutil.h:74
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
Definition bdlb_printmethods.h:306
Definition bdlb_printmethods.h:459
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:331
Definition bdlb_printmethods.h:320
Definition bslalg_hasstliterators.h:99
Definition bslmf_detectnestedtrait.h:464
Definition bslmf_ispair.h:88
Definition bslmf_selecttrait.h:438
Definition bslmf_selecttrait.h:522