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