BDE 4.39.x 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.
305///
306/// \note Note that `OptionType::e_VOID` is *not* nullable, therefore not supported here.
307/// Note that: There is no `swap` member or namespace-level function
308/// declared (and defined) for this class on purpose, the general swap works
309/// fast for such a simple type.
310///
311/// See @ref balcl_optionvalue
313
314 // DATA
315 OptionType::Enum d_type;
316
317 public:
318 // TRAITS
325
326 // CREATORS
327
328 /// Create an `OptionValue_NullOf` object with the specified nullable `optionType`.
329 ///
330 /// \pre The behavior is undefined if
331 /// `optionType == OptionType::e_VOID`.
332 explicit OptionValue_NullOf(OptionType::Enum optionType);
333
334 // ACCESSORS
335
336 /// Return `true` if `TYPE` corresponds to the `type` attribute, and
337 /// `false` if it does not.
338 template <class TYPE>
339 bool isType(const TYPE&) const;
340
341 /// Return the option `type` of this object.
342 OptionType::Enum type() const;
343
344 // Aspects
345
346 /// Format this object to the specified output `stream` at the (absolute
347 /// value of) the optionally specified indentation `level` and return a
348 /// reference to `stream`. If `level` is specified, optionally specify
349 /// `spacesPerLevel`, the number of spaces per indentation level for
350 /// this and all of its nested objects. If `level` is negative,
351 /// suppress indentation of the first line. If `spacesPerLevel` is
352 /// negative, format the entire output on one line, suppressing all but
353 /// the initial indentation (as governed by `level`). If `stream` is
354 /// not valid on entry, this operation has no effect.
355 bsl::ostream& print(bsl::ostream& stream,
356 int level = 0,
357 int spacesPerLevel = 4) const;
358};
359
360// FREE OPERATORS
361
362/// Return `true` if the `type` of the specified `lhs` and `rhs` are equal,
363/// and return `false` if they are not equal. Two `OptionValue_NullOf`
364/// objects are equal when their `type` attributes are equal.
365bool operator==(const OptionValue_NullOf& lhs, const OptionValue_NullOf& rhs);
366
367/// Return `true` if the `type` of the specified `lhs` and `rhs` are not
368/// equal, and return `false` if they are not equal. Two
369/// `OptionValue_NullOf` objects are equal when their `type` attributes are
370/// note equal.
371bool operator!=(const OptionValue_NullOf& lhs, const OptionValue_NullOf& rhs);
372
373/// Write the value of the specified `object` to the specified output
374/// `stream` in a single-line format, and return a reference to `stream`.
375/// If `stream` is not valid on entry, this operation has no effect.
376///
377/// \note Note that this human-readable format is not fully specified, can change
378/// without notice, and is logically equivalent to:
379/// `object.print(stream, 0, -1);`
380bsl::ostream& operator<<(bsl::ostream& stream,
381 const OptionValue_NullOf& object);
382
383 // =================
384 // class OptionValue
385 // =================
386
387/// This class implements a special-use value-semantic variant type used to
388/// represent values parsed from process command lines. Accordingly, this
389/// class can represent values of any of the types defined in
390/// @ref balcl_optiontype . Furthermore, that value can also be in a null state
391/// (defined type but no defined value) to represent allowed options that do
392/// not appear among the command-line arguments (and for which no default value
393/// has been configured).
394///
395/// See @ref balcl_optionvalue
397
398 private:
399 // PRIVATE TYPES
400 typedef OptionType::Bool Bool;
401 typedef OptionType::Char Char;
402 typedef OptionType::Int Int;
403 typedef OptionType::Int64 Int64;
404 typedef OptionType::Double Double;
407 typedef OptionType::Date Date;
408 typedef OptionType::Time Time;
411 typedef OptionType::Int64Array Int64Array;
413 typedef OptionType::StringArray StringArray;
414 typedef OptionType::DatetimeArray DatetimeArray;
416 typedef OptionType::TimeArray TimeArray;
417
418 typedef bdlb::Variant<Bool,
419 Char,
420 Int,
421 Int64,
422 Double,
423 String,
424 Datetime,
425 Date,
426 Time, // DO NOT change the order of these types!
427 CharArray,
428 IntArray,
429 Int64Array,
431 StringArray,
432 DatetimeArray,
433 DateArray,
434 TimeArray,
436
437 // DATA
438 ValueVariant d_value; // the object's value
439
440 // FRIENDS
441 friend bool operator==(const OptionValue&, const OptionValue&);
442 friend void swap(OptionValue&, OptionValue&);
443
444 // PRIVATE MANIPULATORS
445
446 /// Set the type of the contained variant object to have the specified
447 /// `type` and have the default value for `type`.
448 ///
449 /// \pre The behavior is undefined unless `OptionType::e_VOID != type()`.
450 void init(OptionType::Enum type);
451
452 public:
453 // TRAITS
456
457 // CREATORS
458
459 /// Create a command-line-option value object in the unset state (i.e.,
460 /// `OptionType::e_VOID == type()`). Optionally specify a
461 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
462 /// specified, the currently installed default allocator is used.
463 ///
464 /// \note Note that (atypically) this constructor disallows 0 for `basicAllocator`;
465 /// invoking the constructor with 0 dispatches to the constructor
466 /// overload that explicitly accepts an `int` value for its first
467 /// argument (see below).
468 OptionValue();
469 explicit
470 OptionValue(bslma::Allocator *basicAllocator);
471
472 /// Create a command-line-option value object having the type
473 /// corresponding to the specified `type` and, if
474 /// `OptionType::e_VOID != type`, having the default value of that type.
475 /// Optionally specify a `basicAllocator` used to supply memory. If
476 /// `basicAllocator` is 0, the currently installed default allocator is
477 /// used.
479 bslma::Allocator *basicAllocator = 0); // IMPLICIT
480
481 /// Create a command-line-option value object having the type and value
482 /// of the specified `value`. Optionally specify a `basicAllocator`
483 /// used to supply memory. If `basicAllocator` is 0, the currently
484 /// installed default allocator is used.
485 explicit
486 OptionValue(bool value,
487 bslma::Allocator *basicAllocator = 0);
488 explicit
489 OptionValue(char value,
490 bslma::Allocator *basicAllocator = 0);
491 explicit
492 OptionValue(int value,
493 bslma::Allocator *basicAllocator = 0);
494 explicit
496 bslma::Allocator *basicAllocator = 0);
497 explicit
498 OptionValue(double value,
499 bslma::Allocator *basicAllocator = 0);
500 explicit
501 OptionValue(const bsl::string& value,
502 bslma::Allocator *basicAllocator = 0);
503 explicit
505 bslma::Allocator *basicAllocator = 0);
506 explicit
508 bslma::Allocator *basicAllocator = 0);
509 explicit
511 bslma::Allocator *basicAllocator = 0);
512 explicit
513 OptionValue(const bsl::vector<char>& value,
514 bslma::Allocator *basicAllocator = 0);
515 explicit
516 OptionValue(const bsl::vector<int>& value,
517 bslma::Allocator *basicAllocator = 0);
518 explicit
520 bslma::Allocator *basicAllocator = 0);
521 explicit
522 OptionValue(const bsl::vector<double>& value,
523 bslma::Allocator *basicAllocator = 0);
524 explicit
526 bslma::Allocator *basicAllocator = 0);
527 explicit
529 bslma::Allocator *basicAllocator = 0);
530 explicit
532 bslma::Allocator *basicAllocator = 0);
533 explicit
535 bslma::Allocator *basicAllocator = 0);
536
537 /// Create a `OptionValue` object having the same value as the specified
538 /// `original` object. Optionally specify a `basicAllocator` used to
539 /// supply memory. If `basicAllocator` is 0, the currently installed
540 /// default allocator is used.
541 OptionValue(const OptionValue& original,
542 bslma::Allocator *basicAllocator = 0);
543
544 /// Destroy this object.
545 ~OptionValue() = default;
546
547 // MANIPULATORS
548
549 /// Assign to this object the value of the specified `rhs` object, and
550 /// return a reference providing modifiable access to this object.
551 OptionValue& operator=(const OptionValue& rhs);
552
553 /// Reset this object to its default constructed (unset) state. The existing value, if any, is destroyed.
554 ///
555 /// \note Note that on return
556 /// `OptionType::e_VOID == type()`.
557 void reset();
558
559 /// Set the value of this object to the specified `value`.
560 ///
561 /// \pre The behavior is undefined unless `OptionType::TypeToEnum<TYPE>::value == type()`
562 /// for the (template parameter) `TYPE` and
563 /// `OptionType::e_VOID != type()`.
564 template <class TYPE>
565 void set(const TYPE& value);
566
567 /// Set the value of this object, irrespective of that value's type, to its null state.
568 ///
569 /// \pre The behavior is undefined unless `true == hasNonVoidType()`.
570 ///
571 /// \note Note that `type()` is not changed.
572 void setNull();
573
574 /// Set the type of this object to the specified `type` and the value to
575 /// the default value of that type.
577
578 /// Return a reference providing modifiable access to the underlying
579 /// variant object of this command-line-option value object.
580 ///
581 /// \pre The behavior is undefined unless `OptionType::e_VOID != type()`,
582 /// `OptionType::TypeToEnum<TYPE>::value == type()`, and
583 /// `false == isNull()`.
584 template <class TYPE>
585 TYPE& the();
586
587 // Aspects
588
589 /// Efficiently exchange the value of this object with the value of the
590 /// specified `other` object. This method provides the no-throw
591 /// exception-safety guarantee if either `type()` is the same as
592 /// `other.type()`, or neither `type()` nor `other.type()` is a type
593 /// that requires allocation; otherwise, it provides the basic guarantee.
594 ///
595 /// \pre The behavior is undefined unless this object was created
596 /// with the same allocator as `other`.
597 void swap(OptionValue& other);
598
599 // ACCESSORS
600
601 /// Return `true` if this object is in the unset state, and `false` otherwise.
602 ///
603 /// \note Note that if `false == hasNonVoidType()` then
604 /// `OptionType::e_VOID == type()`.
605 bool hasNonVoidType() const;
606
607 /// Return `true` if the value of this object (irrespective of non-`void` type) is null.
608 ///
609 /// \pre The behavior is undefined unless
610 /// `true == hasNonVoidType()`.
611 bool isNull() const;
612
613 /// Return a `const` reference to the value of this command line option.
614 ///
615 /// \pre The behavior is undefined unless `OptionType::e_VOID != type()`,
616 /// `OptionType::typeToEnum<TYPE>::value == type()`, and
617 /// `false == isNull()`.
618 template <class TYPE>
619 const TYPE& the() const;
620
621 /// Return the type of this command-line-option value. The type
622 /// `OptionType::e_VOID` represents the unset state.
624
625 // Aspects
626
627 /// Return the allocator used by this object to supply memory.
628 ///
629 /// \note Note that if no allocator was supplied at construction the currently
630 /// installed default allocator is used.
632
633 /// Write the value of this object to the specified output `stream` in a
634 /// human-readable format, and return a reference to `stream`.
635 /// Optionally specify an initial indentation `level`, whose absolute
636 /// value is incremented recursively for nested objects. If `level` is
637 /// specified, optionally specify `spacesPerLevel`, whose absolute value
638 /// indicates the number of spaces per indentation level for this and
639 /// all of its nested objects. If `level` is negative, suppress
640 /// indentation of the first line. If `spacesPerLevel` is negative,
641 /// format the entire output on one line, suppressing all but the
642 /// initial indentation (as governed by `level`). If `stream` is not valid on entry, this operation has no effect.
643 ///
644 /// \note Note that the format
645 /// is not fully specified, and can change without notice.
646 bsl::ostream& print(bsl::ostream& stream,
647 int level = 0,
648 int spacesPerLevel = 4) const;
649};
650
651// FREE OPERATORS
652
653/// Return `true` if the specified `lhs` and `rhs` objects have the same
654/// value, and `false` otherwise. Two `OptionValue` objects have the same
655/// value if they have the same type, and (if the type is not `e_VOID`) the
656/// value of that type (as accessed through `the*` methods) is the same.
657bool operator==(const OptionValue& lhs, const OptionValue& rhs);
658
659/// Return `true` if the specified `lhs` and `rhs` objects do not have the
660/// same value, and `false` otherwise. Two `OptionValue` objects do not
661/// have the same value if their type is not the same, or (if their type is
662/// not `e_VOID`) the value of that type (as accessed through `the*`
663/// methods) is not the same.
664bool operator!=(const OptionValue& lhs, const OptionValue& rhs);
665
666/// Write the value of the specified `object` to the specified output
667/// `stream` in a single-line format, and return a reference to `stream`.
668/// If `stream` is not valid on entry, this operation has no effect.
669///
670/// \note Note that this human-readable format is not fully specified, can change
671/// without notice, and is logically equivalent to:
672/// @code
673/// print(stream, 0, -1);
674/// @endcode
675bsl::ostream& operator<<(bsl::ostream& stream, const OptionValue& object);
676
677// FREE FUNCTIONS
678
679/// Swap the value of the specified `a` object with the value of the
680/// specified `b` object. This method provides the no-throw
681/// exception-safety guarantee if either `a.type()` is the same as
682/// `b.type()` and `a` and `b` were created with the same allocator, or
683/// neither `a.type()` nor `b.type()` is a type that requires allocation;
684/// otherwise, it provides the basic guarantee.
686
687// ============================================================================
688// INLINE DEFINITIONS
689// ============================================================================
690
691 // -----------------
692 // class OptionValue
693 // -----------------
694
695// CREATORS
696inline
698: d_value()
699{
700}
701
702inline
704: d_value(basicAllocator)
705{
706}
707
708inline
710 bslma::Allocator *basicAllocator)
711: d_value(basicAllocator)
712{
713 init(type);
714}
715
716inline
718 bslma::Allocator *basicAllocator)
719: d_value(value, basicAllocator)
720{
721}
722
723inline
725 bslma::Allocator *basicAllocator)
726: d_value(value, basicAllocator)
727{
728}
729
730inline
732 bslma::Allocator *basicAllocator)
733: d_value(value, basicAllocator)
734{
735}
736
737inline
739 bslma::Allocator *basicAllocator)
740: d_value(value, basicAllocator)
741{
742}
743
744inline
746 bslma::Allocator *basicAllocator)
747: d_value(value, basicAllocator)
748{
749}
750
751inline
753 bslma::Allocator *basicAllocator)
754: d_value(value, basicAllocator)
755{
756 // TBD: This now could be changed to 'bsl::string_view' IFF it is a
757 // compatible change for users.
758 //
759 // Implementation note: Changing 'bsl::string' to a string view would not
760 // be a constructive change, because 'bdlb::NullableValue<bsl::string>' is
761 // not constructible from a string view. Note that 'value', as a
762 // 'bsl::string', is constructible from 'const char *', an 'std::string',
763 // or an 'std::pmr::string'.
764}
765
766inline
768 bslma::Allocator *basicAllocator)
769: d_value(value, basicAllocator)
770{
771}
772
773inline
775 bslma::Allocator *basicAllocator)
776: d_value(value, basicAllocator)
777{
778}
779
780inline
782 bslma::Allocator *basicAllocator)
783: d_value(value, basicAllocator)
784{
785}
786
787inline
789 bslma::Allocator *basicAllocator)
790: d_value(value, basicAllocator)
791{
792}
793
794inline
796 bslma::Allocator *basicAllocator)
797: d_value(value, basicAllocator)
798{
799}
800
801inline
804 bslma::Allocator *basicAllocator)
805: d_value(value, basicAllocator)
806{
807}
808
809inline
811 bslma::Allocator *basicAllocator)
812: d_value(value, basicAllocator)
813{
814}
815
816inline
818 bslma::Allocator *basicAllocator)
819: d_value(value, basicAllocator)
820{
821}
822
823inline
825 bslma::Allocator *basicAllocator)
826: d_value(value, basicAllocator)
827{
828}
829
830inline
832 bslma::Allocator *basicAllocator)
833: d_value(value, basicAllocator)
834{
835}
836
837inline
839 bslma::Allocator *basicAllocator)
840: d_value(value, basicAllocator)
841{
842}
843
844inline
846 bslma::Allocator *basicAllocator)
847: d_value(original.d_value, basicAllocator)
848{
849}
850
851// MANIPULATORS
852inline
854{
855 d_value = rhs.d_value;
856 return *this;
857}
858
859inline
861{
862 d_value.reset();
863}
864
865template <class TYPE>
866inline
867void OptionValue::set(const TYPE& value)
868{
869 BSLS_ASSERT(d_value.is<TYPE>() ||
870 (d_value.is<OptionValue_NullOf>() &&
871 d_value.the<OptionValue_NullOf>().isType(value)));
872
873 d_value.assign(value);
874}
875
876inline
878{
879 BSLS_ASSERT(!d_value.isUnset());
880
881 if (d_value.is<OptionValue_NullOf>()) { // Already null.
882 return; // RETURN
883 }
884
885 d_value.createInPlace<OptionValue_NullOf>(this->type());
886
887}
888
889inline
891{
892 d_value.reset();
893 init(type);
894}
895
896template <class TYPE>
897inline
899{
900 BSLS_ASSERT(d_value.is<TYPE>());
901
902 return d_value.the<TYPE>();
903}
904
905 // Aspects
906
907inline
909{
910 BSLS_ASSERT(allocator() == other.allocator());
911
912 d_value.swap(other.d_value);
913}
914
915// ACCESSORS
916inline
918{
919 return !d_value.isUnset();
920}
921
922inline
924{
925 BSLS_ASSERT(!d_value.isUnset());
926
927 return d_value.is<OptionValue_NullOf>();
928}
929
930template <class TYPE>
931inline
932const TYPE& OptionValue::the() const
933{
934 BSLS_ASSERT(d_value.is<TYPE>());
935
936 return d_value.the<TYPE>();
937}
938
939 // Aspects
940inline
942{
943 return d_value.getAllocator();
944}
945
946} // close package namespace
947
948// FREE OPERATORS
949inline
950bool balcl::operator==(const OptionValue& lhs, const OptionValue& rhs)
951{
952 return lhs.d_value == rhs.d_value;
953}
954
955inline
956bool balcl::operator!=(const OptionValue& lhs, const OptionValue& rhs)
957{
958 return !(lhs == rhs);
959}
960
961inline
962bsl::ostream& balcl::operator<<(bsl::ostream& stream,
963 const OptionValue& object)
964{
965 return object.print(stream, 0, -1);
966}
967
968// FREE FUNCTIONS
969inline
970void balcl::swap(OptionValue& a, OptionValue& b)
971{
972 // 'bdlb::Variant' member 'swap' supports differing allocators.
973
974 a.d_value.swap(b.d_value);
975}
976
977namespace balcl {
978
979 // ------------------------
980 // class OptionValue_NullOf
981 // ------------------------
982// CREATORS
983inline
985: d_type(optionType)
986{
987 BSLS_ASSERT(optionType != OptionType::e_VOID);
988}
989
990// ACCESSORS
991template <class TYPE>
992inline
993bool OptionValue_NullOf::isType(const TYPE&) const
994{
996}
997
998inline
1000{
1001 return d_type;
1002}
1003
1004 // Aspects
1005
1006inline
1007bsl::ostream& OptionValue_NullOf::print(bsl::ostream& stream,
1008 int level,
1009 int spacesPerLevel) const
1010{
1011 return bdlb::PrintMethods::print(stream, "NULL", level, spacesPerLevel);
1012}
1013
1014} // close package namespace
1015
1016// FREE OPERATORS
1017inline
1018bool balcl::operator==(const OptionValue_NullOf& lhs,
1019 const OptionValue_NullOf& rhs)
1020{
1021 return lhs.type() == rhs.type();
1022}
1023
1024inline
1025bool balcl::operator!=(const OptionValue_NullOf& lhs,
1026 const OptionValue_NullOf& rhs)
1027{
1028 return !(lhs == rhs);
1029}
1030
1031 // Aspects
1032
1033inline
1034bsl::ostream& balcl::operator<<(bsl::ostream& stream,
1035 const OptionValue_NullOf& object)
1036{
1037 return object.print(stream, 0, -1);
1038}
1039
1040
1041
1042#endif
1043
1044// ----------------------------------------------------------------------------
1045// Copyright 2020 Bloomberg Finance L.P.
1046//
1047// Licensed under the Apache License, Version 2.0 (the "License");
1048// you may not use this file except in compliance with the License.
1049// You may obtain a copy of the License at
1050//
1051// http://www.apache.org/licenses/LICENSE-2.0
1052//
1053// Unless required by applicable law or agreed to in writing, software
1054// distributed under the License is distributed on an "AS IS" BASIS,
1055// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1056// See the License for the specific language governing permissions and
1057// limitations under the License.
1058// ----------------------------- END-OF-FILE ----------------------------------
1059
1060/** @} */
1061/** @} */
1062/** @} */
Definition balcl_optionvalue.h:312
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition balcl_optionvalue.h:1007
OptionValue_NullOf(OptionType::Enum optionType)
Definition balcl_optionvalue.h:984
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue_NullOf, bslmf::IsBitwiseEqualityComparable)
bool isType(const TYPE &) const
Definition balcl_optionvalue.h:993
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:999
Definition balcl_optionvalue.h:396
friend bool operator==(const OptionValue &, const OptionValue &)
friend void swap(OptionValue &, OptionValue &)
OptionValue & operator=(const OptionValue &rhs)
Definition balcl_optionvalue.h:853
bool isNull() const
Definition balcl_optionvalue.h:923
~OptionValue()=default
Destroy this object.
OptionType::Enum type() const
OptionValue()
Definition balcl_optionvalue.h:697
void reset()
Definition balcl_optionvalue.h:860
bool hasNonVoidType() const
Definition balcl_optionvalue.h:917
void set(const TYPE &value)
Definition balcl_optionvalue.h:867
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:877
void setType(OptionType::Enum type)
Definition balcl_optionvalue.h:890
bslma::Allocator * allocator() const
Definition balcl_optionvalue.h:941
BSLMF_NESTED_TRAIT_DECLARATION(OptionValue, bslma::UsesBslmaAllocator)
TYPE & the()
Definition balcl_optionvalue.h:898
void reset()
Definition bdlb_variant.h:7592
bool is() const
Definition bdlb_variant.h:7725
TYPE & createInPlace(ARGS &&... arguments)
Definition bdlb_variant.h:7574
bool isUnset() const
Definition bdlb_variant.h:7732
TYPE & the()
Definition bdlb_variant.h:7637
VariantImp & assign(const TYPE &value)
void swap(VariantImp &other)
Definition bdlb_variant.h:7602
Definition bdlb_variant.h:2389
Definition bdlt_date.h:294
Definition bdlt_datetime.h:330
Definition bdlt_time.h:195
Definition bslstl_string.h:1252
Definition bslma_allocator.h:545
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
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:725
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition balcl_optiontype.h:288
bsl::vector< bsls::Types::Int64 > Int64Array
Definition balcl_optiontype.h:241
bsls::Types::Int64 Int64
Definition balcl_optiontype.h:233
char Char
Definition balcl_optiontype.h:231
bsl::vector< bdlt::Datetime > DatetimeArray
Definition balcl_optiontype.h:244
bsl::vector< bdlt::Time > TimeArray
Aliases for each of the supported command-line-option types.
Definition balcl_optiontype.h:248
bool Bool
Definition balcl_optiontype.h:230
int Int
Definition balcl_optiontype.h:232
double Double
Definition balcl_optiontype.h:234
bsl::vector< bsl::string > StringArray
Definition balcl_optiontype.h:243
Enum
Definition balcl_optiontype.h:250
@ e_VOID
Definition balcl_optiontype.h:252
Definition bdlb_printmethods.h:306
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwiseequalitycomparable.h:500
Definition bslmf_isbitwisemoveable.h:718
long long Int64
Definition bsls_types.h:134