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