BDE 4.39.x 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#include <bslmf_util.h> // 'forward(V)' for C++03
128
129#include <bsls_deprecate.h>
131
132#include <bsls_assert.h>
134#include <bsls_keyword.h>
135#include <bsls_unspecifiedbool.h>
136#include <bsls_util.h> // 'forward<T>(V)' for C++11
137
138#include <bslstl_optional.h> // bsl::optional, bsl::nullopt_t
139
140#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
141// clang-format off
142// Include version that can be compiled with C++03
143// Generated on Mon Jan 13 08:32:07 2025
144// Command line: sim_cpp11_features.pl bdlb_nullablevalueref.h
145
146# define COMPILING_BDLB_NULLABLEVALUEREF_H
148# undef COMPILING_BDLB_NULLABLEVALUEREF_H
149
150// clang-format on
151#else
152
153
154namespace bdlb {
155
156template <class TYPE>
157class ConstNullableValueRef;
158
159 // ============================
160 // class NullableValueRef<TYPE>
161 // ============================
162
163/// This class is a wrapper for either a `bsl::optional` or
164/// `NullableAllocatedValue`, and provides modifiable access to the wrapped
165/// object.
166///
167/// See @ref bdlb_nullablevalueref
168template <class TYPE>
170
171 // PRIVATE TYPES
172#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
173 // UNSPECIFIED BOOL
174
175 /// This type is needed only in C++03 mode, where `explicit` conversion
176 /// operators are not supported. A `NullableAllocatedValue` is implicitly
177 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
178 /// implicitly convertible to `bool`.
179 typedef BloombergLP::bsls::UnspecifiedBool<NullableValueRef>
180 UnspecifiedBoolUtil;
181 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
182#endif
183
184 // DATA
185
186 // the address of the target
187 void *d_target_p;
188
189 // `true` if the target is a specialization of `bsl::optional`, and
190 // `false` it's a specialization of `NullableAllocatedValue`
191 bool d_isTargetOptional;
192
193 // PRIVATE ACCESSORS
194
195 /// Return a reference providing non-const access to the held `NullableAllocatedValue` object.
196 ///
197 /// \pre The behavior is undefined if the
198 /// target is not a `NullableAllocatedValue`.
199 NullableAllocatedValue<TYPE>& getNAV() const;
200
201 /// Return a reference providing non-const access to the held `bsl::optional` object.
202 ///
203 /// \pre The behavior is undefined if the target is
204 /// not a `bdlb::bsl::optional`.
205 bsl::optional<TYPE>& getOpt() const;
206
207 /// Return `true` if the target of this object is a `bsl::optional`, and
208 /// `false` otherwise.
209 bool hasOpt() const;
210
211 // FRIENDS
212 friend class ConstNullableValueRef<TYPE>;
213
214 // TRAITS
215
216 // This class requires that `TYPE` is not `const`- or `volatile`-
217 // qualified, nor a reference.
219 bsl::is_same<TYPE,
220 typename bsl::remove_cvref<TYPE>::type>::value));
221
222 public:
223 // TYPES
224
225 /// `value_type` is an alias for the template parameter `TYPE`, and
226 /// represents the type of the object managed by the wrapped nullable
227 /// object.
228 typedef TYPE value_type;
229
230 // CREATORS
231
232 /// Create a nullable object wrapper that refers to the specified `opt` object.
233 ///
234 /// \note Note that the created wrapper does not own a copy of the
235 /// underlying nullable value, but instead refers to it, and so the
236 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
237 NullableValueRef(bsl::optional<TYPE>& opt); // IMPLICIT
238
239 /// Create a nullable object wrapper that refers to the specified `opt` object.
240 ///
241 /// \note Note that the created wrapper does not own a copy of the
242 /// underlying nullable value, but instead refers to it, and so the
243 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
245
246 /// Create a nullable object wrapper that refers to the target object of the specified `original` wrapper.
247 ///
248 /// \note Note that the created wrapper
249 /// does not own a copy of the underlying nullable value, but instead
250 /// refers to it, and so the lifetime of the target must exceed the
251 /// lifetime of the created wrapper.
252 NullableValueRef(const NullableValueRef& original);
253
254 /// Destroy this object.
255 /// \note Note that this destructor is generated by the
256 /// compiler, and does not destroy the target.
258
259 // ACCESSORS
260
261 /// Return `true` if the target contains a value, and `false` otherwise.
262 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
263
264 /// Return `false` if the target contains a value, and `true` otherwise.
265 ///
266 /// \note Note that this accessor is provided purely for compatibility with
267 /// `NullableValue` and `NullableAllocatedValue`, and its use is
268 /// discouraged in favor of @ref has_value .
269 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
270
271 /// Return a reference providing non-modifiable access to the underlying
272 /// object of a (template parameter) `TYPE`.
273 ///
274 /// \pre The behavior is undefined if the target has no value.
275 const value_type& value() const;
276
277 /// Return a pointer providing non-modifiable access to the underlying `TYPE` object.
278 ///
279 /// \pre The behavior is undefined if the target has no
280 /// value.
281 const value_type *operator->() const;
282
283 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
284 ///
285 /// \pre The behavior is undefined if the target has no
286 /// value.
287 const value_type& operator*() const;
288
289#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
290 /// Return `true` if the target holds a value, and `false` otherwise.
291 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
292#else
293 /// Simulation of explicit conversion to bool. Inlined to work around xlC
294 /// but when out-of-line.
295 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
296 {
297 return UnspecifiedBoolUtil::makeValue(has_value());
298 }
299#endif
300
301 /// Return the value of the underlying object of a (template parameter)
302 /// `TYPE` if the target is non-null, and the specified @ref default_value otherwise.
303 ///
304 /// \note Note that this method returns *by* *value*, so may be
305 /// inefficient in some contexts.
306 template <class ANY_TYPE>
307 TYPE value_or(const ANY_TYPE& default_value) const;
308
309 // MANIPULATORS
310#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
311 /// Assign to the target the value of the (template parameter) `TYPE`
312 /// created in place using the specified `args` and return a reference
313 /// providing modifiable access to the underlying `TYPE` object. If
314 /// this `optional` object already contains an object (`true ==
315 /// hasValue()`), that object is destroyed before the new object is created.
316 ///
317 /// \note Note that if the constructor of `TYPE` throws an exception
318 /// this object is left in a disengaged state.
319 template <class... ARGS>
321#endif
322
323 /// Return a pointer providing modifiable access to the underlying `TYPE` object.
324 ///
325 /// \pre The behavior is undefined if the target has no
326 /// value.
328
329 /// Return a reference providing modifiable access to the underlying `TYPE` object.
330 ///
331 /// \pre The behavior is undefined if the target has no
332 /// value.
334
335 /// Reset the target to the default constructed state (i.e., to have the
336 /// null value).
338
339 /// Assign to the target the value of the specified `rhs`, and return a
340 /// reference providing modifiable access to this object.
341 NullableValueRef<TYPE>& operator=(const TYPE& rhs);
342
343 /// Assign to the target the value of the specified `rhs`, and return a
344 /// reference providing modifiable access to this object.
346
347 /// Assign to the target the value of the specified `rhs`, and return a
348 /// reference providing modifiable access to this object.
351
352 /// Assign to the target the value of the specified `rhs`, and return a
353 /// reference providing modifiable access to this object.
355
356 /// Reset the target to the default constructed state (i.e., to have the
357 /// null value).
358 void reset();
359
360 /// Return a reference providing modifiable access to the underlying `TYPE` object.
361 ///
362 /// \pre The behavior is undefined unless this object is
363 /// non-null.
364 value_type& value();
365
366 // DEPRECATED FUNCTIONS
367 // provided for compatibility with NullableValue
368
369 /// Return an address providing non-modifiable access to the underlying
370 /// object of a (template parameter) `TYPE` if this object is non-null,
371 /// and the specified `address` otherwise.
372 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::addressOr",
373 "Use 'has_value() ? &value() : address' instead")
374 const TYPE *addressOr(const TYPE *address) const;
375
376#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=5
377
378 /// Assign to this nullable object the value of the (template parameter)
379 /// `TYPE` created in place using the specified `args`. Return a
380 /// reference providing modifiable access to the created (value) object.
381 /// The object is also accessible via the `value` method. If this
382 /// nullable object already contains an object (`false == isNull()`),
383 /// that object is destroyed before the new object is created. If
384 /// `TYPE` has the trait `bslma::UsesBslmaAllocator` (`TYPE` is
385 /// allocator-enabled) the allocator specified at the construction of
386 /// this nullable object is used to supply memory to the value object.
387 /// Attempts to explicitly specify via `args` another allocator to
388 /// supply memory to the created (value) object are disallowed by the compiler.
389 ///
390 /// \note Note that if the constructor of `TYPE` throws an
391 /// exception this object is left in the null state.
392 template <class... ARGS>
393 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::makeValueInplace",
394 "Use 'emplace' instead")
395 TYPE& makeValueInplace(ARGS&&... args);
396#endif
397
398 /// Return the value of the underlying object of a (template parameter)
399 /// `TYPE` if this object is non-null, and the specified `otherValue` otherwise.
400 ///
401 /// \note Note that this method returns *by* *value*, so may be
402 /// inefficient in some contexts.
403 BSLS_DEPRECATE_FEATURE("bdl", "NullableValueRef::valueOr",
404 "Use 'value_or' instead")
405 TYPE valueOr(const TYPE& otherValue) const;
406
407 /// Return an address providing non-modifiable access to the underlying
408 /// object of a (template parameter) `TYPE` if this object is non-null,
409 /// and 0 otherwise.
411 "Use 'has_value() ? &value() : NULL' instead")
412 const TYPE *valueOrNull() const;
413};
414
415// FREE FUNCTIONS
416
417/// Pass the boolean value of whether the specified `input` references a
418/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
419/// (template parameter) type `HASHALG`. If `input.has_value` is true,
420/// additionally pass the value to `hashAlg`.
421template <class HASHALG, class TYPE>
422void hashAppend(HASHALG& hashAlg, const NullableValueRef<TYPE>& input);
423
424// FREE OPERATORS
425
426/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
427/// the same value, and `false` otherwise. Two nullable wrappers have the
428/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
429///
430/// \note Note that this
431/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
432/// compatible.
433template <class LHS_TYPE, class RHS_TYPE>
434bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
435 const NullableValueRef<RHS_TYPE>& rhs);
436
437/// Return `true` if the specified `lhs` and `rhs` objects have the same
438/// value, and `false` otherwise. A nullable wrapper and a value of some
439/// type have the same value if the nullable wrapper is non-null and the
440/// underlying value of it's target compares equal to the other value.
441///
442/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
443/// not compatible.
444template <class LHS_TYPE, class RHS_TYPE>
445bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
446 const RHS_TYPE& rhs);
447template <class LHS_TYPE, class RHS_TYPE>
448bool operator==(const LHS_TYPE& lhs,
449 const NullableValueRef<RHS_TYPE>& rhs);
450
451/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
452/// have the same value, and `false` otherwise. Two nullable wrappers do
453/// not have the same value if one is null and the other is non-null, or if
454/// both are non-null and the values of their underlying objects do not compare equal.
455///
456/// \note Note that this function will fail to compile if
457/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
458template <class LHS_TYPE, class RHS_TYPE>
459bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
460 const NullableValueRef<RHS_TYPE>& rhs);
461
462/// Return `true` if the specified `lhs` and `rhs` objects do not have the
463/// same value, and `false` otherwise. A nullable wrappers and a value of
464/// some type do not have the same value if either the nullable wrappers is
465/// null, or its underlying value does not compare equal to the other value.
466///
467/// \note Note that this function will fail to compile if `LHS_TYPE` and
468/// `RHS_TYPE` are not compatible.
469template <class LHS_TYPE, class RHS_TYPE>
470bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
471 const RHS_TYPE& rhs);
472template <class LHS_TYPE, class RHS_TYPE>
473bool operator!=(const LHS_TYPE& lhs,
474 const NullableValueRef<RHS_TYPE>& rhs);
475
476/// Return `true` if the specified `lhs` nullable wrapper is ordered before
477/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
478/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
479/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
480///
481/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
482/// not compatible.
483template <class LHS_TYPE, class RHS_TYPE>
484bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
485 const NullableValueRef<RHS_TYPE>& rhs);
486
487/// Return `true` if the specified `lhs` nullable wrapper is ordered before
488/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
489/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
490template <class LHS_TYPE, class RHS_TYPE>
491bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
492 const RHS_TYPE& rhs);
493
494/// Return `true` if the specified `lhs` is ordered before the specified
495/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
496/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
497template <class LHS_TYPE, class RHS_TYPE>
498bool operator<(const LHS_TYPE& lhs,
499 const NullableValueRef<RHS_TYPE>& rhs);
500
501
502/// Return `true` if the specified `lhs` nullable wrapper is ordered before
503/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
504/// value, and `false` otherwise. (See `operator<` and `operator==`.)
505///
506/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
507/// are not compatible.
508template <class LHS_TYPE, class RHS_TYPE>
509bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
510 const NullableValueRef<RHS_TYPE>& rhs);
511
512/// Return `true` if the specified `lhs` nullable wrapper is ordered before
513/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
514///
515/// \note Note that this operator
516/// returns `!(rhs < lhs)`.
517template <class LHS_TYPE, class RHS_TYPE>
518bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
519 const RHS_TYPE& rhs);
520
521/// Return `true` if the specified `lhs` is ordered before the specified
522/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
523///
524/// \note Note that this
525/// operator returns `!(rhs < lhs)`.
526template <class LHS_TYPE, class RHS_TYPE>
527bool operator<=(const LHS_TYPE& lhs,
528 const NullableValueRef<RHS_TYPE>& rhs);
529
530/// Return `true` if the specified `lhs` nullable wrapper is ordered after
531/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
532/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
533/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
534///
535/// \note Note that this operator returns `rhs < lhs` when both operands are of
536/// `bsl::optional` type. Also note that this function will fail to compile
537/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
538template <class LHS_TYPE, class RHS_TYPE>
539bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
540 const NullableValueRef<RHS_TYPE>& rhs);
541
542/// Return `true` if the specified `lhs` nullable wrapper is ordered after
543/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
544/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
545///
546/// \note 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()`.
554///
555/// \note Note that this operator returns `rhs < lhs`.
556template <class LHS_TYPE, class RHS_TYPE>
557bool operator>(const LHS_TYPE& lhs,
558 const NullableValueRef<RHS_TYPE>& rhs);
559
560/// Return `true` if the specified `lhs` nullable object is ordered after
561/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
562/// value, and `false` otherwise. (See `operator>` and `operator==`.)
563///
564/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
565/// `bsl::optional` type. Also note that this function will fail to compile
566/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
567template <class LHS_TYPE, class RHS_TYPE>
568bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
569 const NullableValueRef<RHS_TYPE>& rhs);
570
571/// Return `true` if the specified `lhs` nullable wrapper is ordered after
572/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
573///
574/// \note Note that this operator
575/// returns `!(lhs < rhs)`.
576template <class LHS_TYPE, class RHS_TYPE>
577bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
578 const RHS_TYPE& rhs);
579
580/// Return `true` if the specified `lhs` is wrapper after the specified
581/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
582///
583/// \note Note that this
584/// operator returns `!(lhs < rhs)`.
585template <class LHS_TYPE, class RHS_TYPE>
586bool operator>=(const LHS_TYPE& lhs,
587 const NullableValueRef<RHS_TYPE>& rhs);
588
589
590 //================================
591 // Comparisons with bsl::nullopt_t
592 //================================
593
594/// Return `true` if the specified `lhs` is null, and `false` otherwise.
595template <class TYPE>
596bool operator==(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
598
599/// Return `true` if the specified `rhs` is null, and `false` otherwise.
600template <class TYPE>
601bool operator==(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
603
604/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
605template <class TYPE>
606bool operator!=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
608
609/// Return `true` if the specified `rhs` is not null, and `false`
610/// otherwise.
611template <class TYPE>
612bool operator!=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
614
615/// Return `false`. `bsl::nullopt` never orders after a
616/// `NullableValueRef`.
617template <class TYPE>
618bool operator<(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
620
621/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
622///
623/// \note Note that `bsl::nullopt` is ordered before any `NullableValueRef` that
624/// is not null.
625template <class TYPE>
626bool operator<(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
628
629/// Return `true` if the specified `lhs` is not null, and `false`
630/// otherwise.
631template <class TYPE>
632bool operator>(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
634
635/// Return `false`. `bsl::nullopt` never orders after a
636/// `NullableValueRef`.
637template <class TYPE>
638bool operator>(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
640
641/// Return `true` if the specified `lhs` is null, and `false` otherwise.
642template <class TYPE>
643bool operator<=(const NullableValueRef<TYPE>& lhs, const bsl::nullopt_t&)
645
646/// Return `true`.
647template <class TYPE>
648bool operator<=(const bsl::nullopt_t&, const NullableValueRef<TYPE>&)
650
651/// Return `true`.
652template <class TYPE>
653bool operator>=(const NullableValueRef<TYPE>&, const bsl::nullopt_t&)
655
656/// Return `true` if the specified `rhs` is null, and `false` otherwise.
657template <class TYPE>
658bool operator>=(const bsl::nullopt_t&, const NullableValueRef<TYPE>& rhs)
660
661 // =================================
662 // class ConstNullableValueRef<TYPE>
663 // =================================
664
665/// This class is a wrapper for either a `bsl::optional` or
666/// `NullableAllocatedValue`, and provides non-modifiable access to the
667/// wrapped object.
668///
669/// See @ref bdlb_nullablevalueref
670template <class TYPE>
672
673 // PRIVATE TYPES
674#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
675 // UNSPECIFIED BOOL
676
677 /// This type is needed only in C++03 mode, where `explicit` conversion
678 /// operators are not supported. A `NullableAllocatedValue` is implicitly
679 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
680 /// implicitly convertible to `bool`.
681 typedef BloombergLP::bsls::UnspecifiedBool<ConstNullableValueRef>
682 UnspecifiedBoolUtil;
683 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
684#endif
685
686 // DATA
687
688 // the address of the target
689 const void *d_target_p;
690
691 // `true` if the referent is a specialization of `bsl::optional`, and
692 // `false` if it's a specialization of `NullableAllocatedValue`.
693 bool d_isTargetOptional;
694
695 // PRIVATE ACCESSORS
696
697 /// Return a pointer to the held `bdlb::NullableAllocatedValue`.
698 ///
699 /// \pre The behavior is undefined if the target is not a
700 /// `bdlb::NullableAllocatedValue`.
701 const NullableAllocatedValue<TYPE>& getNAV() const;
702
703 /// Return a pointer to the held `bdlb::bsl::optional`.
704 ///
705 /// \pre The behavior is undefined if the target is not a `bdlb::bsl::optional`.
706 const bsl::optional<TYPE>& getOpt() const;
707
708 /// Return `true` if this object currently holds a pointer to a
709 /// bdlb::bsl::optional, and `false` otherwise.
710 bool hasOpt() const;
711
712 // TRAITS
713
714 /// This class requires that `TYPE` is not `const`- or `volatile`-
715 /// qualified, nor a reference.
717 bsl::is_same<TYPE,
718 typename bsl::remove_cvref<TYPE>::type>::value));
719
720 public:
721 // TYPES
722
723 /// `value_type` is an alias for the template parameter `TYPE`, and
724 /// represents the type of the object managed by the wrapped nullable
725 /// object.
726 typedef TYPE value_type;
727
728 // CREATORS
729
730 /// Create a nullable object wrapper that refers to the specified `opt` object.
731 ///
732 /// \note Note that the created wrapper does not own a copy of the
733 /// underlying nullable value, but instead refers to it, and so the
734 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
735 ConstNullableValueRef(const bsl::optional<TYPE>& opt); // IMPLICIT
736
737 /// Create a nullable object wrapper that refers to the specified `opt` object.
738 ///
739 /// \note Note that the created wrapper does not own a copy of the
740 /// underlying nullable value, but instead refers to it, and so the
741 /// lifetime of `opt` must exceed the lifetime of the created wrapper.
743 // IMPLICIT
744
745 /// Create a nullable object wrapper that refers to the target object of the specified `ref` wrapper.
746 ///
747 /// \note Note that the created wrapper does not
748 /// own a copy of the underlying nullable value, but instead refers to
749 /// to it, and so the lifetime of the target must exceed the lifetime of
750 /// the created wrapper.
751 ConstNullableValueRef(const NullableValueRef<TYPE>& ref); // IMPLICIT
752
753 /// Create a nullable object wrapper that refers to the target object of the specified `original` wrapper.
754 ///
755 /// \note Note that the created wrapper
756 /// does not own a copy of the underlying nullable value, but instead
757 /// refers to it, and so the lifetime of the target must exceed the
758 /// lifetime of the created wrapper.
760
761 /// Destroy this object.
762 /// \note Note that this destructor is generated by the
763 /// compiler, and does not destruct the target.
765
766 // ACCESSORS
767
768 /// Return `true` if the target contains a value, and `false` otherwise.
769 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
770
771 /// Return `false` if the target contains a value, and `true` otherwise.
772 ///
773 /// \note Note that this accessor is provided purely for compatibility with
774 /// `NullableValue` and `NullableAllocatedValue`, and its use is
775 /// discouraged in favor of @ref has_value .
776 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
777
778 /// Return a reference providing non-modifiable access to the underlying
779 /// object of a (template parameter) `TYPE`.
780 ///
781 /// \pre The behavior is undefined if the target has no value.
782 const value_type& value() const;
783
784 /// Return a pointer providing non-modifiable access to the underlying `TYPE` object.
785 ///
786 /// \pre The behavior is undefined if the target has no
787 /// value.
788 const value_type *operator->() const;
789
790 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
791 ///
792 /// \pre The behavior is undefined if the target has no
793 /// value.
794 const value_type& operator*() const;
795
796#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
797 /// Return `true` if the target holds a value, and `false` otherwise.
798 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
799#else
800 /// Simulation of explicit conversion to bool. Inlined to work around xlC
801 /// but when out-of-line.
802 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
803 {
804 return UnspecifiedBoolUtil::makeValue(has_value());
805 }
806#endif
807
808 /// Return the value of the underlying object of a (template parameter)
809 /// `TYPE` if the target is non-null, and the specified @ref default_value otherwise.
810 ///
811 /// \note Note that this method returns *by* *value*, so may be
812 /// inefficient in some contexts.
813 template <class ANY_TYPE>
814 TYPE value_or(const ANY_TYPE& default_value) const;
815
816 // DEPRECATED FUNCTIONS
817 // provided for compatibility with NullableValue
818
819 /// Return an address providing non-modifiable access to the underlying
820 /// object of a (template parameter) `TYPE` if this object is non-null,
821 /// and the specified `address` otherwise.
822 BSLS_DEPRECATE_FEATURE("bdl", "ConstNullableValueRef::addressOr",
823 "Use 'has_value() ? &value() : address' instead")
824 const TYPE *addressOr(const TYPE *address) const;
825
826 /// Return the value of the underlying object of a (template parameter)
827 /// `TYPE` if this object is non-null, and the specified `otherValue` otherwise.
828 ///
829 /// \note Note that this method returns *by* *value*, so may be
830 /// inefficient in some contexts.
832 "Use 'value_or' instead")
833 TYPE valueOr(const TYPE& otherValue) const;
834
835 /// Return an address providing non-modifiable access to the underlying
836 /// object of a (template parameter) `TYPE` if this object is non-null,
837 /// and 0 otherwise.
839 "Use 'has_value() ? &value() : NULL' instead")
840 const TYPE *valueOrNull() const;
841
842};
843
844// FREE FUNCTIONS
845
846/// Pass the boolean value of whether the specified `input` references a
847/// non-empty nullable value to the specified `hashAlg` hashing algorithm of
848/// (template parameter) type `HASHALG`. If `input.has_value` is true,
849/// additionally pass the value to `hashAlg`.
850template <class HASHALG, class TYPE>
851void hashAppend(HASHALG& hashAlg, const ConstNullableValueRef<TYPE>& input);
852
853// FREE OPERATORS
854
855/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
856/// the same value, and `false` otherwise. Two nullable wrappers have the
857/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
858///
859/// \note Note that this
860/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
861/// compatible.
862template <class LHS_TYPE, class RHS_TYPE>
863bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
864 const ConstNullableValueRef<RHS_TYPE>& rhs);
865
866/// Return `true` if the specified `lhs` and `rhs` objects have the same
867/// value, and `false` otherwise. A nullable wrapper and a value of some
868/// type have the same value if the nullable wrapper is non-null and the
869/// underlying value of it's target compares equal to the other value.
870///
871/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
872/// not compatible.
873template <class LHS_TYPE, class RHS_TYPE>
874bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
875 const RHS_TYPE& rhs);
876template <class LHS_TYPE, class RHS_TYPE>
877bool operator==(const LHS_TYPE& lhs,
878 const ConstNullableValueRef<RHS_TYPE>& rhs);
879
880/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
881/// have the same value, and `false` otherwise. Two nullable wrappers do
882/// not have the same value if one is null and the other is non-null, or if
883/// bost are non-null and the values of their underlying objects do not compare equal.
884///
885/// \note Note that this function will fail to compile if
886/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
887template <class LHS_TYPE, class RHS_TYPE>
888bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
889 const ConstNullableValueRef<RHS_TYPE>& rhs);
890
891/// Return `true` if the specified `lhs` and `rhs` objects do not have the
892/// same value, and `false` otherwise. A nullable wrappers and a value of
893/// some type do not have the same value if either the nullable wrappers is
894/// null, or its underlying value does not compare equal to the other value.
895///
896/// \note Note that this function will fail to compile if `LHS_TYPE` and
897/// `RHS_TYPE` are not compatible.
898template <class LHS_TYPE, class RHS_TYPE>
899bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
900 const RHS_TYPE& rhs);
901template <class LHS_TYPE, class RHS_TYPE>
902bool operator!=(const LHS_TYPE& lhs,
903 const ConstNullableValueRef<RHS_TYPE>& rhs);
904
905/// Return `true` if the specified `lhs` nullable wrapper is ordered before
906/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
907/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
908/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
909///
910/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
911/// 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`, and `false` otherwise. `lhs` is ordered before
918/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
919template <class LHS_TYPE, class RHS_TYPE>
920bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
921 const RHS_TYPE& rhs);
922
923/// Return `true` if the specified `lhs` is ordered before the specified
924/// `rhs` nullable wrappers, and `false` otherwise. `lhs` is ordered before
925/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
926template <class LHS_TYPE, class RHS_TYPE>
927bool operator<(const LHS_TYPE& lhs,
928 const ConstNullableValueRef<RHS_TYPE>& rhs);
929
930/// Return `true` if the specified `lhs` nullable wrapper is ordered before
931/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
932/// value, and `false` otherwise. (See `operator<` and `operator==`.)
933///
934/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
935/// are not compatible.
936template <class LHS_TYPE, class RHS_TYPE>
937bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
938 const ConstNullableValueRef<RHS_TYPE>& rhs);
939
940/// Return `true` if the specified `lhs` nullable wrapper is ordered before
941/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
942///
943/// \note Note that this operator
944/// returns `!(rhs < lhs)`.
945template <class LHS_TYPE, class RHS_TYPE>
946bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
947 const RHS_TYPE& rhs);
948
949/// Return `true` if the specified `lhs` is ordered before the specified
950/// `rhs` nullable wrapper or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
951///
952/// \note Note that this
953/// operator returns `!(rhs < lhs)`.
954template <class LHS_TYPE, class RHS_TYPE>
955bool operator<=(const LHS_TYPE& lhs,
956 const ConstNullableValueRef<RHS_TYPE>& rhs);
957
958/// Return `true` if the specified `lhs` nullable wrapper is ordered after
959/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
960/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
961/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
962///
963/// \note Note that this operator returns `rhs < lhs` when both operands are of
964/// `NullableValue` type. Also note that this function will fail to compile
965/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
966template <class LHS_TYPE, class RHS_TYPE>
967bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
968 const ConstNullableValueRef<RHS_TYPE>& rhs);
969
970/// Return `true` if the specified `lhs` nullable wrapper is ordered after
971/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
972/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
973///
974/// \note Note that this operator returns `rhs < lhs`.
975template <class LHS_TYPE, class RHS_TYPE>
976bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
977 const RHS_TYPE& rhs);
978
979/// Return `true` if the specified `lhs` is ordered after the specified
980/// `rhs` nullable wrapper, and `false` otherwise. `lhs` is ordered after
981/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`.
982///
983/// \note Note that this operator returns `rhs < lhs`.
984template <class LHS_TYPE, class RHS_TYPE>
985bool operator>(const LHS_TYPE& lhs,
986 const ConstNullableValueRef<RHS_TYPE>& rhs);
987
988/// Return `true` if the specified `lhs` nullable object is ordered after
989/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
990/// value, and `false` otherwise. (See `operator>` and `operator==`.)
991///
992/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
993/// `NullableValue` type. Also note that this function will fail to compile
994/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
995template <class LHS_TYPE, class RHS_TYPE>
996bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
997 const ConstNullableValueRef<RHS_TYPE>& rhs);
998
999/// Return `true` if the specified `lhs` nullable wrapper is ordered after
1000/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
1001///
1002/// \note Note that this operator
1003/// returns `!(lhs < rhs)`.
1004template <class LHS_TYPE, class RHS_TYPE>
1005bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1006 const RHS_TYPE& rhs);
1007
1008/// Return `true` if the specified `lhs` is wrapper after the specified
1009/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
1010///
1011/// \note Note that this
1012/// operator returns `!(lhs < rhs)`.
1013template <class LHS_TYPE, class RHS_TYPE>
1014bool operator>=(const LHS_TYPE& lhs,
1015 const ConstNullableValueRef<RHS_TYPE>& rhs);
1016
1017 //================================
1018 // Comparisons with bsl::nullopt_t
1019 //================================
1020
1021/// Return `true` if the specified `lhs` is null, and `false` otherwise.
1022template <class TYPE>
1023bool operator==(const ConstNullableValueRef<TYPE>& lhs,
1024 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1025
1026/// Return `true` if the specified `rhs` is null, and `false` otherwise.
1027template <class TYPE>
1028bool operator==(const bsl::nullopt_t&,
1030
1031/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
1032template <class TYPE>
1033bool operator!=(const ConstNullableValueRef<TYPE>& lhs,
1034 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1035
1036/// Return `true` if the specified `rhs` is not null, and `false`
1037/// otherwise.
1038template <class TYPE>
1039bool operator!=(const bsl::nullopt_t&,
1041
1042/// Return `false`. `bsl::nullopt` never orders after a
1043/// `ConstNullableValueRef`.
1044template <class TYPE>
1045bool operator<(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
1047
1048/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
1049///
1050/// \note Note that `bsl::nullopt` is ordered before any `ConstNullableValueRef`
1051/// that is not null.
1052template <class TYPE>
1053bool operator<(const bsl::nullopt_t&,
1055
1056/// Return `true` if the specified `lhs` is not null, and `false`
1057/// otherwise.
1058template <class TYPE>
1059bool operator>(const ConstNullableValueRef<TYPE>& lhs,
1060 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1061
1062/// Return `false`. `bsl::nullopt` never orders after a
1063/// `NullableValueRef`.
1064template <class TYPE>
1065bool operator>(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1067
1068/// Return `true` if the specified `lhs` is null, and `false` otherwise.
1069template <class TYPE>
1070bool operator<=(const ConstNullableValueRef<TYPE>& lhs,
1071 const bsl::nullopt_t&) BSLS_KEYWORD_NOEXCEPT;
1072
1073/// Return `true`.
1074template <class TYPE>
1075bool operator<=(const bsl::nullopt_t&, const ConstNullableValueRef<TYPE>&)
1077
1078/// Return `true`.
1079template <class TYPE>
1080bool operator>=(const ConstNullableValueRef<TYPE>&, const bsl::nullopt_t&)
1082
1083/// Return `true` if the specified `rhs` is null, and `false` otherwise.
1084template <class TYPE>
1085bool operator>=(const bsl::nullopt_t&,
1087
1088 //===================================================================
1089 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
1090 //===================================================================
1091
1092/// Return `true` if the specified `lhs` and `rhs` nullable wrappers have
1093/// the same value, and `false` otherwise. Two nullable wrappers have the
1094/// same value if both targets are null, or if both are non-null and the values of their underlying objects compare equal.
1095///
1096/// \note Note that this
1097/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
1098/// compatible.
1099template <class LHS_TYPE, class RHS_TYPE>
1100bool operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1101 const NullableValueRef<RHS_TYPE>& rhs);
1102template <class LHS_TYPE, class RHS_TYPE>
1103bool operator==(const NullableValueRef<LHS_TYPE>& lhs,
1104 const ConstNullableValueRef<RHS_TYPE>& rhs);
1105
1106/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
1107/// have the same value, and `false` otherwise. Two nullable wrappers do
1108/// not have the same value if one is null and the other is non-null, or if
1109/// both are non-null and the values of their underlying objects do not compare equal.
1110///
1111/// \note Note that this function will fail to compile if
1112/// `LHS_TYPE` and `RHS_TYPE` are not compatible.
1113template <class LHS_TYPE, class RHS_TYPE>
1114bool operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1115 const NullableValueRef<RHS_TYPE>& rhs);
1116template <class LHS_TYPE, class RHS_TYPE>
1117bool operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1118 const ConstNullableValueRef<RHS_TYPE>& rhs);
1119
1120/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1121/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1122/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
1123/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
1124///
1125/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
1126/// not compatible.
1127template <class LHS_TYPE, class RHS_TYPE>
1128bool operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1129 const NullableValueRef<RHS_TYPE>& rhs);
1130template <class LHS_TYPE, class RHS_TYPE>
1131bool operator<(const NullableValueRef<LHS_TYPE>& lhs,
1132 const ConstNullableValueRef<RHS_TYPE>& rhs);
1133
1134/// Return `true` if the specified `lhs` nullable wrapper is ordered before
1135/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
1136/// value, and `false` otherwise. (See `operator<` and `operator==`.)
1137///
1138/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE`
1139/// are not compatible.
1140template <class LHS_TYPE, class RHS_TYPE>
1141bool operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1142 const NullableValueRef<RHS_TYPE>& rhs);
1143template <class LHS_TYPE, class RHS_TYPE>
1144bool operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1145 const ConstNullableValueRef<RHS_TYPE>& rhs);
1146
1147/// Return `true` if the specified `lhs` nullable wrapper is ordered after
1148/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
1149/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
1150/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
1151///
1152/// \note Note that this operator returns `rhs < lhs` when both operands are of
1153/// `NullableValue` type. Also note that this function will fail to compile
1154/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1155template <class LHS_TYPE, class RHS_TYPE>
1156bool operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
1157 const NullableValueRef<RHS_TYPE>& rhs);
1158template <class LHS_TYPE, class RHS_TYPE>
1159bool operator>(const NullableValueRef<LHS_TYPE>& lhs,
1160 const ConstNullableValueRef<RHS_TYPE>& rhs);
1161
1162/// Return `true` if the specified `lhs` nullable object is ordered after
1163/// the specified `rhs` nullable wrapper or `lhs` and `rhs` have the same
1164/// value, and `false` otherwise. (See `operator>` and `operator==`.)
1165///
1166/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
1167/// `NullableValue` type. Also note that this function will fail to compile
1168/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
1169template <class LHS_TYPE, class RHS_TYPE>
1170bool operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1171 const NullableValueRef<RHS_TYPE>& rhs);
1172template <class LHS_TYPE, class RHS_TYPE>
1173bool operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1174 const ConstNullableValueRef<RHS_TYPE>& rhs);
1175
1176} // close package namespace
1177
1178 // ----------------------------
1179 // class NullableValueRef<TYPE>
1180 // ----------------------------
1181
1182// PRIVATE ACCESSORS
1183template <class TYPE>
1184inline
1186bdlb::NullableValueRef<TYPE>::getNAV() const
1187{
1188 BSLS_ASSERT(!hasOpt());
1189 return *static_cast<bdlb::NullableAllocatedValue<TYPE> *>(d_target_p);
1190}
1191
1192template <class TYPE>
1193inline
1196{
1197 BSLS_ASSERT(hasOpt());
1198 return *static_cast<bsl::optional<TYPE> *>(d_target_p);
1199}
1200
1201template <class TYPE>
1202inline
1204{
1205 return d_isTargetOptional;
1206}
1207
1208// CREATORS
1209template <class TYPE>
1210inline
1212: d_target_p(&opt)
1213, d_isTargetOptional(true)
1214{
1215}
1216
1217template <class TYPE>
1218inline
1221: d_target_p(&opt)
1222, d_isTargetOptional(false)
1223{
1224}
1225
1226template <class TYPE>
1227inline
1229 const NullableValueRef& original)
1230: d_target_p(original.d_target_p)
1231, d_isTargetOptional(original.d_isTargetOptional)
1232{
1233}
1234
1235// ACCESSORS
1236template <class TYPE>
1237inline
1239{
1240 return hasOpt()
1241 ? getOpt().has_value()
1242 : getNAV().has_value();
1243}
1244
1245template <class TYPE>
1246inline
1248{
1249 return !has_value();
1250}
1251
1252template <class TYPE>
1253inline
1256{
1257 return hasOpt()
1258 ? getOpt().value()
1259 : getNAV().value();
1260}
1261
1262
1263template <class TYPE>
1264inline
1267{
1268 return hasOpt()
1269 ? getOpt().operator->()
1270 : getNAV().operator->();
1271}
1272
1273template <class TYPE>
1274inline
1277{
1278 return hasOpt()
1279 ? getOpt().operator*()
1280 : getNAV().operator*();
1281}
1282
1283#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1284template <class TYPE>
1286{
1287 return has_value();
1288}
1289#endif
1290
1291template <class TYPE>
1292template <class ANY_TYPE>
1293inline
1295 const ANY_TYPE& default_value) const
1296{
1297 if (has_value()) {
1298 return hasOpt()
1299 ? getOpt().value()
1300 : getNAV().value(); // RETURN
1301 }
1302 return default_value;
1303}
1304
1305
1306// MANIPULATORS
1307#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1308template <class TYPE>
1309template <class... ARGS>
1310inline
1313{
1314 return hasOpt()
1315 ? getOpt().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...)
1316 : getNAV().emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1317}
1318#endif
1319
1320template <class TYPE>
1321inline
1324{
1325 return hasOpt()
1326 ? getOpt().operator->()
1327 : getNAV().operator->();
1328}
1329
1330template <class TYPE>
1331inline
1334{
1335 return hasOpt()
1336 ? getOpt().operator*()
1337 : getNAV().operator*();
1338}
1339
1340template <class TYPE>
1341inline
1344{
1345 reset();
1346 return *this;
1347}
1348
1349template <class TYPE>
1350inline
1353{
1354 if (hasOpt()) {
1355 getOpt() = rhs;
1356 }
1357 else {
1358 getNAV() = rhs;
1359 }
1360
1361 return *this;
1362}
1363
1364template <class TYPE>
1365inline
1368{
1369 if (rhs.has_value()) {
1370 *this = rhs.value();
1371 }
1372 else {
1373 reset();
1374 }
1375 return *this;
1376}
1377
1378template <class TYPE>
1379inline
1383{
1384 if (rhs.has_value()) {
1385 *this = rhs.value();
1386 }
1387 else {
1388 reset();
1389 }
1390
1391 return *this;
1392}
1393
1394template <class TYPE>
1395inline
1398{
1399 if (rhs.has_value()) {
1400 *this = rhs.value();
1401 }
1402 else {
1403 reset();
1404 }
1405
1406 return *this;
1407}
1408
1409template <class TYPE>
1410inline
1412{
1413 if (hasOpt()) {
1414 getOpt().reset();
1415 }
1416 else {
1417 getNAV().reset();
1418 }
1419}
1420
1421template <class TYPE>
1422inline
1425{
1426 return hasOpt()
1427 ? getOpt().value()
1428 : getNAV().value();
1429}
1430
1431// DEPRECATED FUNCTIONS
1432template <class TYPE>
1433inline
1434const TYPE *
1435bdlb::NullableValueRef<TYPE>::addressOr(const TYPE *address) const
1436{
1437 return has_value() ? &value() : address;
1438}
1439
1440#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=5
1441template <class TYPE>
1442template <class... ARGS>
1443inline
1445{
1446 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1447}
1448#endif
1449
1450template <class TYPE>
1451inline
1452TYPE bdlb::NullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
1453{
1454 return value_or(otherValue);
1455}
1456
1457template <class TYPE>
1458inline
1460{
1461 return has_value() ? &value() : 0;
1462}
1463
1464// FREE FUNCTIONS
1465template <class HASHALG, class TYPE>
1466void bdlb::hashAppend(HASHALG& hashAlg,
1467 const NullableValueRef<TYPE>& input)
1468{
1469 using ::BloombergLP::bslh::hashAppend;
1470
1471 if (!input.has_value()) {
1472 hashAppend(hashAlg, false);
1473 }
1474 else {
1475 hashAppend(hashAlg, true);
1476 hashAppend(hashAlg, input.value());
1477 }
1478}
1479
1480// FREE OPERATORS
1481template <class LHS_TYPE, class RHS_TYPE>
1482inline
1483bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1484 const NullableValueRef<RHS_TYPE>& rhs)
1485{
1486 if (lhs.has_value()) {
1487 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
1488 }
1489
1490 return !rhs.has_value();
1491}
1492
1493template <class LHS_TYPE, class RHS_TYPE>
1494inline
1495bool bdlb::operator==(const NullableValueRef<LHS_TYPE>& lhs,
1496 const RHS_TYPE& rhs)
1497{
1498 return lhs.has_value() ? lhs.value() == rhs : false;
1499}
1500
1501template <class LHS_TYPE, class RHS_TYPE>
1502inline
1503bool bdlb::operator==(const LHS_TYPE& lhs,
1504 const NullableValueRef<RHS_TYPE>& rhs)
1505{
1506 return rhs.has_value() ? lhs == rhs.value(): false;
1507}
1508
1509template <class LHS_TYPE, class RHS_TYPE>
1510inline
1511bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1512 const NullableValueRef<RHS_TYPE>& rhs)
1513{
1514 if (lhs.has_value()) {
1515 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
1516 }
1517
1518 return rhs.has_value();
1519}
1520
1521template <class LHS_TYPE, class RHS_TYPE>
1522inline
1523bool bdlb::operator!=(const NullableValueRef<LHS_TYPE>& lhs,
1524 const RHS_TYPE& rhs)
1525{
1526 return lhs.has_value() ? lhs.value() != rhs : true;
1527}
1528
1529template <class LHS_TYPE, class RHS_TYPE>
1530inline
1531bool bdlb::operator!=(const LHS_TYPE& lhs,
1532 const NullableValueRef<RHS_TYPE>& rhs)
1533{
1534 return rhs.has_value() ? lhs != rhs.value() : true;
1535}
1536
1537template <class LHS_TYPE, class RHS_TYPE>
1538inline
1539bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1540 const NullableValueRef<RHS_TYPE>& rhs)
1541{
1542 if (!rhs.has_value()) {
1543 return false; // RETURN
1544 }
1545
1546 return lhs.has_value() ? lhs.value() < rhs.value() : true;
1547}
1548
1549template <class LHS_TYPE, class RHS_TYPE>
1550inline
1551bool bdlb::operator<(const NullableValueRef<LHS_TYPE>& lhs,
1552 const RHS_TYPE& rhs)
1553{
1554 return lhs.has_value() ? lhs.value() < rhs : true;
1555}
1556
1557template <class LHS_TYPE, class RHS_TYPE>
1558inline
1559bool bdlb::operator<(const LHS_TYPE& lhs,
1560 const NullableValueRef<RHS_TYPE>& rhs)
1561{
1562 return rhs.has_value() ? lhs < rhs.value() : false;
1563}
1564
1565template <class LHS_TYPE, class RHS_TYPE>
1566inline
1567bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1568 const NullableValueRef<RHS_TYPE>& rhs)
1569{
1570 if (!lhs.has_value()) {
1571 return true; // RETURN
1572 }
1573
1574 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
1575}
1576
1577template <class LHS_TYPE, class RHS_TYPE>
1578inline
1579bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
1580 const RHS_TYPE& rhs)
1581{
1582 return lhs.has_value() ? lhs.value() <= rhs : true;
1583}
1584
1585template <class LHS_TYPE, class RHS_TYPE>
1586inline
1587bool bdlb::operator<=(const LHS_TYPE& lhs,
1588 const NullableValueRef<RHS_TYPE>& rhs)
1589{
1590 return rhs.has_value() ? lhs <= rhs.value() : false;
1591}
1592
1593template <class LHS_TYPE, class RHS_TYPE>
1594inline
1595bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1596 const NullableValueRef<RHS_TYPE>& rhs)
1597{
1598 if (!lhs.has_value()) {
1599 return false; // RETURN
1600 }
1601
1602 return rhs.has_value() ? lhs.value() > rhs.value() : true;
1603}
1604
1605template <class LHS_TYPE, class RHS_TYPE>
1606inline
1607bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
1608 const RHS_TYPE& rhs)
1609{
1610 return lhs.has_value() ? lhs.value() > rhs : false;
1611}
1612
1613template <class LHS_TYPE, class RHS_TYPE>
1614inline
1615bool bdlb::operator>(const LHS_TYPE& lhs,
1616 const NullableValueRef<RHS_TYPE>& rhs)
1617{
1618 return rhs.has_value() ? lhs > rhs.value() : true;
1619}
1620
1621template <class LHS_TYPE, class RHS_TYPE>
1622inline
1623bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1624 const NullableValueRef<RHS_TYPE>& rhs)
1625{
1626 if (!rhs.has_value()) {
1627 return true; // RETURN
1628 }
1629
1630 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
1631}
1632
1633template <class LHS_TYPE, class RHS_TYPE>
1634inline
1635bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
1636 const RHS_TYPE& rhs)
1637{
1638 return lhs.has_value() ? lhs.value() >= rhs : false;
1639}
1640
1641template <class LHS_TYPE, class RHS_TYPE>
1642inline
1643bool bdlb::operator>=(const LHS_TYPE& lhs,
1644 const NullableValueRef<RHS_TYPE>& rhs)
1645{
1646 return rhs.has_value() ? lhs >= rhs.value() : true;
1647}
1648
1649 //--------------------------------
1650 // Comparisons with bsl::nullopt_t
1651 //--------------------------------
1652
1653template <class TYPE>
1654inline
1655bool bdlb::operator==(const NullableValueRef<TYPE>& lhs,
1657{
1658 return !lhs.has_value();
1659}
1660
1661template <class TYPE>
1662inline
1663bool bdlb::operator==(
1664 const bsl::nullopt_t&,
1665 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1666{
1667 return !rhs.has_value();
1668}
1669
1670template <class TYPE>
1671inline bool bdlb::operator!=(const NullableValueRef<TYPE>& lhs,
1673{
1674 return lhs.has_value();
1675}
1676
1677template <class TYPE>
1678inline
1679bool bdlb::operator!=(
1680 const bsl::nullopt_t&,
1681 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1682{
1683 return rhs.has_value();
1684}
1685
1686template <class TYPE>
1687inline
1688bool bdlb::operator<(const NullableValueRef<TYPE>&,
1690{
1691 return false;
1692}
1693
1694template <class TYPE>
1695inline
1696bool bdlb::operator<(
1697 const bsl::nullopt_t&,
1698 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1699{
1700 return rhs.has_value();
1701}
1702
1703template <class TYPE>
1704inline
1705bool bdlb::operator>(const NullableValueRef<TYPE>& lhs,
1707{
1708 return lhs.has_value();
1709}
1710
1711template <class TYPE>
1712inline
1714 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1715{
1716 return false;
1717}
1718
1719template <class TYPE>
1720inline
1721bool bdlb::operator<=(const NullableValueRef<TYPE>& lhs,
1723{
1724 return !lhs.has_value();
1725}
1726
1727template <class TYPE>
1728inline
1729bool bdlb::operator<=(
1730 const bsl::nullopt_t&,
1731 const NullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1732{
1733 return true;
1734}
1735
1736template <class TYPE>
1737inline
1738bool bdlb::operator>=(const NullableValueRef<TYPE>&,
1740{
1741 return true;
1742}
1743
1744template <class TYPE>
1745inline
1746bool bdlb::operator>=(
1747 const bsl::nullopt_t&,
1748 const NullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1749{
1750 return !rhs.has_value();
1751}
1752
1753 // ---------------------------------
1754 // class ConstNullableValueRef<TYPE>
1755 // ---------------------------------
1756
1757// PRIVATE ACCESSORS
1758template <class TYPE>
1759inline
1762{
1763 BSLS_ASSERT(!hasOpt());
1764 return *static_cast<const NullableAllocatedValue<value_type> *>(
1765 d_target_p);
1766}
1767
1768template <class TYPE>
1769inline
1772{
1773 BSLS_ASSERT(hasOpt());
1774 return *static_cast<const bsl::optional<value_type> *>(d_target_p);
1775}
1776
1777template <class TYPE>
1778inline
1780{
1781 return d_isTargetOptional;
1782}
1783
1784// CREATORS
1785template <class TYPE>
1786inline
1788 const bsl::optional<TYPE>& opt)
1789: d_target_p(&opt)
1790, d_isTargetOptional(true)
1791{
1792}
1793
1794template <class TYPE>
1795inline
1798: d_target_p(&opt)
1799, d_isTargetOptional(false)
1800{
1801}
1802
1803template <class TYPE>
1804inline
1806 const NullableValueRef<TYPE>& ref)
1807: d_target_p(ref.d_target_p)
1808, d_isTargetOptional(ref.d_isTargetOptional)
1809{
1810}
1811
1812template <class TYPE>
1813inline
1815 const ConstNullableValueRef& original)
1816: d_target_p(original.d_target_p)
1817, d_isTargetOptional(original.d_isTargetOptional)
1818{
1819}
1820
1821// ACCESSORS
1822template <class TYPE>
1823inline
1824bool
1826{
1827 return hasOpt()
1828 ? getOpt().has_value()
1829 : getNAV().has_value();
1830}
1831
1832template <class TYPE>
1833inline
1834bool
1836{
1837 return !has_value();
1838}
1839
1840template <class TYPE>
1841inline
1844{
1845 return hasOpt()
1846 ? getOpt().value()
1847 : getNAV().value();
1848}
1849
1850
1851template <class TYPE>
1852inline
1855{
1856 return hasOpt()
1857 ? getOpt().operator->()
1858 : getNAV().operator->();
1859}
1860
1861template <class TYPE>
1862inline
1865{
1866 return hasOpt()
1867 ? getOpt().operator*()
1868 : getNAV().operator*();
1869}
1870
1871#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1872template <class TYPE>
1874{
1875 return has_value();
1876}
1877#endif
1878
1879template <class TYPE>
1880template <class ANY_TYPE>
1881inline
1883 const ANY_TYPE& default_value) const
1884{
1885 if (has_value()) {
1886 return hasOpt()
1887 ? getOpt().value()
1888 : getNAV().value(); // RETURN
1889 }
1890 return default_value;
1891}
1892
1893// DEPRECATED FUNCTIONS
1894template <class TYPE>
1895inline
1896const TYPE *
1897bdlb::ConstNullableValueRef<TYPE>::addressOr(const TYPE *address) const
1898{
1899 return has_value() ? &value() : address;
1900}
1901
1902template <class TYPE>
1903inline
1904TYPE
1905bdlb::ConstNullableValueRef<TYPE>::valueOr(const TYPE& otherValue) const
1906{
1907 return value_or(otherValue);
1908}
1909
1910template <class TYPE>
1911inline
1913{
1914 return has_value() ? &value() : 0;
1915}
1916
1917// FREE FUNCTIONS
1918template <class HASHALG, class TYPE>
1919void bdlb::hashAppend(HASHALG& hashAlg,
1920 const ConstNullableValueRef<TYPE>& input)
1921{
1922 using ::BloombergLP::bslh::hashAppend;
1923
1924 if (!input.has_value()) {
1925 hashAppend(hashAlg, false);
1926 }
1927 else {
1928 hashAppend(hashAlg, true);
1929 hashAppend(hashAlg, input.value());
1930 }
1931}
1932
1933// FREE OPERATORS
1934template <class LHS_TYPE, class RHS_TYPE>
1935inline
1936bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1937 const ConstNullableValueRef<RHS_TYPE>& rhs)
1938{
1939 if (lhs.has_value()) {
1940 return rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
1941 }
1942
1943 return !rhs.has_value();
1944}
1945
1946template <class LHS_TYPE, class RHS_TYPE>
1947inline
1948bool bdlb::operator==(const ConstNullableValueRef<LHS_TYPE>& lhs,
1949 const RHS_TYPE& rhs)
1950{
1951 return lhs.has_value() ? lhs.value() == rhs : false;
1952}
1953
1954template <class LHS_TYPE, class RHS_TYPE>
1955inline
1956bool bdlb::operator==(const LHS_TYPE& lhs,
1957 const ConstNullableValueRef<RHS_TYPE>& rhs)
1958{
1959 return rhs.has_value() ? lhs == rhs.value(): false;
1960}
1961
1962template <class LHS_TYPE, class RHS_TYPE>
1963inline
1964bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1965 const ConstNullableValueRef<RHS_TYPE>& rhs)
1966{
1967 if (lhs.has_value()) {
1968 return rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
1969 }
1970
1971 return rhs.has_value();
1972}
1973
1974template <class LHS_TYPE, class RHS_TYPE>
1975inline
1976bool bdlb::operator!=(const ConstNullableValueRef<LHS_TYPE>& lhs,
1977 const RHS_TYPE& rhs)
1978{
1979 return lhs.has_value() ? lhs.value() != rhs : true;
1980}
1981
1982template <class LHS_TYPE, class RHS_TYPE>
1983inline
1984bool bdlb::operator!=(const LHS_TYPE& lhs,
1985 const ConstNullableValueRef<RHS_TYPE>& rhs)
1986{
1987 return rhs.has_value() ? lhs != rhs.value() : true;
1988}
1989
1990template <class LHS_TYPE, class RHS_TYPE>
1991inline
1992bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
1993 const ConstNullableValueRef<RHS_TYPE>& rhs)
1994{
1995 if (!rhs.has_value()) {
1996 return false; // RETURN
1997 }
1998
1999 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2000}
2001
2002template <class LHS_TYPE, class RHS_TYPE>
2003inline
2004bool bdlb::operator<(const ConstNullableValueRef<LHS_TYPE>& lhs,
2005 const RHS_TYPE& rhs)
2006{
2007 return lhs.has_value() ? lhs.value() < rhs : true;
2008}
2009
2010template <class LHS_TYPE, class RHS_TYPE>
2011inline
2012bool bdlb::operator<(const LHS_TYPE& lhs,
2013 const ConstNullableValueRef<RHS_TYPE>& rhs)
2014{
2015 return rhs.has_value() ? lhs < rhs.value() : false;
2016}
2017
2018template <class LHS_TYPE, class RHS_TYPE>
2019inline
2020bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2021 const ConstNullableValueRef<RHS_TYPE>& rhs)
2022{
2023 if (!lhs.has_value()) {
2024 return true; // RETURN
2025 }
2026
2027 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2028}
2029
2030template <class LHS_TYPE, class RHS_TYPE>
2031inline
2032bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2033 const RHS_TYPE& rhs)
2034{
2035 return lhs.has_value() ? lhs.value() <= rhs : true;
2036}
2037
2038template <class LHS_TYPE, class RHS_TYPE>
2039inline
2040bool bdlb::operator<=(const LHS_TYPE& lhs,
2041 const ConstNullableValueRef<RHS_TYPE>& rhs)
2042{
2043 return rhs.has_value() ? lhs <= rhs.value() : false;
2044}
2045
2046template <class LHS_TYPE, class RHS_TYPE>
2047inline
2048bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2049 const ConstNullableValueRef<RHS_TYPE>& rhs)
2050{
2051 if (!lhs.has_value()) {
2052 return false; // RETURN
2053 }
2054
2055 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2056}
2057
2058template <class LHS_TYPE, class RHS_TYPE>
2059inline
2060bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2061 const RHS_TYPE& rhs)
2062{
2063 return lhs.has_value() ? lhs.value() > rhs : false;
2064}
2065
2066template <class LHS_TYPE, class RHS_TYPE>
2067inline
2068bool bdlb::operator>(const LHS_TYPE& lhs,
2069 const ConstNullableValueRef<RHS_TYPE>& rhs)
2070{
2071 return rhs.has_value() ? lhs > rhs.value() : true;
2072}
2073
2074template <class LHS_TYPE, class RHS_TYPE>
2075inline
2076bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2077 const ConstNullableValueRef<RHS_TYPE>& rhs)
2078{
2079 if (!rhs.has_value()) {
2080 return true; // RETURN
2081 }
2082
2083 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2084}
2085
2086template <class LHS_TYPE, class RHS_TYPE>
2087inline
2088bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2089 const RHS_TYPE& rhs)
2090{
2091 return lhs.has_value() ? lhs.value() >= rhs : false;
2092}
2093
2094template <class LHS_TYPE, class RHS_TYPE>
2095inline
2096bool bdlb::operator>=(const LHS_TYPE& lhs,
2097 const ConstNullableValueRef<RHS_TYPE>& rhs)
2098{
2099 return rhs.has_value() ? lhs >= rhs.value() : true;
2100}
2101
2102 //--------------------------------
2103 // Comparisons with bsl::nullopt_t
2104 //--------------------------------
2105
2106template <class TYPE>
2107inline
2108bool bdlb::operator==(const ConstNullableValueRef<TYPE>& lhs,
2110{
2111 return !lhs.has_value();
2112}
2113
2114template <class TYPE>
2115inline
2116bool bdlb::operator==(
2117 const bsl::nullopt_t&,
2118 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2119{
2120 return !rhs.has_value();
2121}
2122
2123template <class TYPE>
2124inline bool bdlb::operator!=(const ConstNullableValueRef<TYPE>& lhs,
2126{
2127 return lhs.has_value();
2128}
2129
2130template <class TYPE>
2131inline
2132bool bdlb::operator!=(
2133 const bsl::nullopt_t&,
2134 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2135{
2136 return rhs.has_value();
2137}
2138
2139template <class TYPE>
2140inline
2141bool bdlb::operator<(const ConstNullableValueRef<TYPE>&,
2143{
2144 return false;
2145}
2146
2147template <class TYPE>
2148inline
2149bool bdlb::operator<(
2150 const bsl::nullopt_t&,
2151 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2152{
2153 return rhs.has_value();
2154}
2155
2156template <class TYPE>
2157inline
2158bool bdlb::operator>(const ConstNullableValueRef<TYPE>& lhs,
2160{
2161 return lhs.has_value();
2162}
2163
2164template <class TYPE>
2165inline
2166bool bdlb::operator>(
2167 const bsl::nullopt_t&,
2168 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2169{
2170 return false;
2171}
2172
2173template <class TYPE>
2174inline
2175bool bdlb::operator<=(const ConstNullableValueRef<TYPE>& lhs,
2177{
2178 return !lhs.has_value();
2179}
2180
2181template <class TYPE>
2182inline
2183bool bdlb::operator<=(
2184 const bsl::nullopt_t&,
2185 const ConstNullableValueRef<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2186{
2187 return true;
2188}
2189
2190template <class TYPE>
2191inline
2192bool bdlb::operator>=(const ConstNullableValueRef<TYPE>&,
2194{
2195 return true;
2196}
2197
2198template <class TYPE>
2199inline
2200bool bdlb::operator>=(
2201 const bsl::nullopt_t&,
2202 const ConstNullableValueRef<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2203{
2204 return !rhs.has_value();
2205}
2206
2207 //-------------------------------------------------------------------
2208 // Comparisons between 'ConstNullableValueRef' and 'NullableValueRef'
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 rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2218 }
2219
2220 return !rhs.has_value();
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 rhs.has_value() ? lhs.value() == rhs.value() : false; // RETURN
2230 }
2231
2232 return !rhs.has_value();
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 rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2242 }
2243
2244 return rhs.has_value();
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 rhs.has_value() ? lhs.value() != rhs.value() : true; // RETURN
2254 }
2255
2256 return rhs.has_value();
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 false; // RETURN
2266 }
2267
2268 return lhs.has_value() ? lhs.value() < rhs.value() : true;
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 false; // RETURN
2278 }
2279
2280 return lhs.has_value() ? lhs.value() < rhs.value() : true;
2281}
2282
2283template <class LHS_TYPE, class RHS_TYPE>
2284inline
2285bool bdlb::operator<=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2286 const NullableValueRef<RHS_TYPE>& rhs)
2287{
2288 if (!lhs.has_value()) {
2289 return true; // RETURN
2290 }
2291
2292 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2293}
2294
2295template <class LHS_TYPE, class RHS_TYPE>
2296inline
2297bool bdlb::operator<=(const NullableValueRef<LHS_TYPE>& lhs,
2298 const ConstNullableValueRef<RHS_TYPE>& rhs)
2299{
2300 if (!lhs.has_value()) {
2301 return true; // RETURN
2302 }
2303
2304 return rhs.has_value() ? lhs.value() <= rhs.value() : false;
2305}
2306
2307template <class LHS_TYPE, class RHS_TYPE>
2308inline
2309bool bdlb::operator>(const ConstNullableValueRef<LHS_TYPE>& lhs,
2310 const NullableValueRef<RHS_TYPE>& rhs)
2311{
2312 if (!lhs.has_value()) {
2313 return false; // RETURN
2314 }
2315
2316 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2317}
2318
2319template <class LHS_TYPE, class RHS_TYPE>
2320inline
2321bool bdlb::operator>(const NullableValueRef<LHS_TYPE>& lhs,
2322 const ConstNullableValueRef<RHS_TYPE>& rhs)
2323{
2324 if (!lhs.has_value()) {
2325 return false; // RETURN
2326 }
2327
2328 return rhs.has_value() ? lhs.value() > rhs.value() : true;
2329}
2330
2331template <class LHS_TYPE, class RHS_TYPE>
2332inline
2333bool bdlb::operator>=(const ConstNullableValueRef<LHS_TYPE>& lhs,
2334 const NullableValueRef<RHS_TYPE>& rhs)
2335{
2336 if (!rhs.has_value()) {
2337 return true; // RETURN
2338 }
2339
2340 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2341}
2342
2343template <class LHS_TYPE, class RHS_TYPE>
2344inline
2345bool bdlb::operator>=(const NullableValueRef<LHS_TYPE>& lhs,
2346 const ConstNullableValueRef<RHS_TYPE>& rhs)
2347{
2348 if (!rhs.has_value()) {
2349 return true; // RETURN
2350 }
2351
2352 return lhs.has_value() ? lhs.value() >= rhs.value() : false;
2353}
2354
2355
2356
2357#endif // End C++11 code
2358
2359#endif // INCLUDED_BDLB_NULLABLEVALUEREF
2360
2361// ----------------------------------------------------------------------------
2362// Copyright 2023 Bloomberg Finance L.P.
2363//
2364// Licensed under the Apache License, Version 2.0 (the "License");
2365// you may not use this file except in compliance with the License.
2366// You may obtain a copy of the License at
2367//
2368// http://www.apache.org/licenses/LICENSE-2.0
2369//
2370// Unless required by applicable law or agreed to in writing, software
2371// distributed under the License is distributed on an "AS IS" BASIS,
2372// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2373// See the License for the specific language governing permissions and
2374// limitations under the License.
2375// ----------------------------- END-OF-FILE ----------------------------------
2376
2377/** @} */
2378/** @} */
2379/** @} */
Definition bdlb_nullablevalueref.h:671
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:726
Definition bdlb_nullableallocatedvalue.h:180
void reset()
Definition bdlb_nullableallocatedvalue.h:1148
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1393
TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)...)
TYPE & value()
Definition bdlb_nullableallocatedvalue.h:1183
Definition bdlb_nullablevalueref.h:169
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:228
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:2043
TYPE value_or(const ANY_TYPE &default_value) const
Definition bdlb_nullablevalueref.h:1294
void reset()
Definition bdlb_nullablevalueref.h:1411
TYPE value_or(const ANY_TYPE &default_value) const
Definition bdlb_nullablevalueref.h:1882
const value_type * operator->() const
Definition bdlb_nullablevalueref.h:1266
const value_type * operator->() const
Definition bdlb_nullablevalueref.h:1854
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return true if the target contains a value, and false otherwise.
Definition bdlb_nullablevalueref.h:1238
NullableValueRef(bsl::optional< TYPE > &opt)
Definition bdlb_nullablevalueref.h:1211
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return true if the target contains a value, and false otherwise.
Definition bdlb_nullablevalueref.h:1825
const value_type & operator*() const
Definition bdlb_nullablevalueref.h:1864
const value_type & value() const
Definition bdlb_nullablevalueref.h:1255
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullablevalueref.h:1247
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullablevalueref.h:1835
const value_type & operator*() const
Definition bdlb_nullablevalueref.h:1276
NullableValueRef< TYPE > & operator=(const bsl::nullopt_t &)
Definition bdlb_nullablevalueref.h:1343
ConstNullableValueRef(const bsl::optional< TYPE > &opt)
Definition bdlb_nullablevalueref.h:1787
const value_type & value() const
Definition bdlb_nullablevalueref.h:1843
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:387
#define BSLS_NOTHROW_SPEC
Definition bsls_exceptionutil.h:386
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_EXPLICIT
Definition bsls_keyword.h:683
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
Definition bdlb_algorithmworkaroundutil.h:74
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
bool operator>=(const Guid &lhs, const Guid &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
bool operator<=(const Guid &lhs, const Guid &rhs)
bool operator>(const Guid &lhs, const Guid &rhs)
bool operator<(const Guid &lhs, const Guid &rhs)
bool operator==(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
Definition bdlat_valuetypefunctions.h:939
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition bslmf_issame.h:146
Definition bslstl_optional.h:522