BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_nullablevalueref.h
Go to the documentation of this file.
1/// @file bdlb_nullablevalueref.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullablevalueref.h -*-C++-*-
8
9#ifndef INCLUDED_BDLB_NULLABLEVALUEREF
10#define INCLUDED_BDLB_NULLABLEVALUEREF
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bdlb_nullablevalueref bdlb_nullablevalueref
16/// @brief *Tech* *preview* for non-owning reference to nullable objects.
17/// @addtogroup bdl
18/// @{
19/// @addtogroup bdlb
20/// @{
21/// @addtogroup bdlb_nullablevalueref
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bdlb_nullablevalueref-purpose"> Purpose</a>
26/// * <a href="#bdlb_nullablevalueref-classes"> Classes </a>
27/// * <a href="#bdlb_nullablevalueref-description"> Description </a>
28/// * <a href="#bdlb_nullablevalueref-ownership-and-lifetime"> Ownership and Lifetime </a>
29/// * <a href="#bdlb_nullablevalueref-usage"> Usage </a>
30/// * <a href="#bdlb_nullablevalueref-example-1-migrating-from-nullablevalue-to-nullableallocatedvalue"> Example 1: Migrating from NullableValue to NullableAllocatedValue </a>
31///
32/// # Purpose {#bdlb_nullablevalueref-purpose}
33/// *Tech* *preview* for non-owning reference to nullable objects.
34///
35/// # Classes {#bdlb_nullablevalueref-classes}
36///
37/// - NullableValueRef: template for modifiable reference to nullable object
38/// - ConstNullableValueRef: template for const reference to nullable object
39///
40/// @see NullableAllocatedValue, bsl::optional, NullableValue
41///
42/// # Description {#bdlb_nullablevalueref-description}
43/// *This* *component* *is* *a* *technology* *preview* and subject
44/// to change. It is provided for evaluation purposes only and should not be
45/// used in a production setting. It provides two template classes,
46/// `bdlb::NullableValueRef<TYPE>` and `bdlb::ConstNullableValueRef<TYPE>`, that
47/// hold a reference to a either a `bdlb::NullableValue` or a
48/// `bdlb::NullableAllocatedValue`, and provide a common interface for dealing
49/// with the referenced object. Once constructed, the "ref" object is not
50/// `re-targetable`, i. e, it cannot be changed to refer to a different nullable
51/// object (the `target`). However, in the case of `NullableValueRef`, the
52/// value that is contained by the target can be changed, cleared, created and
53/// so on.
54///
55/// Neither a `NullableValueRef` nor a `ConstNullableValueRef` owns the target
56/// that it refers to. They do not allocate the value upon construction; they
57/// store a pointer to an already existing nullable value.
58///
59/// ## Ownership and Lifetime {#bdlb_nullablevalueref-ownership-and-lifetime}
60///
61///
62/// Since the NullableValueRef does not own the value that it refers to, the
63/// user must ensure that the value's lifetime does not end before the
64/// NullableValueRef.
65///
66/// ## Usage {#bdlb_nullablevalueref-usage}
67///
68///
69/// The following snippets of code illustrate use of this component.
70///
71/// ### Example 1: Migrating from NullableValue to NullableAllocatedValue {#bdlb_nullablevalueref-example-1-migrating-from-nullablevalue-to-nullableallocatedvalue}
72///
73///
74/// Suppose we have a data structure that contains optional data members that
75/// are implemented with `NullableValue`, and client code that uses them. Now
76/// we want to change the data structure to use `NullableAllocatedValue`, but
77/// without requiring simultaneous changes to the client code. If the client
78/// code uses `NullableValueRef` to access the optional values, the change will
79/// not require any source changes in the clients; a recompile is sufficient.
80///
81/// Given the following functions:
82/// @code
83/// /// Return a reference to a NullableValue for processing
84/// bsl::optional<int> &getOpt()
85/// {
86/// static bdlb::NullableValue<int> nv(23);
87/// return nv;
88/// }
89///
90/// bdlb::NullableAllocatedValue<int> &getNAV()
91/// // Return a reference to a NullableAllocatedValue for processing
92/// {
93/// static bdlb::NullableAllocatedValue<int> nav(34);
94/// return nav;
95/// }
96/// @endcode
97/// We can wrap both of these types into a wrapper, and then treat them
98/// identically.
99/// @code
100/// bdlb::NullableValueRef<int> r1 = getOpt();
101/// bdlb::NullableValueRef<int> r2 = getNAV();
102///
103/// assert(23 == r1.value());
104/// assert(34 == r2.value());
105/// @endcode
106/// @}
107/** @} */
108/** @} */
109
110/** @addtogroup bdl
111 * @{
112 */
113/** @addtogroup bdlb
114 * @{
115 */
116/** @addtogroup bdlb_nullablevalueref
117 * @{
118 */
119
120#include <bdlscm_version.h>
121
122#include <bdlb_nullableallocatedvalue.h> // NullableAllocatedValue
123
124#include <bslmf_assert.h>
125#include <bslmf_issame.h>
126#include <bslmf_removecv.h>
127
128#include <bsls_deprecate.h>
130
131#include <bsls_assert.h>
133#include <bsls_keyword.h>
134#include <bsls_unspecifiedbool.h>
135
136#include <bslstl_optional.h> // bsl::optional, bsl::nullopt_t
137
138#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
139// Include version that can be compiled with C++03
140// Generated on Fri Sep 15 15:38:58 2023
141// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
142# define COMPILING_BDLB_NULLABLEVALUEREF_H
144# undef COMPILING_BDLB_NULLABLEVALUEREF_H
145#else
146
147
148namespace bdlb {
149
150template <class TYPE>
151class ConstNullableValueRef;
152
153 // ============================
154 // class NullableValueRef<TYPE>
155 // ============================
156
157/// This class is a wrapper for either a `bsl::optional` or
158/// `NullableAllocatedValue`, and provides modifiable access to the wrapped
159/// object.
160///
161/// See @ref bdlb_nullablevalueref
162template <class TYPE>
164
165 // PRIVATE TYPES
166#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
167 // UNSPECIFIED BOOL
168
169 /// This type is needed only in C++03 mode, where `explicit` conversion
170 /// operators are not supported. A `NullableAllocatedValue` is implicitly
171 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
172 /// implicitly convertible to `bool`.
173 typedef BloombergLP::bsls::UnspecifiedBool<NullableValueRef>
174 UnspecifiedBoolUtil;
175 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
176#endif
177
178 // DATA
179
180 // the address of the target
181 void *d_target_p;
182
183 // `true` if the target is a specialization of `bsl::optional`, and
184 // `false` it's a specialization of `NullableAllocatedValue`
185 bool d_isTargetOptional;
186
187 // PRIVATE ACCESSORS
188
189 /// Return a reference providing non-const access to the held
190 /// `NullableAllocatedValue` object. The behavior is undefined if the
191 /// target is not a `NullableAllocatedValue`.
192 NullableAllocatedValue<TYPE>& getNAV() const;
193
194 /// Return a reference providing non-const access to the held
195 /// `bsl::optional` object. The behavior is undefined if the target is
196 /// not a `bdlb::bsl::optional`.
197 bsl::optional<TYPE>& getOpt() const;
198
199 /// Return `true` if the target of this object is a `bsl::optional`, and
200 /// `false` otherwise.
201 bool hasOpt() const;
202
203 // FRIENDS
204 friend class ConstNullableValueRef<TYPE>;
205
206 // TRAITS
207
208 // This class requires that `TYPE` is not `const`- or `volatile`-
209 // qualified, nor a reference.
211 bsl::is_same<TYPE,
213
214 public:
215 // TYPES
216
217 /// `value_type` is an alias for the template parameter `TYPE`, and
218 /// represents the type of the object managed by the wrapped nullable
219 /// object.
220 typedef TYPE value_type;
221
222 // CREATORS
223
224 /// Create a nullable object wrapper that refers to the specified `opt`
225 /// object. Note that the created wrapper does not own a copy of the
226 /// underlying nullable value, but instead refers to it, and so the
227 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
228 NullableValueRef(bsl::optional<TYPE>& opt); // IMPLICIT
229
230 /// Create a nullable object wrapper that refers to the specified `opt`
231 /// object. Note that the created wrapper does not own a copy of the
232 /// underlying nullable value, but instead refers to it, and so the
233 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
235
236 /// Create a nullable object wrapper that refers to the target object of
237 /// the specified `original` wrapper. Note that the created wrapper
238 /// does not own a copy of the underlying nullable value, but instead
239 /// refers to it, and so the lifetime of the target must exceed the
240 /// lifetime of the created wrapper.
241 NullableValueRef(const NullableValueRef& original);
242
243 /// Destroy this object. Note that this destructor is generated by the
244 /// compiler, and does not destroy the target.
246
247 // ACCESSORS
248
249 /// Return `true` if the target contains a value, and `false` otherwise.
250 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
251
252 /// Return `false` if the target contains a value, and `true` otherwise.
253 /// Note that this accessor is provided purely for compatibility with
254 /// `NullableValue` and `NullableAllocatedValue`, and its use is
255 /// discouraged in favor of @ref has_value .
256 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
257
258 /// Return a reference providing non-modifiable access to the underlying
259 /// object of a (template parameter) `TYPE`. The behavior is undefined
260 /// if the target has no value.
261 const value_type& value() const;
262
263 /// Return a pointer providing non-modifiable access to the underlying
264 /// `TYPE` object. The behavior is undefined if the target has no
265 /// value.
266 const value_type *operator->() const;
267
268 /// Return a reference providing non-modifiable access to the underlying
269 /// `TYPE` object. The behavior is undefined if the target has no
270 /// value.
271 const value_type& operator*() const;
272
273#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
274 /// Return `true` if the target holds a value, and `false` otherwise.
275 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
276#else
277 /// Simulation of explicit conversion to bool. Inlined to work around xlC
278 /// but when out-of-line.
279 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
280 {
281 return UnspecifiedBoolUtil::makeValue(has_value());
282 }
283#endif
284
285 /// Return the value of the underlying object of a (template parameter)
286 /// `TYPE` if the target is non-null, and the specified @ref default_value
287 /// otherwise. Note that this method returns *by* *value*, so may be
288 /// inefficient in some contexts.
289 template <class ANY_TYPE>
290 TYPE value_or(const ANY_TYPE& default_value) const;
291
292 // MANIPULATORS
293#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
294 /// Assign to the target the value of the (template parameter) `TYPE`
295 /// created in place using the specified `args` and return a reference
296 /// providing modifiable access to the underlying `TYPE` object. If
297 /// this `optional` object already contains an object (`true ==
298 /// hasValue()`), that object is destroyed before the new object is
299 /// created. Note that if the constructor of `TYPE` throws an exception
300 /// this object is left in a disengaged state.
301 template <class... ARGS>
303#endif
304
305 /// Return a pointer providing modifiable access to the underlying
306 /// `TYPE` object. The behavior is undefined if the target has no
307 /// value.
309
310 /// Return a reference providing modifiable access to the underlying
311 /// `TYPE` object. The behavior is undefined if the target has no
312 /// value.
314
315 /// Reset the target to the default constructed state (i.e., to have the
316 /// null value).
318
319 /// Assign to the target the value of the specified `rhs`, and return a
320 /// reference providing modifiable access to this object.
321 NullableValueRef<TYPE>& operator=(const TYPE& rhs);
322
323 /// Assign to the target the value of the specified `rhs`, and return a
324 /// reference providing modifiable access to this object.
326
327 /// Assign to the target the value of the specified `rhs`, and return a
328 /// reference providing modifiable access to this object.
331
332 /// Assign to the target the value of the specified `rhs`, and return a
333 /// reference providing modifiable access to this object.
335
336 /// Reset the target to the default constructed state (i.e., to have the
337 /// null value).
338 void reset();
339
340 /// Return a reference providing modifiable access to the underlying
341 /// `TYPE` object. The behavior is undefined unless this object is
342 /// non-null.
343 value_type& value();
344
345 // DEPRECATED FUNCTIONS
346 // provided for compatibility with NullableValue
347
348 /// Return an address providing non-modifiable access to the underlying
349 /// object of a (template parameter) `TYPE` if this object is non-null,
350 /// and the specified `address` otherwise.
351 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::addressOr",
352 "Use 'has_value() ? &value() : address' instead")
353 const TYPE *addressOr(const TYPE *address) const;
354
355#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=5
356
357 /// Assign to this nullable object the value of the (template parameter)
358 /// `TYPE` created in place using the specified `args`. Return a
359 /// reference providing modifiable access to the created (value) object.
360 /// The object is also accessible via the `value` method. If this
361 /// nullable object already contains an object (`false == isNull()`),
362 /// that object is destroyed before the new object is created. If
363 /// `TYPE` has the trait `bslma::UsesBslmaAllocator` (`TYPE` is
364 /// allocator-enabled) the allocator specified at the construction of
365 /// this nullable object is used to supply memory to the value object.
366 /// Attempts to explicitly specify via `args` another allocator to
367 /// supply memory to the created (value) object are disallowed by the
368 /// compiler. Note that if the constructor of `TYPE` throws an
369 /// exception this object is left in the null state.
370 template <class... ARGS>
371 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
372 "Use 'emplace' instead")
373 TYPE& makeValueInplace(ARGS&&... args);
374#endif
375
376 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::valueOr",
377 "Use 'value_or' instead")
378 /// Return the value of the underlying object of a (template parameter)
379 /// `TYPE` if this object is non-null, and the specified `otherValue`
380 /// otherwise. Note that this method returns *by* *value*, so may be
381 /// inefficient in some contexts.
382 TYPE valueOr(const TYPE& otherValue) const;
383
385 "Use 'has_value() ? &value() : NULL' instead")
386 /// Return an address providing non-modifiable access to the underlying
387 /// object of a (template parameter) `TYPE` if this object is non-null,
388 /// and 0 otherwise.
389 const TYPE *valueOrNull() const;
390};
391
392// FREE FUNCTIONS
393
394/// Pass the boolean value of whether the specified `input` references a
395/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
396/// (template parameter) type `HASHALG`. If `input.has_value` is true,
397/// additionally pass the value to `hashAlg`.
398template <class HASHALG, class TYPE>
399void hashAppend(HASHALG& hashAlg, const NullableValueRef<TYPE>& input);
400
401// FREE OPERATORS
402
403/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
404/// the same value, and `false` otherwise. Two nullable wrappers have the
405/// same value if both targets are null, or if both are non-null and the
406/// values of their underlying objects compare equal. Note that this
407/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
408/// compatible.
409template <class LHS_TYPE, class RHS_TYPE>
410bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
411 const NullableValueRef<RHS_TYPE>& rhs);
412
413/// Return `true` if the specified `lhs` and `rhs` objects have the same
414/// value, and `false` otherwise. A nullable wrapper and a value of some
415/// type have the same value if the nullable wrapper is non-null and the
416/// underlying value of it's target compares equal to the other value. Note
417/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
418/// not compatible.
419template <class LHS_TYPE, class RHS_TYPE>
420bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
421 const RHS_TYPE& rhs);
422template <class LHS_TYPE, class RHS_TYPE>
423bool operator==(const LHS_TYPE& lhs,
424 const NullableValueRef<RHS_TYPE>& rhs);
425
426/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
427/// have the same value, and `false` otherwise. Two nullable wrappers do
428/// not have the same value if one is null and the other is non-null, or if
429/// both are non-null and the values of their underlying objects do not
430/// compare equal. Note that this function will fail to compile if
431/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
432template <class LHS_TYPE, class RHS_TYPE>
433bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
434 const NullableValueRef<RHS_TYPE>& rhs);
435
436/// Return `true` if the specified `lhs` and `rhs` objects do not have the
437/// same value, and `false` otherwise. A nullable wrappers and a value of
438/// some type do not have the same value if either the nullable wrappers is
439/// null, or its underlying value does not compare equal to the other value.
440/// Note that this function will fail to compile if `LHS_TYPE` and
441/// `RHS_TYPE` are not compatible.
442template <class LHS_TYPE, class RHS_TYPE>
443bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
444 const RHS_TYPE& rhs);
445template <class LHS_TYPE, class RHS_TYPE>
446bool operator!=(const LHS_TYPE& lhs,
447 const NullableValueRef<RHS_TYPE>& rhs);
448
449/// Return `true` if the specified `lhs` nullable wrapper is ordered before
450/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
451/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
452/// are non-null and `lhs.value()` is ordered before `rhs.value()`. Note
453/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
454/// not compatible.
455template <class LHS_TYPE, class RHS_TYPE>
456bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
457 const NullableValueRef<RHS_TYPE>& rhs);
458
459/// Return `true` if the specified `lhs` nullable wrapper is ordered before
460/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
461/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
462template <class LHS_TYPE, class RHS_TYPE>
463bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
464 const RHS_TYPE& rhs);
465
466/// Return `true` if the specified `lhs` is ordered before the specified
467/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
468/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
469template <class LHS_TYPE, class RHS_TYPE>
470bool operator<(const LHS_TYPE& lhs,
471 const NullableValueRef<RHS_TYPE>& rhs);
472
473
474/// Return `true` if the specified `lhs` nullable wrapper is ordered before
475/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
476/// value, and `false` otherwise. (See `operator<` and `operator==`.) Note
477/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
478/// are not compatible.
479template <class LHS_TYPE, class RHS_TYPE>
480bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
481 const NullableValueRef<RHS_TYPE>& rhs);
482
483/// Return `true` if the specified `lhs` nullable wrapper is ordered before
484/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
485/// otherwise. (See `operator<` and `operator==`.) Note that this operator
486/// returns `!(rhs < lhs)`.
487template <class LHS_TYPE, class RHS_TYPE>
488bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
489 const RHS_TYPE& rhs);
490
491/// Return `true` if the specified `lhs` is ordered before the specified
492/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and
493/// `false` otherwise. (See `operator<` and `operator==`.) Note that this
494/// operator returns `!(rhs < lhs)`.
495template <class LHS_TYPE, class RHS_TYPE>
496bool operator<=(const LHS_TYPE& lhs,
497 const NullableValueRef<RHS_TYPE>& rhs);
498
499/// Return `true` if the specified `lhs` nullable wrapper is ordered after
500/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
501/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
502/// are non-null and `lhs.value()` is ordered after `rhs.value()`. Note
503/// that this operator returns `rhs < lhs` when both operands are of
504/// `bsl::optional` type. Also note that this function will fail to compile
505/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
506template <class LHS_TYPE, class RHS_TYPE>
507bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
508 const NullableValueRef<RHS_TYPE>& rhs);
509
510/// Return `true` if the specified `lhs` nullable wrapper is ordered after
511/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
512/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
513/// Note that this operator returns `rhs < lhs`.
514template <class LHS_TYPE, class RHS_TYPE>
515bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
516 const RHS_TYPE& rhs);
517
518/// Return `true` if the specified `lhs` is ordered after the specified
519/// `rhs` nullable wrapper, and `false` otherwise. `lhs` is ordered after
520/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`. Note
521/// that this operator returns `rhs < lhs`.
522template <class LHS_TYPE, class RHS_TYPE>
523bool operator>(const LHS_TYPE& lhs,
524 const NullableValueRef<RHS_TYPE>& rhs);
525
526/// Return `true` if the specified `lhs` nullable object is ordered after
527/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
528/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
529/// that this operator returns `!(lhs < rhs)` when both operands are of
530/// `bsl::optional` type. Also note that this function will fail to compile
531/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
532template <class LHS_TYPE, class RHS_TYPE>
533bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
534 const NullableValueRef<RHS_TYPE>& rhs);
535
536/// Return `true` if the specified `lhs` nullable wrapper is ordered after
537/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
538/// otherwise. (See `operator>` and `operator==`.) Note that this operator
539/// returns `!(lhs < rhs)`.
540template <class LHS_TYPE, class RHS_TYPE>
541bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
542 const RHS_TYPE& rhs);
543
544/// Return `true` if the specified `lhs` is wrapper after the specified
545/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
546/// `false` otherwise. (See `operator>` and `operator==`.) Note that this
547/// operator returns `!(lhs < rhs)`.
548template <class LHS_TYPE, class RHS_TYPE>
549bool operator>=(const LHS_TYPE& lhs,
550 const NullableValueRef<RHS_TYPE>& rhs);
551
552
553 //================================
554 // Comparisons with bsl::nullopt_t
555 //================================
556
557/// Return `true` if the specified `lhs` is null, and `false` otherwise.
558template <class TYPE>
559bool operator==(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
561
562/// Return `true` if the specified `rhs` is null, and `false` otherwise.
563template <class TYPE>
564bool operator==(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
566
567/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
568template <class TYPE>
569bool operator!=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
571
572/// Return `true` if the specified `rhs` is not null, and `false`
573/// otherwise.
574template <class TYPE>
575bool operator!=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
577
578/// Return `false`. `bsl::nullopt` never orders after a
579/// `NullableValueRef`.
580template <class TYPE>
581bool operator<(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
583
584/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
585/// Note that `bsl::nullopt` is ordered before any `NullableValueRef` that
586/// is not null.
587template <class TYPE>
588bool operator<(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
590
591/// Return `true` if the specified `lhs` is not null, and `false`
592/// otherwise.
593template <class TYPE>
594bool operator>(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
596
597/// Return `false`. `bsl::nullopt` never orders after a
598/// `NullableValueRef`.
599template <class TYPE>
600bool operator>(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
602
603/// Return `true` if the specified `lhs` is null, and `false` otherwise.
604template <class TYPE>
605bool operator<=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
607
608/// Return `true`.
609template <class TYPE>
610bool operator<=(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
612
613/// Return `true`.
614template <class TYPE>
615bool operator>=(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
617
618/// Return `true` if the specified `rhs` is null, and `false` otherwise.
619template <class TYPE>
620bool operator>=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
622
623 // =================================
624 // class ConstNullableValueRef<TYPE>
625 // =================================
626
627/// This class is a wrapper for either a `bsl::optional` or
628/// `NullableAllocatedValue`, and provides non-modifiable access to the
629/// wrapped object.
630///
631/// See @ref bdlb_nullablevalueref
632template <class TYPE>
634
635 // PRIVATE TYPES
636#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
637 // UNSPECIFIED BOOL
638
639 /// This type is needed only in C++03 mode, where `explicit` conversion
640 /// operators are not supported. A `NullableAllocatedValue` is implicitly
641 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
642 /// implicitly convertible to `bool`.
643 typedef BloombergLP::bsls::UnspecifiedBool<ConstNullableValueRef>
644 UnspecifiedBoolUtil;
645 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
646#endif
647
648 // DATA
649
650 // the address of the target
651 const void *d_target_p;
652
653 // `true` if the referent is a specialization of `bsl::optional`, and
654 // `false` if it's a specialization of `NullableAllocatedValue`.
655 bool d_isTargetOptional;
656
657 // PRIVATE ACCESSORS
658
659 /// Return a pointer to the held `bdlb::NullableAllocatedValue`. The
660 /// behavior is undefined if the target is not a
661 /// `bdlb::NullableAllocatedValue`.
662 const NullableAllocatedValue<TYPE>& getNAV() const;
663
664 /// Return a pointer to the held `bdlb::bsl::optional`. The behavior is
665 /// undefined if the target is not a `bdlb::bsl::optional`.
666 const bsl::optional<TYPE>& getOpt() const;
667
668 /// Return `true` if this object currently holds a pointer to a
669 /// bdlb::bsl::optional, and `false` otherwise.
670 bool hasOpt() const;
671
672 // TRAITS
673
674 /// This class requires that `TYPE` is not `const`- or `volatile`-
675 /// qualified, nor a reference.
677 bsl::is_same<TYPE,
679
680 public:
681 // TYPES
682
683 /// `value_type` is an alias for the template parameter `TYPE`, and
684 /// represents the type of the object managed by the wrapped nullable
685 /// object.
686 typedef TYPE value_type;
687
688 // CREATORS
689
690 /// Create a nullable object wrapper that refers to the specified `opt`
691 /// object. Note that the created wrapper does not own a copy of the
692 /// underlying nullable value, but instead refers to it, and so the
693 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
694 ConstNullableValueRef(const bsl::optional<TYPE>& opt); // IMPLICIT
695
696 /// Create a nullable object wrapper that refers to the specified `opt`
697 /// object. Note that the created wrapper does not own a copy of the
698 /// underlying nullable value, but instead refers to it, and so the
699 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
701 // IMPLICIT
702
703 /// Create a nullable object wrapper that refers to the target object of
704 /// the specified `ref` wrapper. Note that the created wrapper does not
705 /// own a copy of the underlying nullable value, but instead refers to
706 /// to it, and so the lifetime of the target must exceed the lifetime of
707 /// the created wrapper.
708 ConstNullableValueRef(const NullableValueRef<TYPE>& ref); // IMPLICIT
709
710 /// Create a nullable object wrapper that refers to the target object of
711 /// the specified `original` wrapper. Note that the created wrapper
712 /// does not own a copy of the underlying nullable value, but instead
713 /// refers to it, and so the lifetime of the target must exceed the
714 /// lifetime of the created wrapper.
716
717 /// Destroy this object. Note that this destructor is generated by the
718 /// compiler, and does not destruct the target.
720
721 // ACCESSORS
722
723 /// Return `true` if the target contains a value, and `false` otherwise.
724 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
725
726 /// Return `false` if the target contains a value, and `true` otherwise.
727 /// Note that this accessor is provided purely for compatibility with
728 /// `NullableValue` and `NullableAllocatedValue`, and its use is
729 /// discouraged in favor of @ref has_value .
730 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
731
732 /// Return a reference providing non-modifiable access to the underlying
733 /// object of a (template parameter) `TYPE`. The behavior is undefined
734 /// if the target has no value.
735 const value_type& value() const;
736
737 /// Return a pointer providing non-modifiable access to the underlying
738 /// `TYPE` object. The behavior is undefined if the target has no
739 /// value.
740 const value_type *operator->() const;
741
742 /// Return a reference providing non-modifiable access to the underlying
743 /// `TYPE` object. The behavior is undefined if the target has no
744 /// value.
745 const value_type& operator*() const;
746
747#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
748 /// Return `true` if the target holds a value, and `false` otherwise.
749 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
750#else
751 /// Simulation of explicit conversion to bool. Inlined to work around xlC
752 /// but when out-of-line.
753 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
754 {
755 return UnspecifiedBoolUtil::makeValue(has_value());
756 }
757#endif
758
759 /// Return the value of the underlying object of a (template parameter)
760 /// `TYPE` if the target is non-null, and the specified @ref default_value
761 /// otherwise. Note that this method returns *by* *value*, so may be
762 /// inefficient in some contexts.
763 template <class ANY_TYPE>
764 TYPE value_or(const ANY_TYPE& default_value) const;
765
766 // DEPRECATED FUNCTIONS
767 // provided for compatibility with NullableValue
768
769 /// Return an address providing non-modifiable access to the underlying
770 /// object of a (template parameter) `TYPE` if this object is non-null,
771 /// and the specified `address` otherwise.
772 BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::addressOr",
773 "Use 'has_value() ? &value() : address' instead")
774 const TYPE *addressOr(const TYPE *address) const;
775
776 /// Return the value of the underlying object of a (template parameter)
777 /// `TYPE` if this object is non-null, and the specified `otherValue`
778 /// otherwise. Note that this method returns *by* *value*, so may be
779 /// inefficient in some contexts.
781 "Use 'value_or' instead")
782 TYPE valueOr(const TYPE& otherValue) const;
783
784 /// Return an address providing non-modifiable access to the underlying
785 /// object of a (template parameter) `TYPE` if this object is non-null,
786 /// and 0 otherwise.
788 "Use 'has_value() ? &value() : NULL' instead")
789 const TYPE *valueOrNull() const;
790
791};
792
793// FREE FUNCTIONS
794
795/// Pass the boolean value of whether the specified `input` references a
796/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
797/// (template parameter) type `HASHALG`. If `input.has_value` is true,
798/// additionally pass the value to `hashAlg`.
799template <class HASHALG, class TYPE>
800void hashAppend(HASHALG& hashAlg, const ConstNullableValueRef<TYPE>& input);
801
802// FREE OPERATORS
803
804/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
805/// the same value, and `false` otherwise. Two nullable wrappers have the
806/// same value if both targets are null, or if both are non-null and the
807/// values of their underlying objects compare equal. Note that this
808/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
809/// compatible.
810template <class LHS_TYPE, class RHS_TYPE>
811bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
812 const ConstNullableValueRef<RHS_TYPE>& rhs);
813
814/// Return `true` if the specified `lhs` and `rhs` objects have the same
815/// value, and `false` otherwise. A nullable wrapper and a value of some
816/// type have the same value if the nullable wrapper is non-null and the
817/// underlying value of it's target compares equal to the other value. Note
818/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
819/// not compatible.
820template <class LHS_TYPE, class RHS_TYPE>
821bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
822 const RHS_TYPE& rhs);
823template <class LHS_TYPE, class RHS_TYPE>
824bool operator==(const LHS_TYPE& lhs,
825 const ConstNullableValueRef<RHS_TYPE>& rhs);
826
827/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
828/// have the same value, and `false` otherwise. Two nullable wrappers do
829/// not have the same value if one is null and the other is non-null, or if
830/// bost are non-null and the values of their underlying objects do not
831/// compare equal. Note that this function will fail to compile if
832/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
833template <class LHS_TYPE, class RHS_TYPE>
834bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
835 const ConstNullableValueRef<RHS_TYPE>& rhs);
836
837/// Return `true` if the specified `lhs` and `rhs` objects do not have the
838/// same value, and `false` otherwise. A nullable wrappers and a value of
839/// some type do not have the same value if either the nullable wrappers is
840/// null, or its underlying value does not compare equal to the other value.
841/// Note that this function will fail to compile if `LHS_TYPE` and
842/// `RHS_TYPE` are not compatible.
843template <class LHS_TYPE, class RHS_TYPE>
844bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
845 const RHS_TYPE& rhs);
846template <class LHS_TYPE, class RHS_TYPE>
847bool operator!=(const LHS_TYPE& lhs,
848 const ConstNullableValueRef<RHS_TYPE>& rhs);
849
850/// Return `true` if the specified `lhs` nullable wrapper is ordered before
851/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
852/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
853/// are non-null and `lhs.value()` is ordered before `rhs.value()`. Note
854/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
855/// not compatible.
856template <class LHS_TYPE, class RHS_TYPE>
857bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
858 const ConstNullableValueRef<RHS_TYPE>& rhs);
859
860/// Return `true` if the specified `lhs` nullable wrapper is ordered before
861/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
862/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
863template <class LHS_TYPE, class RHS_TYPE>
864bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
865 const RHS_TYPE& rhs);
866
867/// Return `true` if the specified `lhs` is ordered before the specified
868/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
869/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
870template <class LHS_TYPE, class RHS_TYPE>
871bool operator<(const LHS_TYPE& lhs,
872 const ConstNullableValueRef<RHS_TYPE>& rhs);
873
874/// Return `true` if the specified `lhs` nullable wrapper is ordered before
875/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
876/// value, and `false` otherwise. (See `operator<` and `operator==`.) Note
877/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
878/// are not compatible.
879template <class LHS_TYPE, class RHS_TYPE>
880bool operator<=(const ConstNullableValueRef<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` or `lhs` and `rhs` have the same value, and `false`
885/// otherwise. (See `operator<` and `operator==`.) Note that this operator
886/// returns `!(rhs < lhs)`.
887template <class LHS_TYPE, class RHS_TYPE>
888bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
889 const RHS_TYPE& rhs);
890
891/// Return `true` if the specified `lhs` is ordered before the specified
892/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and
893/// `false` otherwise. (See `operator<` and `operator==`.) Note that this
894/// operator returns `!(rhs < lhs)`.
895template <class LHS_TYPE, class RHS_TYPE>
896bool operator<=(const LHS_TYPE& lhs,
897 const ConstNullableValueRef<RHS_TYPE>& rhs);
898
899/// Return `true` if the specified `lhs` nullable wrapper is ordered after
900/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
901/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
902/// are non-null and `lhs.value()` is ordered after `rhs.value()`. Note
903/// that this operator returns `rhs < lhs` when both operands are of
904/// `NullableValue` type. Also note that this function will fail to compile
905/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
906template <class LHS_TYPE, class RHS_TYPE>
907bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
908 const ConstNullableValueRef<RHS_TYPE>& rhs);
909
910/// Return `true` if the specified `lhs` nullable wrapper is ordered after
911/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
912/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
913/// Note that this operator returns `rhs < lhs`.
914template <class LHS_TYPE, class RHS_TYPE>
915bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
916 const RHS_TYPE& rhs);
917
918/// Return `true` if the specified `lhs` is ordered after the specified
919/// `rhs` nullable wrapper, and `false` otherwise. `lhs` is ordered after
920/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`. Note
921/// that this operator returns `rhs < lhs`.
922template <class LHS_TYPE, class RHS_TYPE>
923bool operator>(const LHS_TYPE& lhs,
924 const ConstNullableValueRef<RHS_TYPE>& rhs);
925
926/// Return `true` if the specified `lhs` nullable object is ordered after
927/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
928/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
929/// that this operator returns `!(lhs < rhs)` when both operands are of
930/// `NullableValue` type. Also note that this function will fail to compile
931/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
932template <class LHS_TYPE, class RHS_TYPE>
933bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
934 const ConstNullableValueRef<RHS_TYPE>& rhs);
935
936/// Return `true` if the specified `lhs` nullable wrapper is ordered after
937/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
938/// otherwise. (See `operator>` and `operator==`.) Note that this operator
939/// returns `!(lhs < rhs)`.
940template <class LHS_TYPE, class RHS_TYPE>
941bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
942 const RHS_TYPE& rhs);
943
944/// Return `true` if the specified `lhs` is wrapper after the specified
945/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
946/// `false` otherwise. (See `operator>` and `operator==`.) Note that this
947/// operator returns `!(lhs < rhs)`.
948template <class LHS_TYPE, class RHS_TYPE>
949bool operator>=(const LHS_TYPE& lhs,
950 const ConstNullableValueRef<RHS_TYPE>& rhs);
951
952 //================================
953 // Comparisons with bsl::nullopt_t
954 //================================
955
956/// Return `true` if the specified `lhs` is null, and `false` otherwise.
957template <class TYPE>
958bool operator==(const ConstNullableValueRef<TYPE>& lhs,
959 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
960
961/// Return `true` if the specified `rhs` is null, and `false` otherwise.
962template <class TYPE>
963bool operator==(const bsl::nullopt_t&,
965
966/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
967template <class TYPE>
968bool operator!=(const ConstNullableValueRef<TYPE>& lhs,
969 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
970
971/// Return `true` if the specified `rhs` is not null, and `false`
972/// otherwise.
973template <class TYPE>
974bool operator!=(const bsl::nullopt_t&,
976
977/// Return `false`. `bsl::nullopt` never orders after a
978/// `ConstNullableValueRef`.
979template <class TYPE>
980bool operator<(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
982
983/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
984/// Note that `bsl::nullopt` is ordered before any `ConstNullableValueRef`
985/// that is not null.
986template <class TYPE>
987bool operator<(const bsl::nullopt_t&,
989
990/// Return `true` if the specified `lhs` is not null, and `false`
991/// otherwise.
992template <class TYPE>
993bool operator>(const ConstNullableValueRef<TYPE>& lhs,
994 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
995
996/// Return `false`. `bsl::nullopt` never orders after a
997/// `NullableValueRef`.
998template <class TYPE>
999bool operator>(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1001
1002/// Return `true` if the specified `lhs` is null, and `false` otherwise.
1003template <class TYPE>
1004bool operator<=(const ConstNullableValueRef<TYPE>& lhs,
1005 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1006
1007/// Return `true`.
1008template <class TYPE>
1009bool operator<=(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1011
1012/// Return `true`.
1013template <class TYPE>
1014bool operator>=(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
1016
1017/// Return `true` if the specified `rhs` is null, and `false` otherwise.
1018template <class TYPE>
1019bool operator>=(const bsl::nullopt_t&,
1021
1022 //===================================================================
1023 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
1024 //===================================================================
1025
1026/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
1027/// the same value, and `false` otherwise. Two nullable wrappers have the
1028/// same value if both targets are null, or if both are non-null and the
1029/// values of their underlying objects compare equal. Note that this
1030/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
1031/// compatible.
1032template <class LHS_TYPE, class RHS_TYPE>
1033bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1034 const NullableValueRef<RHS_TYPE>& rhs);
1035template <class LHS_TYPE, class RHS_TYPE>
1036bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
1037 const ConstNullableValueRef<RHS_TYPE>& rhs);
1038
1039/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
1040/// have the same value, and `false` otherwise. Two nullable wrappers do
1041/// not have the same value if one is null and the other is non-null, or if
1042/// both are non-null and the values of their underlying objects do not
1043/// compare equal. Note that this function will fail to compile if
1044/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
1045template <class LHS_TYPE, class RHS_TYPE>
1046bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1047 const NullableValueRef<RHS_TYPE>& rhs);
1048template <class LHS_TYPE, class RHS_TYPE>
1049bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1050 const ConstNullableValueRef<RHS_TYPE>& rhs);
1051
1052/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1053/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1054/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
1055/// are non-null and `lhs.value()` is ordered before `rhs.value()`. Note
1056/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
1057/// not compatible.
1058template <class LHS_TYPE, class RHS_TYPE>
1059bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1060 const NullableValueRef<RHS_TYPE>& rhs);
1061template <class LHS_TYPE, class RHS_TYPE>
1062bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
1063 const ConstNullableValueRef<RHS_TYPE>& rhs);
1064
1065/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1066/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
1067/// value, and `false` otherwise. (See `operator<` and `operator==`.) Note
1068/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
1069/// are not compatible.
1070template <class LHS_TYPE, class RHS_TYPE>
1071bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1072 const NullableValueRef<RHS_TYPE>& rhs);
1073template <class LHS_TYPE, class RHS_TYPE>
1074bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1075 const ConstNullableValueRef<RHS_TYPE>& rhs);
1076
1077/// Return `true` if the specified `lhs` nullable wrapper is ordered after
1078/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1079/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
1080/// are non-null and `lhs.value()` is ordered after `rhs.value()`. Note
1081/// that this operator returns `rhs < lhs` when both operands are of
1082/// `NullableValue` type. Also note that this function will fail to compile
1083/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1084template <class LHS_TYPE, class RHS_TYPE>
1085bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1086 const NullableValueRef<RHS_TYPE>& rhs);
1087template <class LHS_TYPE, class RHS_TYPE>
1088bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
1089 const ConstNullableValueRef<RHS_TYPE>& rhs);
1090
1091/// Return `true` if the specified `lhs` nullable object is ordered after
1092/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
1093/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
1094/// that this operator returns `!(lhs < rhs)` when both operands are of
1095/// `NullableValue` type. Also note that this function will fail to compile
1096/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1097template <class LHS_TYPE, class RHS_TYPE>
1098bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1099 const NullableValueRef<RHS_TYPE>& rhs);
1100template <class LHS_TYPE, class RHS_TYPE>
1101bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1102 const ConstNullableValueRef<RHS_TYPE>& rhs);
1103
1104} // close package namespace
1105
1106 // ----------------------------
1107 // class NullableValueRef<TYPE>
1108 // ----------------------------
1109
1110// PRIVATE ACCESSORS
1111template <class TYPE>
1112inline
1114bdlb::NullableValueRef<TYPE>::getNAV() const
1115{
1116 BSLS_ASSERT(!hasOpt());
1117 return *static_cast<bdlb::NullableAllocatedValue<TYPE> *>(d_target_p);
1118}
1119
1120template <class TYPE>
1121inline
1124{
1125 BSLS_ASSERT(hasOpt());
1126 return *static_cast<bsl::optional<TYPE> *>(d_target_p);
1127}
1128
1129template <class TYPE>
1130inline
1132{
1133 return d_isTargetOptional;
1134}
1135
1136// CREATORS
1137template <class TYPE>
1138inline
1140: d_target_p(&opt)
1141, d_isTargetOptional(true)
1142{
1143}
1144
1145template <class TYPE>
1146inline
1149: d_target_p(&opt)
1150, d_isTargetOptional(false)
1151{
1152}
1153
1154template <class TYPE>
1155inline
1157 const NullableValueRef& original)
1158: d_target_p(original.d_target_p)
1159, d_isTargetOptional(original.d_isTargetOptional)
1160{
1161}
1162
1163// ACCESSORS
1164template <class TYPE>
1165inline
1167{
1168 return hasOpt()
1169 ? getOpt().has_value()
1170 : getNAV().has_value();
1171}
1172
1173template <class TYPE>
1174inline
1176{
1177 return !has_value();
1178}
1179
1180template <class TYPE>
1181inline
1184{
1185 return hasOpt()
1186 ? getOpt().value()
1187 : getNAV().value();
1188}
1189
1190
1191template <class TYPE>
1192inline
1195{
1196 return hasOpt()
1197 ? getOpt().operator->()
1198 : getNAV().operator->();
1199}
1200
1201template <class TYPE>
1202inline
1205{
1206 return hasOpt()
1207 ? getOpt().operator*()
1208 : getNAV().operator*();
1209}
1210
1211#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1212template <class TYPE>
1214{
1215 return has_value();
1216}
1217#endif
1218
1219template <class TYPE>
1220template <class ANY_TYPE>
1221inline
1223 const ANY_TYPE& default_value) const
1224{
1225 if (has_value()) {
1226 return hasOpt()
1227 ? getOpt().value()
1228 : getNAV().value(); // RETURN
1229 }
1230 return default_value;
1231}
1232
1233
1234// MANIPULATORS
1235#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1236template <class TYPE>
1237template <class... ARGS>
1238inline
1241{
1242 return hasOpt()
1243 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...)
1244 : getNAV().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1245}
1246#endif
1247
1248template <class TYPE>
1249inline
1252{
1253 return hasOpt()
1254 ? getOpt().operator->()
1255 : getNAV().operator->();
1256}
1257
1258template <class TYPE>
1259inline
1262{
1263 return hasOpt()
1264 ? getOpt().operator*()
1265 : getNAV().operator*();
1266}
1267
1268template <class TYPE>
1269inline
1272{
1273 reset();
1274 return *this;
1275}
1276
1277template <class TYPE>
1278inline
1281{
1282 if (hasOpt()) {
1283 getOpt() = rhs;
1284 }
1285 else {
1286 getNAV() = rhs;
1287 }
1288
1289 return *this;
1290}
1291
1292template <class TYPE>
1293inline
1296{
1297 if (rhs.has_value()) {
1298 *this = rhs.value();
1299 }
1300 else {
1301 reset();
1302 }
1303 return *this;
1304}
1305
1306template <class TYPE>
1307inline
1311{
1312 if (rhs.has_value()) {
1313 *this = rhs.value();
1314 }
1315 else {
1316 reset();
1317 }
1318
1319 return *this;
1320}
1321
1322template <class TYPE>
1323inline
1326{
1327 if (rhs.has_value()) {
1328 *this = rhs.value();
1329 }
1330 else {
1331 reset();
1332 }
1333
1334 return *this;
1335}
1336
1337template <class TYPE>
1338inline
1340{
1341 if (hasOpt()) {
1342 getOpt().reset();
1343 }
1344 else {
1345 getNAV().reset();
1346 }
1347}
1348
1349template <class TYPE>
1350inline
1353{
1354 return hasOpt()
1355 ? getOpt().value()
1356 : getNAV().value();
1357}
1358
1359// DEPRECATED FUNCTIONS
1360template <class TYPE>
1361inline
1362const TYPE *
1363bdlb::NullableValueRef<TYPE>::addressOr(const TYPE *address) const
1364{
1365 return has_value() ? &value() : address;
1366}
1367
1368#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=5
1369template <class TYPE>
1370template <class... ARGS>
1371inline
1373{
1374 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1375}
1376#endif
1377
1378template <class TYPE>
1379inline
1380TYPE bdlb::NullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
1381{
1382 return value_or(otherValue);
1383}
1384
1385template <class TYPE>
1386inline
1388{
1389 return has_value() ? &value() : 0;
1390}
1391
1392// FREE FUNCTIONS
1393template <class HASHALG, class TYPE>
1394void bdlb::hashAppend(HASHALG& hashAlg,
1395 const NullableValueRef<TYPE>& input)
1396{
1397 using ::BloombergLP::bslh::hashAppend;
1398
1399 if (!input.has_value()) {
1400 hashAppend(hashAlg, false);
1401 }
1402 else {
1403 hashAppend(hashAlg, true);
1404 hashAppend(hashAlg, input.value());
1405 }
1406}
1407
1408// FREE OPERATORS
1409template <class LHS_TYPE, class RHS_TYPE>
1410inline
1411bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1412 const NullableValueRef<RHS_TYPE>& rhs)
1413{
1414 if (lhs.has_value()) {
1415 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
1416 }
1417
1418 return !rhs.has_value();
1419}
1420
1421template <class LHS_TYPE, class RHS_TYPE>
1422inline
1423bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1424 const RHS_TYPE& rhs)
1425{
1426 return lhs.has_value() ? lhs.value() == rhs : false;
1427}
1428
1429template <class LHS_TYPE, class RHS_TYPE>
1430inline
1431bool bdlb::operator==(const LHS_TYPE& lhs,
1432 const NullableValueRef<RHS_TYPE>& rhs)
1433{
1434 return rhs.has_value() ? lhs == rhs.value(): false;
1435}
1436
1437template <class LHS_TYPE, class RHS_TYPE>
1438inline
1439bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1440 const NullableValueRef<RHS_TYPE>& rhs)
1441{
1442 if (lhs.has_value()) {
1443 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
1444 }
1445
1446 return rhs.has_value();
1447}
1448
1449template <class LHS_TYPE, class RHS_TYPE>
1450inline
1451bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1452 const RHS_TYPE& rhs)
1453{
1454 return lhs.has_value() ? lhs.value() != rhs : true;
1455}
1456
1457template <class LHS_TYPE, class RHS_TYPE>
1458inline
1459bool bdlb::operator!=(const LHS_TYPE& lhs,
1460 const NullableValueRef<RHS_TYPE>& rhs)
1461{
1462 return rhs.has_value() ? lhs != rhs.value() : true;
1463}
1464
1465template <class LHS_TYPE, class RHS_TYPE>
1466inline
1467bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1468 const NullableValueRef<RHS_TYPE>& rhs)
1469{
1470 if (!rhs.has_value()) {
1471 return false; // RETURN
1472 }
1473
1474 return lhs.has_value() ? lhs.value() < rhs.value() : true;
1475}
1476
1477template <class LHS_TYPE, class RHS_TYPE>
1478inline
1479bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1480 const RHS_TYPE& rhs)
1481{
1482 return lhs.has_value() ? lhs.value() < rhs : true;
1483}
1484
1485template <class LHS_TYPE, class RHS_TYPE>
1486inline
1487bool bdlb::operator<(const LHS_TYPE& lhs,
1488 const NullableValueRef<RHS_TYPE>& rhs)
1489{
1490 return rhs.has_value() ? lhs < rhs.value() : false;
1491}
1492
1493template <class LHS_TYPE, class RHS_TYPE>
1494inline
1495bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1496 const NullableValueRef<RHS_TYPE>& rhs)
1497{
1498 if (!lhs.has_value()) {
1499 return true; // RETURN
1500 }
1501
1502 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
1503}
1504
1505template <class LHS_TYPE, class RHS_TYPE>
1506inline
1507bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1508 const RHS_TYPE& rhs)
1509{
1510 return lhs.has_value() ? lhs.value() <= rhs : true;
1511}
1512
1513template <class LHS_TYPE, class RHS_TYPE>
1514inline
1515bool bdlb::operator<=(const LHS_TYPE& lhs,
1516 const NullableValueRef<RHS_TYPE>& rhs)
1517{
1518 return rhs.has_value() ? lhs <= rhs.value() : false;
1519}
1520
1521template <class LHS_TYPE, class RHS_TYPE>
1522inline
1523bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1524 const NullableValueRef<RHS_TYPE>& rhs)
1525{
1526 if (!lhs.has_value()) {
1527 return false; // RETURN
1528 }
1529
1530 return rhs.has_value() ? lhs.value() > rhs.value() : true;
1531}
1532
1533template <class LHS_TYPE, class RHS_TYPE>
1534inline
1535bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1536 const RHS_TYPE& rhs)
1537{
1538 return lhs.has_value() ? lhs.value() > rhs : false;
1539}
1540
1541template <class LHS_TYPE, class RHS_TYPE>
1542inline
1543bool bdlb::operator>(const LHS_TYPE& lhs,
1544 const NullableValueRef<RHS_TYPE>& rhs)
1545{
1546 return rhs.has_value() ? lhs > rhs.value() : true;
1547}
1548
1549template <class LHS_TYPE, class RHS_TYPE>
1550inline
1551bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1552 const NullableValueRef<RHS_TYPE>& rhs)
1553{
1554 if (!rhs.has_value()) {
1555 return true; // RETURN
1556 }
1557
1558 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
1559}
1560
1561template <class LHS_TYPE, class RHS_TYPE>
1562inline
1563bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1564 const RHS_TYPE& rhs)
1565{
1566 return lhs.has_value() ? lhs.value() >= rhs : false;
1567}
1568
1569template <class LHS_TYPE, class RHS_TYPE>
1570inline
1571bool bdlb::operator>=(const LHS_TYPE& lhs,
1572 const NullableValueRef<RHS_TYPE>& rhs)
1573{
1574 return rhs.has_value() ? lhs >= rhs.value() : true;
1575}
1576
1577 //--------------------------------
1578 // Comparisons with bsl::nullopt_t
1579 //--------------------------------
1580
1581template <class TYPE>
1582inline
1583bool bdlb::operator==(const NullableValueRef<TYPE>& lhs,
1585{
1586 return !lhs.has_value();
1587}
1588
1589template <class TYPE>
1590inline
1591bool bdlb::operator==(
1592 const bsl::nullopt_t&,
1593 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1594{
1595 return !rhs.has_value();
1596}
1597
1598template <class TYPE>
1599inline bool bdlb::operator!=(const NullableValueRef<TYPE>& lhs,
1601{
1602 return lhs.has_value();
1603}
1604
1605template <class TYPE>
1606inline
1607bool bdlb::operator!=(
1608 const bsl::nullopt_t&,
1609 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1610{
1611 return rhs.has_value();
1612}
1613
1614template <class TYPE>
1615inline
1616bool bdlb::operator<(const NullableValueRef<TYPE>&,
1618{
1619 return false;
1620}
1621
1622template <class TYPE>
1623inline
1624bool bdlb::operator<(
1625 const bsl::nullopt_t&,
1626 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1627{
1628 return rhs.has_value();
1629}
1630
1631template <class TYPE>
1632inline
1633bool bdlb::operator>(const NullableValueRef<TYPE>& lhs,
1635{
1636 return lhs.has_value();
1637}
1638
1639template <class TYPE>
1640inline
1642 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1643{
1644 return false;
1645}
1646
1647template <class TYPE>
1648inline
1649bool bdlb::operator<=(const NullableValueRef<TYPE>& lhs,
1651{
1652 return !lhs.has_value();
1653}
1654
1655template <class TYPE>
1656inline
1657bool bdlb::operator<=(
1658 const bsl::nullopt_t&,
1659 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1660{
1661 return true;
1662}
1663
1664template <class TYPE>
1665inline
1666bool bdlb::operator>=(const NullableValueRef<TYPE>&,
1668{
1669 return true;
1670}
1671
1672template <class TYPE>
1673inline
1674bool bdlb::operator>=(
1675 const bsl::nullopt_t&,
1676 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1677{
1678 return !rhs.has_value();
1679}
1680
1681 // ---------------------------------
1682 // class ConstNullableValueRef<TYPE>
1683 // ---------------------------------
1684
1685// PRIVATE ACCESSORS
1686template <class TYPE>
1687inline
1690{
1691 BSLS_ASSERT(!hasOpt());
1692 return *static_cast<const NullableAllocatedValue<value_type> *>(
1693 d_target_p);
1694}
1695
1696template <class TYPE>
1697inline
1700{
1701 BSLS_ASSERT(hasOpt());
1702 return *static_cast<const bsl::optional<value_type> *>(d_target_p);
1703}
1704
1705template <class TYPE>
1706inline
1708{
1709 return d_isTargetOptional;
1710}
1711
1712// CREATORS
1713template <class TYPE>
1714inline
1716 const bsl::optional<TYPE>& opt)
1717: d_target_p(&opt)
1718, d_isTargetOptional(true)
1719{
1720}
1721
1722template <class TYPE>
1723inline
1726: d_target_p(&opt)
1727, d_isTargetOptional(false)
1728{
1729}
1730
1731template <class TYPE>
1732inline
1734 const NullableValueRef<TYPE>& ref)
1735: d_target_p(ref.d_target_p)
1736, d_isTargetOptional(ref.d_isTargetOptional)
1737{
1738}
1739
1740template <class TYPE>
1741inline
1743 const ConstNullableValueRef& original)
1744: d_target_p(original.d_target_p)
1745, d_isTargetOptional(original.d_isTargetOptional)
1746{
1747}
1748
1749// ACCESSORS
1750template <class TYPE>
1751inline
1752bool
1754{
1755 return hasOpt()
1756 ? getOpt().has_value()
1757 : getNAV().has_value();
1758}
1759
1760template <class TYPE>
1761inline
1762bool
1764{
1765 return !has_value();
1766}
1767
1768template <class TYPE>
1769inline
1772{
1773 return hasOpt()
1774 ? getOpt().value()
1775 : getNAV().value();
1776}
1777
1778
1779template <class TYPE>
1780inline
1783{
1784 return hasOpt()
1785 ? getOpt().operator->()
1786 : getNAV().operator->();
1787}
1788
1789template <class TYPE>
1790inline
1793{
1794 return hasOpt()
1795 ? getOpt().operator*()
1796 : getNAV().operator*();
1797}
1798
1799#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1800template <class TYPE>
1802{
1803 return has_value();
1804}
1805#endif
1806
1807template <class TYPE>
1808template <class ANY_TYPE>
1809inline
1811 const ANY_TYPE& default_value) const
1812{
1813 if (has_value()) {
1814 return hasOpt()
1815 ? getOpt().value()
1816 : getNAV().value(); // RETURN
1817 }
1818 return default_value;
1819}
1820
1821// DEPRECATED FUNCTIONS
1822template <class TYPE>
1823inline
1824const TYPE *
1825bdlb::ConstNullableValueRef<TYPE>::addressOr(const TYPE *address) const
1826{
1827 return has_value() ? &value() : address;
1828}
1829
1830template <class TYPE>
1831inline
1832TYPE
1833bdlb::ConstNullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
1834{
1835 return value_or(otherValue);
1836}
1837
1838template <class TYPE>
1839inline
1841{
1842 return has_value() ? &value() : 0;
1843}
1844
1845// FREE FUNCTIONS
1846template <class HASHALG, class TYPE>
1847void bdlb::hashAppend(HASHALG& hashAlg,
1848 const ConstNullableValueRef<TYPE>& input)
1849{
1850 using ::BloombergLP::bslh::hashAppend;
1851
1852 if (!input.has_value()) {
1853 hashAppend(hashAlg, false);
1854 }
1855 else {
1856 hashAppend(hashAlg, true);
1857 hashAppend(hashAlg, input.value());
1858 }
1859}
1860
1861// FREE OPERATORS
1862template <class LHS_TYPE, class RHS_TYPE>
1863inline
1864bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1865 const ConstNullableValueRef<RHS_TYPE>& rhs)
1866{
1867 if (lhs.has_value()) {
1868 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
1869 }
1870
1871 return !rhs.has_value();
1872}
1873
1874template <class LHS_TYPE, class RHS_TYPE>
1875inline
1876bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1877 const RHS_TYPE& rhs)
1878{
1879 return lhs.has_value() ? lhs.value() == rhs : false;
1880}
1881
1882template <class LHS_TYPE, class RHS_TYPE>
1883inline
1884bool bdlb::operator==(const LHS_TYPE& lhs,
1885 const ConstNullableValueRef<RHS_TYPE>& rhs)
1886{
1887 return rhs.has_value() ? lhs == rhs.value(): false;
1888}
1889
1890template <class LHS_TYPE, class RHS_TYPE>
1891inline
1892bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1893 const ConstNullableValueRef<RHS_TYPE>& rhs)
1894{
1895 if (lhs.has_value()) {
1896 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
1897 }
1898
1899 return rhs.has_value();
1900}
1901
1902template <class LHS_TYPE, class RHS_TYPE>
1903inline
1904bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1905 const RHS_TYPE& rhs)
1906{
1907 return lhs.has_value() ? lhs.value() != rhs : true;
1908}
1909
1910template <class LHS_TYPE, class RHS_TYPE>
1911inline
1912bool bdlb::operator!=(const LHS_TYPE& lhs,
1913 const ConstNullableValueRef<RHS_TYPE>& rhs)
1914{
1915 return rhs.has_value() ? lhs != rhs.value() : true;
1916}
1917
1918template <class LHS_TYPE, class RHS_TYPE>
1919inline
1920bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1921 const ConstNullableValueRef<RHS_TYPE>& rhs)
1922{
1923 if (!rhs.has_value()) {
1924 return false; // RETURN
1925 }
1926
1927 return lhs.has_value() ? lhs.value() < rhs.value() : true;
1928}
1929
1930template <class LHS_TYPE, class RHS_TYPE>
1931inline
1932bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1933 const RHS_TYPE& rhs)
1934{
1935 return lhs.has_value() ? lhs.value() < rhs : true;
1936}
1937
1938template <class LHS_TYPE, class RHS_TYPE>
1939inline
1940bool bdlb::operator<(const LHS_TYPE& lhs,
1941 const ConstNullableValueRef<RHS_TYPE>& rhs)
1942{
1943 return rhs.has_value() ? lhs < rhs.value() : false;
1944}
1945
1946template <class LHS_TYPE, class RHS_TYPE>
1947inline
1948bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1949 const ConstNullableValueRef<RHS_TYPE>& rhs)
1950{
1951 if (!lhs.has_value()) {
1952 return true; // RETURN
1953 }
1954
1955 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
1956}
1957
1958template <class LHS_TYPE, class RHS_TYPE>
1959inline
1960bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1961 const RHS_TYPE& rhs)
1962{
1963 return lhs.has_value() ? lhs.value() <= rhs : true;
1964}
1965
1966template <class LHS_TYPE, class RHS_TYPE>
1967inline
1968bool bdlb::operator<=(const LHS_TYPE& lhs,
1969 const ConstNullableValueRef<RHS_TYPE>& rhs)
1970{
1971 return rhs.has_value() ? lhs <= rhs.value() : false;
1972}
1973
1974template <class LHS_TYPE, class RHS_TYPE>
1975inline
1976bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1977 const ConstNullableValueRef<RHS_TYPE>& rhs)
1978{
1979 if (!lhs.has_value()) {
1980 return false; // RETURN
1981 }
1982
1983 return rhs.has_value() ? lhs.value() > rhs.value() : true;
1984}
1985
1986template <class LHS_TYPE, class RHS_TYPE>
1987inline
1988bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1989 const RHS_TYPE& rhs)
1990{
1991 return lhs.has_value() ? lhs.value() > rhs : false;
1992}
1993
1994template <class LHS_TYPE, class RHS_TYPE>
1995inline
1996bool bdlb::operator>(const LHS_TYPE& lhs,
1997 const ConstNullableValueRef<RHS_TYPE>& rhs)
1998{
1999 return rhs.has_value() ? lhs > rhs.value() : true;
2000}
2001
2002template <class LHS_TYPE, class RHS_TYPE>
2003inline
2004bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2005 const ConstNullableValueRef<RHS_TYPE>& rhs)
2006{
2007 if (!rhs.has_value()) {
2008 return true; // RETURN
2009 }
2010
2011 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2012}
2013
2014template <class LHS_TYPE, class RHS_TYPE>
2015inline
2016bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2017 const RHS_TYPE& rhs)
2018{
2019 return lhs.has_value() ? lhs.value() >= rhs : false;
2020}
2021
2022template <class LHS_TYPE, class RHS_TYPE>
2023inline
2024bool bdlb::operator>=(const LHS_TYPE& lhs,
2025 const ConstNullableValueRef<RHS_TYPE>& rhs)
2026{
2027 return rhs.has_value() ? lhs >= rhs.value() : true;
2028}
2029
2030 //--------------------------------
2031 // Comparisons with bsl::nullopt_t
2032 //--------------------------------
2033
2034template <class TYPE>
2035inline
2036bool bdlb::operator==(const ConstNullableValueRef<TYPE>& lhs,
2038{
2039 return !lhs.has_value();
2040}
2041
2042template <class TYPE>
2043inline
2044bool bdlb::operator==(
2045 const bsl::nullopt_t&,
2046 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2047{
2048 return !rhs.has_value();
2049}
2050
2051template <class TYPE>
2052inline bool bdlb::operator!=(const ConstNullableValueRef<TYPE>& lhs,
2054{
2055 return lhs.has_value();
2056}
2057
2058template <class TYPE>
2059inline
2060bool bdlb::operator!=(
2061 const bsl::nullopt_t&,
2062 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2063{
2064 return rhs.has_value();
2065}
2066
2067template <class TYPE>
2068inline
2069bool bdlb::operator<(const ConstNullableValueRef<TYPE>&,
2071{
2072 return false;
2073}
2074
2075template <class TYPE>
2076inline
2077bool bdlb::operator<(
2078 const bsl::nullopt_t&,
2079 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2080{
2081 return rhs.has_value();
2082}
2083
2084template <class TYPE>
2085inline
2086bool bdlb::operator>(const ConstNullableValueRef<TYPE>& lhs,
2088{
2089 return lhs.has_value();
2090}
2091
2092template <class TYPE>
2093inline
2094bool bdlb::operator>(
2095 const bsl::nullopt_t&,
2096 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2097{
2098 return false;
2099}
2100
2101template <class TYPE>
2102inline
2103bool bdlb::operator<=(const ConstNullableValueRef<TYPE>& lhs,
2105{
2106 return !lhs.has_value();
2107}
2108
2109template <class TYPE>
2110inline
2111bool bdlb::operator<=(
2112 const bsl::nullopt_t&,
2113 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2114{
2115 return true;
2116}
2117
2118template <class TYPE>
2119inline
2120bool bdlb::operator>=(const ConstNullableValueRef<TYPE>&,
2122{
2123 return true;
2124}
2125
2126template <class TYPE>
2127inline
2128bool bdlb::operator>=(
2129 const bsl::nullopt_t&,
2130 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2131{
2132 return !rhs.has_value();
2133}
2134
2135 //-------------------------------------------------------------------
2136 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
2137 //-------------------------------------------------------------------
2138
2139template <class LHS_TYPE, class RHS_TYPE>
2140inline
2141bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
2142 const NullableValueRef<RHS_TYPE>& rhs)
2143{
2144 if (lhs.has_value()) {
2145 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2146 }
2147
2148 return !rhs.has_value();
2149}
2150
2151template <class LHS_TYPE, class RHS_TYPE>
2152inline
2153bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
2154 const ConstNullableValueRef<RHS_TYPE>& rhs)
2155{
2156 if (lhs.has_value()) {
2157 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2158 }
2159
2160 return !rhs.has_value();
2161}
2162
2163template <class LHS_TYPE, class RHS_TYPE>
2164inline
2165bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2166 const NullableValueRef<RHS_TYPE>& rhs)
2167{
2168 if (lhs.has_value()) {
2169 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2170 }
2171
2172 return rhs.has_value();
2173}
2174
2175template <class LHS_TYPE, class RHS_TYPE>
2176inline
2177bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
2178 const ConstNullableValueRef<RHS_TYPE>& rhs)
2179{
2180 if (lhs.has_value()) {
2181 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2182 }
2183
2184 return rhs.has_value();
2185}
2186
2187template <class LHS_TYPE, class RHS_TYPE>
2188inline
2189bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
2190 const NullableValueRef<RHS_TYPE>& rhs)
2191{
2192 if (!rhs.has_value()) {
2193 return false; // RETURN
2194 }
2195
2196 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2197}
2198
2199template <class LHS_TYPE, class RHS_TYPE>
2200inline
2201bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
2202 const ConstNullableValueRef<RHS_TYPE>& rhs)
2203{
2204 if (!rhs.has_value()) {
2205 return false; // RETURN
2206 }
2207
2208 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2209}
2210
2211template <class LHS_TYPE, class RHS_TYPE>
2212inline
2213bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2214 const NullableValueRef<RHS_TYPE>& rhs)
2215{
2216 if (!lhs.has_value()) {
2217 return true; // RETURN
2218 }
2219
2220 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2221}
2222
2223template <class LHS_TYPE, class RHS_TYPE>
2224inline
2225bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
2226 const ConstNullableValueRef<RHS_TYPE>& rhs)
2227{
2228 if (!lhs.has_value()) {
2229 return true; // RETURN
2230 }
2231
2232 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2233}
2234
2235template <class LHS_TYPE, class RHS_TYPE>
2236inline
2237bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2238 const NullableValueRef<RHS_TYPE>& rhs)
2239{
2240 if (!lhs.has_value()) {
2241 return false; // RETURN
2242 }
2243
2244 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2245}
2246
2247template <class LHS_TYPE, class RHS_TYPE>
2248inline
2249bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
2250 const ConstNullableValueRef<RHS_TYPE>& rhs)
2251{
2252 if (!lhs.has_value()) {
2253 return false; // RETURN
2254 }
2255
2256 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2257}
2258
2259template <class LHS_TYPE, class RHS_TYPE>
2260inline
2261bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2262 const NullableValueRef<RHS_TYPE>& rhs)
2263{
2264 if (!rhs.has_value()) {
2265 return true; // RETURN
2266 }
2267
2268 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2269}
2270
2271template <class LHS_TYPE, class RHS_TYPE>
2272inline
2273bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
2274 const ConstNullableValueRef<RHS_TYPE>& rhs)
2275{
2276 if (!rhs.has_value()) {
2277 return true; // RETURN
2278 }
2279
2280 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2281}
2282
2283
2284
2285#endif // End C++11 code
2286
2287#endif // INCLUDED_BDLB_NULLABLEVALUEREF
2288
2289// ----------------------------------------------------------------------------
2290// Copyright 2023 Bloomberg Finance L.P.
2291//
2292// Licensed under the Apache License, Version 2.0 (the "License");
2293// you may not use this file except in compliance with the License.
2294// You may obtain a copy of the License at
2295//
2296// http://www.apache.org/licenses/LICENSE-2.0
2297//
2298// Unless required by applicable law or agreed to in writing, software
2299// distributed under the License is distributed on an "AS IS" BASIS,
2300// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2301// See the License for the specific language governing permissions and
2302// limitations under the License.
2303// ----------------------------- END-OF-FILE ----------------------------------
2304
2305/** @} */
2306/** @} */
2307/** @} */
Definition bdlb_nullablevalueref.h:633
BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::addressOr", "Use 'has_value() ? &value() : address' instead") const TYPE *addressOr(const TYPE *address) const
TYPE value_type
Definition bdlb_nullablevalueref.h:686
Definition bdlb_nullableallocatedvalue.h:174
void reset()
Definition bdlb_nullableallocatedvalue.h:1104
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1349
TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)...)
TYPE & value()
Definition bdlb_nullableallocatedvalue.h:1139
Definition bdlb_nullablevalueref.h:163
BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::valueOr", "Use 'value_or' instead") TYPE valueOr(const TYPE &otherValue) const
TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)...)
TYPE value_type
Definition bdlb_nullablevalueref.h:220
BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace", "Use 'emplace' instead") TYPE &makeValueInplace(ARGS &&... args)
BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::addressOr", "Use 'has_value() ? &value() : address' instead") const TYPE *addressOr(const TYPE *address) const
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_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_EXPLICIT
Definition bsls_keyword.h:641
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
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