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