BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balcl_optionvalue.h
Go to the documentation of this file.
1/// @file balcl_optionvalue.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balcl_optionvalue.h -*-C++-*-
8#ifndef INCLUDED_BALCL_OPTIONVALUE
9#define INCLUDED_BALCL_OPTIONVALUE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balcl_optionvalue balcl_optionvalue
15/// @brief Provide a variant type for command-line-option values.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balcl
19/// @{
20/// @addtogroup balcl_optionvalue
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balcl_optionvalue-purpose"> Purpose</a>
25/// * <a href="#balcl_optionvalue-classes"> Classes </a>
26/// * <a href="#balcl_optionvalue-description"> Description </a>
27/// * <a href="#balcl_optionvalue-usage"> Usage </a>
28/// * <a href="#balcl_optionvalue-example-1-basic-use-of-balcl-optionvalue"> Example 1: Basic Use of balcl::OptionValue </a>
29/// * <a href="#balcl_optionvalue-example-2-interpreting-option-parser-results"> Example 2: Interpreting Option Parser Results </a>
30///
31/// # Purpose {#balcl_optionvalue-purpose}
32/// Provide a variant type for command-line-option values.
33///
34/// # Classes {#balcl_optionvalue-classes}
35///
36/// - balcl::OptionValue: the value of a user supplied command-line option
37///
38/// @see balcl_optiontype, balcl_commandline
39///
40/// # Description {#balcl_optionvalue-description}
41/// This component provides a value-semantic class,
42/// `balcl::OptionValue`, that can have a value of any of the types specified by
43/// `balcl::OptionType` -- i.e., any of the values that can be associated with a
44/// command-line option by `balcl::CommandLine`. The `balcl::OptionValue` class
45/// has two related states:
46///
47/// 1. A default-constructed `balcl::OptionValue` object is in the "unset state"
48/// -- meaning that no type has been defined for a value (its type is
49/// `void`). In this state, `balcl::OptionType::e_VOID == type()` and
50/// `false == hasNonVoidType()`. To have a value, a type must be specified
51/// for the value by using the `setType` method or using one of the
52/// constructors that define an initial value. {Example 1} shows how this
53/// state can be set and reset.
54///
55/// 2. If a `balcl::OptionValue` object has a (non-`void`) type it can have a
56/// value of that type or be in a "null state". Objects in the null state
57/// can be used to represent the value of command-line options that were not
58/// entered on the command line (assuming no default value was specified for
59/// the option). {Example 2} shows how this feature can be used.
60///
61/// ## Usage {#balcl_optionvalue-usage}
62///
63///
64/// This section illustrates intended use of this component.
65///
66/// ### Example 1: Basic Use of balcl::OptionValue {#balcl_optionvalue-example-1-basic-use-of-balcl-optionvalue}
67///
68///
69/// The following snippets of code illustrate how to create and use a
70/// `balcl::OptionValue` object. Note that `balcl::OptionValue` objects are
71/// typically used in a description of a sequence of command-line options (see
72/// @ref balcl_optiontype ).
73///
74/// First, we create a default `balcl::OptionValue`, `valueA`, and observe that
75/// it is in the unset state:
76/// @code
77/// balcl::OptionValue valueA;
78///
79/// assert(false == valueA.hasNonVoidType());
80/// assert(balcl::OptionType::e_VOID == valueA.type());
81/// @endcode
82/// Next, we create a second `balcl::OptionValue` having the value 5, and then
83/// confirm its value and observe that it does not compare equal to the
84/// `valueA`:
85/// @code
86/// balcl::OptionValue valueB(5);
87///
88/// assert(true == valueB.hasNonVoidType());
89/// assert(balcl::OptionType::e_INT == valueB.type());
90/// assert(5 == valueB.the<int>());
91///
92/// assert(valueA != valueB);
93/// @endcode
94/// Then, we call the `reset` method of `valueB` resetting it to the unset
95/// state, and observe that `valueA` now compares equal to `valueB`:
96/// @code
97/// valueB.reset();
98///
99/// assert(valueA == valueB);
100/// @endcode
101/// Now, we change the type of `valueA` so that it can be hold a `double` value:
102/// @code
103/// valueA.setType(balcl::OptionType::e_DOUBLE);
104/// assert(true == valueA.hasNonVoidType());
105/// assert(balcl::OptionType::e_DOUBLE == valueA.type());
106/// assert(double() == valueA.the<double>());
107///
108/// valueA.set(6.0);
109/// assert(6.0 == valueA.the<double>());
110/// @endcode
111/// Finally, we set the object to the null state. Notice that the type of that
112/// value is not changed:
113/// @code
114/// valueA.setNull();
115/// assert(true == valueA.isNull());
116/// assert(balcl::OptionType::e_DOUBLE == valueA.type());
117/// @endcode
118///
119/// ### Example 2: Interpreting Option Parser Results {#balcl_optionvalue-example-2-interpreting-option-parser-results}
120///
121///
122/// Command-line options have values of many different types (e.g., `int`,
123/// `double`, string, date) or their values may not be specified -- after all,
124/// some command-line options may be *optional*. The `balcl::OptionValue` class
125/// can be used to represent such values.
126///
127/// First, we define `MyCommandLineParser`, a simple command-line argument
128/// parser. This class accepts a description (e.g., option name, value type) of
129/// allowable options on construction and provides a `parse` method that accepts
130/// `argc` and `argv`, the values made available (by the operating system) to
131/// `main`:
132/// @code
133/// // =========================
134/// // class MyCommandLineParser
135/// // =========================
136///
137/// class MyCommandLineParser {
138/// // ...
139///
140/// public:
141/// // CREATORS
142///
143/// /// Create an object that can parse command-line arguments that
144/// /// satisfy the specified `descriptions`, an array containing the
145/// /// specified `count` elements.
146/// MyCommandLineParser(const MyOptionDescription *descriptions,
147/// bsl::size_t count);
148///
149/// // ...
150///
151/// // MANIPULATORS
152///
153/// /// Parse the command-line options in the specified `argv`, an array
154/// /// having the specified `argc` elements. Return 0 on success --
155/// /// i.e., the options were compatible with the option descriptions
156/// /// specified on construction -- and a non-zero value otherwise.
157/// int parse(int argc, const char **argv);
158///
159/// // ...
160/// @endcode
161/// After a successful call to the `parse` method, the results are available by
162/// several accessors. Note that the `index` of a result corresponds to the
163/// index of that option in the description provided on construction:
164/// @code
165/// // ACCESSORS
166///
167/// /// Return `true` if the most recent call to `parsed` was successful
168/// /// and `false` otherwise.
169/// bool isParsed() const;
170///
171/// /// Return of the name of the parsed option at the specified `index`
172/// /// position. The behavior is undefined unless
173/// /// `0 <= index < numOptions()` and `true == isParsed()`
174/// const char *name (bsl::size_t index) const;
175///
176/// /// Return a `const` reference to the value (possibly in a null
177/// /// state) of the parsed option at the specified `index` position.
178/// /// The behavior is undefined unless `0 <= index < numOptions()` and
179/// /// `true == isParsed()`.
180/// const balcl::OptionValue& value(bsl::size_t index) const;
181///
182/// /// Return the number of parsed options. The behavior is undefined
183/// /// unless `true == isParsed()`.
184/// bsl::size_t numOptions() const;
185///
186/// // ...
187/// };
188/// @endcode
189/// Note that neither our option description nor our parser support the concept
190/// of default values for options that are not entered on the command line.
191///
192/// Then, we create a description having three allowable options (elided), a
193/// parser object, and invoke `parse` on the arguments available from `main`:
194/// @code
195/// int main(int argc, const char **argv)
196/// {
197/// MyOptionDescription optionDescriptions[NUM_OPTIONS] = {
198/// // ...
199/// };
200///
201/// MyCommandLineParser parser(optionDescriptions, NUM_OPTIONS);
202///
203/// int rc = parser.parse(argc, argv);
204/// assert(0 == rc);
205/// assert(true == parser.isParsed());
206/// @endcode
207/// Now, we examine the value of each defined option:
208/// @code
209/// for (bsl::size_t i = 0; i < parser.numOptions(); ++i) {
210/// const char *name = parser.name(i);
211/// const balcl::OptionValue& value = parser.value(i);
212/// @endcode
213/// Since our (toy) parser has no feature for handling default values for
214/// options that are not specified on the command line, we must handle those
215/// explicitly.
216///
217/// If the option named "outputDir" was set, we use that value; otherwise, we
218/// set a default value, the current directory:
219/// @code
220/// if (0 == bsl::strcmp("outputDir", name)) {
221/// setOutputDir(value.isNull()
222/// ? "."
223/// : value.the<bsl::string>().c_str());
224/// }
225/// @endcode
226/// If the option named "verbosityLevel" was set we use that value; otherwise,
227/// we set a default value, `1`:
228/// @code
229/// if (0 == bsl::strcmp("verbosityLevel", name)) {
230/// setVerbosityLevel(value.isNull()
231/// ? 1
232/// : value.the<int>());
233/// }
234/// @endcode
235/// The option named "caseInsensitive" has no associated value. If that option
236/// appeared on the command line, the value of the program flag is set to
237/// `true`, otherwise (`false == isNull()`) that flag is set to `false`:
238/// @code
239/// if (0 == bsl::strcmp("caseInsensitive", name)) {
240/// setCaseInsensitivityFlag(value.isNull()
241/// ? false
242/// : true);
243/// }
244/// }
245/// @endcode
246/// Finally, we continue with the execution of our program using the values
247/// obtained from the command-line options:
248/// @code
249/// // ...
250///
251/// return 0;
252/// }
253/// @endcode
254/// @}
255/** @} */
256/** @} */
257
258/** @addtogroup bal
259 * @{
260 */
261/** @addtogroup balcl
262 * @{
263 */
264/** @addtogroup balcl_optionvalue
265 * @{
266 */
267
268#include <balscm_version.h>
269
270#include <balcl_optiontype.h>
271
272#include <bdlt_date.h>
273#include <bdlt_datetime.h>
274#include <bdlt_time.h>
275
276#include <bdlb_printmethods.h> // 'bdlb::HasPrintMethod', 'bdlb::PrintMethods'
277#include <bdlb_variant.h>
278
279#include <bslma_allocator.h>
281
285#include <bslmf_nil.h>
286
287#include <bsls_assert.h>
288#include <bsls_types.h> // 'bsls::Types::Int64'
289
290#include <bsl_iosfwd.h> // 'bsl::ostream'
291#include <bsl_string.h>
292#include <bsl_vector.h>
293
294
295
296namespace balcl {
297
298 // ========================
299 // class OptionValue_NullOf
300 // ========================
301
302/// This single-attribute class represents a null value of a given nullable
303/// `balcl::OptionType`. `OptionValue` uses this type to represent its
304/// state where there is a known type, but no value for it. Note that
305/// `OptionType::e_VOID` is *not* nullable, therefore not supported here.
306/// Note that: There is no `swap` member or namespace-level function
307/// declared (and defined) for this class on purpose, the general swap works
308/// fast for such a simple type.
309///
310/// See @ref balcl_optionvalue
312
313 // DATA
314 OptionType::Enum d_type;
315
316 public:
317 // TRAITS
324
325 // CREATORS
326
327 /// Create an `OptionValue_NullOf` object with the specified nullable
328 /// `optionType`. The behavior is undefined if
329 /// `optionType == OptionType::e_VOID`.
330 explicit OptionValue_NullOf(OptionType::Enum optionType);
331
332 // ACCESSORS
333
334 /// Return `true` if `TYPE` corresponds to the `type` attribute, and
335 /// `false` if it does not.
336 template <class TYPE>
337 bool isType(const TYPE&) const;
338
339 /// Return the option `type` of this object.
340 OptionType::Enum type() const;
341
342 // Aspects
343
344 /// Format this object to the specified output `stream` at the (absolute
345 /// value of) the optionally specified indentation `level` and return a
346 /// reference to `stream`. If `level` is specified, optionally specify
347 /// `spacesPerLevel`, the number of spaces per indentation level for
348 /// this and all of its nested objects. If `level` is negative,
349 /// suppress indentation of the first line. If `spacesPerLevel` is
350 /// negative, format the entire output on one line, suppressing all but
351 /// the initial indentation (as governed by `level`). If `stream` is
352 /// not valid on entry, this operation has no effect.
353 bsl::ostream& print(bsl::ostream& stream,
354 int level = 0,
355 int spacesPerLevel = 4) const;
356};
357
358// FREE OPERATORS
359
360/// Return `true` if the `type` of the specified `lhs` and `rhs` are equal,
361/// and return `false` if they are not equal. Two `OptionValue_NullOf`
362/// objects are equal when their `type` attributes are equal.
363bool operator==(const OptionValue_NullOf& lhs, const OptionValue_NullOf& rhs);
364
365/// Return `true` if the `type` of the specified `lhs` and `rhs` are not
366/// equal, and return `false` if they are not equal. Two
367/// `OptionValue_NullOf` objects are equal when their `type` attributes are
368/// note equal.
369bool operator!=(const OptionValue_NullOf& lhs, const OptionValue_NullOf& rhs);
370
371/// Write the value of the specified `object` to the specified output
372/// `stream` in a single-line format, and return a reference to `stream`.
373/// If `stream` is not valid on entry, this operation has no effect. Note
374/// that this human-readable format is not fully specified, can change
375/// without notice, and is logically equivalent to:
376/// `object.print(stream, 0, -1);`
377bsl::ostream& operator<<(bsl::ostream& stream,
378 const OptionValue_NullOf& object);
379
380 // =================
381 // class OptionValue
382 // =================
383
384/// This class implements a special-use value-semantic variant type used to
385/// represent values parsed from process command lines. Accordingly, this
386/// class can represent values of any of the types defined in
387/// @ref balcl_optiontype . Furthermore, that value can also be in a null state
388/// (defined type but no defined value) to represent allowed options that do
389/// not appear among the command-line arguments (and for which no default value
390/// has been configured).
391///
392/// See @ref balcl_optionvalue
394
395 private:
396 // PRIVATE TYPES
397 typedef OptionType::Bool Bool;
398 typedef OptionType::Char Char;
399 typedef OptionType::Int Int;
400 typedef OptionType::Int64 Int64;
401 typedef OptionType::Double Double;
404 typedef OptionType::Date Date;
405 typedef OptionType::Time Time;
414
415 typedef bdlb::Variant<Bool,
416 Char,
417 Int,
418 Int64,
419 Double,
420 String,
421 Datetime,
422 Date,
423 Time, // DO NOT change the order of these types!
424 CharArray,
425 IntArray,
430 DateArray,
431 TimeArray,
433
434 // DATA
435 ValueVariant d_value; // the object's value
436
437 // FRIENDS
438 friend bool operator==(const OptionValue&, const OptionValue&);
439 friend void swap(OptionValue&, OptionValue&);
440
441 // PRIVATE MANIPULATORS
442
443 /// Set the type of the contained variant object to have the specified
444 /// `type` and have the default value for `type`. The behavior is
445 /// undefined unless `OptionType::e_VOID != type()`.
446 void init(OptionType::Enum type);
447
448 public:
449 // TRAITS
452
453 // CREATORS
454
455 OptionValue();
456 /// Create a command-line-option value object in the unset state (i.e.,
457 /// `OptionType::e_VOID == type()`). Optionally specify a
458 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
459 /// specified, the currently installed default allocator is used. Note
460 /// that (atypically) this constructor disallows 0 for `basicAllocator`;
461 /// invoking the constructor with 0 dispatches to the constructor
462 /// overload that explicitly accepts an `int` value for its first
463 /// argument (see below).
464 explicit
465 OptionValue(bslma::Allocator *basicAllocator);
466
467 /// Create a command-line-option value object having the type
468 /// corresponding to the specified `type` and, if
469 /// `OptionType::e_VOID != type`, having the default value of that type.
470 /// Optionally specify a `basicAllocator` used to supply memory. If
471 /// `basicAllocator` is 0, the currently installed default allocator is
472 /// used.
474 bslma::Allocator *basicAllocator = 0); // IMPLICIT
475
476 explicit
477 OptionValue(bool value,
478 bslma::Allocator *basicAllocator = 0);
479 explicit
480 OptionValue(char value,
481 bslma::Allocator *basicAllocator = 0);
482 explicit
483 OptionValue(int value,
484 bslma::Allocator *basicAllocator = 0);
485 explicit
487 bslma::Allocator *basicAllocator = 0);
488 explicit
489 OptionValue(double value,
490 bslma::Allocator *basicAllocator = 0);
491 explicit
492 OptionValue(const bsl::string& value,
493 bslma::Allocator *basicAllocator = 0);
494 explicit
496 bslma::Allocator *basicAllocator = 0);
497 explicit
499 bslma::Allocator *basicAllocator = 0);
500 explicit
502 bslma::Allocator *basicAllocator = 0);
503 explicit
504 OptionValue(const bsl::vector<char>& value,
505 bslma::Allocator *basicAllocator = 0);
506 explicit
507 OptionValue(const bsl::vector<int>& value,
508 bslma::Allocator *basicAllocator = 0);
509 explicit
511 bslma::Allocator *basicAllocator = 0);
512 explicit
513 OptionValue(const bsl::vector<double>& value,
514 bslma::Allocator *basicAllocator = 0);
515 explicit
517 bslma::Allocator *basicAllocator = 0);
518 explicit
520 bslma::Allocator *basicAllocator = 0);
521 explicit
523 bslma::Allocator *basicAllocator = 0);
524 /// Create a command-line-option value object having the type and value
525 /// of the specified `value`. Optionally specify a `basicAllocator`
526 /// used to supply memory. If `basicAllocator` is 0, the currently
527 /// installed default allocator is used.
528 explicit
530 bslma::Allocator *basicAllocator = 0);
531
532 /// Create a `OptionValue` object having the same value as the specified
533 /// `original` object. Optionally specify a `basicAllocator` used to
534 /// supply memory. If `basicAllocator` is 0, the currently installed
535 /// default allocator is used.
536 OptionValue(const OptionValue& original,
537 bslma::Allocator *basicAllocator = 0);
538
539 /// Destroy this object.
540 ~OptionValue() = default;
541
542 // MANIPULATORS
543
544 /// Assign to this object the value of the specified `rhs` object, and
545 /// return a reference providing modifiable access to this object.
546 OptionValue& operator=(const OptionValue& rhs);
547
548 /// Reset this object to its default constructed (unset) state. The
549 /// existing value, if any, is destroyed. Note that on return
550 /// `OptionType::e_VOID == type()`.
551 void reset();
552
553 /// Set the value of this object to the specified `value`. The behavior
554 /// is undefined unless `OptionType::TypeToEnum<TYPE>::value == type()`
555 /// for the (template parameter) `TYPE` and
556 /// `OptionType::e_VOID != type()`.
557 template <class TYPE>
558 void set(const TYPE& value);
559
560 /// Set the value of this object, irrespective of that value's type, to
561 /// its null state. The behavior is undefined unless
562 /// `true == hasNonVoidType()`. Note that `type()` is not changed.
563 void setNull();
564
565 /// Set the type of this object to the specified `type` and the value to
566 /// the default value of that type.
568
569 /// Return a reference providing modifiable access to the underlying
570 /// variant object of this command-line-option value object. The
571 /// behavior is undefined unless `OptionType::e_VOID != type()`,
572 /// `OptionType::TypeToEnum<TYPE>::value == type()`, and
573 /// `false == isNull()`.
574 template <class TYPE>
575 TYPE& the();
576
577 // Aspects
578
579 /// Efficiently exchange the value of this object with the value of the
580 /// specified `other` object. This method provides the no-throw
581 /// exception-safety guarantee if either `type()` is the same as
582 /// `other.type()`, or neither `type()` nor `other.type()` is a type
583 /// that requires allocation; otherwise, it provides the basic
584 /// guarantee. The behavior is undefined unless this object was created
585 /// with the same allocator as `other`.
586 void swap(OptionValue& other);
587
588 // ACCESSORS
589
590 /// Return `true` if this object is in the unset state, and `false`
591 /// otherwise. Note that if `false == hasNonVoidType()` then
592 /// `OptionType::e_VOID == type()`.
593 bool hasNonVoidType() const;
594
595 /// Return `true` if the value of this object (irrespective of
596 /// non-`void` type) is null. The behavior is undefined unless
597 /// `true == hasNonVoidType()`.
598 bool isNull() const;
599
600 /// Return a `const` reference to the value of this command line option.
601 /// The behavior is undefined unless `OptionType::e_VOID != type()`,
602 /// `OptionType::typeToEnum<TYPE>::value == type()`, and
603 /// `false == isNull()`.
604 template <class TYPE>
605 const TYPE& the() const;
606
607 /// Return the type of this command-line-option value. The type
608 /// `OptionType::e_VOID` represents the unset state.
610
611 // Aspects
612
613 /// Return the allocator used by this object to supply memory. Note
614 /// that if no allocator was supplied at construction the currently
615 /// installed default allocator is used.
617
618 /// Write the value of this object to the specified output `stream` in a
619 /// human-readable format, and return a reference to `stream`.
620 /// Optionally specify an initial indentation `level`, whose absolute
621 /// value is incremented recursively for nested objects. If `level` is
622 /// specified, optionally specify `spacesPerLevel`, whose absolute value
623 /// indicates the number of spaces per indentation level for this and
624 /// all of its nested objects. If `level` is negative, suppress
625 /// indentation of the first line. If `spacesPerLevel` is negative,
626 /// format the entire output on one line, suppressing all but the
627 /// initial indentation (as governed by `level`). If `stream` is not
628 /// valid on entry, this operation has no effect. Note that the format
629 /// is not fully specified, and can change without notice.
630 bsl::ostream& print(bsl::ostream& stream,
631 int level = 0,
632 int spacesPerLevel = 4) const;
633};
634
635// FREE OPERATORS
636
637/// Return `true` if the specified `lhs` and `rhs` objects have the same
638/// value, and `false` otherwise. Two `OptionValue` objects have the same
639/// value if they have the same type, and (if the type is not `e_VOID`) the
640/// value of that type (as accessed through `the*` methods) is the same.
641bool operator==(const OptionValue& lhs, const OptionValue& rhs);
642
643/// Return `true` if the specified `lhs` and `rhs` objects do not have the
644/// same value, and `false` otherwise. Two `OptionValue` objects do not
645/// have the same value if their type is not the same, or (if their type is
646/// not `e_VOID`) the value of that type (as accessed through `the*`
647/// methods) is not the same.
648bool operator!=(const OptionValue& lhs, const OptionValue& rhs);
649
650/// Write the value of the specified `object` to the specified output
651/// `stream` in a single-line format, and return a reference to `stream`.
652/// If `stream` is not valid on entry, this operation has no effect. Note
653/// that this human-readable format is not fully specified, can change
654/// without notice, and is logically equivalent to:
655/// @code
656/// print(stream, 0, -1);
657/// @endcode
658bsl::ostream& operator<<(bsl::ostream& stream, const OptionValue& object);
659
660// FREE FUNCTIONS
661
662/// Swap the value of the specified `a` object with the value of the
663/// specified `b` object. This method provides the no-throw
664/// exception-safety guarantee if either `a.type()` is the same as
665/// `b.type()` and `a` and `b` were created with the same allocator, or
666/// neither `a.type()` nor `b.type()` is a type that requires allocation;
667/// otherwise, it provides the basic guarantee.
669
670// ============================================================================
671// INLINE DEFINITIONS
672// ============================================================================
673
674 // -----------------
675 // class OptionValue
676 // -----------------
677
678// CREATORS
679inline
681: d_value()
682{
683}
684
685inline
687: d_value(basicAllocator)
688{
689}
690
691inline
693 bslma::Allocator *basicAllocator)
694: d_value(basicAllocator)
695{
696 init(type);
697}
698
699inline
701 bslma::Allocator *basicAllocator)
702: d_value(value, basicAllocator)
703{
704}
705
706inline
708 bslma::Allocator *basicAllocator)
709: d_value(value, basicAllocator)
710{
711}
712
713inline
715 bslma::Allocator *basicAllocator)
716: d_value(value, basicAllocator)
717{
718}
719
720inline
722 bslma::Allocator *basicAllocator)
723: d_value(value, basicAllocator)
724{
725}
726
727inline
729 bslma::Allocator *basicAllocator)
730: d_value(value, basicAllocator)
731{
732}
733
734inline
736 bslma::Allocator *basicAllocator)
737: d_value(value, basicAllocator)
738{
739 // TBD: This now could be changed to 'bsl::string_view' IFF it is a
740 // compatible change for users.
741 //
742 // Implementation note: Changing 'bsl::string' to a string view would not
743 // be a constructive change, because 'bdlb::NullableValue<bsl::string>' is
744 // not constructible from a string view. Note that 'value', as a
745 // 'bsl::string', is constructible from 'const char *', an 'std::string',
746 // or an 'std::pmr::string'.
747}
748
749inline
751 bslma::Allocator *basicAllocator)
752: d_value(value, basicAllocator)
753{
754}
755
756inline
758 bslma::Allocator *basicAllocator)
759: d_value(value, basicAllocator)
760{
761}
762
763inline
765 bslma::Allocator *basicAllocator)
766: d_value(value, basicAllocator)
767{
768}
769
770inline
772 bslma::Allocator *basicAllocator)
773: d_value(value, basicAllocator)
774{
775}
776
777inline
779 bslma::Allocator *basicAllocator)
780: d_value(value, basicAllocator)
781{
782}
783
784inline
787 bslma::Allocator *basicAllocator)
788: d_value(value, basicAllocator)
789{
790}
791
792inline
794 bslma::Allocator *basicAllocator)
795: d_value(value, basicAllocator)
796{
797}
798
799inline
801 bslma::Allocator *basicAllocator)
802: d_value(value, basicAllocator)
803{
804}
805
806inline
808 bslma::Allocator *basicAllocator)
809: d_value(value, basicAllocator)
810{
811}
812
813inline
815 bslma::Allocator *basicAllocator)
816: d_value(value, basicAllocator)
817{
818}
819
820inline
822 bslma::Allocator *basicAllocator)
823: d_value(value, basicAllocator)
824{
825}
826
827inline
829 bslma::Allocator *basicAllocator)
830: d_value(original.d_value, basicAllocator)
831{
832}
833
834// MANIPULATORS
835inline
837{
838 d_value = rhs.d_value;
839 return *this;
840}
841
842inline
844{
845 d_value.reset();
846}
847
848template <class TYPE>
849inline
850void OptionValue::set(const TYPE& value)
851{
852 BSLS_ASSERT(d_value.is<TYPE>() ||
853 (d_value.is<OptionValue_NullOf>() &&
854 d_value.the<OptionValue_NullOf>().isType(value)));
855
856 d_value.assign(value);
857}
858
859inline
861{
862 BSLS_ASSERT(!d_value.isUnset());
863
864 if (d_value.is<OptionValue_NullOf>()) { // Already null.
865 return; // RETURN
866 }
867
868 d_value.createInPlace<OptionValue_NullOf>(this->type());
869
870}
871
872inline
874{
875 d_value.reset();
876 init(type);
877}
878
879template <class TYPE>
880inline
882{
883 BSLS_ASSERT(d_value.is<TYPE>());
884
885 return d_value.the<TYPE>();
886}
887
888 // Aspects
889
890inline
892{
893 BSLS_ASSERT(allocator() == other.allocator());
894
895 d_value.swap(other.d_value);
896}
897
898// ACCESSORS
899inline
901{
902 return !d_value.isUnset();
903}
904
905inline
907{
908 BSLS_ASSERT(!d_value.isUnset());
909
910 return d_value.is<OptionValue_NullOf>();
911}
912
913template <class TYPE>
914inline
915const TYPE& OptionValue::the() const
916{
917 BSLS_ASSERT(d_value.is<TYPE>());
918
919 return d_value.the<TYPE>();
920}
921
922 // Aspects
923inline
925{
926 return d_value.getAllocator();
927}
928
929} // close package namespace
930
931// FREE OPERATORS
932inline
933bool balcl::operator==(const OptionValue& lhs, const OptionValue& rhs)
934{
935 return lhs.d_value == rhs.d_value;
936}
937
938inline
939bool balcl::operator!=(const OptionValue& lhs, const OptionValue& rhs)
940{
941 return !(lhs == rhs);
942}
943
944inline
945bsl::ostream& balcl::operator<<(bsl::ostream& stream,
946 const OptionValue& object)
947{
948 return object.print(stream, 0, -1);
949}
950
951// FREE FUNCTIONS
952inline
953void balcl::swap(OptionValue& a, OptionValue& b)
954{
955 // 'bdlb::Variant' member 'swap' supports differing allocators.
956
957 a.d_value.swap(b.d_value);
958}
959
960namespace balcl {
961
962 // ------------------------
963 // class OptionValue_NullOf
964 // ------------------------
965// CREATORS
966inline
968: d_type(optionType)
969{
970 BSLS_ASSERT(optionType != OptionType::e_VOID);
971}
972
973// ACCESSORS
974template <class TYPE>
975inline
976bool OptionValue_NullOf::isType(const TYPE&) const
977{
979}
980
981inline
983{
984 return d_type;
985}
986
987 // Aspects
988
989inline
990bsl::ostream& OptionValue_NullOf::print(bsl::ostream& stream,
991 int level,
992 int spacesPerLevel) const
993{
994 return bdlb::PrintMethods::print(stream, "NULL", level, spacesPerLevel);
995}
996
997} // close package namespace
998
999// FREE OPERATORS
1000inline
1001bool balcl::operator==(const OptionValue_NullOf& lhs,
1002 const OptionValue_NullOf& rhs)
1003{
1004 return lhs.type() == rhs.type();
1005}
1006
1007inline
1008bool balcl::operator!=(const OptionValue_NullOf& lhs,
1009 const OptionValue_NullOf& rhs)
1010{
1011 return !(lhs == rhs);
1012}
1013
1014 // Aspects
1015
1016inline
1017bsl::ostream& balcl::operator<<(bsl::ostream& stream,
1018 const OptionValue_NullOf& object)
1019{
1020 return object.print(stream, 0, -1);
1021}
1022
1023
1024
1025#endif
1026
1027// ----------------------------------------------------------------------------
1028// Copyright 2020 Bloomberg Finance L.P.
1029//
1030// Licensed under the Apache License, Version 2.0 (the "License");
1031// you may not use this file except in compliance with the License.
1032// You may obtain a copy of the License at
1033//
1034// http://www.apache.org/licenses/LICENSE-2.0
1035//
1036// Unless required by applicable law or agreed to in writing, software
1037// distributed under the License is distributed on an "AS IS" BASIS,
1038// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1039// See the License for the specific language governing permissions and
1040// limitations under the License.
1041// ----------------------------- END-OF-FILE ----------------------------------
1042
1043/** @} */
1044/** @} */
1045/** @} */
Definition balcl_optionvalue.h:311
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition balcl_optionvalue.h:990
OptionValue_NullOf(OptionType::Enum optionType)
Definition balcl_optionvalue.h:967
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue_NullOf, bslmf::IsBitwiseEqualityComparable)
bool isType(const TYPE &) const
Definition balcl_optionvalue.h:976
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue_NullOf, bdlb::HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue_NullOf, bslmf::IsBitwiseMoveable)
OptionType::Enum type() const
Return the option type of this object.
Definition balcl_optionvalue.h:982
Definition balcl_optionvalue.h:393
friend bool operator==(const OptionValue &, const OptionValue &)
friend void swap(OptionValue &, OptionValue &)
OptionValue & operator=(const OptionValue &rhs)
Definition balcl_optionvalue.h:836
bool isNull() const
Definition balcl_optionvalue.h:906
~OptionValue()=default
Destroy this object.
OptionType::Enum type() const
OptionValue()
Definition balcl_optionvalue.h:680
void reset()
Definition balcl_optionvalue.h:843
bool hasNonVoidType() const
Definition balcl_optionvalue.h:900
void set(const TYPE &value)
Definition balcl_optionvalue.h:850
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue, bdlb::HasPrintMethod)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
void setNull()
Definition balcl_optionvalue.h:860
void setType(OptionType::Enum type)
Definition balcl_optionvalue.h:873
bslma::Allocator * allocator() const
Definition balcl_optionvalue.h:924
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue, bslma::UsesBslmaAllocator)
TYPE & the()
Definition balcl_optionvalue.h:881
void reset()
Definition bdlb_variant.h:7472
bool is() const
Definition bdlb_variant.h:7605
TYPE & createInPlace(ARGS &&... arguments)
Definition bdlb_variant.h:7454
bool isUnset() const
Definition bdlb_variant.h:7612
TYPE & the()
Definition bdlb_variant.h:7517
VariantImp & assign(const TYPE &value)
void swap(VariantImp &other)
Definition bdlb_variant.h:7482
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlb_variant.h:7619
Definition bdlb_variant.h:2312
Definition bdlt_date.h:294
Definition bdlt_datetime.h:331
Definition bdlt_time.h:196
Definition bslstl_string.h:1281
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balcl_commandline.h:1364
bool operator==(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const CommandLine &rhs)
void swap(OptionValue &a, OptionValue &b)
bool operator!=(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:719
Definition balcl_optiontype.h:282
bsls::Types::Int64 Int64
Definition balcl_optiontype.h:231
char Char
Definition balcl_optiontype.h:229
bool Bool
Definition balcl_optiontype.h:228
int Int
Definition balcl_optiontype.h:230
double Double
Definition balcl_optiontype.h:232
Enum
Definition balcl_optiontype.h:248
@ e_VOID
Definition balcl_optiontype.h:250
Definition bdlb_printmethods.h:306
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwiseequalitycomparable.h:499
Definition bslmf_isbitwisemoveable.h:718
long long Int64
Definition bsls_types.h:132