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