BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_nullablevalue_cpp03.h
Go to the documentation of this file.
1/// @file bdlb_nullablevalue_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullablevalue_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BDLB_NULLABLEVALUE_CPP03
12#define INCLUDED_BDLB_NULLABLEVALUE_CPP03
13
14/// @defgroup bdlb_nullablevalue_cpp03 bdlb_nullablevalue_cpp03
15/// @brief Provide C++03 implementation for bdlb_nullablevalue.h
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_nullablevalue_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_nullablevalue_cpp03-purpose"> Purpose</a>
25/// * <a href="#bdlb_nullablevalue_cpp03-classes"> Classes </a>
26/// * <a href="#bdlb_nullablevalue_cpp03-description"> Description </a>
27///
28/// # Purpose {#bdlb_nullablevalue_cpp03-purpose}
29/// Provide C++03 implementation for bdlb_nullablevalue.h
30///
31/// # Classes {#bdlb_nullablevalue_cpp03-classes}
32/// See bdlb_nullablevalue.h for list of classes
33///
34/// @see bdlb_nullablevalue
35///
36/// # Description {#bdlb_nullablevalue_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Wed Sep 4 19:02:35 2024
48/// Command line: sim_cpp11_features.pl bdlb_nullablevalue.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bdl
54 * @{
55 */
56/** @addtogroup bdlb
57 * @{
58 */
59/** @addtogroup bdlb_nullablevalue_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BDLB_NULLABLEVALUE_H
64
65
66namespace bdlb {
67
68template <class TYPE>
69class NullableValue_WithAllocator;
70
71template <class TYPE>
72class NullableValue_WithoutAllocator;
73
74 // ==========================
75 // Component-private concepts
76 // ==========================
77
78#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
79template <class t_TYPE>
80void nullableValue_acceptsBslOptional(const bsl::optional<t_TYPE>&);
81
82template <class t_TYPE>
83void nullableValue_acceptsStdOptional(const std::optional<t_TYPE>&);
84
85/// This component-private concept models the Standard's exposition-only
86/// `boolean-testable` concept.
87template <class t_TYPE>
88concept NullableValue_ConvertibleToBool =
89 bsl::is_convertible_v<t_TYPE, bool>;
90
91/// This component-private concept is used in the subsequent implementation
92/// of the component-private concept `NullableValue_DerivedFromOptional`.
93template <class t_TYPE>
94concept NullableValue_DerivedFromBslOptional =
95 requires (const t_TYPE& t) { optional_acceptsBslOptional(t); };
96
97/// This component-private concept is used in the subsequent implementation
98/// of the component-private concept `NullableValue_DerivedFromOptional`.
99template <class t_TYPE>
100concept NullableValue_DerivedFromStdOptional =
101 requires (const t_TYPE& t) { optional_acceptsStdOptional(t); };
102
103/// This component-private concept models whether a type is derived from one
104/// of `std::optional`, or `bsl::optional`. Note that this concept is always
105/// satisfied for `bdlb::NullableValue` as it is derived from
106/// `bsl::optional`.
107template <class t_TYPE>
108concept NullableValue_DerivedFromOptional =
109 NullableValue_DerivedFromBslOptional<t_TYPE> ||
110 NullableValue_DerivedFromStdOptional<t_TYPE>;
111
112#endif // BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
113
114 // =========================
115 // class NullableValue<TYPE>
116 // =========================
117
118/// This template class extends the set of values of its value-semantic
119/// `TYPE` parameter to include the notion of a "null" value. If `TYPE` is
120/// fully value-semantic, then the augmented type `NullableValue<TYPE>` will
121/// be as well. In addition to supporting all homogeneous value-semantic
122/// operations, conversions between comparable underlying value types is
123/// also supported. Two nullable objects with different underlying types
124/// compare equal if their underlying types are comparable and either (1)
125/// both objects are null or (2) the non-null values compare equal. A null
126/// nullable object is considered ordered before any non-null nullable
127/// object. Attempts to copy construct, copy assign, or compare
128/// incompatible values types will fail to compile. The `NullableValue`
129/// template cannot be instantiated on an incomplete type, a type that
130/// overloads unary `operator&`, or `bsl::nullopt_t`.
131///
132/// See @ref bdlb_nullablevalue_cpp03
133template <class TYPE>
134class NullableValue : public bsl::optional<TYPE> {
135
136 // PRIVATE TYPES
137 typedef bslmf::MovableRefUtil MoveUtil;
138
139 struct EnableType {
140 };
141
142 /// This trivial tag type is used as a dummy when `NullableValue` wraps
143 /// a non-allocator-aware type.
144 struct NoAlloc {
145 };
146
147 /// Type alias to the allocator type used by this `NullableValue`. Note
148 /// that we can't refer to `optional::allocator_type` because the
149 /// conditional needs the type to exist even for non allocator aware
150 /// types.
153 NoAlloc>::type AllocType;
154
155 // FRIENDS
156 template <class ANY_TYPE>
157 friend class NullableValue;
158
159 public:
160 // TYPES
161
162 /// Base class of this type.
164
165 /// `ValueType` is an alias for the underlying `TYPE` upon which this
166 /// template class is instantiated, and represents the type of the
167 /// managed object.
168 typedef TYPE ValueType;
169
170 /// The type of allocator used by this object. If `TYPE` is not
171 /// allocator aware, `allocator_type` is a private non-allocator type
172 /// that effectively removes the allocator-specific constructors from
173 /// consideration during overload resolution.
174 typedef AllocType allocator_type;
175
176 // TRAITS
177
178 // `UsesBslmaAllocator`, `IsBitwiseCopyable`, and `IsBitwiseMoveable`
179 // are true for `NullableValue` only if the corresponding trait is true
180 // for `TYPE`. `HasPrintMethod` is always true for `NullableValue`.
191
192 // CREATORS
193
194 /// Create a nullable object having the null value. If `TYPE` takes an
195 /// optional allocator at construction, use the currently installed
196 /// default allocator to supply memory.
198
199 /// Create a nullable object that has the null value and that uses the
200 /// specified `allocator` (e.g., the address of a `bslma::Allocator`
201 /// object) to supply memory. Note that this constructor will not
202 /// participate in overload resolution unless `TYPE` is allocator aware.
203 explicit NullableValue(const allocator_type& allocator)
205
206 /// Create a nullable object having the value of the specified
207 /// `original` object. If `TYPE` takes an optional allocator at
208 /// construction, use the currently installed default allocator to
209 /// supply memory.
210 NullableValue(const NullableValue& original);
211
212 /// Create a nullable object having the same value as the specified
213 /// `original` object by moving the contents of `original` to the
214 /// newly-created object. If `TYPE` takes an optional allocator at
215 /// construction, the allocator associated with `original` is propagated
216 /// for use in the newly-created object. `original` is left in a valid
217 /// but unspecified state.
218 NullableValue(bslmf::MovableRef<NullableValue> original)
220 bsl::is_nothrow_move_constructible<TYPE>::value);
221
222 /// Create a nullable object that has the value of the specified
223 /// `original` object and uses the specified `allocator` (e.g., the
224 /// address of a `bslma::Allocator` object) to supply memory. Note that
225 /// this constructor will not participate in overload resolution unless
226 /// `TYPE` is allocator aware.
227 NullableValue(const NullableValue& original,
228 const allocator_type& allocator);
229
230 /// Create a nullable object having the same value as the specified
231 /// `original` object but using the specified `allocator` (e.g., the
232 /// address of a `bslma::Allocator` object) to supply memory. The
233 /// contents of `original` are moved to the newly-created object using
234 /// the extended move constructor for `TYPE`. `original` is left in a
235 /// valid but unspecified state. Note that this constructor will not
236 /// participate in overload resolution unless `TYPE` is allocator aware.
237 NullableValue(bslmf::MovableRef<NullableValue> original,
238 const allocator_type& allocator);
239
240 /// Create a nullable object having the specified `value` (of
241 /// `BDE_OTHER_TYPE`) converted to `TYPE`. If `TYPE` takes an optional
242 /// allocator at construction, use the currently installed default
243 /// allocator to supply memory. Note that this constructor will not
244 /// participate in overload resolution unless `BDE_OTHER_TYPE` is
245 /// convertible to `TYPE` and is not convertible to `allocator_type`.
246 template <class BDE_OTHER_TYPE>
248 typename bsl::enable_if<
249 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
250 !bsl::is_convertible<BDE_OTHER_TYPE,
252 EnableType>::type = EnableType()); // IMPLICIT
253
254 /// Create a nullable object that has the specified `value` (of
255 /// `BDE_OTHER_TYPE`) converted to `TYPE` and that uses the specified
256 /// `allocator` (e.g., the address of a `bslma::Allocator` object) to
257 /// supply memory. Note that this constructor will not participate in
258 /// overload resolution unless `TYPE` is allocator aware and
259 /// `BDE_OTHER_TYPE` is convertible to `TYPE`.
260 template <class BDE_OTHER_TYPE>
263 const allocator_type& allocator,
264 typename bsl::enable_if<
265 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value,
266 EnableType>::type = EnableType());
267
268 template <class BDE_OTHER_TYPE>
269 NullableValue(const bsl::optional<BDE_OTHER_TYPE>& value,
270 typename bsl::enable_if<
271 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
272 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
273 EnableType>::type = EnableType()); // IMPLICIT
274
275 template <class BDE_OTHER_TYPE>
276 NullableValue(const bsl::optional<BDE_OTHER_TYPE>& value,
277 const allocator_type& allocator,
278 typename bsl::enable_if<
279 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
280 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
281 EnableType>::type = EnableType()); // IMPLICIT
282
283 template <class BDE_OTHER_TYPE>
285 NullableValue<BDE_OTHER_TYPE>) value,
286 typename bsl::enable_if<
287 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
288 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
289 EnableType>::type = EnableType()); // IMPLICIT
290
291 template <class BDE_OTHER_TYPE>
293 NullableValue<BDE_OTHER_TYPE>) value,
294 const allocator_type& allocator,
295 typename bsl::enable_if<
296 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
297 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
298 EnableType>::type = EnableType()); // IMPLICIT
299
300 template <class BDE_OTHER_TYPE>
302 typename bsl::enable_if<
303 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
304 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
305 EnableType>::type = EnableType()); // IMPLICIT
306
307 template <class BDE_OTHER_TYPE>
309 bsl::optional<BDE_OTHER_TYPE>) value,
310 const allocator_type& allocator,
311 typename bsl::enable_if<
312 bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value &&
313 !bsl::is_same<bsl::optional<BDE_OTHER_TYPE>, TYPE>::value,
314 EnableType>::type = EnableType()); // IMPLICIT
315
316 /// Create a nullable object having the null value if the specified
317 /// `original` object is null, and the value of `original.value()` (of
318 /// `BDE_OTHER_TYPE`) converted to `TYPE` otherwise. If `TYPE` takes an
319 /// optional allocator at construction, use the currently installed
320 /// default allocator to supply memory. Note that this method will fail
321 /// to compile if `TYPE and `BDE_OTHER_TYPE' are not compatible.
322 template <class BDE_OTHER_TYPE>
323 explicit NullableValue(const NullableValue<BDE_OTHER_TYPE>& original);
324
325 /// Create a nullable object that has the null value if the specified
326 /// `original` object is null, and the value of `original.value()` (of
327 /// `BDE_OTHER_TYPE`) converted to `TYPE` otherwise. Use the specified
328 /// `allocator` (e.g., the address of a `bslma::Allocator` object) to
329 /// supply memory. Note that this constructor will not participate in
330 /// overload resolution unless `TYPE` is allocator aware. Also note
331 /// that compilation will fail if this function is called with a
332 /// `BDE_OTHER_TYPE` that is not convertible to `TYPE`.
333 template <class BDE_OTHER_TYPE>
334 NullableValue(const NullableValue<BDE_OTHER_TYPE>& original,
335 const allocator_type& allocator);
336
337 /// Create a nullable object having the null value. If `TYPE` takes an
338 /// optional allocator at construction, use the currently installed
339 /// default allocator to supply memory for subsequent values assigned to
340 /// this object.
341 NullableValue(const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT; // IMPLICIT
342
343 /// Create a nullable object that has the null value; use the specified
344 /// `allocator` (e.g., the address of a `bslma::Allocator` object) to
345 /// supply memory for subsequent values assigned to this object. Note
346 /// that this constructor will not participate in overload resolution
347 /// unless `TYPE` is allocator aware.
348 NullableValue(const bsl::nullopt_t&,
349 const allocator_type& allocator) BSLS_KEYWORD_NOEXCEPT;
350
351 // Destroy this object.
352 ~NullableValue();
353
354 // MANIPULATORS
355
356 /// Assign to this object the value of the specified `rhs`, and return a
357 /// reference providing modifiable access to this object.
358 NullableValue<TYPE>& operator=(const NullableValue& rhs);
359
360 /// Assign to this object the value of the specified `rhs`, and return a
361 /// reference providing modifiable access to this object. The contents
362 /// of `rhs` are either move-inserted into or move-assigned to this
363 /// object. `rhs` is left in a valid but unspecified state.
364 NullableValue<TYPE>& operator=(bslmf::MovableRef<NullableValue> rhs);
365
366 /// Assign to this object the null value if the specified `rhs` object
367 /// is null, and the value of `rhs.value()` (of `BDE_OTHER_TYPE`)
368 /// converted to `TYPE` otherwise. Return a reference providing
369 /// modifiable access to this object. Note that this method will fail
370 /// to compile if `TYPE and `BDE_OTHER_TYPE' are not compatible.
371 template <class BDE_OTHER_TYPE>
372 NullableValue<TYPE>& operator=(const NullableValue<BDE_OTHER_TYPE>& rhs);
373
374 /// Assign to this object the null value if the specified `rhs` object
375 /// is null, and the value of `rhs.value()` (of `BDE_OTHER_TYPE`)
376 /// converted to `TYPE` otherwise. Return a reference providing
377 /// modifiable access to this object. Note that this method will fail
378 /// to compile if `TYPE and `BDE_OTHER_TYPE' are not compatible.
379 template <class BDE_OTHER_TYPE>
380 NullableValue<TYPE>& operator=(
382 NullableValue<BDE_OTHER_TYPE>) rhs);
383
384 /// Assign to this object the null value if the specified `rhs` object
385 /// is null, and the value of `rhs.value()` (of `BDE_OTHER_TYPE`)
386 /// converted to `TYPE` otherwise. Return a reference providing
387 /// modifiable access to this object. Note that this method will fail
388 /// to compile if `TYPE and `BDE_OTHER_TYPE' are not compatible.
389 template <class BDE_OTHER_TYPE>
390 typename bsl::enable_if<bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value,
391 NullableValue<TYPE>&>::type
392 operator=(const bsl::optional<BDE_OTHER_TYPE>& rhs);
393
394 /// Assign to this object the null value if the specified `rhs` object
395 /// is null, and the value of `rhs.value()` (of `BDE_OTHER_TYPE`)
396 /// converted to `TYPE` otherwise. Return a reference providing
397 /// modifiable access to this object. Note that this method will fail
398 /// to compile if `TYPE and `BDE_OTHER_TYPE' are not compatible.
399 template <class BDE_OTHER_TYPE>
400 typename bsl::enable_if<bsl::is_convertible<BDE_OTHER_TYPE, TYPE>::value,
401 NullableValue<TYPE>&>::type
402 operator=(BSLMF_MOVABLEREF_DEDUCE(bsl::optional<BDE_OTHER_TYPE>) rhs);
403
404 /// Assign to this object the value of the specified `rhs`, and return a
405 /// reference providing modifiable access to this object.
406 NullableValue<TYPE>& operator=(const TYPE& rhs);
407
408 /// Assign to this object the value of the specified `rhs`, and return a
409 /// reference providing modifiable access to this object. The contents
410 /// of `rhs` are either move-inserted into or move-assigned to this
411 /// object. `rhs` is left in a valid but unspecified state.
412 NullableValue<TYPE>& operator=(bslmf::MovableRef<TYPE> rhs);
413
414 /// Assign to this object the value of the specified `rhs` object (of
415 /// `BDE_OTHER_TYPE`) converted to `TYPE`, and return a reference
416 /// providing modifiable access to this object. Note that this method
417 /// will fail to compile if `TYPE` and `BDE_OTHER_TYPE` are not
418 /// compatible. Note that on C++03 but not in C++11 and beyond, if
419 /// `BDE_OTHER_TYPE` is `bslmf::MovableRef<TYPE3>` and `TYPE` supports
420 /// moves and/or assigns from that type, a move rather than a copy may
421 /// take place.
422 template <class BDE_OTHER_TYPE>
423 NullableValue<TYPE>& operator=(const BDE_OTHER_TYPE& rhs);
424
425 /// Reset this object to the default constructed state (i.e., to have
426 /// the null value), and return a reference providing modifiable access
427 /// to this object.
428 NullableValue<TYPE>& operator=(const bsl::nullopt_t&)
430
431 /// Assign to this object the value read from the specified input
432 /// `stream` using the specified `version` format, and return a
433 /// reference to `stream`. If `stream` is initially invalid, this
434 /// operation has no effect. If `version` is not supported, this object
435 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
436 /// If `version` is supported but `stream` becomes invalid during this
437 /// operation, this object has an undefined, but valid, state. Note
438 /// that no version is read from `stream`. See the `bslx` package-level
439 /// documentation for more information on BDEX streaming of
440 /// value-semantic types and containers.
441 template <class STREAM>
442 STREAM& bdexStreamIn(STREAM& stream, int version);
443
444 /// Assign to this object the specified `value` (of `BDE_OTHER_TYPE`)
445 /// converted to `TYPE`, and return a reference providing modifiable
446 /// access to the underlying `TYPE` object. Note that this method will
447 /// fail to compile if `TYPE and `BDE_OTHER_TYPE` are not compatible.
448 template <class BDE_OTHER_TYPE>
450
451 /// Assign to this object the default value for `TYPE`, and return a
452 /// reference providing modifiable access to the underlying `TYPE`
453 /// object.
454 TYPE& makeValue();
455
456#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
457// {{{ BEGIN GENERATED CODE
458// Command line: sim_cpp11_features.pl bdlb_nullablevalue.h
459#ifndef BDLB_NULLABLEVALUE_VARIADIC_LIMIT
460#define BDLB_NULLABLEVALUE_VARIADIC_LIMIT 5
461#endif
462#ifndef BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A
463#define BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A BDLB_NULLABLEVALUE_VARIADIC_LIMIT
464#endif
465
466#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 0
467 TYPE& makeValueInplace();
468#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 0
469
470#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 1
471 template <class ARGS_1>
473#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 1
474
475#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 2
476 template <class ARGS_1,
477 class ARGS_2>
479 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2);
480#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 2
481
482#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 3
483 template <class ARGS_1,
484 class ARGS_2,
485 class ARGS_3>
488 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3);
489#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 3
490
491#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 4
492 template <class ARGS_1,
493 class ARGS_2,
494 class ARGS_3,
495 class ARGS_4>
499 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4);
500#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 4
501
502#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 5
503 template <class ARGS_1,
504 class ARGS_2,
505 class ARGS_3,
506 class ARGS_4,
507 class ARGS_5>
512 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5);
513#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_A >= 5
514
515#else
516// The generated code below is a workaround for the absence of perfect
517// forwarding in some compilers.
518
519 template <class... ARGS>
521// }}} END GENERATED CODE
522#endif
523
524 /// Return a reference providing modifiable access to the underlying
525 /// `TYPE` object. The behavior is undefined unless this object is
526 /// non-null.
527 TYPE& value();
528
529 // ACCESSORS
530
531 /// Return an address providing non-modifiable access to the underlying
532 /// object of a (template parameter) `TYPE` if this object is non-null,
533 /// and the specified `address` otherwise.
534 const TYPE *addressOr(const TYPE *address) const;
535
536 /// Write the value of this object, using the specified `version`
537 /// format, to the specified output `stream`, and return a reference to
538 /// `stream`. If `stream` is initially invalid, this operation has no
539 /// effect. If `version` is not supported, `stream` is invalidated, but
540 /// otherwise unmodified. Note that `version` is not written to
541 /// `stream`. See the `bslx` package-level documentation for more
542 /// information on BDEX streaming of value-semantic types and
543 /// containers.
544 template <class STREAM>
545 STREAM& bdexStreamOut(STREAM& stream, int version) const;
546
547 /// Return `true` if this object is null, and `false` otherwise.
548 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
549
550 /// Return the maximum valid BDEX format version, as indicated by the
551 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
552 /// method. Note that it is highly recommended that `versionSelector`
553 /// be formatted as "YYYYMMDD", a date representation. Also note that
554 /// `versionSelector` should be a *compile*-time-chosen value that
555 /// selects a format version supported by both externalizer and
556 /// unexternalizer. See the `bslx` package-level documentation for more
557 /// information on BDEX streaming of value-semantic types and
558 /// containers.
559 int maxSupportedBdexVersion(int versionSelector) const;
560
561#ifndef BDE_OMIT_INTERNAL_DEPRECATED
562 /// Return the most current BDEX streaming version number supported by
563 /// this class. (See the `bslx` package-level documentation for more
564 /// information on BDEX streaming of value-semantic types and
565 /// containers.)
566 int maxSupportedBdexVersion() const;
567#endif // BDE_OMIT_INTERNAL_DEPRECATED
568
569 /// Format this object to the specified output `stream` at the (absolute
570 /// value of) the optionally specified indentation `level` and return a
571 /// reference to `stream`. If `level` is specified, optionally specify
572 /// `spacesPerLevel`, the number of spaces per indentation level for
573 /// this and all of its nested objects. If `level` is negative,
574 /// suppress indentation of the first line. If `spacesPerLevel` is
575 /// negative, format the entire output on one line, suppressing all but
576 /// the initial indentation (as governed by `level`). If `stream` is
577 /// not valid on entry, this operation has no effect.
578 bsl::ostream& print(bsl::ostream& stream,
579 int level = 0,
580 int spacesPerLevel = 4) const;
581
582 /// Return a reference providing non-modifiable access to the underlying
583 /// object of a (template parameter) `TYPE`. The behavior is undefined
584 /// unless this object is non-null.
585 const TYPE& value() const;
586
587 /// Return the value of the underlying object of a (template parameter)
588 /// `TYPE` if this object is non-null, and the specified `value`
589 /// otherwise. Note that this method returns *by* *value*, so may be
590 /// inefficient in some contexts.
591 TYPE valueOr(const TYPE& value) const;
592
593 #if BSLS_DEPRECATE_IS_ACTIVE(BDL, 3, 5)
595 #endif
596 /// @deprecated Use @ref addressOr instead.
597 ///
598 /// Return an address providing non-modifiable access to the underlying
599 /// object of a (template parameter) `TYPE` if this object is non-null,
600 /// and the specified `value` otherwise.
601 const TYPE *valueOr(const TYPE *value) const;
602
603 /// Return an address providing non-modifiable access to the underlying
604 /// object of a (template parameter) `TYPE` if this object is non-null,
605 /// and 0 otherwise.
606 const TYPE *valueOrNull() const;
607
608};
609
610// FREE OPERATORS
611
612/// Return `true` if the specified `lhs` and `rhs` nullable objects have the
613/// same value, and `false` otherwise. Two nullable objects have the same
614/// value if both are null, or if both are non-null and the values of their
615/// underlying objects compare equal. Note that this function will fail to
616/// compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
617template <class LHS_TYPE, class RHS_TYPE>
618bool operator==(const NullableValue<LHS_TYPE>& lhs,
619 const NullableValue<RHS_TYPE>& rhs)
620#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
621 requires requires {
622 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
623 }
624#endif
625;
626template <class LHS_TYPE, class RHS_TYPE>
627bool operator==(const NullableValue<LHS_TYPE>& lhs,
628 const bsl::optional<RHS_TYPE>& rhs)
629#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
630 requires requires {
631 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
632 }
633#endif
634;
635template <class LHS_TYPE, class RHS_TYPE>
636bool operator==(const bsl::optional<LHS_TYPE>& lhs,
637 const NullableValue<RHS_TYPE>& rhs)
638#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
639 requires requires {
640 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
641 }
642#endif
643;
644#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
645template <class LHS_TYPE, class RHS_TYPE>
646bool operator==(const NullableValue<LHS_TYPE>& lhs,
647 const std::optional<RHS_TYPE>& rhs)
648#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
649 requires requires {
650 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
651 }
652#endif
653;
654template <class LHS_TYPE, class RHS_TYPE>
655bool operator==(const std::optional<LHS_TYPE>& lhs,
656 const NullableValue<RHS_TYPE>& rhs)
657#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
658 requires requires {
659 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
660 }
661#endif
662;
663#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
664
665/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
666/// have the same value, and `false` otherwise. Two nullable objects do not
667/// have the same value if one is null and the other is non-null, or if both
668/// are non-null and the values of their underlying objects do not compare
669/// equal. Note that this function will fail to compile if `LHS_TYPE` and
670/// `RHS_TYPE` are not compatible.
671template <class LHS_TYPE, class RHS_TYPE>
672bool operator!=(const NullableValue<LHS_TYPE>& lhs,
673 const NullableValue<RHS_TYPE>& rhs)
674#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
675 requires requires {
676 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
677 }
678#endif
679;
680template <class LHS_TYPE, class RHS_TYPE>
681bool operator!=(const bsl::optional<LHS_TYPE>& lhs,
682 const NullableValue<RHS_TYPE>& rhs)
683#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
684 requires requires {
685 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
686 }
687#endif
688;
689template <class LHS_TYPE, class RHS_TYPE>
690bool operator!=(const NullableValue<LHS_TYPE>& lhs,
691 const bsl::optional<RHS_TYPE>& rhs)
692#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
693 requires requires {
694 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
695 }
696#endif
697;
698#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
699template <class LHS_TYPE, class RHS_TYPE>
700bool operator!=(const std::optional<LHS_TYPE>& lhs,
701 const NullableValue<RHS_TYPE>& rhs)
702#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
703 requires requires {
704 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
705 }
706#endif
707;
708template <class LHS_TYPE, class RHS_TYPE>
709bool operator!=(const NullableValue<LHS_TYPE>& lhs,
710 const std::optional<RHS_TYPE>& rhs)
711#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
712 requires requires {
713 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
714 }
715#endif
716;
717#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
718
719/// Return `true` if the specified `lhs` and `rhs` objects do not have the
720/// same value, and `false` otherwise. A nullable object and a value of
721/// some type do not have the same value if either the nullable object is
722/// null, or its underlying value does not compare equal to the other value.
723/// Note that this function will fail to compile if `LHS_TYPE` and
724/// `RHS_TYPE` are not compatible.
725template <class LHS_TYPE, class RHS_TYPE>
726bool operator!=(const NullableValue<LHS_TYPE>& lhs,
727 const RHS_TYPE& rhs)
728#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
729 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
730 requires { { *lhs != rhs } -> NullableValue_ConvertibleToBool; }
731#endif
732;
733template <class LHS_TYPE, class RHS_TYPE>
734bool operator!=(const LHS_TYPE& lhs,
735 const NullableValue<RHS_TYPE>& rhs)
736#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
737 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
738 requires { { lhs != *rhs } -> NullableValue_ConvertibleToBool; }
739#endif
740;
741
742/// Return `true` if the specified `lhs` and `rhs` objects have the same
743/// value, and `false` otherwise. A nullable object and a value of some
744/// type have the same value if the nullable object is non-null and its
745/// underlying value compares equal to the other value. Note that this
746/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
747/// compatible.
748template <class LHS_TYPE, class RHS_TYPE>
749bool operator==(const NullableValue<LHS_TYPE>& lhs,
750 const RHS_TYPE& rhs)
751#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
752 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
753 requires { { *lhs == rhs } -> NullableValue_ConvertibleToBool; }
754#endif
755;
756template <class LHS_TYPE, class RHS_TYPE>
757bool operator==(const LHS_TYPE& lhs,
758 const NullableValue<RHS_TYPE>& rhs)
759#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
760 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
761 requires { { lhs == *rhs } -> NullableValue_ConvertibleToBool; }
762#endif
763;
764
765
766/// Return `true` if the specified `lhs` nullable object is ordered before
767/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
768/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
769/// are non-null and `lhs.value()` is ordered before `rhs.value()`. Note
770/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
771/// not compatible.
772template <class LHS_TYPE, class RHS_TYPE>
773bool operator<(const NullableValue<LHS_TYPE>& lhs,
774 const NullableValue<RHS_TYPE>& rhs)
775#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
776 requires requires {
777 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
778 }
779#endif
780;
781template <class LHS_TYPE, class RHS_TYPE>
782bool operator<(const bsl::optional<LHS_TYPE>& lhs,
783 const NullableValue<RHS_TYPE>& rhs)
784#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
785 requires requires {
786 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
787 }
788#endif
789;
790template <class LHS_TYPE, class RHS_TYPE>
791bool operator<(const NullableValue<LHS_TYPE>& lhs,
792 const bsl::optional<RHS_TYPE>& rhs)
793#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
794 requires requires {
795 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
796 }
797#endif
798;
799#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
800template <class LHS_TYPE, class RHS_TYPE>
801bool operator<(const std::optional<LHS_TYPE>& lhs,
802 const NullableValue<RHS_TYPE>& rhs)
803#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
804 requires requires {
805 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
806 }
807#endif
808;
809template <class LHS_TYPE, class RHS_TYPE>
810bool operator<(const NullableValue<LHS_TYPE>& lhs,
811 const std::optional<RHS_TYPE>& rhs)
812#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
813 requires requires {
814 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
815 }
816#endif
817;
818#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
819
820/// Return `true` if the specified `lhs` nullable object is ordered before
821/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
822/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
823template <class LHS_TYPE, class RHS_TYPE>
824bool operator<(const NullableValue<LHS_TYPE>& lhs,
825 const RHS_TYPE& rhs)
826#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
827 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
828 requires { { *lhs < rhs } -> NullableValue_ConvertibleToBool; }
829#endif
830;
831
832/// Return `true` if the specified `lhs` is ordered before the specified
833/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered before
834/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
835template <class LHS_TYPE, class RHS_TYPE>
836bool operator<(const LHS_TYPE& lhs,
837 const NullableValue<RHS_TYPE>& rhs)
838#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
839 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
840 requires { { lhs < *rhs } -> NullableValue_ConvertibleToBool; }
841#endif
842;
843
844/// Return `true` if the specified `lhs` nullable object is ordered after
845/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
846/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
847/// are non-null and `lhs.value()` is ordered after `rhs.value()`. Note
848/// that this operator returns `*lhs > *rhs` when both operands are of
849/// `NullableValue` type and both have values. Also note that this function
850/// will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
851template <class LHS_TYPE, class RHS_TYPE>
852bool operator>(const NullableValue<LHS_TYPE>& lhs,
853 const NullableValue<RHS_TYPE>& rhs)
854#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
855 requires requires {
856 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
857 }
858#endif
859;
860template <class LHS_TYPE, class RHS_TYPE>
861bool operator>(const bsl::optional<LHS_TYPE>& lhs,
862 const NullableValue<RHS_TYPE>& rhs)
863#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
864 requires requires {
865 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
866 }
867#endif
868;
869template <class LHS_TYPE, class RHS_TYPE>
870bool operator>(const NullableValue<LHS_TYPE>& lhs,
871 const bsl::optional<RHS_TYPE>& rhs)
872#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
873 requires requires {
874 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
875 }
876#endif
877;
878#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
879template <class LHS_TYPE, class RHS_TYPE>
880bool operator>(const std::optional<LHS_TYPE>& lhs,
881 const NullableValue<RHS_TYPE>& rhs)
882#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
883 requires requires {
884 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
885 }
886#endif
887;
888template <class LHS_TYPE, class RHS_TYPE>
889bool operator>(const NullableValue<LHS_TYPE>& lhs,
890 const std::optional<RHS_TYPE>& rhs)
891#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
892 requires requires {
893 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
894 }
895#endif
896;
897#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
898
899/// Return `true` if the specified `lhs` nullable object is ordered after
900/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
901/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
902template <class LHS_TYPE, class RHS_TYPE>
903bool operator>(const NullableValue<LHS_TYPE>& lhs,
904 const RHS_TYPE& rhs)
905#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
906 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
907 requires { { *lhs > rhs } -> NullableValue_ConvertibleToBool; }
908#endif
909;
910
911/// Return `true` if the specified `lhs` is ordered after the specified
912/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered after
913/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`.
914template <class LHS_TYPE, class RHS_TYPE>
915bool operator>(const LHS_TYPE& lhs,
916 const NullableValue<RHS_TYPE>& rhs)
917#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
918 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
919 requires { { lhs > *rhs } -> NullableValue_ConvertibleToBool; }
920#endif
921;
922
923/// Return `true` if the specified `lhs` nullable object is ordered before
924/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
925/// value, and `false` otherwise. (See `operator<` and `operator==`.) Note
926/// that this operator returns `*lhs <= *rhs` when both operands are of
927/// `NullableValue` type and have a value. Also note that this function
928/// will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
929template <class LHS_TYPE, class RHS_TYPE>
930bool operator<=(const NullableValue<LHS_TYPE>& lhs,
931 const NullableValue<RHS_TYPE>& rhs)
932#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
933 requires requires {
934 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
935 }
936#endif
937;
938template <class LHS_TYPE, class RHS_TYPE>
939bool operator<=(const bsl::optional<LHS_TYPE>& lhs,
940 const NullableValue<RHS_TYPE>& rhs)
941#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
942 requires requires {
943 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
944 }
945#endif
946;
947template <class LHS_TYPE, class RHS_TYPE>
948bool operator<=(const NullableValue<LHS_TYPE>& lhs,
949 const bsl::optional<RHS_TYPE>& rhs)
950#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
951 requires requires {
952 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
953 }
954#endif
955;
956#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
957template <class LHS_TYPE, class RHS_TYPE>
958bool operator<=(const std::optional<LHS_TYPE>& lhs,
959 const NullableValue<RHS_TYPE>& rhs)
960#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
961 requires requires {
962 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
963 }
964#endif
965;
966template <class LHS_TYPE, class RHS_TYPE>
967bool operator<=(const NullableValue<LHS_TYPE>& lhs,
968 const std::optional<RHS_TYPE>& rhs)
969#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
970 requires requires {
971 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
972 }
973#endif
974;
975#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
976
977/// Return `true` if the specified `lhs` nullable object is ordered before
978/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
979/// otherwise. (See `operator<` and `operator==`.)
980template <class LHS_TYPE, class RHS_TYPE>
981bool operator<=(const NullableValue<LHS_TYPE>& lhs,
982 const RHS_TYPE& rhs)
983#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
984 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
985 requires { { *lhs <= rhs } -> NullableValue_ConvertibleToBool; }
986#endif
987;
988
989/// Return `true` if the specified `lhs` is ordered before the specified
990/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
991/// `false` otherwise. (See `operator<` and `operator==`.)
992template <class LHS_TYPE, class RHS_TYPE>
993bool operator<=(const LHS_TYPE& lhs,
994 const NullableValue<RHS_TYPE>& rhs)
995#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
996 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
997 requires { { lhs <= *rhs } -> NullableValue_ConvertibleToBool; }
998#endif
999;
1000
1001/// Return `true` if the specified `lhs` nullable object is ordered after
1002/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
1003/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
1004/// that this operator returns `*lhs >= *rhs` when both operands are of
1005/// `NullableValue` type and have a value. Also note that this function
1006/// will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1007template <class LHS_TYPE, class RHS_TYPE>
1008bool operator>=(const NullableValue<LHS_TYPE>& lhs,
1009 const NullableValue<RHS_TYPE>& rhs)
1010#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1011 requires requires {
1012 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
1013 }
1014#endif
1015;
1016template <class LHS_TYPE, class RHS_TYPE>
1017bool operator>=(const bsl::optional<LHS_TYPE>& lhs,
1018 const NullableValue<RHS_TYPE>& rhs)
1019#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1020 requires requires {
1021 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
1022 }
1023#endif
1024;
1025template <class LHS_TYPE, class RHS_TYPE>
1026bool operator>=(const NullableValue<LHS_TYPE>& lhs,
1027 const bsl::optional<RHS_TYPE>& rhs)
1028#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1029 requires requires {
1030 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
1031 }
1032#endif
1033;
1034#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1035template <class LHS_TYPE, class RHS_TYPE>
1036bool operator>=(const std::optional<LHS_TYPE>& lhs,
1037 const NullableValue<RHS_TYPE>& rhs)
1038#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1039 requires requires {
1040 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
1041 }
1042#endif
1043;
1044template <class LHS_TYPE, class RHS_TYPE>
1045bool operator>=(const NullableValue<LHS_TYPE>& lhs,
1046 const std::optional<RHS_TYPE>& rhs)
1047#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1048 requires requires {
1049 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
1050 }
1051#endif
1052;
1053#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1054
1055/// Return `true` if the specified `lhs` nullable object is ordered after
1056/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
1057/// otherwise. (See `operator>` and `operator==`.)
1058template <class LHS_TYPE, class RHS_TYPE>
1059bool operator>=(const NullableValue<LHS_TYPE>& lhs,
1060 const RHS_TYPE& rhs)
1061#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1062 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
1063 requires { { *lhs >= rhs } -> NullableValue_ConvertibleToBool; }
1064#endif
1065;
1066
1067/// Return `true` if the specified `lhs` is ordered after the specified
1068/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
1069/// `false` otherwise. (See `operator>` and `operator==`.)
1070template <class LHS_TYPE, class RHS_TYPE>
1071bool operator>=(const LHS_TYPE& lhs,
1072 const NullableValue<RHS_TYPE>& rhs)
1073#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1074 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
1075 requires { { lhs >= *rhs } -> NullableValue_ConvertibleToBool; }
1076#endif
1077;
1078
1079#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON && \
1080 defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1081
1082/// Perform a three-way comparison of the specified `lhs` and the specified
1083/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
1084/// return the result of that comparison.
1085template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
1086constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE> operator<=>(
1087 const NullableValue<LHS_TYPE>& lhs,
1088 const NullableValue<RHS_TYPE>& rhs);
1089template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
1090constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE> operator<=>(
1091 const NullableValue<LHS_TYPE>& lhs,
1092 const bsl::optional<RHS_TYPE>& rhs);
1093template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
1094constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE> operator<=>(
1095 const NullableValue<LHS_TYPE>& lhs,
1096 const std::optional<RHS_TYPE>& rhs);
1097template <class LHS_TYPE, class RHS_TYPE>
1098 requires(!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
1099 bsl::three_way_comparable_with<LHS_TYPE, RHS_TYPE>
1100constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE>
1101 operator<=>(const NullableValue<LHS_TYPE>& lhs, const RHS_TYPE& rhs);
1102
1103/// Perform a three-way comparison of the specified `value` and one of type
1104/// `bsl::nullopt_t`; return the result of that comparison.
1105template <class TYPE>
1106constexpr std::strong_ordering
1107 operator<=>(const NullableValue<TYPE>& value,
1109
1110#endif // SUPPORT_THREE_WAY_COMPARISON && HAS_CPP20_CONCEPTS
1111
1112/// Return `true` if the specified `value` is null, and `false` otherwise.
1113template <class TYPE>
1115bool operator==(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
1117
1118#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1119
1120/// Return `true` if the specified `value` is null, and `false` otherwise.
1121template <class TYPE>
1123bool operator==(const bsl::nullopt_t&,const NullableValue<TYPE>& value)
1125
1126/// Return `true` if the specified `value` is not null, and `false`
1127/// otherwise.
1128template <class TYPE>
1130bool operator!=(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
1132template <class TYPE>
1134bool operator!=(const bsl::nullopt_t&,const NullableValue<TYPE>& value)
1136
1137# ifndef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1138
1139/// Return `false`. Note that `bdlb::nullOpt` never orders after a
1140/// `NullableValue`.
1141template <class TYPE>
1143bool operator<(const NullableValue<TYPE>&, const bsl::nullopt_t&)
1145
1146/// Return `true` if the specified `value` is not null, and `false`
1147/// otherwise. Note that `bdlb::nullOpt` is ordered before any
1148/// `NullableValue` that is not null.
1149template <class TYPE>
1151bool operator<(const bsl::nullopt_t&,const NullableValue<TYPE>& value)
1153
1154/// Return `true` if the specified `value` is not null, and `false`
1155/// otherwise.
1156template <class TYPE>
1158bool operator>(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
1160
1161// Return `false`. Note that `bdlb::nullOpt` never orders after a
1162// `NullableValue`.
1163template <class TYPE>
1165bool operator>(const bsl::nullopt_t&,const NullableValue<TYPE>&)
1167
1168/// Return `true` if the specified `value` is null, and `false` otherwise.
1169template <class TYPE>
1171bool operator<=(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
1173
1174/// Return `true`.
1175template <class TYPE>
1177bool operator<=(const bsl::nullopt_t&,const NullableValue<TYPE>&)
1179
1180/// Return `true`.
1181template <class TYPE>
1183bool operator>=(const NullableValue<TYPE>&, const bsl::nullopt_t&)
1185
1186/// Return `true` if the specified `value` is null, and `false` otherwise.
1187template <class TYPE>
1189bool operator>=(const bsl::nullopt_t&,const NullableValue<TYPE>& value)
1191
1192# endif // !BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1193#endif // !BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1194
1195/// Write the value of the specified `object` to the specified output
1196/// `stream` in a single-line format, and return a reference to `stream`.
1197/// If `stream` is not valid on entry, this operation has no effect. Note
1198/// that this human-readable format is not fully specified, can change
1199/// without notice, and is logically equivalent to:
1200/// @code
1201/// print(stream, 0, -1);
1202/// @endcode
1203template <class TYPE>
1204bsl::ostream& operator<<(bsl::ostream& stream,
1205 const NullableValue<TYPE>& object);
1206
1207// FREE FUNCTIONS
1208
1209/// Pass the boolean value of whether the specified `input` contains a value
1210/// to the specified `hashAlg` hashing algorithm of (template parameter)
1211/// type `HASHALG`. If `input` contains a value, additionally pass that
1212/// value to `hashAlg`.
1213template <class HASHALG, class TYPE>
1214void hashAppend(HASHALG& hashAlg, const NullableValue<TYPE>& input);
1215
1216/// Exchange the values of the specified `rhs` and `lhs` objects. This
1217/// function provides the no-throw exception-safety guarantee if the
1218/// (template parameter) `TYPE` provides that guarantee, the two objects
1219/// were created with the same allocator (if applicable), and the result of
1220/// the `isNull` method for the two objects is the same; otherwise this
1221/// function provides the basic guarantee.
1222template <class TYPE>
1224 void>::type
1225swap(NullableValue<TYPE>& lhs, NullableValue<TYPE>& rhs);
1226template <class TYPE>
1228 void>::type
1229swap(NullableValue<TYPE>& lhs, NullableValue<TYPE>& rhs);
1230
1231// ============================================================================
1232// INLINE DEFINITIONS
1233// ============================================================================
1234
1235
1236 // -------------------------
1237 // class NullableValue<TYPE>
1238 // -------------------------
1239
1240// CREATORS
1241template <class TYPE>
1242inline
1244{}
1245
1246template <class TYPE>
1247inline
1249 const allocator_type& allocator) BSLS_KEYWORD_NOEXCEPT
1250: Base(bsl::allocator_arg, allocator)
1251{}
1252
1253template <class TYPE>
1254inline
1255NullableValue<TYPE>::NullableValue(const NullableValue& original)
1256: Base(static_cast<const bsl::optional<TYPE>&>(original))
1257{}
1258
1259template <class TYPE>
1260inline
1261NullableValue<TYPE>::NullableValue(const NullableValue& original,
1262 const allocator_type& allocator)
1263: Base(bsl::allocator_arg,
1264 allocator,
1265 static_cast<const bsl::optional<TYPE>&>(original))
1266{}
1267
1268template <class TYPE>
1269inline
1270NullableValue<TYPE>::NullableValue(bslmf::MovableRef<NullableValue> original)
1273: Base(MoveUtil::move(
1274 static_cast<bsl::optional<TYPE>&>(MoveUtil::access(original))))
1275{}
1276
1277template <class TYPE>
1278inline
1279NullableValue<TYPE>::NullableValue(bslmf::MovableRef<NullableValue> original,
1280 const allocator_type& allocator)
1281: Base(bsl::allocator_arg,
1282 allocator,
1283 MoveUtil::move(static_cast<bsl::optional<TYPE>&>(
1284 MoveUtil::access(original))))
1285{}
1286
1287template <class TYPE>
1288template <class BDE_OTHER_TYPE>
1289inline
1290NullableValue<TYPE>::NullableValue(
1291 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value,
1292 typename bsl::enable_if<
1295 EnableType>::type)
1296: Base(BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, value))
1297{}
1298
1299template <class TYPE>
1300template <class BDE_OTHER_TYPE>
1301inline
1302NullableValue<TYPE>::NullableValue(
1303 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value,
1304 const allocator_type& allocator,
1306 EnableType>::type)
1307: Base(bsl::allocator_arg,
1308 allocator,
1309 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, value))
1310{}
1311
1312template <class TYPE>
1313template <class BDE_OTHER_TYPE>
1314inline
1315NullableValue<TYPE>::NullableValue(
1316 const bsl::optional<BDE_OTHER_TYPE>& value,
1317 typename bsl::enable_if<
1320 EnableType>::type)
1321: Base(value)
1322{}
1323
1324template <class TYPE>
1325template <class BDE_OTHER_TYPE>
1326inline
1327NullableValue<TYPE>::NullableValue(
1328 const bsl::optional<BDE_OTHER_TYPE>& value,
1329 const allocator_type& allocator,
1330 typename bsl::enable_if<
1333 EnableType>::type)
1334: Base(bsl::allocator_arg, allocator, value)
1335{}
1336
1337template <class TYPE>
1338template <class BDE_OTHER_TYPE>
1339inline
1340NullableValue<TYPE>::NullableValue(BSLMF_MOVABLEREF_DEDUCE(
1341 NullableValue<BDE_OTHER_TYPE>) value,
1342 typename bsl::enable_if<
1345 EnableType>::type)
1346: Base(MoveUtil::move(static_cast<bsl::optional<BDE_OTHER_TYPE>&>(
1347 MoveUtil::access(value))))
1348{}
1349
1350template <class TYPE>
1351template <class BDE_OTHER_TYPE>
1352inline
1353NullableValue<TYPE>::NullableValue(BSLMF_MOVABLEREF_DEDUCE(
1354 NullableValue<BDE_OTHER_TYPE>) value,
1355 const allocator_type& allocator,
1356 typename bsl::enable_if<
1359 EnableType>::type)
1360: Base(bsl::allocator_arg,
1361 allocator,
1362 MoveUtil::move(static_cast<bsl::optional<BDE_OTHER_TYPE>&>(
1363 MoveUtil::access(value))))
1364{}
1365
1366template <class TYPE>
1367template <class BDE_OTHER_TYPE>
1368inline
1369NullableValue<TYPE>::NullableValue(
1371 typename bsl::enable_if<
1374 EnableType>::type)
1375: Base(MoveUtil::move(value))
1376{}
1377
1378template <class TYPE>
1379template <class BDE_OTHER_TYPE>
1380inline
1381NullableValue<TYPE>::NullableValue(
1384 const allocator_type& allocator,
1385 typename bsl::enable_if<
1388 EnableType>::type)
1389: Base(bsl::allocator_arg, allocator, MoveUtil::move(value))
1390{}
1391
1392template <class TYPE>
1393template <class BDE_OTHER_TYPE>
1394inline
1395NullableValue<TYPE>::NullableValue(
1396 const NullableValue<BDE_OTHER_TYPE>& original)
1397: Base(static_cast<const bsl::optional<BDE_OTHER_TYPE>&>(original))
1398{}
1399
1400template <class TYPE>
1401template <class BDE_OTHER_TYPE>
1402inline
1403NullableValue<TYPE>::NullableValue(
1404 const NullableValue<BDE_OTHER_TYPE>& original,
1405 const allocator_type& allocator)
1406: Base(bsl::allocator_arg,
1407 allocator,
1408 static_cast<const bsl::optional<BDE_OTHER_TYPE>&>(original))
1409{}
1410
1411template <class TYPE>
1412inline
1413NullableValue<TYPE>::NullableValue(const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT
1414: Base()
1415{}
1416
1417template <class TYPE>
1418inline
1419NullableValue<TYPE>::NullableValue(
1420 const bsl::nullopt_t&,
1421 const allocator_type& allocator) BSLS_KEYWORD_NOEXCEPT
1422: Base(bsl::allocator_arg, allocator)
1423{}
1424
1425// MANIPULATORS
1426template <class TYPE>
1427inline
1428NullableValue<TYPE>& NullableValue<TYPE>::operator=(const NullableValue& rhs)
1429{
1430 // Constraints on 'bsl::optional' assignment operator may affect the
1431 // assignment. In order to avoid changes to behavior, we implement the
1432 // assignment or conversion directly.
1433
1434 if (rhs.has_value()) {
1435 if (this->has_value()) {
1436 this->value() = rhs.value();
1437 }
1438 else {
1439 this->emplace(rhs.value());
1440 }
1441 }
1442 else {
1443 this->reset();
1444 }
1445
1446 return *this;
1447}
1448
1449template <class TYPE>
1450inline
1451NullableValue<TYPE>& NullableValue<TYPE>::operator=(
1453{
1454 // Constraints on 'bsl::optional' assignment operator may affect the
1455 // assignment. In order to avoid changes to behavior, we implement the
1456 // assignment or conversion directly.
1457
1458 NullableValue& localRhs = rhs;
1459
1460 if (localRhs.has_value()) {
1461 if (this->has_value()) {
1462 this->value() = MoveUtil::move(localRhs.value());
1463 }
1464 else {
1465 this->emplace(MoveUtil::move(localRhs.value()));
1466 }
1467 }
1468 else {
1469 this->reset();
1470 }
1471
1472 return *this;
1473}
1474
1475template <class TYPE>
1476template <class BDE_OTHER_TYPE>
1477NullableValue<TYPE>& NullableValue<TYPE>::operator=(
1478 const NullableValue<BDE_OTHER_TYPE>& rhs)
1479{
1480 // Constraints on 'bsl::optional' assignment operator may affect the
1481 // assignment. In order to avoid changes to behavior, we implement the
1482 // assignment or conversion directly.
1483
1484 if (rhs.has_value()) {
1485 if (this->has_value()) {
1486 this->value() = rhs.value();
1487 }
1488 else {
1489 this->emplace(rhs.value());
1490 }
1491 }
1492 else {
1493 this->reset();
1494 }
1495
1496 return *this;
1497}
1498
1499template <class TYPE>
1500template <class BDE_OTHER_TYPE>
1501NullableValue<TYPE>& NullableValue<TYPE>::operator=(
1502 BSLMF_MOVABLEREF_DEDUCE(NullableValue<BDE_OTHER_TYPE>) rhs)
1503{
1504 // Constraints on 'bsl::optional' assignment operator may affect the
1505 // assignment. In order to avoid changes to behavior, we implement the
1506 // assignment or conversion directly.
1507
1508 NullableValue<BDE_OTHER_TYPE>& rhsLocal = rhs;
1509
1510 if (rhsLocal.has_value()) {
1511 if (this->has_value()) {
1512 this->value() = MoveUtil::move(rhsLocal.value());
1513 }
1514 else {
1515 this->emplace(MoveUtil::move(rhsLocal.value()));
1516 }
1517 }
1518 else {
1519 this->reset();
1520 }
1521
1522 return *this;
1523}
1524
1525template <class TYPE>
1526template <class BDE_OTHER_TYPE>
1528 NullableValue<TYPE>&>::type
1529NullableValue<TYPE>::operator=(const bsl::optional<BDE_OTHER_TYPE>& rhs)
1530{
1531 Base& base = *this;
1532
1533 base = rhs;
1534
1535 return *this;
1536}
1537
1538template <class TYPE>
1539template <class BDE_OTHER_TYPE>
1541 NullableValue<TYPE>&>::type
1542NullableValue<TYPE>::operator=(
1544{
1545 Base& base = *this;
1546
1547 base = MoveUtil::move(rhs);
1548
1549 return *this;
1550}
1551
1552template <class TYPE>
1553inline
1554NullableValue<TYPE>& NullableValue<TYPE>::operator=(const TYPE& rhs)
1555{
1556 // Constraints on 'bsl::optional' assignment operator may affect the
1557 // assignment. In order to avoid changes to behavior, we implement the
1558 // assignment or conversion directly.
1559
1560 if (this->has_value()) {
1561 this->value() = rhs;
1562 }
1563 else {
1564 this->emplace(rhs);
1565 }
1566
1567 return *this;
1568}
1569
1570template <class TYPE>
1571inline
1572NullableValue<TYPE>& NullableValue<TYPE>::operator=(
1574{
1575 // Constraints on 'bsl::optional' assignment operator may affect the
1576 // assignment. In order to avoid changes to behavior, we implement the
1577 // assignment or conversion directly.
1578
1579 if (this->has_value()) {
1580 this->value() = MoveUtil::move(rhs);
1581 }
1582 else {
1583 this->emplace(MoveUtil::move(rhs));
1584 }
1585
1586 return *this;
1587}
1588
1589template <class TYPE>
1590template <class BDE_OTHER_TYPE>
1591inline
1592NullableValue<TYPE>& NullableValue<TYPE>::operator=(const BDE_OTHER_TYPE& rhs)
1593{
1594 // Constraints on 'bsl::optional' assignment operator may affect the
1595 // assignment. In order to avoid changes to behavior, we implement the
1596 // assignment or conversion directly.
1597
1598 if (this->has_value()) {
1599 this->value() = rhs;
1600 }
1601 else {
1602 this->emplace(rhs);
1603 }
1604
1605 return *this;
1606}
1607
1608template <class TYPE>
1609inline
1610NullableValue<TYPE>& NullableValue<TYPE>::operator=(
1612{
1613 this->reset();
1614
1615 return *this;
1616}
1617
1618template <class TYPE>
1619template <class STREAM>
1620STREAM& NullableValue<TYPE>::bdexStreamIn(STREAM& stream, int version)
1621{
1623
1624 char isNull = 0; // Redundant initialization to suppress -Werror.
1625
1626 stream.getInt8(isNull);
1627
1628 if (stream) {
1629 if (!isNull) {
1630 bdexStreamIn(stream, this->emplace(), version);
1631 }
1632 else {
1633 this->reset();
1634 }
1635 }
1636
1637 return stream;
1638}
1639
1640template <class TYPE>
1641template <class BDE_OTHER_TYPE>
1642inline
1643TYPE& NullableValue<TYPE>::makeValue(
1644 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value)
1645{
1646 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, value));
1647}
1648
1649template <class TYPE>
1650inline
1651TYPE& NullableValue<TYPE>::makeValue()
1652{
1653 return this->emplace();
1654}
1655
1656#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1657// {{{ BEGIN GENERATED CODE
1658// Command line: sim_cpp11_features.pl bdlb_nullablevalue.h
1659#ifndef BDLB_NULLABLEVALUE_VARIADIC_LIMIT
1660#define BDLB_NULLABLEVALUE_VARIADIC_LIMIT 5
1661#endif
1662#ifndef BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B
1663#define BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B BDLB_NULLABLEVALUE_VARIADIC_LIMIT
1664#endif
1665#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 0
1666template <class TYPE>
1667inline
1668TYPE& NullableValue<TYPE>::makeValueInplace(
1669 )
1670{
1671 return this->emplace();
1672}
1673#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 0
1674
1675#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 1
1676template <class TYPE>
1677template <class ARGS_1>
1678inline
1679TYPE& NullableValue<TYPE>::makeValueInplace(
1680 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
1681{
1682 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1683}
1684#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 1
1685
1686#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 2
1687template <class TYPE>
1688template <class ARGS_1,
1689 class ARGS_2>
1690inline
1691TYPE& NullableValue<TYPE>::makeValueInplace(
1692 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1693 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
1694{
1695 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1696 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1697}
1698#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 2
1699
1700#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 3
1701template <class TYPE>
1702template <class ARGS_1,
1703 class ARGS_2,
1704 class ARGS_3>
1705inline
1706TYPE& NullableValue<TYPE>::makeValueInplace(
1707 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1708 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1709 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
1710{
1711 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1712 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1713 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1714}
1715#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 3
1716
1717#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 4
1718template <class TYPE>
1719template <class ARGS_1,
1720 class ARGS_2,
1721 class ARGS_3,
1722 class ARGS_4>
1723inline
1724TYPE& NullableValue<TYPE>::makeValueInplace(
1725 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1726 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1727 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1728 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
1729{
1730 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1731 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1732 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1733 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1734}
1735#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 4
1736
1737#if BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 5
1738template <class TYPE>
1739template <class ARGS_1,
1740 class ARGS_2,
1741 class ARGS_3,
1742 class ARGS_4,
1743 class ARGS_5>
1744inline
1745TYPE& NullableValue<TYPE>::makeValueInplace(
1746 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1747 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1748 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1749 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
1750 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
1751{
1752 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1753 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1754 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1755 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1756 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1757}
1758#endif // BDLB_NULLABLEVALUE_VARIADIC_LIMIT_B >= 5
1759
1760#else
1761// The generated code below is a workaround for the absence of perfect
1762// forwarding in some compilers.
1763template <class TYPE>
1764template <class... ARGS>
1765inline
1766TYPE& NullableValue<TYPE>::makeValueInplace(
1768{
1769 return this->emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1770}
1771// }}} END GENERATED CODE
1772#endif
1773
1774template <class TYPE>
1775inline
1776TYPE& NullableValue<TYPE>::value()
1777{
1778#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1779 BSLS_REVIEW_OPT(this->has_value());
1780
1781 return this->dereferenceRaw();
1782#else
1783 return **this;
1784#endif
1785}
1786// ACCESSORS
1787template <class TYPE>
1788inline
1789const TYPE *NullableValue<TYPE>::addressOr(const TYPE *address) const
1790{
1791 return this->has_value() ? this-> operator->() : address;
1792}
1793
1794template <class TYPE>
1795template <class STREAM>
1796STREAM& NullableValue<TYPE>::bdexStreamOut(STREAM& stream, int version) const
1797{
1799
1800 const bool isNull = !this->has_value();
1801
1802 stream.putInt8(isNull ? 1 : 0);
1803
1804 if (!isNull) {
1805 bdexStreamOut(stream, this->value(), version);
1806 }
1807
1808 return stream;
1809}
1810
1811template <class TYPE>
1812inline
1813bool NullableValue<TYPE>::isNull() const BSLS_KEYWORD_NOEXCEPT
1814{
1815 return !this->has_value();
1816}
1817
1818template <class TYPE>
1819inline
1820int NullableValue<TYPE>::maxSupportedBdexVersion(int versionSelector) const
1821{
1823
1824 // We need to call the 'bslx::VersionFunctions' helper function, because we
1825 // cannot guarantee that 'TYPE' implements 'maxSupportedBdexVersion' as a
1826 // class method.
1827
1828 return maxSupportedBdexVersion(reinterpret_cast<TYPE *>(0),
1829 versionSelector);
1830}
1831
1832#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1833template <class TYPE>
1834inline
1835int NullableValue<TYPE>::maxSupportedBdexVersion() const
1836{
1838
1839 // We need to call the 'bslx::VersionFunctions' helper function, because we
1840 // cannot guarantee that 'TYPE' implements 'maxSupportedBdexVersion' as a
1841 // class method.
1842
1843 return maxSupportedBdexVersion(reinterpret_cast<TYPE *>(0));
1844}
1845#endif // BDE_OMIT_INTERNAL_DEPRECATED
1846
1847template <class TYPE>
1848bsl::ostream& NullableValue<TYPE>::print(bsl::ostream& stream,
1849 int level,
1850 int spacesPerLevel) const
1851{
1852 if (!this->has_value()) {
1853 return bdlb::PrintMethods::print(stream,
1854 "NULL",
1855 level,
1856 spacesPerLevel); // RETURN
1857 }
1858
1860 stream, this->value(), level, spacesPerLevel);
1861}
1862
1863template <class TYPE>
1864inline
1865const TYPE& NullableValue<TYPE>::value() const
1866{
1867#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1868 BSLS_REVIEW_OPT(this->has_value());
1869
1870 return this->dereferenceRaw();
1871#else
1872 return **this;
1873#endif
1874}
1875
1876template <class TYPE>
1877inline
1878TYPE NullableValue<TYPE>::valueOr(const TYPE& value) const
1879{
1880 return this->value_or(value);
1881}
1882
1883template <class TYPE>
1884inline
1885const TYPE *NullableValue<TYPE>::valueOr(const TYPE *value) const
1886{
1887 return this->has_value() ? this-> operator->() : value;
1888}
1889
1890template <class TYPE>
1891inline
1892const TYPE *NullableValue<TYPE>::valueOrNull() const
1893{
1894 return this->has_value() ? this-> operator->() : 0;
1895}
1896
1897} // close package namespace
1898
1899// FREE OPERATORS
1900template <class LHS_TYPE, class RHS_TYPE>
1901inline
1902bool bdlb::operator==(const NullableValue<LHS_TYPE>& lhs,
1903 const NullableValue<RHS_TYPE>& rhs)
1904#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1905 requires requires {
1906 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
1907 }
1908#endif
1909{
1910 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) ==
1911 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
1912}
1913
1914
1915template <class LHS_TYPE, class RHS_TYPE>
1916inline
1917bool bdlb::operator==(const NullableValue<LHS_TYPE>& lhs,
1918 const bsl::optional<RHS_TYPE>& rhs)
1919#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1920 requires requires {
1921 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
1922 }
1923#endif
1924{
1925 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) == rhs;
1926}
1927
1928template <class LHS_TYPE, class RHS_TYPE>
1929inline
1931 const NullableValue<RHS_TYPE>& rhs)
1932#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1933 requires requires {
1934 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
1935 }
1936#endif
1937{
1938 return lhs == static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
1939}
1940
1941#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1942template <class LHS_TYPE, class RHS_TYPE>
1943inline
1944bool bdlb::operator==(const NullableValue<LHS_TYPE>& lhs,
1945 const std::optional<RHS_TYPE>& rhs)
1946#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1947 requires requires {
1948 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
1949 }
1950#endif
1951{
1952 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) == rhs;
1953}
1954
1955template <class LHS_TYPE, class RHS_TYPE>
1956inline
1957bool bdlb::operator==(const std::optional<LHS_TYPE>& lhs,
1958 const NullableValue<RHS_TYPE>& rhs)
1959#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1960 requires requires {
1961 { *lhs == *rhs } -> NullableValue_ConvertibleToBool;
1962 }
1963#endif
1964{
1965 return lhs == static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
1966}
1967#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1968
1969template <class LHS_TYPE, class RHS_TYPE>
1970inline
1971bool bdlb::operator!=(const NullableValue<LHS_TYPE>& lhs,
1972 const NullableValue<RHS_TYPE>& rhs)
1973 #ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1974 requires requires {
1975 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
1976 }
1977#endif
1978{
1979 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) !=
1980 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
1981}
1982
1983template <class LHS_TYPE, class RHS_TYPE>
1984inline
1986 const NullableValue<RHS_TYPE>& rhs)
1987#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
1988 requires requires {
1989 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
1990 }
1991#endif
1992{
1993 return lhs != static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
1994}
1995
1996template <class LHS_TYPE, class RHS_TYPE>
1997inline
1998bool bdlb::operator!=(const NullableValue<LHS_TYPE>& lhs,
1999 const bsl::optional<RHS_TYPE>& rhs)
2000#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2001 requires requires {
2002 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
2003 }
2004#endif
2005{
2006 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) != rhs;
2007}
2008
2009#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2010template <class LHS_TYPE, class RHS_TYPE>
2011inline
2012bool bdlb::operator!=(const std::optional<LHS_TYPE>& lhs,
2013 const NullableValue<RHS_TYPE>& rhs)
2014#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2015 requires requires {
2016 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
2017 }
2018#endif
2019{
2020 return lhs != static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2021}
2022
2023template <class LHS_TYPE, class RHS_TYPE>
2024inline
2025bool bdlb::operator!=(const NullableValue<LHS_TYPE>& lhs,
2026 const std::optional<RHS_TYPE>& rhs)
2027#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2028 requires requires {
2029 { *lhs != *rhs } -> NullableValue_ConvertibleToBool;
2030 }
2031#endif
2032{
2033 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) != rhs;
2034}
2035#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2036
2037template <class LHS_TYPE, class RHS_TYPE>
2038inline
2039bool bdlb::operator==(const NullableValue<LHS_TYPE>& lhs, const RHS_TYPE& rhs)
2040#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2041 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2042 requires { { *lhs == rhs } -> NullableValue_ConvertibleToBool; }
2043#endif
2044{
2045 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) == rhs;
2046}
2047
2048template <class LHS_TYPE, class RHS_TYPE>
2049inline
2050bool bdlb::operator==(const LHS_TYPE& lhs, const NullableValue<RHS_TYPE>& rhs)
2051#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2052 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2053 requires { { lhs == *rhs } -> NullableValue_ConvertibleToBool; }
2054#endif
2055{
2056 return lhs == static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2057}
2058
2059template <class LHS_TYPE, class RHS_TYPE>
2060inline
2061bool bdlb::operator!=(const NullableValue<LHS_TYPE>& lhs, const RHS_TYPE& rhs)
2062#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2063 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2064 requires { { *lhs != rhs } -> NullableValue_ConvertibleToBool; }
2065#endif
2066{
2067 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) != rhs;
2068}
2069
2070template <class LHS_TYPE, class RHS_TYPE>
2071inline
2072bool bdlb::operator!=(const LHS_TYPE& lhs, const NullableValue<RHS_TYPE>& rhs)
2073#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2074 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2075 requires { { lhs != *rhs } -> NullableValue_ConvertibleToBool; }
2076#endif
2077{
2078 return lhs != static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2079}
2080
2081template <class LHS_TYPE, class RHS_TYPE>
2082inline
2083bool bdlb::operator<(const NullableValue<LHS_TYPE>& lhs,
2084 const NullableValue<RHS_TYPE>& rhs)
2085#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2086 requires requires {
2087 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
2088 }
2089#endif
2090{
2091 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <
2092 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2093}
2094
2095template <class LHS_TYPE, class RHS_TYPE>
2096inline
2098 const NullableValue<RHS_TYPE>& rhs)
2099#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2100 requires requires {
2101 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
2102 }
2103#endif
2104{
2105 return lhs < static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2106}
2107
2108template <class LHS_TYPE, class RHS_TYPE>
2109inline
2110bool bdlb::operator<(const NullableValue<LHS_TYPE>& lhs,
2111 const bsl::optional<RHS_TYPE>& rhs)
2112#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2113 requires requires {
2114 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
2115 }
2116#endif
2117{
2118 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) < rhs;
2119}
2120
2121#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2122template <class LHS_TYPE, class RHS_TYPE>
2123inline
2124bool bdlb::operator<(const std::optional<LHS_TYPE>& lhs,
2125 const NullableValue<RHS_TYPE>& rhs)
2126#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2127 requires requires {
2128 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
2129 }
2130#endif
2131{
2132 return lhs < static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2133}
2134
2135template <class LHS_TYPE, class RHS_TYPE>
2136inline
2137bool bdlb::operator<(const NullableValue<LHS_TYPE>& lhs,
2138 const std::optional<RHS_TYPE>& rhs)
2139#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2140 requires requires {
2141 { *lhs < *rhs } -> NullableValue_ConvertibleToBool;
2142 }
2143#endif
2144{
2145 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) < rhs;
2146}
2147#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2148
2149template <class LHS_TYPE, class RHS_TYPE>
2150inline
2151bool bdlb::operator<(const NullableValue<LHS_TYPE>& lhs, const RHS_TYPE& rhs)
2152#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2153 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2154 requires { { *lhs < rhs } -> NullableValue_ConvertibleToBool; }
2155#endif
2156{
2157 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) < rhs;
2158}
2159
2160template <class LHS_TYPE, class RHS_TYPE>
2161inline
2162bool bdlb::operator<(const LHS_TYPE& lhs, const NullableValue<RHS_TYPE>& rhs)
2163#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2164 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2165 requires { { lhs < *rhs } -> NullableValue_ConvertibleToBool; }
2166#endif
2167{
2168 return lhs < static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2169}
2170
2171template <class LHS_TYPE, class RHS_TYPE>
2172inline
2173bool bdlb::operator>(const NullableValue<LHS_TYPE>& lhs,
2174 const NullableValue<RHS_TYPE>& rhs)
2175#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2176 requires requires {
2177 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
2178 }
2179#endif
2180{
2181 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) >
2182 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2183}
2184
2185template <class LHS_TYPE, class RHS_TYPE>
2186inline
2188 const NullableValue<RHS_TYPE>& rhs)
2189#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2190 requires requires {
2191 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
2192 }
2193#endif
2194{
2195 return lhs > static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2196}
2197
2198template <class LHS_TYPE, class RHS_TYPE>
2199inline
2200bool bdlb::operator>(const NullableValue<LHS_TYPE>& lhs,
2201 const bsl::optional<RHS_TYPE>& rhs)
2202#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2203 requires requires {
2204 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
2205 }
2206#endif
2207{
2208 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) > rhs;
2209}
2210
2211#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2212template <class LHS_TYPE, class RHS_TYPE>
2213inline
2214bool bdlb::operator>(const std::optional<LHS_TYPE>& lhs,
2215 const NullableValue<RHS_TYPE>& rhs)
2216#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2217 requires requires {
2218 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
2219 }
2220#endif
2221{
2222 return lhs > static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2223}
2224
2225template <class LHS_TYPE, class RHS_TYPE>
2226inline
2227bool bdlb::operator>(const NullableValue<LHS_TYPE>& lhs,
2228 const std::optional<RHS_TYPE>& rhs)
2229#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2230 requires requires {
2231 { *lhs > *rhs } -> NullableValue_ConvertibleToBool;
2232 }
2233#endif
2234{
2235 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) > rhs;
2236}
2237#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2238
2239template <class LHS_TYPE, class RHS_TYPE>
2240inline
2241bool bdlb::operator>(const NullableValue<LHS_TYPE>& lhs,
2242 const RHS_TYPE& rhs)
2243#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2244 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2245 requires { { *lhs > rhs } -> NullableValue_ConvertibleToBool; }
2246#endif
2247{
2248 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) > rhs;
2249}
2250
2251template <class LHS_TYPE, class RHS_TYPE>
2252inline
2253bool bdlb::operator>(const LHS_TYPE& lhs,
2254 const NullableValue<RHS_TYPE>& rhs)
2255#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2256 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2257 requires { { lhs > *rhs } -> NullableValue_ConvertibleToBool; }
2258#endif
2259{
2260 return lhs > static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2261}
2262
2263template <class LHS_TYPE, class RHS_TYPE>
2264inline
2265bool bdlb::operator<=(const NullableValue<LHS_TYPE>& lhs,
2266 const NullableValue<RHS_TYPE>& rhs)
2267#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2268 requires requires {
2269 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
2270 }
2271#endif
2272{
2273 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <=
2274 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2275}
2276
2277template <class LHS_TYPE, class RHS_TYPE>
2278inline
2280 const NullableValue<RHS_TYPE>& rhs)
2281#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2282 requires requires {
2283 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
2284 }
2285#endif
2286{
2287 return lhs <= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2288}
2289
2290template <class LHS_TYPE, class RHS_TYPE>
2291inline
2292bool bdlb::operator<=(const NullableValue<LHS_TYPE>& lhs,
2293 const bsl::optional<RHS_TYPE>& rhs)
2294#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2295 requires requires {
2296 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
2297 }
2298#endif
2299{
2300 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <= rhs;
2301}
2302
2303#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2304template <class LHS_TYPE, class RHS_TYPE>
2305inline
2306bool bdlb::operator<=(const std::optional<LHS_TYPE>& lhs,
2307 const NullableValue<RHS_TYPE>& rhs)
2308#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2309 requires requires {
2310 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
2311 }
2312#endif
2313{
2314 return lhs <= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2315}
2316
2317template <class LHS_TYPE, class RHS_TYPE>
2318inline
2319bool bdlb::operator<=(const NullableValue<LHS_TYPE>& lhs,
2320 const std::optional<RHS_TYPE>& rhs)
2321#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2322 requires requires {
2323 { *lhs <= *rhs } -> NullableValue_ConvertibleToBool;
2324 }
2325#endif
2326{
2327 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <= rhs;
2328}
2329#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2330
2331template <class LHS_TYPE, class RHS_TYPE>
2332inline
2333bool bdlb::operator<=(const NullableValue<LHS_TYPE>& lhs,
2334 const RHS_TYPE& rhs)
2335#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2336 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2337 requires { { *lhs <= rhs } -> NullableValue_ConvertibleToBool; }
2338#endif
2339{
2340 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <= rhs;
2341}
2342
2343template <class LHS_TYPE, class RHS_TYPE>
2344inline
2345bool bdlb::operator<=(const LHS_TYPE& lhs,
2346 const NullableValue<RHS_TYPE>& rhs)
2347#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2348 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2349 requires { { lhs <= *rhs } -> NullableValue_ConvertibleToBool; }
2350#endif
2351{
2352 return lhs <= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2353}
2354
2355
2356template <class LHS_TYPE, class RHS_TYPE>
2357inline
2358bool bdlb::operator>=(const NullableValue<LHS_TYPE>& lhs,
2359 const NullableValue<RHS_TYPE>& rhs)
2360#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2361 requires requires {
2362 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
2363 }
2364#endif
2365{
2366 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) >=
2367 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2368}
2369
2370template <class LHS_TYPE, class RHS_TYPE>
2371inline
2373 const NullableValue<RHS_TYPE>& rhs)
2374#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2375 requires requires {
2376 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
2377 }
2378#endif
2379{
2380 return lhs >= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2381}
2382
2383template <class LHS_TYPE, class RHS_TYPE>
2384inline
2385bool bdlb::operator>=(const NullableValue<LHS_TYPE>& lhs,
2386 const bsl::optional<RHS_TYPE>& rhs)
2387#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2388 requires requires {
2389 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
2390 }
2391#endif
2392{
2393 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) >= rhs;
2394}
2395
2396#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2397template <class LHS_TYPE, class RHS_TYPE>
2398inline
2399bool bdlb::operator>=(const std::optional<LHS_TYPE>& lhs,
2400 const NullableValue<RHS_TYPE>& rhs)
2401#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2402 requires requires {
2403 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
2404 }
2405#endif
2406{
2407 return lhs >= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2408}
2409
2410template <class LHS_TYPE, class RHS_TYPE>
2411inline
2412bool bdlb::operator>=(const NullableValue<LHS_TYPE>& lhs,
2413 const std::optional<RHS_TYPE>& rhs)
2414#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2415 requires requires {
2416 { *lhs >= *rhs } -> NullableValue_ConvertibleToBool;
2417 }
2418#endif
2419{
2420 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) >= rhs;
2421}
2422#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2423
2424template <class LHS_TYPE, class RHS_TYPE>
2425inline
2426bool bdlb::operator>=(const NullableValue<LHS_TYPE>& lhs,
2427 const RHS_TYPE& rhs)
2428#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2429 requires (!NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2430 requires { { *lhs >= rhs } -> NullableValue_ConvertibleToBool; }
2431#endif
2432{
2433 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) >= rhs;
2434}
2435
2436template <class LHS_TYPE, class RHS_TYPE>
2437inline
2438bool bdlb::operator>=(const LHS_TYPE& lhs,
2439 const NullableValue<RHS_TYPE>& rhs)
2440#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2441 requires (!NullableValue_DerivedFromOptional<LHS_TYPE>) &&
2442 requires { { lhs >= *rhs } -> NullableValue_ConvertibleToBool; }
2443#endif
2444{
2445 return lhs >= static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2446}
2447
2448
2449#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON && \
2450 defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2451
2452template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
2453constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE>
2454bdlb::operator<=>(const NullableValue<LHS_TYPE>& lhs,
2455 const NullableValue<RHS_TYPE>& rhs)
2456{
2457 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <=>
2458 static_cast<const bsl::optional<RHS_TYPE>&>(rhs);
2459}
2460
2461template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
2462constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE>
2463bdlb::operator<=>(const NullableValue<LHS_TYPE>& lhs,
2464 const bsl::optional<RHS_TYPE>& rhs)
2465{
2466 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <=> rhs;
2467}
2468
2469template <class LHS_TYPE, bsl::three_way_comparable_with<LHS_TYPE> RHS_TYPE>
2470constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE>
2471bdlb::operator<=>(const NullableValue<LHS_TYPE>& lhs,
2472 const std::optional<RHS_TYPE>& rhs)
2473{
2474 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <=> rhs;
2475}
2476
2477template <class LHS_TYPE, class RHS_TYPE>
2478 requires(!bdlb::NullableValue_DerivedFromOptional<RHS_TYPE>) &&
2479 bsl::three_way_comparable_with<LHS_TYPE, RHS_TYPE>
2480constexpr std::compare_three_way_result_t<LHS_TYPE, RHS_TYPE>
2481bdlb::operator<=>(const NullableValue<LHS_TYPE>& lhs, const RHS_TYPE& rhs)
2482{
2483 return static_cast<const bsl::optional<LHS_TYPE>&>(lhs) <=> rhs;
2484}
2485
2486template <class TYPE>
2487constexpr std::strong_ordering
2488bdlb::operator<=>(const NullableValue<TYPE>& value,
2490{
2491 return (!value.isNull()) <=> false;
2492}
2493
2494#endif // SUPPORT_THREE_WAY_COMPARISON && HAS_CPP20_CONCEPTS
2495
2496template <class TYPE>
2498bool bdlb::operator==(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
2500{
2501 return !value.has_value();
2502}
2503
2504#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2505
2506template <class TYPE>
2508bool bdlb::operator==(const bsl::nullopt_t&, const NullableValue<TYPE>& value)
2510{
2511 return !value.has_value();
2512}
2513
2514template <class TYPE>
2516bool bdlb::operator!=(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
2518{
2519 return value.has_value();
2520}
2521
2522template <class TYPE>
2524bool bdlb::operator!=(const bsl::nullopt_t&, const NullableValue<TYPE>& value)
2526{
2527 return value.has_value();
2528}
2529
2530# ifndef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2531
2532template <class TYPE>
2534bool bdlb::operator<(const NullableValue<TYPE>&, const bsl::nullopt_t&)
2536{
2537 return false;
2538}
2539
2540template <class TYPE>
2542bool bdlb::operator<(const bsl::nullopt_t&, const NullableValue<TYPE>& value)
2544{
2545 return value.has_value();
2546}
2547
2548template <class TYPE>
2550bool bdlb::operator>(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
2552{
2553 return value.has_value();
2554}
2555
2556template <class TYPE>
2558bool bdlb::operator>(const bsl::nullopt_t&, const NullableValue<TYPE>&)
2560{
2561 return false;
2562}
2563
2564template <class TYPE>
2566bool bdlb::operator<=(const NullableValue<TYPE>& value, const bsl::nullopt_t&)
2568{
2569 return !value.has_value();
2570}
2571
2572template <class TYPE>
2574bool bdlb::operator<=(const bsl::nullopt_t&, const NullableValue<TYPE>&)
2576{
2577 return true;
2578}
2579
2580template <class TYPE>
2582bool bdlb::operator>=(const NullableValue<TYPE>&, const bsl::nullopt_t&)
2584{
2585 return true;
2586}
2587
2588template <class TYPE>
2590bool bdlb::operator>=(const bsl::nullopt_t&, const NullableValue<TYPE>& value)
2592{
2593 return !value.has_value();
2594}
2595
2596# endif // !BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2597#endif // !BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2598
2599template <class TYPE>
2600inline
2601bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
2602 const NullableValue<TYPE>& object)
2603{
2604 return object.print(stream, 0, -1);
2605}
2606
2607// FREE FUNCTIONS
2608template <class HASHALG, class TYPE>
2609void bdlb::hashAppend(HASHALG& hashAlg, const NullableValue<TYPE>& input)
2610{
2611 if (!input.isNull()) {
2612 hashAppend(hashAlg, true);
2613 hashAppend(hashAlg, input.value());
2614 }
2615 else {
2616 hashAppend(hashAlg, false);
2617 }
2618}
2619
2620template <class TYPE>
2621inline
2623 void>::type
2624bdlb::swap(NullableValue<TYPE>& lhs, NullableValue<TYPE>& rhs)
2625{
2626 swap(static_cast<bsl::optional<TYPE>&>(lhs),
2627 static_cast<bsl::optional<TYPE>&>(rhs));
2628}
2629
2630template <class TYPE>
2631inline
2633 void>::type
2634bdlb::swap(NullableValue<TYPE>& lhs, NullableValue<TYPE>& rhs)
2635{
2636 lhs.swap(rhs);
2637}
2638
2639
2640
2641#ifdef BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
2642// This hack works around a bug in gcc's defintion for is-optional. See
2643// bslstl_optional.h for more information.
2644
2645namespace std {
2646template <typename _Tp>
2647inline constexpr bool __is_optional_v<BloombergLP::bdlb::NullableValue<_Tp>> =
2648 true;
2649}
2650#endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
2651
2652#ifdef BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
2653// This hack works around a bug in MSVC's C++20 defintion for is-optional. See
2654// bslstl_optional.h for more information.
2655
2656namespace std {
2657template <typename _Tp>
2658inline
2659constexpr bool _Is_specialization_v<BloombergLP::bdlb::NullableValue<_Tp>,
2660 std::optional> = true;
2661}
2662#endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
2663
2664#else // if ! defined(DEFINED_BDLB_NULLABLEVALUE_H)
2665# error Not valid except when included from bdlb_nullablevalue.h
2666#endif // ! defined(COMPILING_BDLB_NULLABLEVALUE_H)
2667
2668#endif // ! defined(INCLUDED_BDLB_NULLABLEVALUE_CPP03)
2669
2670// ----------------------------------------------------------------------------
2671// Copyright 2016 Bloomberg Finance L.P.
2672//
2673// Licensed under the Apache License, Version 2.0 (the "License");
2674// you may not use this file except in compliance with the License.
2675// You may obtain a copy of the License at
2676//
2677// http://www.apache.org/licenses/LICENSE-2.0
2678//
2679// Unless required by applicable law or agreed to in writing, software
2680// distributed under the License is distributed on an "AS IS" BASIS,
2681// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2682// See the License for the specific language governing permissions and
2683// limitations under the License.
2684// ----------------------------- END-OF-FILE ----------------------------------
2685
2686/** @} */
2687/** @} */
2688/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
#define BSLMF_NESTED_TRAIT_DECLARATION_IF(t_TYPE, t_TRAIT, t_COND)
Definition bslmf_nestedtraitdeclaration.h:243
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlb_nullablevalue.h:1694
bsl::optional< TYPE > Base
Base class of this type.
Definition bdlb_nullablevalue.h:286
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Return true if this object is null, and false otherwise.
Definition bdlb_nullablevalue.h:1779
const TYPE * valueOrNull() const
Definition bdlb_nullablevalue.h:1858
AllocType allocator_type
Definition bdlb_nullablevalue.h:297
TYPE & makeValue()
Definition bdlb_nullablevalue.h:1725
TYPE valueOr(const TYPE &value) const
Definition bdlb_nullablevalue.h:1844
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlb_nullablevalue.h:1814
const TYPE * addressOr(const TYPE *address) const
Definition bdlb_nullablevalue.h:1755
TYPE & makeValueInplace(ARGS &&... args)
Definition bdlb_nullablevalue.h:1734
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlb_nullablevalue.h:1762
int maxSupportedBdexVersion() const
Definition bdlb_nullablevalue.h:1801
friend class NullableValue
Definition bdlb_nullablevalue.h:280
TYPE & value()
Definition bdlb_nullablevalue.h:1742
TYPE ValueType
Definition bdlb_nullablevalue.h:291
Definition bslma_bslallocator.h:580
Definition bslstl_optional.h:1861
optional() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:4630
Definition bslmf_movableref.h:751
#define BSLMF_MOVABLEREF_DEDUCE(...)
Definition bslmf_movableref.h:690
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2012
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_DEPRECATE
Definition bsls_deprecate.h:720
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_REVIEW_OPT(X)
Definition bsls_review.h:977
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void swap(OptionValue &a, OptionValue &b)
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
bool operator<(const MetricId &lhs, const MetricId &rhs)
STREAM & bdexStreamOut(STREAM &stream, const DayCountConvention::Enum &value, int version)
int maxSupportedBdexVersion(const DayCountConvention::Enum *, int versionSelector)
STREAM & bdexStreamIn(STREAM &stream, DayCountConvention::Enum &variable, int version)
bool isNull(const TYPE &object)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
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
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const BigEndianInt16 &integer)
bool operator>=(const Guid &lhs, const Guid &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
void swap(NullableAllocatedValue< TYPE > &a, NullableAllocatedValue< TYPE > &b)
bool operator<=(const Guid &lhs, const Guid &rhs)
bool operator>(const Guid &lhs, const Guid &rhs)
bool operator<(const Guid &lhs, const Guid &rhs)
bool operator==(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
STREAM & bdexStreamIn(STREAM &stream, VALUE_TYPE &variable)
Definition bslx_instreamfunctions.h:1247
STREAM & bdexStreamOut(STREAM &stream, const TYPE &value)
Definition bslx_outstreamfunctions.h:992
int maxSupportedBdexVersion(const TYPE *, int versionSelector)
Definition bslx_versionfunctions.h:519
Definition bdldfp_decimal.h:5188
Definition bdlb_printmethods.h:306
Definition bslmf_conditional.h:120
Definition bslmf_enableif.h:525
Definition bslmf_isconvertible.h:867
Definition bslmf_isnothrowmoveconstructible.h:358
Definition bslmf_issame.h:146
Definition bslstl_optional.h:467
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisecopyable.h:298
Definition bslmf_isbitwisemoveable.h:718
Definition bslmf_movableref.h:791