BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlb_nullablevalueref_cpp03.h
Go to the documentation of this file.
1/// @file bdlb_nullablevalueref_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullablevalueref_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BDLB_NULLABLEVALUEREF_CPP03
12#define INCLUDED_BDLB_NULLABLEVALUEREF_CPP03
13
14/// @defgroup bdlb_nullablevalueref_cpp03 bdlb_nullablevalueref_cpp03
15/// @brief Provide C++03 implementation for bdlb_nullablevalueref.h
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_nullablevalueref_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_nullablevalueref_cpp03-purpose"> Purpose</a>
25/// * <a href="#bdlb_nullablevalueref_cpp03-classes"> Classes </a>
26/// * <a href="#bdlb_nullablevalueref_cpp03-description"> Description </a>
27///
28/// # Purpose {#bdlb_nullablevalueref_cpp03-purpose}
29/// Provide C++03 implementation for bdlb_nullablevalueref.h
30///
31/// # Classes {#bdlb_nullablevalueref_cpp03-classes}
32/// See bdlb_nullablevalueref.h for list of classes
33///
34/// @see bdlb_nullablevalueref
35///
36/// # Description {#bdlb_nullablevalueref_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Wed Nov 6 15:09:19 2024
48/// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bdl
54 * @{
55 */
56/** @addtogroup bdlb
57 * @{
58 */
59/** @addtogroup bdlb_nullablevalueref_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BDLB_NULLABLEVALUEREF_H
64
65
66namespace bdlb {
67
68template <class TYPE>
69class ConstNullableValueRef;
70
71 // ============================
72 // class NullableValueRef<TYPE>
73 // ============================
74
75/// This class is a wrapper for either a `bsl::optional` or
76/// `NullableAllocatedValue`, and provides modifiable access to the wrapped
77/// object.
78///
79/// See @ref bdlb_nullablevalueref_cpp03
80template <class TYPE>
81class NullableValueRef {
82
83 // PRIVATE TYPES
84#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
85 // UNSPECIFIED BOOL
86
87 /// This type is needed only in C++03 mode, where `explicit` conversion
88 /// operators are not supported. A `NullableAllocatedValue` is implicitly
89 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
90 /// implicitly convertible to `bool`.
91 typedef BloombergLP::bsls::UnspecifiedBool<NullableValueRef>
92 UnspecifiedBoolUtil;
93 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
94#endif
95
96 // DATA
97
98 // the address of the target
99 void *d_target_p;
100
101 // `true` if the target is a specialization of `bsl::optional`, and
102 // `false` it's a specialization of `NullableAllocatedValue`
103 bool d_isTargetOptional;
104
105 // PRIVATE ACCESSORS
106
107 /// Return a reference providing non-const access to the held `NullableAllocatedValue` object.
108 ///
109 /// \pre The behavior is undefined if the
110 /// target is not a `NullableAllocatedValue`.
111 NullableAllocatedValue<TYPE>& getNAV() const;
112
113 /// Return a reference providing non-const access to the held `bsl::optional` object.
114 ///
115 /// \pre The behavior is undefined if the target is
116 /// not a `bdlb::bsl::optional`.
117 bsl::optional<TYPE>& getOpt() const;
118
119 /// Return `true` if the target of this object is a `bsl::optional`, and
120 /// `false` otherwise.
121 bool hasOpt() const;
122
123 // FRIENDS
124 friend class ConstNullableValueRef<TYPE>;
125
126 // TRAITS
127
128 // This class requires that `TYPE` is not `const`- or `volatile`-
129 // qualified, nor a reference.
131 bsl::is_same<TYPE,
132 typename bsl::remove_cvref<TYPE>::type>::value));
133
134 public:
135 // TYPES
136
137 /// `value_type` is an alias for the template parameter `TYPE`, and
138 /// represents the type of the object managed by the wrapped nullable
139 /// object.
140 typedef TYPE value_type;
141
142 // CREATORS
143
144 /// Create a nullable object wrapper that refers to the specified `opt` object.
145 ///
146 /// \note Note that the created wrapper does not own a copy of the
147 /// underlying nullable value, but instead refers to it, and so the
148 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
149 NullableValueRef(bsl::optional<TYPE>& opt); // IMPLICIT
150
151 /// Create a nullable object wrapper that refers to the specified `opt` object.
152 ///
153 /// \note Note that the created wrapper does not own a copy of the
154 /// underlying nullable value, but instead refers to it, and so the
155 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
156 NullableValueRef(NullableAllocatedValue<TYPE>& opt); // IMPLICIT
157
158 /// Create a nullable object wrapper that refers to the target object of the specified `original` wrapper.
159 ///
160 /// \note Note that the created wrapper
161 /// does not own a copy of the underlying nullable value, but instead
162 /// refers to it, and so the lifetime of the target must exceed the
163 /// lifetime of the created wrapper.
164 NullableValueRef(const NullableValueRef& original);
165
166 /// Destroy this object.
167 /// \note Note that this destructor is generated by the
168 /// compiler, and does not destroy the target.
170
171 // ACCESSORS
172
173 /// Return `true` if the target contains a value, and `false` otherwise.
174 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
175
176 /// Return `false` if the target contains a value, and `true` otherwise.
177 ///
178 /// \note Note that this accessor is provided purely for compatibility with
179 /// `NullableValue` and `NullableAllocatedValue`, and its use is
180 /// discouraged in favor of @ref has_value .
181 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
182
183 /// Return a reference providing non-modifiable access to the underlying
184 /// object of a (template parameter) `TYPE`.
185 ///
186 /// \pre The behavior is undefined if the target has no value.
187 const value_type& value() const;
188
189 /// Return a pointer providing non-modifiable access to the underlying `TYPE` object.
190 ///
191 /// \pre The behavior is undefined if the target has no
192 /// value.
193 const value_type *operator->() const;
194
195 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
196 ///
197 /// \pre The behavior is undefined if the target has no
198 /// value.
199 const value_type& operator*() const;
200
201#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
202 /// Return `true` if the target holds a value, and `false` otherwise.
203 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
204#else
205 /// Simulation of explicit conversion to bool. Inlined to work around xlC
206 /// but when out-of-line.
207 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
208 {
209 return UnspecifiedBoolUtil::makeValue(has_value());
210 }
211#endif
212
213 /// Return the value of the underlying object of a (template parameter)
214 /// `TYPE` if the target is non-null, and the specified @ref default_value otherwise.
215 ///
216 /// \note Note that this method returns *by* *value*, so may be
217 /// inefficient in some contexts.
218 template <class ANY_TYPE>
219 TYPE value_or(const ANY_TYPE& default_value) const;
220
221 // MANIPULATORS
222#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
223// {{{ BEGIN GENERATED CODE
224// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
225#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
226#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT 5
227#endif
228#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A
229#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
230#endif
231#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 0
232 TYPE& emplace();
233#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 0
234
235#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 1
236 template <class ARGS_1>
238#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 1
239
240#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 2
241 template <class ARGS_1,
242 class ARGS_2>
245#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 2
246
247#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 3
248 template <class ARGS_1,
249 class ARGS_2,
250 class ARGS_3>
254#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 3
255
256#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 4
257 template <class ARGS_1,
258 class ARGS_2,
259 class ARGS_3,
260 class ARGS_4>
265#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 4
266
267#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 5
268 template <class ARGS_1,
269 class ARGS_2,
270 class ARGS_3,
271 class ARGS_4,
272 class ARGS_5>
278#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_A >= 5
279
280#else
281// The generated code below is a workaround for the absence of perfect
282// forwarding in some compilers.
283 template <class... ARGS>
285// }}} END GENERATED CODE
286#endif
287
288 /// Return a pointer providing modifiable access to the underlying `TYPE` object.
289 ///
290 /// \pre The behavior is undefined if the target has no
291 /// value.
293
294 /// Return a reference providing modifiable access to the underlying `TYPE` object.
295 ///
296 /// \pre The behavior is undefined if the target has no
297 /// value.
299
300 /// Reset the target to the default constructed state (i.e., to have the
301 /// null value).
302 NullableValueRef<TYPE>& operator=(const bsl::nullopt_t&);
303
304 /// Assign to the target the value of the specified `rhs`, and return a
305 /// reference providing modifiable access to this object.
306 NullableValueRef<TYPE>& operator=(const TYPE& rhs);
307
308 /// Assign to the target the value of the specified `rhs`, and return a
309 /// reference providing modifiable access to this object.
310 NullableValueRef<TYPE>& operator=(const bsl::optional<TYPE>& rhs);
311
312 /// Assign to the target the value of the specified `rhs`, and return a
313 /// reference providing modifiable access to this object.
314 NullableValueRef<TYPE>& operator=(
315 const NullableAllocatedValue<TYPE>& rhs);
316
317 /// Assign to the target the value of the specified `rhs`, and return a
318 /// reference providing modifiable access to this object.
319 NullableValueRef<TYPE>& operator=(const NullableValueRef& rhs);
320
321 /// Reset the target to the default constructed state (i.e., to have the
322 /// null value).
323 void reset();
324
325 /// Return a reference providing modifiable access to the underlying `TYPE` object.
326 ///
327 /// \pre The behavior is undefined unless this object is
328 /// non-null.
329 value_type& value();
330
331 // DEPRECATED FUNCTIONS
332 // provided for compatibility with NullableValue
333
334 /// Return an address providing non-modifiable access to the underlying
335 /// object of a (template parameter) `TYPE` if this object is non-null,
336 /// and the specified `address` otherwise.
337 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::addressOr",
338 "Use 'has_value() ? &value() : address' instead")
339 const TYPE *addressOr(const TYPE *address) const;
340
341#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
342// {{{ BEGIN GENERATED CODE
343// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
344#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
345#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT 5
346#endif
347#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B
348#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
349#endif
350
351#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 0
352 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
353 "Use 'emplace' instead")
354 TYPE& makeValueInplace();
355#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 0
356
357#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 1
358 template <class ARGS_1>
359 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
360 "Use 'emplace' instead")
361 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1);
362#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 1
363
364#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 2
365 template <class ARGS_1,
366 class ARGS_2>
367 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
368 "Use 'emplace' instead")
369 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
370 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2);
371#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 2
372
373#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 3
374 template <class ARGS_1,
375 class ARGS_2,
376 class ARGS_3>
377 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
378 "Use 'emplace' instead")
379 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
381 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3);
382#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 3
383
384#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 4
385 template <class ARGS_1,
386 class ARGS_2,
387 class ARGS_3,
388 class ARGS_4>
389 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
390 "Use 'emplace' instead")
391 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
394 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4);
395#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 4
396
397#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 5
398 template <class ARGS_1,
399 class ARGS_2,
400 class ARGS_3,
401 class ARGS_4,
402 class ARGS_5>
403 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
404 "Use 'emplace' instead")
405 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
409 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5);
410#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_B >= 5
411
412#else
413// The generated code below is a workaround for the absence of perfect
414// forwarding in some compilers.
415
416 template <class... ARGS>
417 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
418 "Use 'emplace' instead")
419 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
420// }}} END GENERATED CODE
421#endif
422
423 /// Return the value of the underlying object of a (template parameter)
424 /// `TYPE` if this object is non-null, and the specified `otherValue` otherwise.
425 ///
426 /// \note Note that this method returns *by* *value*, so may be
427 /// inefficient in some contexts.
428 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::valueOr",
429 "Use 'value_or' instead")
430 TYPE valueOr(const TYPE& otherValue) const;
431
432 /// Return an address providing non-modifiable access to the underlying
433 /// object of a (template parameter) `TYPE` if this object is non-null,
434 /// and 0 otherwise.
435 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::valueOrNull",
436 "Use 'has_value() ? &value() : NULL' instead")
437 const TYPE *valueOrNull() const;
438};
439
440// FREE FUNCTIONS
441
442/// Pass the boolean value of whether the specified `input` references a
443/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
444/// (template parameter) type `HASHALG`. If `input.has_value` is true,
445/// additionally pass the value to `hashAlg`.
446template <class HASHALG, class TYPE>
447void hashAppend(HASHALG& hashAlg, const NullableValueRef<TYPE>& input);
448
449// FREE OPERATORS
450
451/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
452/// the same value, and `false` otherwise. Two nullable wrappers have the
453/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
454///
455/// \note Note that this
456/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
457/// compatible.
458template <class LHS_TYPE, class RHS_TYPE>
459bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
460 const NullableValueRef<RHS_TYPE>& rhs);
461
462/// Return `true` if the specified `lhs` and `rhs` objects have the same
463/// value, and `false` otherwise. A nullable wrapper and a value of some
464/// type have the same value if the nullable wrapper is non-null and the
465/// underlying value of it's target compares equal to the other value.
466///
467/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
468/// not compatible.
469template <class LHS_TYPE, class RHS_TYPE>
470bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
471 const RHS_TYPE& rhs);
472template <class LHS_TYPE, class RHS_TYPE>
473bool operator==(const LHS_TYPE& lhs,
474 const NullableValueRef<RHS_TYPE>& rhs);
475
476/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
477/// have the same value, and `false` otherwise. Two nullable wrappers do
478/// not have the same value if one is null and the other is non-null, or if
479/// both are non-null and the values of their underlying objects do not compare equal.
480///
481/// \note Note that this function will fail to compile if
482/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
483template <class LHS_TYPE, class RHS_TYPE>
484bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
485 const NullableValueRef<RHS_TYPE>& rhs);
486
487/// Return `true` if the specified `lhs` and `rhs` objects do not have the
488/// same value, and `false` otherwise. A nullable wrappers and a value of
489/// some type do not have the same value if either the nullable wrappers is
490/// null, or its underlying value does not compare equal to the other value.
491///
492/// \note Note that this function will fail to compile if `LHS_TYPE` and
493/// `RHS_TYPE` are not compatible.
494template <class LHS_TYPE, class RHS_TYPE>
495bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
496 const RHS_TYPE& rhs);
497template <class LHS_TYPE, class RHS_TYPE>
498bool operator!=(const LHS_TYPE& lhs,
499 const NullableValueRef<RHS_TYPE>& rhs);
500
501/// Return `true` if the specified `lhs` nullable wrapper is ordered before
502/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
503/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
504/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
505///
506/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
507/// not compatible.
508template <class LHS_TYPE, class RHS_TYPE>
509bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
510 const NullableValueRef<RHS_TYPE>& rhs);
511
512/// Return `true` if the specified `lhs` nullable wrapper is ordered before
513/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
514/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
515template <class LHS_TYPE, class RHS_TYPE>
516bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
517 const RHS_TYPE& rhs);
518
519/// Return `true` if the specified `lhs` is ordered before the specified
520/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
521/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
522template <class LHS_TYPE, class RHS_TYPE>
523bool operator<(const LHS_TYPE& lhs,
524 const NullableValueRef<RHS_TYPE>& rhs);
525
526
527/// Return `true` if the specified `lhs` nullable wrapper is ordered before
528/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
529/// value, and `false` otherwise. (See `operator<` and `operator==`.)
530///
531/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
532/// are not compatible.
533template <class LHS_TYPE, class RHS_TYPE>
534bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
535 const NullableValueRef<RHS_TYPE>& rhs);
536
537/// Return `true` if the specified `lhs` nullable wrapper is ordered before
538/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
539///
540/// \note Note that this operator
541/// returns `!(rhs < lhs)`.
542template <class LHS_TYPE, class RHS_TYPE>
543bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
544 const RHS_TYPE& rhs);
545
546/// Return `true` if the specified `lhs` is ordered before the specified
547/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
548///
549/// \note Note that this
550/// operator returns `!(rhs < lhs)`.
551template <class LHS_TYPE, class RHS_TYPE>
552bool operator<=(const LHS_TYPE& lhs,
553 const NullableValueRef<RHS_TYPE>& rhs);
554
555/// Return `true` if the specified `lhs` nullable wrapper is ordered after
556/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
557/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
558/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
559///
560/// \note Note that this operator returns `rhs < lhs` when both operands are of
561/// `bsl::optional` type. Also note that this function will fail to compile
562/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
563template <class LHS_TYPE, class RHS_TYPE>
564bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
565 const NullableValueRef<RHS_TYPE>& rhs);
566
567/// Return `true` if the specified `lhs` nullable wrapper is ordered after
568/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
569/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
570///
571/// \note Note that this operator returns `rhs < lhs`.
572template <class LHS_TYPE, class RHS_TYPE>
573bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
574 const RHS_TYPE& rhs);
575
576/// Return `true` if the specified `lhs` is ordered after the specified
577/// `rhs` nullable wrapper, and `false` otherwise. `lhs` is ordered after
578/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`.
579///
580/// \note Note that this operator returns `rhs < lhs`.
581template <class LHS_TYPE, class RHS_TYPE>
582bool operator>(const LHS_TYPE& lhs,
583 const NullableValueRef<RHS_TYPE>& rhs);
584
585/// Return `true` if the specified `lhs` nullable object is ordered after
586/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
587/// value, and `false` otherwise. (See `operator>` and `operator==`.)
588///
589/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
590/// `bsl::optional` type. Also note that this function will fail to compile
591/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
592template <class LHS_TYPE, class RHS_TYPE>
593bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
594 const NullableValueRef<RHS_TYPE>& rhs);
595
596/// Return `true` if the specified `lhs` nullable wrapper is ordered after
597/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
598///
599/// \note Note that this operator
600/// returns `!(lhs < rhs)`.
601template <class LHS_TYPE, class RHS_TYPE>
602bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
603 const RHS_TYPE& rhs);
604
605/// Return `true` if the specified `lhs` is wrapper after the specified
606/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
607///
608/// \note Note that this
609/// operator returns `!(lhs < rhs)`.
610template <class LHS_TYPE, class RHS_TYPE>
611bool operator>=(const LHS_TYPE& lhs,
612 const NullableValueRef<RHS_TYPE>& rhs);
613
614
615 //================================
616 // Comparisons with bsl::nullopt_t
617 //================================
618
619/// Return `true` if the specified `lhs` is null, and `false` otherwise.
620template <class TYPE>
621bool operator==(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
623
624/// Return `true` if the specified `rhs` is null, and `false` otherwise.
625template <class TYPE>
626bool operator==(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
628
629/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
630template <class TYPE>
631bool operator!=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
633
634/// Return `true` if the specified `rhs` is not null, and `false`
635/// otherwise.
636template <class TYPE>
637bool operator!=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
639
640/// Return `false`. `bsl::nullopt` never orders after a
641/// `NullableValueRef`.
642template <class TYPE>
643bool operator<(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
645
646/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
647///
648/// \note Note that `bsl::nullopt` is ordered before any `NullableValueRef` that
649/// is not null.
650template <class TYPE>
651bool operator<(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
653
654/// Return `true` if the specified `lhs` is not null, and `false`
655/// otherwise.
656template <class TYPE>
657bool operator>(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
659
660/// Return `false`. `bsl::nullopt` never orders after a
661/// `NullableValueRef`.
662template <class TYPE>
663bool operator>(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
665
666/// Return `true` if the specified `lhs` is null, and `false` otherwise.
667template <class TYPE>
668bool operator<=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
670
671/// Return `true`.
672template <class TYPE>
673bool operator<=(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
675
676/// Return `true`.
677template <class TYPE>
678bool operator>=(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
680
681/// Return `true` if the specified `rhs` is null, and `false` otherwise.
682template <class TYPE>
683bool operator>=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
685
686 // =================================
687 // class ConstNullableValueRef<TYPE>
688 // =================================
689
690/// This class is a wrapper for either a `bsl::optional` or
691/// `NullableAllocatedValue`, and provides non-modifiable access to the
692/// wrapped object.
693///
694/// See @ref bdlb_nullablevalueref_cpp03
695template <class TYPE>
696class ConstNullableValueRef {
697
698 // PRIVATE TYPES
699#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
700 // UNSPECIFIED BOOL
701
702 /// This type is needed only in C++03 mode, where `explicit` conversion
703 /// operators are not supported. A `NullableAllocatedValue` is implicitly
704 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
705 /// implicitly convertible to `bool`.
706 typedef BloombergLP::bsls::UnspecifiedBool<ConstNullableValueRef>
707 UnspecifiedBoolUtil;
708 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
709#endif
710
711 // DATA
712
713 // the address of the target
714 const void *d_target_p;
715
716 // `true` if the referent is a specialization of `bsl::optional`, and
717 // `false` if it's a specialization of `NullableAllocatedValue`.
718 bool d_isTargetOptional;
719
720 // PRIVATE ACCESSORS
721
722 /// Return a pointer to the held `bdlb::NullableAllocatedValue`.
723 ///
724 /// \pre The behavior is undefined if the target is not a
725 /// `bdlb::NullableAllocatedValue`.
726 const NullableAllocatedValue<TYPE>& getNAV() const;
727
728 /// Return a pointer to the held `bdlb::bsl::optional`.
729 ///
730 /// \pre The behavior is undefined if the target is not a `bdlb::bsl::optional`.
731 const bsl::optional<TYPE>& getOpt() const;
732
733 /// Return `true` if this object currently holds a pointer to a
734 /// bdlb::bsl::optional, and `false` otherwise.
735 bool hasOpt() const;
736
737 // TRAITS
738
739 /// This class requires that `TYPE` is not `const`- or `volatile`-
740 /// qualified, nor a reference.
742 bsl::is_same<TYPE,
743 typename bsl::remove_cvref<TYPE>::type>::value));
744
745 public:
746 // TYPES
747
748 /// `value_type` is an alias for the template parameter `TYPE`, and
749 /// represents the type of the object managed by the wrapped nullable
750 /// object.
751 typedef TYPE value_type;
752
753 // CREATORS
754
755 /// Create a nullable object wrapper that refers to the specified `opt` object.
756 ///
757 /// \note Note that the created wrapper does not own a copy of the
758 /// underlying nullable value, but instead refers to it, and so the
759 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
760 ConstNullableValueRef(const bsl::optional<TYPE>& opt); // IMPLICIT
761
762 /// Create a nullable object wrapper that refers to the specified `opt` object.
763 ///
764 /// \note Note that the created wrapper does not own a copy of the
765 /// underlying nullable value, but instead refers to it, and so the
766 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
767 ConstNullableValueRef(const NullableAllocatedValue<TYPE>& opt);
768 // IMPLICIT
769
770 /// Create a nullable object wrapper that refers to the target object of the specified `ref` wrapper.
771 ///
772 /// \note Note that the created wrapper does not
773 /// own a copy of the underlying nullable value, but instead refers to
774 /// to it, and so the lifetime of the target must exceed the lifetime of
775 /// the created wrapper.
776 ConstNullableValueRef(const NullableValueRef<TYPE>& ref); // IMPLICIT
777
778 /// Create a nullable object wrapper that refers to the target object of the specified `original` wrapper.
779 ///
780 /// \note Note that the created wrapper
781 /// does not own a copy of the underlying nullable value, but instead
782 /// refers to it, and so the lifetime of the target must exceed the
783 /// lifetime of the created wrapper.
784 ConstNullableValueRef(const ConstNullableValueRef& original);
785
786 /// Destroy this object.
787 /// \note Note that this destructor is generated by the
788 /// compiler, and does not destruct the target.
789 ~ConstNullableValueRef();
790
791 // ACCESSORS
792
793 /// Return `true` if the target contains a value, and `false` otherwise.
794 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
795
796 /// Return `false` if the target contains a value, and `true` otherwise.
797 ///
798 /// \note Note that this accessor is provided purely for compatibility with
799 /// `NullableValue` and `NullableAllocatedValue`, and its use is
800 /// discouraged in favor of @ref has_value .
801 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
802
803 /// Return a reference providing non-modifiable access to the underlying
804 /// object of a (template parameter) `TYPE`.
805 ///
806 /// \pre The behavior is undefined if the target has no value.
807 const value_type& value() const;
808
809 /// Return a pointer providing non-modifiable access to the underlying `TYPE` object.
810 ///
811 /// \pre The behavior is undefined if the target has no
812 /// value.
813 const value_type *operator->() const;
814
815 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
816 ///
817 /// \pre The behavior is undefined if the target has no
818 /// value.
819 const value_type& operator*() const;
820
821#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
822 /// Return `true` if the target holds a value, and `false` otherwise.
823 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
824#else
825 /// Simulation of explicit conversion to bool. Inlined to work around xlC
826 /// but when out-of-line.
827 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
828 {
829 return UnspecifiedBoolUtil::makeValue(has_value());
830 }
831#endif
832
833 /// Return the value of the underlying object of a (template parameter)
834 /// `TYPE` if the target is non-null, and the specified @ref default_value otherwise.
835 ///
836 /// \note Note that this method returns *by* *value*, so may be
837 /// inefficient in some contexts.
838 template <class ANY_TYPE>
839 TYPE value_or(const ANY_TYPE& default_value) const;
840
841 // DEPRECATED FUNCTIONS
842 // provided for compatibility with NullableValue
843
844 /// Return an address providing non-modifiable access to the underlying
845 /// object of a (template parameter) `TYPE` if this object is non-null,
846 /// and the specified `address` otherwise.
847 BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::addressOr",
848 "Use 'has_value() ? &value() : address' instead")
849 const TYPE *addressOr(const TYPE *address) const;
850
851 /// Return the value of the underlying object of a (template parameter)
852 /// `TYPE` if this object is non-null, and the specified `otherValue` otherwise.
853 ///
854 /// \note Note that this method returns *by* *value*, so may be
855 /// inefficient in some contexts.
856 BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::valueOr",
857 "Use 'value_or' instead")
858 TYPE valueOr(const TYPE& otherValue) const;
859
860 /// Return an address providing non-modifiable access to the underlying
861 /// object of a (template parameter) `TYPE` if this object is non-null,
862 /// and 0 otherwise.
863 BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::valueOrNull",
864 "Use 'has_value() ? &value() : NULL' instead")
865 const TYPE *valueOrNull() const;
866
867};
868
869// FREE FUNCTIONS
870
871/// Pass the boolean value of whether the specified `input` references a
872/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
873/// (template parameter) type `HASHALG`. If `input.has_value` is true,
874/// additionally pass the value to `hashAlg`.
875template <class HASHALG, class TYPE>
876void hashAppend(HASHALG& hashAlg, const ConstNullableValueRef<TYPE>& input);
877
878// FREE OPERATORS
879
880/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
881/// the same value, and `false` otherwise. Two nullable wrappers have the
882/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
883///
884/// \note Note that this
885/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
886/// compatible.
887template <class LHS_TYPE, class RHS_TYPE>
888bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
889 const ConstNullableValueRef<RHS_TYPE>& rhs);
890
891/// Return `true` if the specified `lhs` and `rhs` objects have the same
892/// value, and `false` otherwise. A nullable wrapper and a value of some
893/// type have the same value if the nullable wrapper is non-null and the
894/// underlying value of it's target compares equal to the other value.
895///
896/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
897/// not compatible.
898template <class LHS_TYPE, class RHS_TYPE>
899bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
900 const RHS_TYPE& rhs);
901template <class LHS_TYPE, class RHS_TYPE>
902bool operator==(const LHS_TYPE& lhs,
903 const ConstNullableValueRef<RHS_TYPE>& rhs);
904
905/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
906/// have the same value, and `false` otherwise. Two nullable wrappers do
907/// not have the same value if one is null and the other is non-null, or if
908/// bost are non-null and the values of their underlying objects do not compare equal.
909///
910/// \note Note that this function will fail to compile if
911/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
912template <class LHS_TYPE, class RHS_TYPE>
913bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
914 const ConstNullableValueRef<RHS_TYPE>& rhs);
915
916/// Return `true` if the specified `lhs` and `rhs` objects do not have the
917/// same value, and `false` otherwise. A nullable wrappers and a value of
918/// some type do not have the same value if either the nullable wrappers is
919/// null, or its underlying value does not compare equal to the other value.
920///
921/// \note Note that this function will fail to compile if `LHS_TYPE` and
922/// `RHS_TYPE` are not compatible.
923template <class LHS_TYPE, class RHS_TYPE>
924bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
925 const RHS_TYPE& rhs);
926template <class LHS_TYPE, class RHS_TYPE>
927bool operator!=(const LHS_TYPE& lhs,
928 const ConstNullableValueRef<RHS_TYPE>& rhs);
929
930/// Return `true` if the specified `lhs` nullable wrapper is ordered before
931/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
932/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
933/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
934///
935/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
936/// not compatible.
937template <class LHS_TYPE, class RHS_TYPE>
938bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
939 const ConstNullableValueRef<RHS_TYPE>& rhs);
940
941/// Return `true` if the specified `lhs` nullable wrapper is ordered before
942/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
943/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
944template <class LHS_TYPE, class RHS_TYPE>
945bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
946 const RHS_TYPE& rhs);
947
948/// Return `true` if the specified `lhs` is ordered before the specified
949/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
950/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
951template <class LHS_TYPE, class RHS_TYPE>
952bool operator<(const LHS_TYPE& lhs,
953 const ConstNullableValueRef<RHS_TYPE>& rhs);
954
955/// Return `true` if the specified `lhs` nullable wrapper is ordered before
956/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
957/// value, and `false` otherwise. (See `operator<` and `operator==`.)
958///
959/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
960/// are not compatible.
961template <class LHS_TYPE, class RHS_TYPE>
962bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
963 const ConstNullableValueRef<RHS_TYPE>& rhs);
964
965/// Return `true` if the specified `lhs` nullable wrapper is ordered before
966/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
967///
968/// \note Note that this operator
969/// returns `!(rhs < lhs)`.
970template <class LHS_TYPE, class RHS_TYPE>
971bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
972 const RHS_TYPE& rhs);
973
974/// Return `true` if the specified `lhs` is ordered before the specified
975/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
976///
977/// \note Note that this
978/// operator returns `!(rhs < lhs)`.
979template <class LHS_TYPE, class RHS_TYPE>
980bool operator<=(const LHS_TYPE& lhs,
981 const ConstNullableValueRef<RHS_TYPE>& rhs);
982
983/// Return `true` if the specified `lhs` nullable wrapper is ordered after
984/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
985/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
986/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
987///
988/// \note Note that this operator returns `rhs < lhs` when both operands are of
989/// `NullableValue` type. Also note that this function will fail to compile
990/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
991template <class LHS_TYPE, class RHS_TYPE>
992bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
993 const ConstNullableValueRef<RHS_TYPE>& rhs);
994
995/// Return `true` if the specified `lhs` nullable wrapper is ordered after
996/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
997/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
998///
999/// \note Note that this operator returns `rhs < lhs`.
1000template <class LHS_TYPE, class RHS_TYPE>
1001bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1002 const RHS_TYPE& rhs);
1003
1004/// Return `true` if the specified `lhs` is ordered after the specified
1005/// `rhs` nullable wrapper, and `false` otherwise. `lhs` is ordered after
1006/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`.
1007///
1008/// \note Note that this operator returns `rhs < lhs`.
1009template <class LHS_TYPE, class RHS_TYPE>
1010bool operator>(const LHS_TYPE& lhs,
1011 const ConstNullableValueRef<RHS_TYPE>& rhs);
1012
1013/// Return `true` if the specified `lhs` nullable object is ordered after
1014/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
1015/// value, and `false` otherwise. (See `operator>` and `operator==`.)
1016///
1017/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
1018/// `NullableValue` type. Also note that this function will fail to compile
1019/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1020template <class LHS_TYPE, class RHS_TYPE>
1021bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1022 const ConstNullableValueRef<RHS_TYPE>& rhs);
1023
1024/// Return `true` if the specified `lhs` nullable wrapper is ordered after
1025/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
1026///
1027/// \note Note that this operator
1028/// returns `!(lhs < rhs)`.
1029template <class LHS_TYPE, class RHS_TYPE>
1030bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1031 const RHS_TYPE& rhs);
1032
1033/// Return `true` if the specified `lhs` is wrapper after the specified
1034/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
1035///
1036/// \note Note that this
1037/// operator returns `!(lhs < rhs)`.
1038template <class LHS_TYPE, class RHS_TYPE>
1039bool operator>=(const LHS_TYPE& lhs,
1040 const ConstNullableValueRef<RHS_TYPE>& rhs);
1041
1042 //================================
1043 // Comparisons with bsl::nullopt_t
1044 //================================
1045
1046/// Return `true` if the specified `lhs` is null, and `false` otherwise.
1047template <class TYPE>
1048bool operator==(const ConstNullableValueRef<TYPE>& lhs,
1049 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1050
1051/// Return `true` if the specified `rhs` is null, and `false` otherwise.
1052template <class TYPE>
1053bool operator==(const bsl::nullopt_t&,
1054 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
1055
1056/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
1057template <class TYPE>
1058bool operator!=(const ConstNullableValueRef<TYPE>& lhs,
1059 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1060
1061/// Return `true` if the specified `rhs` is not null, and `false`
1062/// otherwise.
1063template <class TYPE>
1064bool operator!=(const bsl::nullopt_t&,
1065 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
1066
1067/// Return `false`. `bsl::nullopt` never orders after a
1068/// `ConstNullableValueRef`.
1069template <class TYPE>
1070bool operator<(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
1072
1073/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
1074///
1075/// \note Note that `bsl::nullopt` is ordered before any `ConstNullableValueRef`
1076/// that is not null.
1077template <class TYPE>
1078bool operator<(const bsl::nullopt_t&,
1079 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
1080
1081/// Return `true` if the specified `lhs` is not null, and `false`
1082/// otherwise.
1083template <class TYPE>
1084bool operator>(const ConstNullableValueRef<TYPE>& lhs,
1085 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1086
1087/// Return `false`. `bsl::nullopt` never orders after a
1088/// `NullableValueRef`.
1089template <class TYPE>
1090bool operator>(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1092
1093/// Return `true` if the specified `lhs` is null, and `false` otherwise.
1094template <class TYPE>
1095bool operator<=(const ConstNullableValueRef<TYPE>& lhs,
1096 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1097
1098/// Return `true`.
1099template <class TYPE>
1100bool operator<=(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1102
1103/// Return `true`.
1104template <class TYPE>
1105bool operator>=(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
1107
1108/// Return `true` if the specified `rhs` is null, and `false` otherwise.
1109template <class TYPE>
1110bool operator>=(const bsl::nullopt_t&,
1111 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT;
1112
1113 //===================================================================
1114 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
1115 //===================================================================
1116
1117/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
1118/// the same value, and `false` otherwise. Two nullable wrappers have the
1119/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
1120///
1121/// \note Note that this
1122/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
1123/// compatible.
1124template <class LHS_TYPE, class RHS_TYPE>
1125bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1126 const NullableValueRef<RHS_TYPE>& rhs);
1127template <class LHS_TYPE, class RHS_TYPE>
1128bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
1129 const ConstNullableValueRef<RHS_TYPE>& rhs);
1130
1131/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
1132/// have the same value, and `false` otherwise. Two nullable wrappers do
1133/// not have the same value if one is null and the other is non-null, or if
1134/// both are non-null and the values of their underlying objects do not compare equal.
1135///
1136/// \note Note that this function will fail to compile if
1137/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
1138template <class LHS_TYPE, class RHS_TYPE>
1139bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1140 const NullableValueRef<RHS_TYPE>& rhs);
1141template <class LHS_TYPE, class RHS_TYPE>
1142bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1143 const ConstNullableValueRef<RHS_TYPE>& rhs);
1144
1145/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1146/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1147/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
1148/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
1149///
1150/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
1151/// not compatible.
1152template <class LHS_TYPE, class RHS_TYPE>
1153bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1154 const NullableValueRef<RHS_TYPE>& rhs);
1155template <class LHS_TYPE, class RHS_TYPE>
1156bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
1157 const ConstNullableValueRef<RHS_TYPE>& rhs);
1158
1159/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1160/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
1161/// value, and `false` otherwise. (See `operator<` and `operator==`.)
1162///
1163/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
1164/// are not compatible.
1165template <class LHS_TYPE, class RHS_TYPE>
1166bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1167 const NullableValueRef<RHS_TYPE>& rhs);
1168template <class LHS_TYPE, class RHS_TYPE>
1169bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1170 const ConstNullableValueRef<RHS_TYPE>& rhs);
1171
1172/// Return `true` if the specified `lhs` nullable wrapper is ordered after
1173/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1174/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
1175/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
1176///
1177/// \note Note that this operator returns `rhs < lhs` when both operands are of
1178/// `NullableValue` type. Also note that this function will fail to compile
1179/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1180template <class LHS_TYPE, class RHS_TYPE>
1181bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1182 const NullableValueRef<RHS_TYPE>& rhs);
1183template <class LHS_TYPE, class RHS_TYPE>
1184bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
1185 const ConstNullableValueRef<RHS_TYPE>& rhs);
1186
1187/// Return `true` if the specified `lhs` nullable object is ordered after
1188/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
1189/// value, and `false` otherwise. (See `operator>` and `operator==`.)
1190///
1191/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
1192/// `NullableValue` type. Also note that this function will fail to compile
1193/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1194template <class LHS_TYPE, class RHS_TYPE>
1195bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1196 const NullableValueRef<RHS_TYPE>& rhs);
1197template <class LHS_TYPE, class RHS_TYPE>
1198bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1199 const ConstNullableValueRef<RHS_TYPE>& rhs);
1200
1201} // close package namespace
1202
1203 // ----------------------------
1204 // class NullableValueRef<TYPE>
1205 // ----------------------------
1206
1207// PRIVATE ACCESSORS
1208template <class TYPE>
1209inline
1210bdlb::NullableAllocatedValue<TYPE>&
1211bdlb::NullableValueRef<TYPE>::getNAV() const
1212{
1213 BSLS_ASSERT(!hasOpt());
1214 return *static_cast<bdlb::NullableAllocatedValue<TYPE> *>(d_target_p);
1215}
1216
1217template <class TYPE>
1218inline
1221{
1222 BSLS_ASSERT(hasOpt());
1223 return *static_cast<bsl::optional<TYPE> *>(d_target_p);
1224}
1225
1226template <class TYPE>
1227inline
1229{
1230 return d_isTargetOptional;
1231}
1232
1233// CREATORS
1234template <class TYPE>
1235inline
1237: d_target_p(&opt)
1238, d_isTargetOptional(true)
1239{
1240}
1241
1242template <class TYPE>
1243inline
1245 NullableAllocatedValue<TYPE>& opt)
1246: d_target_p(&opt)
1247, d_isTargetOptional(false)
1248{
1249}
1250
1251template <class TYPE>
1252inline
1254 const NullableValueRef& original)
1255: d_target_p(original.d_target_p)
1256, d_isTargetOptional(original.d_isTargetOptional)
1257{
1258}
1259
1260// ACCESSORS
1261template <class TYPE>
1262inline
1264{
1265 return hasOpt()
1266 ? getOpt().has_value()
1267 : getNAV().has_value();
1268}
1269
1270template <class TYPE>
1271inline
1273{
1274 return !has_value();
1275}
1276
1277template <class TYPE>
1278inline
1281{
1282 return hasOpt()
1283 ? getOpt().value()
1284 : getNAV().value();
1285}
1286
1287
1288template <class TYPE>
1289inline
1292{
1293 return hasOpt()
1294 ? getOpt().operator->()
1295 : getNAV().operator->();
1296}
1297
1298template <class TYPE>
1299inline
1302{
1303 return hasOpt()
1304 ? getOpt().operator*()
1305 : getNAV().operator*();
1306}
1307
1308#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1309template <class TYPE>
1311{
1312 return has_value();
1313}
1314#endif
1315
1316template <class TYPE>
1317template <class ANY_TYPE>
1318inline
1320 const ANY_TYPE& default_value) const
1321{
1322 if (has_value()) {
1323 return hasOpt()
1324 ? getOpt().value()
1325 : getNAV().value(); // RETURN
1326 }
1327 return default_value;
1328}
1329
1330
1331// MANIPULATORS
1332#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1333// {{{ BEGIN GENERATED CODE
1334// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
1335#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
1336#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT 5
1337#endif
1338#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C
1339#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
1340#endif
1341#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 0
1342template <class TYPE>
1343inline
1345 )
1346{
1347 return hasOpt()
1348 ? getOpt().emplace()
1349 : getNAV().emplace();
1350}
1351#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 0
1352
1353#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 1
1354template <class TYPE>
1355template <class ARGS_1>
1356inline
1358 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
1359{
1360 return hasOpt()
1361 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1))
1362 : getNAV().emplace(
1363 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1364}
1365#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 1
1366
1367#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 2
1368template <class TYPE>
1369template <class ARGS_1,
1370 class ARGS_2>
1371inline
1373 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1374 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
1375{
1376 return hasOpt()
1377 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1378 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2))
1379 : getNAV().emplace(
1380 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1381 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1382}
1383#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 2
1384
1385#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 3
1386template <class TYPE>
1387template <class ARGS_1,
1388 class ARGS_2,
1389 class ARGS_3>
1390inline
1392 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1393 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1394 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
1395{
1396 return hasOpt()
1397 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1398 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1399 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3))
1400 : getNAV().emplace(
1401 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1402 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1403 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1404}
1405#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 3
1406
1407#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 4
1408template <class TYPE>
1409template <class ARGS_1,
1410 class ARGS_2,
1411 class ARGS_3,
1412 class ARGS_4>
1413inline
1415 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1416 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1417 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1418 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
1419{
1420 return hasOpt()
1421 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1422 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1423 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1424 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4))
1425 : getNAV().emplace(
1426 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1427 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1428 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1429 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1430}
1431#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 4
1432
1433#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 5
1434template <class TYPE>
1435template <class ARGS_1,
1436 class ARGS_2,
1437 class ARGS_3,
1438 class ARGS_4,
1439 class ARGS_5>
1440inline
1442 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1443 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1444 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1445 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
1446 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
1447{
1448 return hasOpt()
1449 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1450 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1451 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1452 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1453 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5))
1454 : getNAV().emplace(
1455 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1456 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1457 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1458 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1459 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1460}
1461#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_C >= 5
1462
1463#else
1464// The generated code below is a workaround for the absence of perfect
1465// forwarding in some compilers.
1466template <class TYPE>
1467template <class... ARGS>
1468inline
1471{
1472 return hasOpt()
1473 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...)
1474 : getNAV().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1475}
1476// }}} END GENERATED CODE
1477#endif
1478
1479template <class TYPE>
1480inline
1483{
1484 return hasOpt()
1485 ? getOpt().operator->()
1486 : getNAV().operator->();
1487}
1488
1489template <class TYPE>
1490inline
1493{
1494 return hasOpt()
1495 ? getOpt().operator*()
1496 : getNAV().operator*();
1497}
1498
1499template <class TYPE>
1500inline
1503{
1504 reset();
1505 return *this;
1506}
1507
1508template <class TYPE>
1509inline
1512{
1513 if (hasOpt()) {
1514 getOpt() = rhs;
1515 }
1516 else {
1517 getNAV() = rhs;
1518 }
1519
1520 return *this;
1521}
1522
1523template <class TYPE>
1524inline
1527{
1528 if (rhs.has_value()) {
1529 *this = rhs.value();
1530 }
1531 else {
1532 reset();
1533 }
1534 return *this;
1535}
1536
1537template <class TYPE>
1538inline
1541 const NullableAllocatedValue<TYPE>& rhs)
1542{
1543 if (rhs.has_value()) {
1544 *this = rhs.value();
1545 }
1546 else {
1547 reset();
1548 }
1549
1550 return *this;
1551}
1552
1553template <class TYPE>
1554inline
1556bdlb::NullableValueRef<TYPE>::operator=(const NullableValueRef& rhs)
1557{
1558 if (rhs.has_value()) {
1559 *this = rhs.value();
1560 }
1561 else {
1562 reset();
1563 }
1564
1565 return *this;
1566}
1567
1568template <class TYPE>
1569inline
1571{
1572 if (hasOpt()) {
1573 getOpt().reset();
1574 }
1575 else {
1576 getNAV().reset();
1577 }
1578}
1579
1580template <class TYPE>
1581inline
1584{
1585 return hasOpt()
1586 ? getOpt().value()
1587 : getNAV().value();
1588}
1589
1590// DEPRECATED FUNCTIONS
1591template <class TYPE>
1592inline
1593const TYPE *
1594bdlb::NullableValueRef<TYPE>::addressOr(const TYPE *address) const
1595{
1596 return has_value() ? &value() : address;
1597}
1598
1599#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1600// {{{ BEGIN GENERATED CODE
1601// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
1602#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
1603#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT 5
1604#endif
1605#ifndef BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D
1606#define BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT
1607#endif
1608#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 0
1609template <class TYPE>
1610inline
1612 )
1613{
1614 return emplace();
1615}
1616#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 0
1617
1618#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 1
1619template <class TYPE>
1620template <class ARGS_1>
1621inline
1623 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
1624{
1625 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1626}
1627#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 1
1628
1629#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 2
1630template <class TYPE>
1631template <class ARGS_1,
1632 class ARGS_2>
1633inline
1635 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1636 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
1637{
1638 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1639 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1640}
1641#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 2
1642
1643#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 3
1644template <class TYPE>
1645template <class ARGS_1,
1646 class ARGS_2,
1647 class ARGS_3>
1648inline
1650 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1651 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1652 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
1653{
1654 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1655 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1656 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1657}
1658#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 3
1659
1660#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 4
1661template <class TYPE>
1662template <class ARGS_1,
1663 class ARGS_2,
1664 class ARGS_3,
1665 class ARGS_4>
1666inline
1668 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1669 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1670 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1671 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
1672{
1673 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1674 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1675 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1676 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1677}
1678#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 4
1679
1680#if BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 5
1681template <class TYPE>
1682template <class ARGS_1,
1683 class ARGS_2,
1684 class ARGS_3,
1685 class ARGS_4,
1686 class ARGS_5>
1687inline
1689 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1690 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1691 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1692 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
1693 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
1694{
1695 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1696 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1697 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1698 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1699 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1700}
1701#endif // BDLB_NULLABLEVALUEREF_VARIADIC_LIMIT_D >= 5
1702
1703#else
1704// The generated code below is a workaround for the absence of perfect
1705// forwarding in some compilers.
1706template <class TYPE>
1707template <class... ARGS>
1708inline
1711{
1712 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1713}
1714// }}} END GENERATED CODE
1715#endif
1716
1717template <class TYPE>
1718inline
1719TYPE bdlb::NullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
1720{
1721 return value_or(otherValue);
1722}
1723
1724template <class TYPE>
1725inline
1727{
1728 return has_value() ? &value() : 0;
1729}
1730
1731// FREE FUNCTIONS
1732template <class HASHALG, class TYPE>
1733void bdlb::hashAppend(HASHALG& hashAlg,
1734 const NullableValueRef<TYPE>& input)
1735{
1736 using ::BloombergLP::bslh::hashAppend;
1737
1738 if (!input.has_value()) {
1739 hashAppend(hashAlg, false);
1740 }
1741 else {
1742 hashAppend(hashAlg, true);
1743 hashAppend(hashAlg, input.value());
1744 }
1745}
1746
1747// FREE OPERATORS
1748template <class LHS_TYPE, class RHS_TYPE>
1749inline
1750bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1751 const NullableValueRef<RHS_TYPE>& rhs)
1752{
1753 if (lhs.has_value()) {
1754 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
1755 }
1756
1757 return !rhs.has_value();
1758}
1759
1760template <class LHS_TYPE, class RHS_TYPE>
1761inline
1762bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1763 const RHS_TYPE& rhs)
1764{
1765 return lhs.has_value() ? lhs.value() == rhs : false;
1766}
1767
1768template <class LHS_TYPE, class RHS_TYPE>
1769inline
1770bool bdlb::operator==(const LHS_TYPE& lhs,
1771 const NullableValueRef<RHS_TYPE>& rhs)
1772{
1773 return rhs.has_value() ? lhs == rhs.value(): false;
1774}
1775
1776template <class LHS_TYPE, class RHS_TYPE>
1777inline
1778bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1779 const NullableValueRef<RHS_TYPE>& rhs)
1780{
1781 if (lhs.has_value()) {
1782 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
1783 }
1784
1785 return rhs.has_value();
1786}
1787
1788template <class LHS_TYPE, class RHS_TYPE>
1789inline
1790bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1791 const RHS_TYPE& rhs)
1792{
1793 return lhs.has_value() ? lhs.value() != rhs : true;
1794}
1795
1796template <class LHS_TYPE, class RHS_TYPE>
1797inline
1798bool bdlb::operator!=(const LHS_TYPE& lhs,
1799 const NullableValueRef<RHS_TYPE>& rhs)
1800{
1801 return rhs.has_value() ? lhs != rhs.value() : true;
1802}
1803
1804template <class LHS_TYPE, class RHS_TYPE>
1805inline
1806bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1807 const NullableValueRef<RHS_TYPE>& rhs)
1808{
1809 if (!rhs.has_value()) {
1810 return false; // RETURN
1811 }
1812
1813 return lhs.has_value() ? lhs.value() < rhs.value() : true;
1814}
1815
1816template <class LHS_TYPE, class RHS_TYPE>
1817inline
1818bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1819 const RHS_TYPE& rhs)
1820{
1821 return lhs.has_value() ? lhs.value() < rhs : true;
1822}
1823
1824template <class LHS_TYPE, class RHS_TYPE>
1825inline
1826bool bdlb::operator<(const LHS_TYPE& lhs,
1827 const NullableValueRef<RHS_TYPE>& rhs)
1828{
1829 return rhs.has_value() ? lhs < rhs.value() : false;
1830}
1831
1832template <class LHS_TYPE, class RHS_TYPE>
1833inline
1834bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1835 const NullableValueRef<RHS_TYPE>& rhs)
1836{
1837 if (!lhs.has_value()) {
1838 return true; // RETURN
1839 }
1840
1841 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
1842}
1843
1844template <class LHS_TYPE, class RHS_TYPE>
1845inline
1846bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1847 const RHS_TYPE& rhs)
1848{
1849 return lhs.has_value() ? lhs.value() <= rhs : true;
1850}
1851
1852template <class LHS_TYPE, class RHS_TYPE>
1853inline
1854bool bdlb::operator<=(const LHS_TYPE& lhs,
1855 const NullableValueRef<RHS_TYPE>& rhs)
1856{
1857 return rhs.has_value() ? lhs <= rhs.value() : false;
1858}
1859
1860template <class LHS_TYPE, class RHS_TYPE>
1861inline
1862bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1863 const NullableValueRef<RHS_TYPE>& rhs)
1864{
1865 if (!lhs.has_value()) {
1866 return false; // RETURN
1867 }
1868
1869 return rhs.has_value() ? lhs.value() > rhs.value() : true;
1870}
1871
1872template <class LHS_TYPE, class RHS_TYPE>
1873inline
1874bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1875 const RHS_TYPE& rhs)
1876{
1877 return lhs.has_value() ? lhs.value() > rhs : false;
1878}
1879
1880template <class LHS_TYPE, class RHS_TYPE>
1881inline
1882bool bdlb::operator>(const LHS_TYPE& lhs,
1883 const NullableValueRef<RHS_TYPE>& rhs)
1884{
1885 return rhs.has_value() ? lhs > rhs.value() : true;
1886}
1887
1888template <class LHS_TYPE, class RHS_TYPE>
1889inline
1890bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1891 const NullableValueRef<RHS_TYPE>& rhs)
1892{
1893 if (!rhs.has_value()) {
1894 return true; // RETURN
1895 }
1896
1897 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
1898}
1899
1900template <class LHS_TYPE, class RHS_TYPE>
1901inline
1902bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1903 const RHS_TYPE& rhs)
1904{
1905 return lhs.has_value() ? lhs.value() >= rhs : false;
1906}
1907
1908template <class LHS_TYPE, class RHS_TYPE>
1909inline
1910bool bdlb::operator>=(const LHS_TYPE& lhs,
1911 const NullableValueRef<RHS_TYPE>& rhs)
1912{
1913 return rhs.has_value() ? lhs >= rhs.value() : true;
1914}
1915
1916 //--------------------------------
1917 // Comparisons with bsl::nullopt_t
1918 //--------------------------------
1919
1920template <class TYPE>
1921inline
1922bool bdlb::operator==(const NullableValueRef<TYPE>& lhs,
1924{
1925 return !lhs.has_value();
1926}
1927
1928template <class TYPE>
1929inline
1930bool bdlb::operator==(
1931 const bsl::nullopt_t&,
1932 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1933{
1934 return !rhs.has_value();
1935}
1936
1937template <class TYPE>
1938inline bool bdlb::operator!=(const NullableValueRef<TYPE>& lhs,
1940{
1941 return lhs.has_value();
1942}
1943
1944template <class TYPE>
1945inline
1946bool bdlb::operator!=(
1947 const bsl::nullopt_t&,
1948 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1949{
1950 return rhs.has_value();
1951}
1952
1953template <class TYPE>
1954inline
1955bool bdlb::operator<(const NullableValueRef<TYPE>&,
1957{
1958 return false;
1959}
1960
1961template <class TYPE>
1962inline
1963bool bdlb::operator<(
1964 const bsl::nullopt_t&,
1965 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1966{
1967 return rhs.has_value();
1968}
1969
1970template <class TYPE>
1971inline
1972bool bdlb::operator>(const NullableValueRef<TYPE>& lhs,
1974{
1975 return lhs.has_value();
1976}
1977
1978template <class TYPE>
1979inline
1981 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1982{
1983 return false;
1984}
1985
1986template <class TYPE>
1987inline
1988bool bdlb::operator<=(const NullableValueRef<TYPE>& lhs,
1990{
1991 return !lhs.has_value();
1992}
1993
1994template <class TYPE>
1995inline
1996bool bdlb::operator<=(
1997 const bsl::nullopt_t&,
1998 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1999{
2000 return true;
2001}
2002
2003template <class TYPE>
2004inline
2005bool bdlb::operator>=(const NullableValueRef<TYPE>&,
2007{
2008 return true;
2009}
2010
2011template <class TYPE>
2012inline
2013bool bdlb::operator>=(
2014 const bsl::nullopt_t&,
2015 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2016{
2017 return !rhs.has_value();
2018}
2019
2020 // ---------------------------------
2021 // class ConstNullableValueRef<TYPE>
2022 // ---------------------------------
2023
2024// PRIVATE ACCESSORS
2025template <class TYPE>
2026inline
2029{
2030 BSLS_ASSERT(!hasOpt());
2031 return *static_cast<const NullableAllocatedValue<value_type> *>(
2032 d_target_p);
2033}
2034
2035template <class TYPE>
2036inline
2039{
2040 BSLS_ASSERT(hasOpt());
2041 return *static_cast<const bsl::optional<value_type> *>(d_target_p);
2042}
2043
2044template <class TYPE>
2045inline
2047{
2048 return d_isTargetOptional;
2049}
2050
2051// CREATORS
2052template <class TYPE>
2053inline
2055 const bsl::optional<TYPE>& opt)
2056: d_target_p(&opt)
2057, d_isTargetOptional(true)
2058{
2059}
2060
2061template <class TYPE>
2062inline
2064 const NullableAllocatedValue<TYPE>& opt)
2065: d_target_p(&opt)
2066, d_isTargetOptional(false)
2067{
2068}
2069
2070template <class TYPE>
2071inline
2073 const NullableValueRef<TYPE>& ref)
2074: d_target_p(ref.d_target_p)
2075, d_isTargetOptional(ref.d_isTargetOptional)
2076{
2077}
2078
2079template <class TYPE>
2080inline
2082 const ConstNullableValueRef& original)
2083: d_target_p(original.d_target_p)
2084, d_isTargetOptional(original.d_isTargetOptional)
2085{
2086}
2087
2088// ACCESSORS
2089template <class TYPE>
2090inline
2091bool
2093{
2094 return hasOpt()
2095 ? getOpt().has_value()
2096 : getNAV().has_value();
2097}
2098
2099template <class TYPE>
2100inline
2101bool
2103{
2104 return !has_value();
2105}
2106
2107template <class TYPE>
2108inline
2111{
2112 return hasOpt()
2113 ? getOpt().value()
2114 : getNAV().value();
2115}
2116
2117
2118template <class TYPE>
2119inline
2122{
2123 return hasOpt()
2124 ? getOpt().operator->()
2125 : getNAV().operator->();
2126}
2127
2128template <class TYPE>
2129inline
2132{
2133 return hasOpt()
2134 ? getOpt().operator*()
2135 : getNAV().operator*();
2136}
2137
2138#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
2139template <class TYPE>
2141{
2142 return has_value();
2143}
2144#endif
2145
2146template <class TYPE>
2147template <class ANY_TYPE>
2148inline
2150 const ANY_TYPE& default_value) const
2151{
2152 if (has_value()) {
2153 return hasOpt()
2154 ? getOpt().value()
2155 : getNAV().value(); // RETURN
2156 }
2157 return default_value;
2158}
2159
2160// DEPRECATED FUNCTIONS
2161template <class TYPE>
2162inline
2163const TYPE *
2164bdlb::ConstNullableValueRef<TYPE>::addressOr(const TYPE *address) const
2165{
2166 return has_value() ? &value() : address;
2167}
2168
2169template <class TYPE>
2170inline
2171TYPE
2172bdlb::ConstNullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
2173{
2174 return value_or(otherValue);
2175}
2176
2177template <class TYPE>
2178inline
2180{
2181 return has_value() ? &value() : 0;
2182}
2183
2184// FREE FUNCTIONS
2185template <class HASHALG, class TYPE>
2186void bdlb::hashAppend(HASHALG& hashAlg,
2187 const ConstNullableValueRef<TYPE>& input)
2188{
2189 using ::BloombergLP::bslh::hashAppend;
2190
2191 if (!input.has_value()) {
2192 hashAppend(hashAlg, false);
2193 }
2194 else {
2195 hashAppend(hashAlg, true);
2196 hashAppend(hashAlg, input.value());
2197 }
2198}
2199
2200// FREE OPERATORS
2201template <class LHS_TYPE, class RHS_TYPE>
2202inline
2203bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
2204 const ConstNullableValueRef<RHS_TYPE>& rhs)
2205{
2206 if (lhs.has_value()) {
2207 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2208 }
2209
2210 return !rhs.has_value();
2211}
2212
2213template <class LHS_TYPE, class RHS_TYPE>
2214inline
2215bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
2216 const RHS_TYPE& rhs)
2217{
2218 return lhs.has_value() ? lhs.value() == rhs : false;
2219}
2220
2221template <class LHS_TYPE, class RHS_TYPE>
2222inline
2223bool bdlb::operator==(const LHS_TYPE& lhs,
2224 const ConstNullableValueRef<RHS_TYPE>& rhs)
2225{
2226 return rhs.has_value() ? lhs == rhs.value(): false;
2227}
2228
2229template <class LHS_TYPE, class RHS_TYPE>
2230inline
2231bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2232 const ConstNullableValueRef<RHS_TYPE>& rhs)
2233{
2234 if (lhs.has_value()) {
2235 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2236 }
2237
2238 return rhs.has_value();
2239}
2240
2241template <class LHS_TYPE, class RHS_TYPE>
2242inline
2243bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2244 const RHS_TYPE& rhs)
2245{
2246 return lhs.has_value() ? lhs.value() != rhs : true;
2247}
2248
2249template <class LHS_TYPE, class RHS_TYPE>
2250inline
2251bool bdlb::operator!=(const LHS_TYPE& lhs,
2252 const ConstNullableValueRef<RHS_TYPE>& rhs)
2253{
2254 return rhs.has_value() ? lhs != rhs.value() : true;
2255}
2256
2257template <class LHS_TYPE, class RHS_TYPE>
2258inline
2259bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
2260 const ConstNullableValueRef<RHS_TYPE>& rhs)
2261{
2262 if (!rhs.has_value()) {
2263 return false; // RETURN
2264 }
2265
2266 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2267}
2268
2269template <class LHS_TYPE, class RHS_TYPE>
2270inline
2271bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
2272 const RHS_TYPE& rhs)
2273{
2274 return lhs.has_value() ? lhs.value() < rhs : true;
2275}
2276
2277template <class LHS_TYPE, class RHS_TYPE>
2278inline
2279bool bdlb::operator<(const LHS_TYPE& lhs,
2280 const ConstNullableValueRef<RHS_TYPE>& rhs)
2281{
2282 return rhs.has_value() ? lhs < rhs.value() : false;
2283}
2284
2285template <class LHS_TYPE, class RHS_TYPE>
2286inline
2287bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2288 const ConstNullableValueRef<RHS_TYPE>& rhs)
2289{
2290 if (!lhs.has_value()) {
2291 return true; // RETURN
2292 }
2293
2294 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2295}
2296
2297template <class LHS_TYPE, class RHS_TYPE>
2298inline
2299bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2300 const RHS_TYPE& rhs)
2301{
2302 return lhs.has_value() ? lhs.value() <= rhs : true;
2303}
2304
2305template <class LHS_TYPE, class RHS_TYPE>
2306inline
2307bool bdlb::operator<=(const LHS_TYPE& lhs,
2308 const ConstNullableValueRef<RHS_TYPE>& rhs)
2309{
2310 return rhs.has_value() ? lhs <= rhs.value() : false;
2311}
2312
2313template <class LHS_TYPE, class RHS_TYPE>
2314inline
2315bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2316 const ConstNullableValueRef<RHS_TYPE>& rhs)
2317{
2318 if (!lhs.has_value()) {
2319 return false; // RETURN
2320 }
2321
2322 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2323}
2324
2325template <class LHS_TYPE, class RHS_TYPE>
2326inline
2327bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2328 const RHS_TYPE& rhs)
2329{
2330 return lhs.has_value() ? lhs.value() > rhs : false;
2331}
2332
2333template <class LHS_TYPE, class RHS_TYPE>
2334inline
2335bool bdlb::operator>(const LHS_TYPE& lhs,
2336 const ConstNullableValueRef<RHS_TYPE>& rhs)
2337{
2338 return rhs.has_value() ? lhs > rhs.value() : true;
2339}
2340
2341template <class LHS_TYPE, class RHS_TYPE>
2342inline
2343bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2344 const ConstNullableValueRef<RHS_TYPE>& rhs)
2345{
2346 if (!rhs.has_value()) {
2347 return true; // RETURN
2348 }
2349
2350 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2351}
2352
2353template <class LHS_TYPE, class RHS_TYPE>
2354inline
2355bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2356 const RHS_TYPE& rhs)
2357{
2358 return lhs.has_value() ? lhs.value() >= rhs : false;
2359}
2360
2361template <class LHS_TYPE, class RHS_TYPE>
2362inline
2363bool bdlb::operator>=(const LHS_TYPE& lhs,
2364 const ConstNullableValueRef<RHS_TYPE>& rhs)
2365{
2366 return rhs.has_value() ? lhs >= rhs.value() : true;
2367}
2368
2369 //--------------------------------
2370 // Comparisons with bsl::nullopt_t
2371 //--------------------------------
2372
2373template <class TYPE>
2374inline
2375bool bdlb::operator==(const ConstNullableValueRef<TYPE>& lhs,
2377{
2378 return !lhs.has_value();
2379}
2380
2381template <class TYPE>
2382inline
2383bool bdlb::operator==(
2384 const bsl::nullopt_t&,
2385 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2386{
2387 return !rhs.has_value();
2388}
2389
2390template <class TYPE>
2391inline bool bdlb::operator!=(const ConstNullableValueRef<TYPE>& lhs,
2393{
2394 return lhs.has_value();
2395}
2396
2397template <class TYPE>
2398inline
2399bool bdlb::operator!=(
2400 const bsl::nullopt_t&,
2401 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2402{
2403 return rhs.has_value();
2404}
2405
2406template <class TYPE>
2407inline
2408bool bdlb::operator<(const ConstNullableValueRef<TYPE>&,
2410{
2411 return false;
2412}
2413
2414template <class TYPE>
2415inline
2416bool bdlb::operator<(
2417 const bsl::nullopt_t&,
2418 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2419{
2420 return rhs.has_value();
2421}
2422
2423template <class TYPE>
2424inline
2425bool bdlb::operator>(const ConstNullableValueRef<TYPE>& lhs,
2427{
2428 return lhs.has_value();
2429}
2430
2431template <class TYPE>
2432inline
2433bool bdlb::operator>(
2434 const bsl::nullopt_t&,
2435 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2436{
2437 return false;
2438}
2439
2440template <class TYPE>
2441inline
2442bool bdlb::operator<=(const ConstNullableValueRef<TYPE>& lhs,
2444{
2445 return !lhs.has_value();
2446}
2447
2448template <class TYPE>
2449inline
2450bool bdlb::operator<=(
2451 const bsl::nullopt_t&,
2452 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2453{
2454 return true;
2455}
2456
2457template <class TYPE>
2458inline
2459bool bdlb::operator>=(const ConstNullableValueRef<TYPE>&,
2461{
2462 return true;
2463}
2464
2465template <class TYPE>
2466inline
2467bool bdlb::operator>=(
2468 const bsl::nullopt_t&,
2469 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2470{
2471 return !rhs.has_value();
2472}
2473
2474 //-------------------------------------------------------------------
2475 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
2476 //-------------------------------------------------------------------
2477
2478template <class LHS_TYPE, class RHS_TYPE>
2479inline
2480bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
2481 const NullableValueRef<RHS_TYPE>& rhs)
2482{
2483 if (lhs.has_value()) {
2484 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2485 }
2486
2487 return !rhs.has_value();
2488}
2489
2490template <class LHS_TYPE, class RHS_TYPE>
2491inline
2492bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
2493 const ConstNullableValueRef<RHS_TYPE>& rhs)
2494{
2495 if (lhs.has_value()) {
2496 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2497 }
2498
2499 return !rhs.has_value();
2500}
2501
2502template <class LHS_TYPE, class RHS_TYPE>
2503inline
2504bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2505 const NullableValueRef<RHS_TYPE>& rhs)
2506{
2507 if (lhs.has_value()) {
2508 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2509 }
2510
2511 return rhs.has_value();
2512}
2513
2514template <class LHS_TYPE, class RHS_TYPE>
2515inline
2516bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
2517 const ConstNullableValueRef<RHS_TYPE>& rhs)
2518{
2519 if (lhs.has_value()) {
2520 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2521 }
2522
2523 return rhs.has_value();
2524}
2525
2526template <class LHS_TYPE, class RHS_TYPE>
2527inline
2528bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
2529 const NullableValueRef<RHS_TYPE>& rhs)
2530{
2531 if (!rhs.has_value()) {
2532 return false; // RETURN
2533 }
2534
2535 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2536}
2537
2538template <class LHS_TYPE, class RHS_TYPE>
2539inline
2540bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
2541 const ConstNullableValueRef<RHS_TYPE>& rhs)
2542{
2543 if (!rhs.has_value()) {
2544 return false; // RETURN
2545 }
2546
2547 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2548}
2549
2550template <class LHS_TYPE, class RHS_TYPE>
2551inline
2552bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2553 const NullableValueRef<RHS_TYPE>& rhs)
2554{
2555 if (!lhs.has_value()) {
2556 return true; // RETURN
2557 }
2558
2559 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2560}
2561
2562template <class LHS_TYPE, class RHS_TYPE>
2563inline
2564bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
2565 const ConstNullableValueRef<RHS_TYPE>& rhs)
2566{
2567 if (!lhs.has_value()) {
2568 return true; // RETURN
2569 }
2570
2571 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2572}
2573
2574template <class LHS_TYPE, class RHS_TYPE>
2575inline
2576bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2577 const NullableValueRef<RHS_TYPE>& rhs)
2578{
2579 if (!lhs.has_value()) {
2580 return false; // RETURN
2581 }
2582
2583 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2584}
2585
2586template <class LHS_TYPE, class RHS_TYPE>
2587inline
2588bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
2589 const ConstNullableValueRef<RHS_TYPE>& rhs)
2590{
2591 if (!lhs.has_value()) {
2592 return false; // RETURN
2593 }
2594
2595 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2596}
2597
2598template <class LHS_TYPE, class RHS_TYPE>
2599inline
2600bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2601 const NullableValueRef<RHS_TYPE>& rhs)
2602{
2603 if (!rhs.has_value()) {
2604 return true; // RETURN
2605 }
2606
2607 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2608}
2609
2610template <class LHS_TYPE, class RHS_TYPE>
2611inline
2612bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
2613 const ConstNullableValueRef<RHS_TYPE>& rhs)
2614{
2615 if (!rhs.has_value()) {
2616 return true; // RETURN
2617 }
2618
2619 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2620}
2621
2622
2623
2624#else // if ! defined(DEFINED_BDLB_NULLABLEVALUEREF_H)
2625# error Not valid except when included from bdlb_nullablevalueref.h
2626#endif // ! defined(COMPILING_BDLB_NULLABLEVALUEREF_H)
2627
2628#endif // ! defined(INCLUDED_BDLB_NULLABLEVALUEREF_CPP03)
2629
2630// ----------------------------------------------------------------------------
2631// Copyright 2023 Bloomberg Finance L.P.
2632//
2633// Licensed under the Apache License, Version 2.0 (the "License");
2634// you may not use this file except in compliance with the License.
2635// You may obtain a copy of the License at
2636//
2637// http://www.apache.org/licenses/LICENSE-2.0
2638//
2639// Unless required by applicable law or agreed to in writing, software
2640// distributed under the License is distributed on an "AS IS" BASIS,
2641// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2642// See the License for the specific language governing permissions and
2643// limitations under the License.
2644// ----------------------------- END-OF-FILE ----------------------------------
2645
2646/** @} */
2647/** @} */
2648/** @} */
Definition bdlb_nullablevalueref.h:671
TYPE value_type
Definition bdlb_nullablevalueref.h:726
Definition bdlb_nullableallocatedvalue.h:180
Definition bdlb_nullablevalueref.h:169
TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)...)
TYPE value_type
Definition bdlb_nullablevalueref.h:228
Definition bslstl_optional.h:2043
TYPE value_or(const ANY_TYPE &default_value) const
Definition bdlb_nullablevalueref.h:1294
void reset()
Definition bdlb_nullablevalueref.h:1411
TYPE value_or(const ANY_TYPE &default_value) const
Definition bdlb_nullablevalueref.h:1882
const value_type * operator->() const
Definition bdlb_nullablevalueref.h:1266
const value_type * operator->() const
Definition bdlb_nullablevalueref.h:1854
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return true if the target contains a value, and false otherwise.
Definition bdlb_nullablevalueref.h:1238
NullableValueRef(bsl::optional< TYPE > &opt)
Definition bdlb_nullablevalueref.h:1211
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return true if the target contains a value, and false otherwise.
Definition bdlb_nullablevalueref.h:1825
const value_type & operator*() const
Definition bdlb_nullablevalueref.h:1864
const value_type & value() const
Definition bdlb_nullablevalueref.h:1255
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullablevalueref.h:1247
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullablevalueref.h:1835
const value_type & operator*() const
Definition bdlb_nullablevalueref.h:1276
NullableValueRef< TYPE > & operator=(const bsl::nullopt_t &)
Definition bdlb_nullablevalueref.h:1343
ConstNullableValueRef(const bsl::optional< TYPE > &opt)
Definition bdlb_nullablevalueref.h:1787
const value_type & value() const
Definition bdlb_nullablevalueref.h:1843
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#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_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:387
#define BSLS_NOTHROW_SPEC
Definition bsls_exceptionutil.h:386
#define BSLS_KEYWORD_EXPLICIT
Definition bsls_keyword.h:683
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
void reset(TYPE *object)
Reset the value of the specified object to its default value.
Definition bdlb_algorithmworkaroundutil.h:74
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
bool operator>=(const Guid &lhs, const Guid &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
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
reference_wrapper< T > ref(T &object)
Return a reference wrapper that represents the specified object.
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition bslmf_issame.h:146
Definition bslstl_optional.h:522