BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlb_nullableallocatedvalue.h
Go to the documentation of this file.
1/// @file bdlb_nullableallocatedvalue.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullableallocatedvalue.h -*-C++-*-
8#ifndef INCLUDED_BDLB_NULLABLEALLOCATEDVALUE
9#define INCLUDED_BDLB_NULLABLEALLOCATEDVALUE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_nullableallocatedvalue bdlb_nullableallocatedvalue
15/// @brief Provide a template for nullable allocated (out-of-place) objects.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_nullableallocatedvalue
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_nullableallocatedvalue-purpose"> Purpose</a>
25/// * <a href="#bdlb_nullableallocatedvalue-classes"> Classes </a>
26/// * <a href="#bdlb_nullableallocatedvalue-description"> Description </a>
27/// * <a href="#bdlb_nullableallocatedvalue-usage"> Usage </a>
28/// * <a href="#bdlb_nullableallocatedvalue-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bdlb_nullableallocatedvalue-purpose}
31/// Provide a template for nullable allocated (out-of-place) objects.
32///
33/// # Classes {#bdlb_nullableallocatedvalue-classes}
34///
35/// - bdlb::NullableAllocatedValue: template for nullable allocated objects
36///
37/// @see bdlb_nullablevalue
38///
39/// # Description {#bdlb_nullableallocatedvalue-description}
40/// This component provides a template class,
41/// `bdlb::NullableAllocatedValue<TYPE>`, that has nearly the same interface as
42/// `bdlb::NullableValue` (see @ref bdlb_nullablevalue ), but, in contrast with that
43/// template class, the implementation of `bdlb::NullableAllocatedValue` does
44/// not require that the `TYPE` parameter be a complete type when the *class* is
45/// instantiated. However, the template parameter `TYPE` must be complete when
46/// *methods* of the class (and free operators) are instantiated.
47///
48/// For small types (no larger than a pointer) with simple alignment needs, the
49/// object is embedded into the NullableAllocatedValue object. For types that
50/// do not fit these requirements, the object of template parameter `TYPE` that
51/// is managed by a `bdlb::NullableAllocatedValue<TYPE>` object is allocated
52/// out-of-place.
53///
54/// ## Usage {#bdlb_nullableallocatedvalue-usage}
55///
56///
57/// This section illustrates intended use of this component.
58///
59/// ### Example 1: Basic Usage {#bdlb_nullableallocatedvalue-example-1-basic-usage}
60///
61///
62/// Suppose we want to create a linked list of nodes that contain integers:
63/// @code
64/// struct LinkedListNode {
65/// int d_value;
66/// bdlb::NullableAllocatedValue<LinkedListNode> d_next;
67/// };
68/// @endcode
69/// Note that `bdlb::NullableValue<LinkedListNode>` cannot be used for `d_next`
70/// because `bdlb::NullableValue` requires that the template parameter `TYPE` be
71/// a complete type when the class is instantiated.
72///
73/// We can now traverse a linked list and add a new value at the end using the
74/// following code:
75/// @code
76/// /// Add the specified `value` to the end of the list that contains the
77/// /// specified `node`.
78/// void addValueAtEnd(LinkedListNode *node, int value)
79/// {
80/// while (!node->d_next.isNull()) {
81/// node = &node->d_next.value();
82/// }
83///
84/// node->d_next.makeValue();
85/// node = &node->d_next.value();
86/// node->d_value = value;
87/// }
88/// @endcode
89/// @}
90/** @} */
91/** @} */
92
93/** @addtogroup bdl
94 * @{
95 */
96/** @addtogroup bdlb
97 * @{
98 */
99/** @addtogroup bdlb_nullableallocatedvalue
100 * @{
101 */
102
103#include <bdlscm_version.h>
104
106#include <bdlb_printmethods.h>
107
109#include <bslalg_swaputil.h>
110
111#include <bslma_allocator.h>
113#include <bslma_default.h>
114
117#include <bslmf_util.h> // 'forward(V)' for C++03
118
119#include <bsls_assert.h>
121#include <bsls_deprecate.h>
123#include <bsls_keyword.h>
124#include <bsls_review.h>
125#include <bsls_util.h> // 'forward<T>(V)' for C++11
126
127#include <bslstl_optional.h> // bsl::nullopt
128
132
133#include <bsl_algorithm.h>
134#include <bsl_cstddef.h> // bsl::size_t
135#include <bsl_cstdint.h> // uintptr_t
136#include <bsl_iosfwd.h>
137
138#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
139#include <bslalg_typetraits.h>
140#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
141
142#include <stddef.h> // NULL
143
144#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
145// clang-format off
146// Include version that can be compiled with C++03
147// Generated on Mon Jan 13 08:32:07 2025
148// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
149
150# define COMPILING_BDLB_NULLABLEALLOCATEDVALUE_H
152# undef COMPILING_BDLB_NULLABLEALLOCATEDVALUE_H
153
154// clang-format on
155#else
156
157
158namespace bdlb {
159
160 // ==================================
161 // class NullableAllocatedValue<TYPE>
162 // ==================================
163
164/// This template class extends the set of values of its value-semantic
165/// `TYPE` parameter to include the notion of a "null" value. If `TYPE` is
166/// fully value-semantic, then the augmented type
167/// `NullableAllocatedValue<TYPE>` will be as well. In addition to
168/// supporting all homogeneous value-semantic operations, conversions
169/// between comparable underlying value types is also supported. Two
170/// nullable objects with different underlying types compare equal if their
171/// underlying types are comparable and either (1) both objects are null or
172/// (2) the non-null values compare equal. Attempts to copy construct, copy
173/// assign, or compare incompatible values types will fail to compile. The
174/// `NullableAllocatedValue` template can be instantiated on an incomplete
175/// type, but it cannot be instantiated on a type that overloads
176/// `operator&`.
177///
178/// See @ref bdlb_nullableallocatedvalue
179template <class TYPE>
181
182 enum { k_HAS_VALUE = 0 };
183 // flag for checking if the value is present
184
185 // DATA
187 union {
189 char d_buffer[sizeof(TYPE *)];
190 } d_storage;
191
192 // PRIVATE TYPES
193# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
194 // UNSPECIFIED BOOL
195
196 /// This type is needed only in C++03 mode, where `explicit` conversion
197 /// operators are not supported. A `NullableAllocatedValue` is implicitly
198 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
199 /// implicitly convertible to `bool`.
200 typedef BloombergLP::bsls::UnspecifiedBool<NullableAllocatedValue>
201 UnspecifiedBoolUtil;
202 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
203# endif
204
205 // PRIVATE CLASS METHODS
206
207 /// Returns `true` if an object of the template parameter `TYPE` can be
208 /// stored locally, instead of being allocated on the heap.
209 static bool isLocal() BSLS_KEYWORD_NOEXCEPT;
210
211 // PRIVATE ACCESSORS
212
213 /// return a pointer to the held value. If the value does not exist and
214 /// the storage is local, then return a pointer to storage suitable for
215 /// constructing the held value. If the value does not exist and the
216 /// storage is not local, return NULL.
217 TYPE *getAddress();
218 const TYPE *getAddress() const;
219
220 // PRIVATE MANIPULATORS
221
222 /// Clear the flag in the `d_allocator` field that indicates that this
223 /// object does not hold a value.
224 void clearHasValueFlag() BSLS_KEYWORD_NOEXCEPT;
225
226 /// Set the flag in the `d_allocator` field that indicates that this
227 /// object holds a value.
228 void setHasValueFlag() BSLS_KEYWORD_NOEXCEPT;
229
230 /// Set the value of the pointer to the held value to the specified `newPtr`.
231 ///
232 /// \pre The behavior is undefined if the storage is local.
233 void setRemoteAddress(TYPE *newPtr);
234
235 /// Efficiently exchange the value of this object with the value of the
236 /// specified `other` object. At least one of `this` or `other` is not
237 /// empty, and the values are stored locally. This method provides the
238 /// no-throw exception-safety guarantee.
239 ///
240 /// \pre The behavior is undefined unless this object was created with the same allocator as `other`.
241 void swapLocal(NullableAllocatedValue& other);
242
243 /// Efficiently exchange the value of this object with the value of the
244 /// specified `other` object. At least one of `this` or `other` is not
245 /// empty, and the values are stored remotely. This method provides the
246 /// no-throw exception-safety guarantee.
247 ///
248 /// \pre The behavior is undefined unless this object was created with the same allocator as `other`.
249 void swapRemote(NullableAllocatedValue& other);
250
251
252 public:
253 // TYPES
254
255 /// `ValueType` is an alias for the underlying `TYPE` upon which this
256 /// template class is instantiated, and represents the type of the
257 /// managed object.
258 typedef TYPE ValueType;
259
260 // TRAITS
262 bslma::UsesBslmaAllocator);
264 bslmf::IsBitwiseMoveable);
267
268 // CREATORS
269
270 /// Create a nullable object having the null value. Use the currently
271 /// installed default allocator to supply memory.
273
274 /// Create a nullable object that has the null value and that uses the
275 /// mechanism of the specified `allocator` to supply memory.
277
278 /// Create a nullable object having the null value. Use the currently
279 /// installed default allocator to supply memory.
280 NullableAllocatedValue(const bsl::nullopt_t&); // IMPLICIT
281
282 /// Create a nullable object that has the null value and that uses the
283 /// mechanism of the specified `allocator` to supply memory.
284 NullableAllocatedValue(const bsl::nullopt_t&,
285 const bsl::allocator<char>& allocator);
286
287 /// Create a nullable object having the value of the specified
288 /// `original` object. Use the currently installed default allocator
289 /// to supply memory.
291
292 /// Create a nullable object having the value of the specified
293 /// `original` object and that uses the mechanism of the specified
294 /// `allocator` to supply memory.
296 const bsl::allocator<char>& allocator);
297
298 /// Create a nullable object having the specified `value`. Use the
299 /// currently installed default allocator to supply memory.
300 NullableAllocatedValue(const TYPE& value); // IMPLICIT
301
302 /// Create a nullable object having the specified `value` and that uses
303 /// the mechanism of specified `allocator` to supply memory.
305 const bsl::allocator<char>& allocator);
306
307 /// Destroy this object.
309
310 // MANIPULATORS
311
312 /// Assign to this object the value of the specified `rhs`, and return a
313 /// reference providing modifiable access to this object.
314 NullableAllocatedValue<TYPE>& operator=(const NullableAllocatedValue& rhs);
315
316 /// Reset this object to the default constructed state (i.e., to have
317 /// the null value).
318 NullableAllocatedValue<TYPE>& operator=(const bsl::nullopt_t&);
319
320 /// Assign to this object the value of the specified `rhs`, and return a
321 /// reference providing modifiable access to the underlying `TYPE`
322 /// object.
323 NullableAllocatedValue<TYPE>& operator=(const TYPE& rhs);
324
325 /// Return a pointer providing modifiable access to the underlying `TYPE` object.
326 ///
327 /// \pre The behavior is undefined if the object has no
328 /// value.
329 TYPE *operator->();
330
331 /// Return a reference providing modifiable access to the underlying `TYPE` object.
332 ///
333 /// \pre The behavior is undefined if the object has no
334 /// value.
335 TYPE& operator*();
336
337#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
338 /// Assign to this object the value of the (template parameter) `TYPE`
339 /// created in place using the specified `args` and return a reference
340 /// providing modifiable access to the underlying `TYPE` object. If
341 /// this `optional` object already contains an object (`true ==
342 /// hasValue()`), that object is destroyed before the new object is created.
343 ///
344 /// \note Note that if the constructor of `TYPE` throws an exception
345 /// this object is left in a disengaged state.
346 template <class... ARGS>
348
349# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
350 /// Assign to this object the value of the (template parameter) `TYPE`
351 /// created in place using the specified `il` and specified `args` and
352 /// return a reference providing modifiable access to the underlying
353 /// `TYPE` object. If this object already contains an object (`true ==
354 /// hasValue()`), that object is destroyed before the new object is created.
355 ///
356 /// \note Note that if the constructor of `TYPE` throws an exception
357 /// this object is left in a disengaged state.
358 template <class INIT_LIST_TYPE, class... ARGS>
359 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
361
362# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
363#endif
364
365 /// Assign to this object the value read from the specified input
366 /// `stream` using the specified `version` format, and return a
367 /// reference to `stream`. If `stream` is initially invalid, this
368 /// operation has no effect. If `version` is not supported, this object
369 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
370 /// If `version` is supported but `stream` becomes invalid during this
371 /// operation, this object has an undefined, but valid, state.
372 ///
373 /// \note Note that no version is read from `stream`. See the `bslx` package-level
374 /// documentation for more information on BDEX streaming of
375 /// value-semantic types and containers.
376 template <class STREAM>
377 STREAM& bdexStreamIn(STREAM& stream, int version);
378
379 /// Assign to this object the specified `val`, and return a reference
380 /// providing modifiable access to the underlying `TYPE` object.
381 TYPE& makeValue(const TYPE& val);
382
383 /// Assign to this object the default value for `TYPE`, and return a
384 /// reference providing modifiable access to the underlying `TYPE`
385 /// object.
386 TYPE& makeValue();
387
388 /// Reset this object to the default constructed state (i.e., to have
389 /// the null value).
390 void reset();
391
392 /// Efficiently exchange the value of this object with the value of the
393 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
394 ///
395 /// \pre The behavior is undefined unless this
396 /// object was created with the same allocator as `other`.
398
399 /// Return a reference providing modifiable access to the underlying `TYPE` object.
400 ///
401 /// \pre The behavior is undefined unless this object is
402 /// non-null.
403 TYPE& value();
404
405 // ACCESSORS
406
407 /// Write the value of this object, using the specified `version`
408 /// format, to the specified output `stream`, and return a reference to
409 /// `stream`. If `stream` is initially invalid, this operation has no
410 /// effect. If `version` is not supported, `stream` is invalidated, but otherwise unmodified.
411 ///
412 /// \note Note that `version` is not written to
413 /// `stream`. See the `bslx` package-level documentation for more
414 /// information on BDEX streaming of value-semantic types and
415 /// containers.
416 template <class STREAM>
417 STREAM& bdexStreamOut(STREAM& stream, int version) const;
418
419 /// Return a `bsl::allocator` constructed from the `bslma::Allocator` used by this object to supply memory.
420 ///
421 /// \note Note that if no allocator was
422 /// supplied at construction the default allocator in effect at
423 /// construction is used.
425
426 /// Return `true` if this object contains a value, and `false`
427 /// otherwise.
429
430 /// Return `false` if this object contains a value, and `true` otherwise.
431 ///
432 /// \note Note that this is the opposite of @ref has_value .
434
435 /// Return the maximum valid BDEX format version, as indicated by the
436 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
437 ///
438 /// \note Note that it is highly recommended that `versionSelector`
439 /// be formatted as "YYYYMMDD", a date representation. Also note that
440 /// `versionSelector` should be a *compile*-time-chosen value that
441 /// selects a format version supported by both externalizer and
442 /// unexternalizer. See the `bslx` package-level documentation for more
443 /// information on BDEX streaming of value-semantic types and
444 /// containers.
445 int maxSupportedBdexVersion(int versionSelector) const;
446
447#ifndef BDE_OMIT_INTERNAL_DEPRECATED
448 /// Return the most current BDEX streaming version number supported by
449 /// this class. (See the package-group-level documentation for more
450 /// information on BDEX streaming of container types.)
452#endif // BDE_OMIT_INTERNAL_DEPRECATED
453
454 /// Return the value of the underlying object of a (template parameter)
455 /// `TYPE` if this object is non-null, and the specified @ref default_value otherwise.
456 ///
457 /// \note Note that this method returns *by* *value*, so may be
458 /// inefficient in some contexts.
459 template <class ANY_TYPE>
460 TYPE value_or(const ANY_TYPE& default_value) const;
461
462 /// Return a pointer providing non-modifiable access to the underlying `TYPE` object.
463 ///
464 /// \pre The behavior is undefined if the object has no
465 /// value.
466 const TYPE *operator->() const;
467
468 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
469 ///
470 /// \pre The behavior is undefined if the object has no
471 /// value.
472 const TYPE& operator*() const;
473
474
475# ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
476 /// Return `true` if this object is contains a value, and `true`
477 /// otherwise.
478 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
479# else // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
480 /// Simulation of explicit conversion to bool. Inlined to work around xlC
481 /// bug when out-of-line.
482 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
483 {
484 return UnspecifiedBoolUtil::makeValue(has_value());
485 }
486# endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
487
488 // Aspects
489
490 /// Return the allocator used by this object to supply memory.
492
493 /// Format this object to the specified output `stream` at the (absolute
494 /// value of) the optionally specified indentation `level` and return a
495 /// reference to `stream`. If `level` is specified, optionally specify
496 /// `spacesPerLevel`, the number of spaces per indentation level for
497 /// this and all of its nested objects. If `level` is negative,
498 /// suppress indentation of the first line. If `spacesPerLevel` is
499 /// negative, format the entire output on one line, suppressing all but
500 /// the initial indentation (as governed by `level`). If `stream` is
501 /// not valid on entry, this operation has no effect.
502 bsl::ostream& print(bsl::ostream& stream,
503 int level = 0,
504 int spacesPerLevel = 4) const;
505
506 /// Return a reference providing non-modifiable access to the underlying `TYPE` object.
507 ///
508 /// \pre The behavior is undefined unless this object is
509 /// non-null.
510 const TYPE& value() const;
511
512 // DEPRECATED FUNCTIONS
513 // provided for compatibility with NullableValue
514
515 /// Return an address providing non-modifiable access to the underlying
516 /// object of a (template parameter) `TYPE` if this object is non-null,
517 /// and the specified `address` otherwise.
518 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::addressOr",
519 "Use 'has_value() ? &value() : address' instead")
520 const TYPE *addressOr(const TYPE *address) const;
521
522#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=10
523
524 /// Assign to this nullable object the value of the (template parameter)
525 /// `TYPE` created in place using the specified `args`. Return a
526 /// reference providing modifiable access to the created (value) object.
527 /// The object is also accessible via the `value` method. If this
528 /// nullable object already contains an object (`false == isNull()`),
529 /// that object is destroyed before the new object is created. If
530 /// `TYPE` has the trait `bslma::UsesBslmaAllocator` (`TYPE` is
531 /// allocator-enabled) the allocator specified at the construction of
532 /// this nullable object is used to supply memory to the value object.
533 /// Attempts to explicitly specify via `args` another allocator to
534 /// supply memory to the created (value) object are disallowed by the compiler.
535 ///
536 /// \note Note that if the constructor of `TYPE` throws an
537 /// exception this object is left in the null state.
538 template <class... ARGS>
539 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
540 "Use 'emplace' instead")
541 TYPE& makeValueInplace(ARGS&&... args);
542#endif
543
544 /// Return the value of the underlying object of a (template parameter)
545 /// `TYPE` if this object is non-null, and the specified `otherValue` otherwise.
546 ///
547 /// \note Note that this method returns *by* *value*, so may be
548 /// inefficient in some contexts.
549 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::valueOr",
550 "Use 'value_or' instead")
551 TYPE valueOr(const TYPE& otherValue) const;
552
553 /// Return an address providing non-modifiable access to the underlying
554 /// object of a (template parameter) `TYPE` if this object is non-null,
555 /// and 0 otherwise.
557 "Use 'has_value() ? &value() : NULL' instead")
558 const TYPE *valueOrNull() const;
559
560};
561
562// FREE OPERATORS
563
564/// Return `true` if the specified `lhs` and `rhs` nullable objects have the
565/// same value, and `false` otherwise. Two nullable objects have the same
566/// value if both are null, or if both are non-null and the values of their underlying objects compare equal.
567///
568/// \note Note that this function will fail to
569/// compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
570template <class LHS_TYPE, class RHS_TYPE>
571bool operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
572 const NullableAllocatedValue<RHS_TYPE>& rhs);
573
574/// Return `true` if the specified `lhs` and `rhs` objects have the same
575/// value, and `false` otherwise. A nullable object and a value of some
576/// type have the same value if the nullable object is non-null and its underlying value compares equal to the other value.
577///
578/// \note Note that this
579/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
580/// compatible.
581template <class LHS_TYPE, class RHS_TYPE>
582bool operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
583 const RHS_TYPE& rhs);
584template <class LHS_TYPE, class RHS_TYPE>
585bool operator==(const LHS_TYPE& lhs,
586 const NullableAllocatedValue<RHS_TYPE>& rhs);
587
588/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
589/// have the same value, and `false` otherwise. Two nullable objects do not
590/// have the same value if one is null and the other is non-null, or if both
591/// are non-null and the values of their underlying objects do not compare equal.
592///
593/// \note Note that this function will fail to compile if `LHS_TYPE` and
594/// `RHS_TYPE` are not compatible.
595template <class LHS_TYPE, class RHS_TYPE>
596bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
597 const NullableAllocatedValue<RHS_TYPE>& rhs);
598
599/// Return `true` if the specified `lhs` and `rhs` objects do not have the
600/// same value, and `false` otherwise. A nullable object and a value of
601/// some type do not have the same value if either the nullable object is
602/// null, or its underlying value does not compare equal to the other value.
603///
604/// \note Note that this function will fail to compile if `LHS_TYPE` and
605/// `RHS_TYPE` are not compatible.
606template <class LHS_TYPE, class RHS_TYPE>
607bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
608 const RHS_TYPE& rhs);
609template <class LHS_TYPE, class RHS_TYPE>
610bool operator!=(const LHS_TYPE& lhs,
611 const NullableAllocatedValue<RHS_TYPE>& rhs);
612
613/// Return `true` if the specified `lhs` nullable object is ordered before
614/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
615/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
616/// are non-null and `lhs.value()` is ordered before `rhs.value()`.
617///
618/// \note Note that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
619/// not compatible.
620template <class LHS_TYPE, class RHS_TYPE>
621bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
622 const NullableAllocatedValue<RHS_TYPE>& rhs);
623
624/// Return `true` if the specified `lhs` nullable object is ordered before
625/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
626/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
627template <class LHS_TYPE, class RHS_TYPE>
628bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
629 const RHS_TYPE& rhs);
630
631/// Return `true` if the specified `lhs` is ordered before the specified
632/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered before
633/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
634template <class LHS_TYPE, class RHS_TYPE>
635bool operator<(const LHS_TYPE& lhs,
636 const NullableAllocatedValue<RHS_TYPE>& rhs);
637
638
639/// Return `true` if the specified `lhs` nullable object is ordered before
640/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
641/// value, and `false` otherwise. (See `operator<` and `operator==`.)
642///
643/// \note Note that this operator returns `!(rhs < lhs)` when both operands are of
644/// `NullableValue` type. Also note that this function will fail to compile
645/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
646template <class LHS_TYPE, class RHS_TYPE>
647bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
648 const NullableAllocatedValue<RHS_TYPE>& rhs);
649
650/// Return `true` if the specified `lhs` nullable object is ordered before
651/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
652///
653/// \note Note that this operator
654/// returns `!(rhs < lhs)`.
655template <class LHS_TYPE, class RHS_TYPE>
656bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
657 const RHS_TYPE& rhs);
658
659/// Return `true` if the specified `lhs` is ordered before the specified
660/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
661///
662/// \note Note that this
663/// operator returns `!(rhs < lhs)`.
664template <class LHS_TYPE, class RHS_TYPE>
665bool operator<=(const LHS_TYPE& lhs,
666 const NullableAllocatedValue<RHS_TYPE>& rhs);
667
668/// Return `true` if the specified `lhs` nullable object is ordered after
669/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
670/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
671/// are non-null and `lhs.value()` is ordered after `rhs.value()`.
672///
673/// \note Note that this operator returns `rhs < lhs` when both operands are of
674/// `NullableValue` type. Also note that this function will fail to compile
675/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
676template <class LHS_TYPE, class RHS_TYPE>
677bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
678 const NullableAllocatedValue<RHS_TYPE>& rhs);
679
680/// Return `true` if the specified `lhs` nullable object is ordered after
681/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
682/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
683///
684/// \note Note that this operator returns `rhs < lhs`.
685template <class LHS_TYPE, class RHS_TYPE>
686bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
687 const RHS_TYPE& rhs);
688
689/// Return `true` if the specified `lhs` is ordered after the specified
690/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered after
691/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`.
692///
693/// \note Note that this operator returns `rhs < lhs`.
694template <class LHS_TYPE, class RHS_TYPE>
695bool operator>(const LHS_TYPE& lhs,
696 const NullableAllocatedValue<RHS_TYPE>& rhs);
697
698/// Return `true` if the specified `lhs` nullable object is ordered after
699/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
700/// value, and `false` otherwise. (See `operator>` and `operator==`.)
701///
702/// \note Note that this operator returns `!(lhs < rhs)` when both operands are of
703/// `NullableValue` type. Also note that this function will fail to compile
704/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
705template <class LHS_TYPE, class RHS_TYPE>
706bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
707 const NullableAllocatedValue<RHS_TYPE>& rhs);
708
709/// Return `true` if the specified `lhs` nullable object is ordered after
710/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
711///
712/// \note Note that this operator
713/// returns `!(lhs < rhs)`.
714template <class LHS_TYPE, class RHS_TYPE>
715bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
716 const RHS_TYPE& rhs);
717
718/// Return `true` if the specified `lhs` is ordered after the specified
719/// `rhs` nullable object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator>` and `operator==`.)
720///
721/// \note Note that this
722/// operator returns `!(lhs < rhs)`.
723template <class LHS_TYPE, class RHS_TYPE>
724bool operator>=(const LHS_TYPE& lhs,
725 const NullableAllocatedValue<RHS_TYPE>& rhs);
726
727/// Write the value of the specified `object` to the specified output
728/// `stream` in a single-line format, and return a reference to `stream`.
729/// If `stream` is not valid on entry, this operation has no effect.
730///
731/// \note Note that this human-readable format is not fully specified, can change
732/// without notice, and is logically equivalent to:
733/// @code
734/// print(stream, 0, -1);
735/// @endcode
736template <class TYPE>
737bsl::ostream& operator<<(bsl::ostream& stream,
738 const NullableAllocatedValue<TYPE>& object);
739
740 //================================
741 // Comparisons with bsl::nullopt_t
742 //================================
743
744/// Return `true` if the specified `lhs` is null, and `false` otherwise.
745template <class TYPE>
746bool operator==(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
748
749/// Return `true` if the specified `rhs` is null, and `false` otherwise.
750template <class TYPE>
751bool operator==(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
753
754/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
755template <class TYPE>
756bool operator!=(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
758
759/// Return `true` if the specified `rhs` is not null, and `false`
760/// otherwise.
761template <class TYPE>
762bool operator!=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
764
765/// Return `false`.
766/// \note Note that `bsl::nullopt` never orders after a
767/// `NullableAllocatedValue`.
768template <class TYPE>
769bool operator<(const NullableAllocatedValue<TYPE>&, const bsl::nullopt_t&)
771
772/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
773///
774/// \note Note that `bsl::nullopt` is ordered before any `NullableAllocatedValue`
775/// that is not null.
776template <class TYPE>
777bool operator<(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
779
780/// Return `true` if the specified `lhs` is not null, and `false`
781/// otherwise.
782template <class TYPE>
783bool operator>(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
785
786/// Return `false`.
787/// \note Note that `bsl::nullopt` never orders after a
788/// `NullableAllocatedValue`.
789template <class TYPE>
790bool operator>(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>&)
792
793/// Return `true` if the specified `lhs` is null, and `false` otherwise.
794template <class TYPE>
795bool operator<=(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
797
798/// Return `true`.
799template <class TYPE>
800bool operator<=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>&)
802
803/// Return `true`.
804template <class TYPE>
805bool operator>=(const NullableAllocatedValue<TYPE>&, const bsl::nullopt_t&)
807
808/// Return `true` if the specified `rhs` is null, and `false` otherwise.
809template <class TYPE>
810bool operator>=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
812
813 //===============================
814 // Comparisons with bsl::optional
815 //===============================
816
817/// If neither of the specified `lhs` and `rhs` contain a value, return
818/// `true`. If one contains a value, and the other does not, return
819/// `false`. Otherwise, return `lhs.value == rhs.value()`.
820template <class LHS_TYPE, class RHS_TYPE>
821bool operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
822 const bsl::optional<RHS_TYPE>& rhs);
823template <class LHS_TYPE, class RHS_TYPE>
824bool operator==(const bsl::optional<LHS_TYPE>& lhs,
825 const NullableAllocatedValue<RHS_TYPE>& rhs);
826
827/// If neither of the specified `lhs` and `rhs` contain a value, return
828/// `false`. If one contains a value, and the other does not, return
829/// `true`. Otherwise, return `lhs.value != rhs.value()`.
830template <class LHS_TYPE, class RHS_TYPE>
831bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
832 const bsl::optional<RHS_TYPE>& rhs);
833template <class LHS_TYPE, class RHS_TYPE>
834bool operator!=(const bsl::optional<LHS_TYPE>& lhs,
835 const NullableAllocatedValue<RHS_TYPE>& rhs);
836
837/// If neither of the specified `lhs` and `rhs` contain a value, return
838/// `false`. If `lhs` contains a value, and `rhs` does not, return `false`.
839/// If `lhs` does not contains a value, `rhs` does, return `true`.
840/// Otherwise, return `lhs.value < rhs.value()`.
841template <class LHS_TYPE, class RHS_TYPE>
842bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
843 const bsl::optional<RHS_TYPE>& rhs);
844
845/// If neither of the specified `lhs` and `rhs` contain a value, return
846/// `false`. If `lhs` contains a value, and `rhs` does not, return `false`.
847/// If `lhs` does not contains a value, `rhs` does, return `true`.
848/// Otherwise, return `lhs.value < rhs.value()`.
849template <class LHS_TYPE, class RHS_TYPE>
850bool operator<(const bsl::optional<LHS_TYPE>& lhs,
851 const NullableAllocatedValue<RHS_TYPE>& rhs);
852
853/// If neither of the specified `lhs` and `rhs` contain a value, return
854/// `false`. If `lhs` contains a value, and `rhs` does not, return `true`.
855/// If `lhs` does not contains a value, `rhs` does, return `false`.
856/// Otherwise, return `lhs.value > rhs.value()`.
857template <class LHS_TYPE, class RHS_TYPE>
858bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
859 const bsl::optional<RHS_TYPE>& rhs);
860
861/// If neither of the specified `lhs` and `rhs` contain a value, return
862/// `false`. If `lhs` contains a value, and `rhs` does not, return `true`.
863/// If `lhs` does not contains a value, `rhs` does, return `false`.
864/// Otherwise, return `lhs.value > rhs.value()`.
865template <class LHS_TYPE, class RHS_TYPE>
866bool operator>(const bsl::optional<LHS_TYPE>& lhs,
867 const NullableAllocatedValue<RHS_TYPE>& rhs);
868
869/// If neither of the specified `lhs` and `rhs` contain a value, return
870/// `true`. If `lhs` contains a value, and `rhs` does not, return `false`.
871/// If `lhs` does not contains a value, `rhs` does, return `true`.
872/// Otherwise, return `lhs.value <= rhs.value()`.
873template <class LHS_TYPE, class RHS_TYPE>
874bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
875 const bsl::optional<RHS_TYPE>& rhs);
876
877/// If neither of the specified `lhs` and `rhs` contain a value, return
878/// `true`. If `lhs` contains a value, and `rhs` does not, return `false`.
879/// If `lhs` does not contains a value, `rhs` does, return `true`.
880/// Otherwise, return `lhs.value <= rhs.value()`.
881template <class LHS_TYPE, class RHS_TYPE>
882bool operator<=(const bsl::optional<LHS_TYPE>& lhs,
883 const NullableAllocatedValue<RHS_TYPE>& rhs);
884
885/// If neither of the specified `lhs` and `rhs` contain a value, return
886/// `true`. If `lhs` contains a value, and `rhs` does not, return `true`.
887/// If `lhs` does not contains a value, `rhs` does, return `false`.
888/// Otherwise, return `lhs.value >= rhs.value()`.
889template <class LHS_TYPE, class RHS_TYPE>
890bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
891 const bsl::optional<RHS_TYPE>& rhs);
892
893/// If neither of the specified `lhs` and `rhs` contain a value, return
894/// `true`. If `lhs` contains a value, and `rhs` does not, return `true`.
895/// If `lhs` does not contains a value, `rhs` does, return `false`.
896/// Otherwise, return `lhs.value >= rhs.value()`.
897template <class LHS_TYPE, class RHS_TYPE>
898bool operator>=(const bsl::optional<LHS_TYPE>& lhs,
899 const NullableAllocatedValue<RHS_TYPE>& rhs);
900
901// FREE FUNCTIONS
902
903/// Pass the boolean value of whether the specified `input` contains a value
904/// to the specified `hashAlg` hashing algorithm of (template parameter)
905/// type `HASHALG`. If `input` contains a value, additionally pass that
906/// value to `hashAlg`.
907template <class HASHALG, class TYPE>
908void hashAppend(HASHALG& hashAlg, const NullableAllocatedValue<TYPE>& input);
909
910/// Exchange the values of the specified `a` and `b` objects. This function
911/// provides the no-throw exception-safety guarantee if the two objects were
912/// created with the same allocator and the basic guarantee otherwise.
913template <class TYPE>
914void swap(NullableAllocatedValue<TYPE>& a,
915 NullableAllocatedValue<TYPE>& b);
916
917// ============================================================================
918// INLINE DEFINITIONS
919// ============================================================================
920
921 // ----------------------------------
922 // class NullableAllocatedValue<TYPE>
923 // ----------------------------------
924
925// CREATORS
926template <class TYPE>
927inline
929: d_allocator(bslma::Default::defaultAllocator())
930{
931 d_storage.d_pointer_p = 0;
932}
933
934template <class TYPE>
935inline
938: d_allocator(allocator.mechanism())
939{
940 d_storage.d_pointer_p = 0;
941}
942
943template <class TYPE>
944inline
946: d_allocator(bslma::Default::defaultAllocator())
947{
948 d_storage.d_pointer_p = 0;
949}
950
951template <class TYPE>
952inline
955 const bsl::allocator<char>& allocator)
956: d_allocator(allocator.mechanism())
957{
958 d_storage.d_pointer_p = 0;
959}
960
961template <class TYPE>
962inline
965: d_allocator(bslma::Default::defaultAllocator())
966{
967 if (original.has_value()) {
968 makeValue(original.value());
969 }
970 else {
971 d_storage.d_pointer_p = 0;
972 }
973}
974
975template <class TYPE>
976inline
979 const bsl::allocator<char>& allocator)
980: d_allocator(allocator.mechanism())
981{
982 if (original.has_value()) {
983 makeValue(original.value());
984 }
985 else {
986 d_storage.d_pointer_p = 0;
987 }
988}
989
990template <class TYPE>
991inline
993: d_allocator(bslma::Default::defaultAllocator())
994{
996}
997
998template <class TYPE>
999inline
1001 const TYPE& value,
1002 const bsl::allocator<char>& allocator)
1003: d_allocator(allocator.mechanism())
1004{
1006}
1007
1008template <class TYPE>
1009inline
1014
1015// PRIVATE CLASS METHODS
1016template <class TYPE>
1018{
1019// we can store it locally if it will fit into a pointer, and it doesn't have
1020// an exceptionally large alignment requirement.
1021 return (sizeof(TYPE) <= sizeof(TYPE *)) &&
1023 (static_cast<bsl::size_t>(bsls::AlignmentFromType<TYPE >::VALUE) <=
1024 static_cast<bsl::size_t>(bsls::AlignmentFromType<TYPE *>::VALUE));
1025}
1026
1027// MANIPULATORS
1028template <class TYPE>
1029inline
1030NullableAllocatedValue<TYPE>&
1033{
1034 if (rhs.has_value()) {
1035 makeValue(rhs.value());
1036 }
1037 else {
1038 reset();
1039 }
1040
1041 return *this;
1042}
1043
1044template <class TYPE>
1045inline
1048{
1049 reset();
1050 return *this;
1051}
1052
1053template <class TYPE>
1054inline
1057{
1058 makeValue(rhs);
1059 return *this;
1060}
1061
1062template <class TYPE>
1063template <class STREAM>
1064STREAM& NullableAllocatedValue<TYPE>::bdexStreamIn(STREAM& stream, int version)
1065{
1067
1068 char isNullFlag = 0; // Redundant initialization to suppress -Werror.
1069
1070 stream.getInt8(isNullFlag);
1071
1072 if (stream) {
1073 if (!isNullFlag) {
1074 makeValue();
1075 bdexStreamIn(stream, value(), version);
1076 }
1077 else {
1078 reset();
1079 }
1080 }
1081
1082 return stream;
1083}
1084
1085template <class TYPE>
1086inline
1088{
1089 if (has_value()) {
1090 TYPE &v = value();
1091 v = val;
1092 return v; // RETURN
1093 }
1094
1095 bslma::Allocator *alloc = allocator();
1096 if (isLocal()) {
1097 bslalg::ScalarPrimitives::copyConstruct(getAddress(), val, alloc);
1098 }
1099 else {
1100 TYPE *tmpPtr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1101
1102 bslma::DeallocatorProctor<bslma::Allocator> proctor(tmpPtr, alloc);
1103 bslalg::ScalarPrimitives::copyConstruct(tmpPtr, val, alloc);
1104 proctor.release();
1105 setRemoteAddress(tmpPtr);
1106 }
1107
1108 setHasValueFlag();
1109 return value();
1110}
1111
1112template <class TYPE>
1113inline
1115{
1116 reset();
1117
1118 // Note that this alternative implementation, instead of 'reset()',
1119 // provides stronger exception-safety, but it breaks some client code that
1120 // uses 'NullableAllocatedValue' with a non-value-semantic 'TYPE'.
1121 //..
1122 // if (d_value_p) {
1123 // *d_value_p = TYPE(allocator());
1124 // return *d_value_p; // RETURN
1125 // }
1126 //..
1127
1128 bslma::Allocator *alloc = allocator();
1129 if (isLocal()) {
1130 bslalg::ScalarPrimitives::defaultConstruct(getAddress(), alloc);
1131 }
1132 else {
1133 TYPE *tmpPtr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1134
1135 bslma::DeallocatorProctor<bslma::Allocator> proctor(tmpPtr, alloc);
1137 proctor.release();
1138 setRemoteAddress(tmpPtr);
1139 }
1140
1141 setHasValueFlag();
1142
1143 return value();
1144}
1145
1146template <class TYPE>
1147inline
1149{
1150 if (has_value()) {
1151 TYPE *p = getAddress();
1152 BSLS_ASSERT(p);
1153 p->~TYPE();
1154 if (!isLocal()) {
1155 allocator()->deallocate(p);
1156 }
1157 clearHasValueFlag();
1158 }
1159}
1160
1161template <class TYPE>
1163{
1164 // Member 'swap' is undefined for non-equal allocators.
1165
1166 BSLS_ASSERT(allocator() == other.allocator());
1167
1168 // Nothing to do if both objects are null.
1169 if (isNull() && other.isNull()) {
1170 return; // RETURN
1171 }
1172
1173 if (isLocal()) {
1174 swapLocal(other);
1175 }
1176 else {
1177 swapRemote(other);
1178 }
1179}
1180
1181template <class TYPE>
1182inline
1184{
1185 BSLS_ASSERT(has_value());
1186 return *getAddress();
1187}
1188
1189template <class TYPE>
1190inline
1192{
1193 BSLS_ASSERT(has_value());
1194 return getAddress();
1195}
1196
1197template <class TYPE>
1198inline
1200{
1201 BSLS_ASSERT(has_value());
1202 return value();
1203}
1204
1205#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1206template <class TYPE>
1207template <class... ARGS>
1208inline
1211{
1212 bslma::Allocator *alloc = allocator();
1213 TYPE *ptr = getAddress();
1214 // First, we get destruct the existing value - w/o releasing the storage
1215 if (has_value()) {
1216 BSLS_ASSERT(ptr);
1217 ptr->~TYPE();
1218 clearHasValueFlag();
1219 }
1220 else if (!isLocal()) {
1221 // Allocate some space for the object that we're creating. If this
1222 // throws, we have no cleanup to do; because the object is already
1223 // empty.
1224 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1225 setRemoteAddress(ptr);
1226 }
1227
1228 if (isLocal()) {
1229 BloombergLP::bslma::ConstructionUtil::construct(
1230 ptr,
1231 alloc,
1232 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1233 }
1234 else {
1236 BloombergLP::bslma::ConstructionUtil::construct(
1237 ptr,
1238 alloc,
1239 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1240 proctor.release();
1241 }
1242 setHasValueFlag();
1243 return value();
1244}
1245
1246# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1247template <class TYPE>
1248template <class INIT_LIST_TYPE, class... ARGS>
1250 std::initializer_list<INIT_LIST_TYPE> il,
1252{
1253 bslma::Allocator *alloc = allocator();
1254 TYPE *ptr = getAddress();
1255 // First, we get destruct the existing value - w/o releasing the storage
1256 if (has_value()) {
1257 BSLS_ASSERT(ptr);
1258 ptr->~TYPE();
1259 clearHasValueFlag();
1260 }
1261 else if (!isLocal()) {
1262 // Allocate some space for the object that we're creating. If this
1263 // throws, we have no cleanup to do; because the object is already
1264 // empty.
1265 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1266 setRemoteAddress(ptr);
1267 }
1268
1269 if (isLocal()) {
1270 BloombergLP::bslma::ConstructionUtil::construct(
1271 ptr,
1272 alloc,
1273 il,
1274 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1275 }
1276 else {
1278 BloombergLP::bslma::ConstructionUtil::construct(
1279 ptr,
1280 alloc,
1281 il,
1282 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1283 proctor.release();
1284 }
1285 setHasValueFlag();
1286 return value();
1287}
1288# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1289#endif
1290
1291// PRIVATE ACCESSORS
1292template <class TYPE>
1293inline
1294TYPE *NullableAllocatedValue<TYPE>::getAddress() {
1295 if (isLocal()) {
1296 return reinterpret_cast<TYPE *>(
1297 static_cast<void *>(d_storage.d_buffer)); // RETURN
1298 }
1299 else {
1300 return d_storage.d_pointer_p; // RETURN
1301 }
1302}
1303
1304template <class TYPE>
1305inline
1306const TYPE *NullableAllocatedValue<TYPE>::getAddress() const {
1307 if (isLocal()) {
1308 return reinterpret_cast<const TYPE *>(
1309 static_cast<const void *>(d_storage.d_buffer)); // RETURN
1310 }
1311 else {
1312 return d_storage.d_pointer_p; // RETURN
1313 }
1314}
1315
1316// PRIVATE MANIPULATORS
1317template <class TYPE>
1318inline
1319void NullableAllocatedValue<TYPE>::clearHasValueFlag() BSLS_KEYWORD_NOEXCEPT
1320{
1321 d_allocator.clearFlag(k_HAS_VALUE);
1322}
1323
1324template <class TYPE>
1325inline
1326void NullableAllocatedValue<TYPE>::setHasValueFlag() BSLS_KEYWORD_NOEXCEPT
1327{
1328 d_allocator.setFlag(k_HAS_VALUE);
1329}
1330
1331template <class TYPE>
1332inline
1333void NullableAllocatedValue<TYPE>::setRemoteAddress(TYPE *newPtr) {
1334 BSLS_ASSERT(!isLocal());
1335 d_storage.d_pointer_p = newPtr;
1336}
1337
1338template <class TYPE>
1339inline
1340void NullableAllocatedValue<TYPE>::swapLocal(NullableAllocatedValue& other)
1341{
1342// At most one of 'isNull()' and 'other.isNull()' is true
1343// Swapping the 'd_allocator's would be wrong here.
1344 if (isNull()) {
1345 makeValue(other.value());
1346 other.reset();
1347 }
1348 else if (other.isNull()) {
1349 other.makeValue(value());
1350 reset();
1351 }
1352 else {
1353 bslalg::SwapUtil::swap(getAddress(), other.getAddress());
1354 }
1355}
1356
1357template <class TYPE>
1358inline
1359void NullableAllocatedValue<TYPE>::swapRemote(NullableAllocatedValue& other)
1360{
1361 bslalg::SwapUtil::swap(&d_allocator, &other.d_allocator);
1362 bslalg::SwapUtil::swap(& d_storage.d_pointer_p,
1363 &other.d_storage.d_pointer_p);
1364}
1365
1366// ACCESSORS
1367template <class TYPE>
1368template <class STREAM>
1370 int version) const
1371{
1373
1374 stream.putInt8(has_value() ? 0 : 1);
1375
1376 if (has_value()) {
1377 bdexStreamOut(stream, value(), version);
1378 }
1379
1380 return stream;
1381}
1382
1383template <class TYPE>
1384inline
1386{
1387 return allocator();
1388}
1389
1390
1391template <class TYPE>
1392inline
1394{
1395 return d_allocator.readFlag(k_HAS_VALUE);
1396}
1397
1398template <class TYPE>
1399inline
1401{
1402 return !has_value();
1403}
1404
1405# ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1406template <class TYPE>
1408{
1409 return has_value();
1410}
1411# endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1412
1413template <class TYPE>
1414inline
1416 int versionSelector) const
1417{
1419
1420 // We need to call the 'bslx::VersionFunctions' helper function, because we
1421 // cannot guarantee that 'TYPE' implements 'maxSupportedBdexVersion' as a
1422 // class method.
1423
1424 return maxSupportedBdexVersion(reinterpret_cast<TYPE *>(0),
1425 versionSelector);
1426}
1427
1428#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1429template <class TYPE>
1430inline
1432{
1433 return maxSupportedBdexVersion(0);
1434}
1435#endif // BDE_OMIT_INTERNAL_DEPRECATED
1436
1437template <class TYPE>
1438template <class ANY_TYPE>
1439inline TYPE
1440NullableAllocatedValue<TYPE>::value_or(const ANY_TYPE& default_value) const
1441{
1442 return has_value() ? value() : static_cast<TYPE>(default_value);
1443}
1444
1445template <class TYPE>
1446inline
1448{
1449 BSLS_ASSERT(has_value());
1450 return &value();
1451}
1452
1453template <class TYPE>
1454inline
1456{
1457 BSLS_ASSERT(has_value());
1458 return value();
1459}
1460
1461 // Aspects
1462
1463template <class TYPE>
1464inline
1466{
1467 return d_allocator.getPointer();
1468}
1469
1470template <class TYPE>
1471inline
1473 bsl::ostream& stream,
1474 int level,
1475 int spacesPerLevel) const
1476{
1477 if (!has_value()) {
1478 return bdlb::PrintMethods::print(stream,
1479 "NULL",
1480 level,
1481 spacesPerLevel); // RETURN
1482 }
1483
1484 return bdlb::PrintMethods::print(stream, value(), level, spacesPerLevel);
1485}
1486
1487template <class TYPE>
1488inline
1490{
1491#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1492 // TBD: The assert below was commented out because a call to this function
1493 // is sometimes used as an argument to a template function that only looks
1494 // at the value type (and does not access the value).
1495
1496 // BSLS_REVIEW(has_value());
1497#else
1498 BSLS_ASSERT(has_value());
1499#endif
1500
1501 return *getAddress();
1502}
1503
1504// DEPRECATED FUNCTIONS
1505
1506template <class TYPE>
1507inline
1508const TYPE *NullableAllocatedValue<TYPE>::addressOr(const TYPE *address) const
1509{
1510 return has_value() ? &value() : address;
1511}
1512
1513#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=10
1514template <class TYPE>
1515template <class... ARGS>
1516inline
1517TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(ARGS&&... args)
1518{
1519 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1520}
1521#endif
1522
1523template <class TYPE>
1524inline
1525TYPE NullableAllocatedValue<TYPE>::valueOr(const TYPE& otherValue) const
1526{
1527 return has_value() ? value() : otherValue;
1528}
1529
1530template <class TYPE>
1531inline
1532const TYPE *NullableAllocatedValue<TYPE>::valueOrNull() const {
1533 return has_value() ? &value() : NULL;
1534}
1535
1536} // close package namespace
1537
1538// FREE OPERATORS
1539template <class LHS_TYPE, class RHS_TYPE>
1540inline
1541bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
1542 const NullableAllocatedValue<RHS_TYPE>& rhs)
1543{
1544 if (lhs.isNull()) {
1545 return rhs.isNull(); // RETURN
1546 }
1547
1548 return rhs.isNull() ? false : lhs.value() == rhs.value();
1549}
1550
1551template <class LHS_TYPE, class RHS_TYPE>
1552inline
1553bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
1554 const RHS_TYPE& rhs)
1555{
1556 return lhs.isNull() ? false : lhs.value() == rhs;
1557}
1558
1559template <class LHS_TYPE, class RHS_TYPE>
1560inline
1561bool bdlb::operator==(const LHS_TYPE& lhs,
1562 const NullableAllocatedValue<RHS_TYPE>& rhs)
1563{
1564 return rhs.isNull() ? false : lhs == rhs.value();
1565}
1566
1567template <class LHS_TYPE, class RHS_TYPE>
1568inline
1569bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1570 const NullableAllocatedValue<RHS_TYPE>& rhs)
1571{
1572 if (lhs.isNull()) {
1573 return !rhs.isNull(); // RETURN
1574 }
1575
1576 return rhs.isNull() ? true : lhs.value() != rhs.value();
1577}
1578
1579template <class LHS_TYPE, class RHS_TYPE>
1580inline
1581bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1582 const RHS_TYPE& rhs)
1583{
1584 return lhs.isNull() ? true : lhs.value() != rhs;
1585}
1586
1587template <class LHS_TYPE, class RHS_TYPE>
1588inline
1589bool bdlb::operator!=(const LHS_TYPE& lhs,
1590 const NullableAllocatedValue<RHS_TYPE>& rhs)
1591{
1592 return rhs.isNull() ? true : lhs != rhs.value();
1593}
1594
1595template <class LHS_TYPE, class RHS_TYPE>
1596inline
1597bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
1598 const NullableAllocatedValue<RHS_TYPE>& rhs)
1599{
1600 if (rhs.isNull()) {
1601 return false; // RETURN
1602 }
1603
1604 return lhs.isNull() ? true : lhs.value() < rhs.value();
1605}
1606
1607template <class LHS_TYPE, class RHS_TYPE>
1608inline
1609bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
1610 const RHS_TYPE& rhs)
1611{
1612 return lhs.isNull() ? true : lhs.value() < rhs;
1613}
1614
1615template <class LHS_TYPE, class RHS_TYPE>
1616inline
1617bool bdlb::operator<(const LHS_TYPE& lhs,
1618 const NullableAllocatedValue<RHS_TYPE>& rhs)
1619{
1620 return rhs.isNull() ? false : lhs < rhs.value();
1621}
1622
1623template <class LHS_TYPE, class RHS_TYPE>
1624inline
1625bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1626 const NullableAllocatedValue<RHS_TYPE>& rhs)
1627{
1628 if (lhs.isNull()) {
1629 return true; // RETURN
1630 }
1631
1632 return rhs.isNull() ? false : lhs.value() <= rhs.value();
1633}
1634
1635template <class LHS_TYPE, class RHS_TYPE>
1636inline
1637bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1638 const RHS_TYPE& rhs)
1639{
1640 return lhs.isNull() ? true : lhs.value() <= rhs;
1641}
1642
1643template <class LHS_TYPE, class RHS_TYPE>
1644inline
1645bool bdlb::operator<=(const LHS_TYPE& lhs,
1646 const NullableAllocatedValue<RHS_TYPE>& rhs)
1647{
1648 return rhs.isNull() ? false : lhs <= rhs.value();
1649}
1650
1651template <class LHS_TYPE, class RHS_TYPE>
1652inline
1653bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
1654 const NullableAllocatedValue<RHS_TYPE>& rhs)
1655{
1656 if (lhs.isNull()) {
1657 return false; // RETURN
1658 }
1659
1660 return rhs.isNull() ? true : lhs.value() > rhs.value();
1661}
1662
1663template <class LHS_TYPE, class RHS_TYPE>
1664inline
1665bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
1666 const RHS_TYPE& rhs)
1667{
1668 return lhs.isNull() ? false : lhs.value() > rhs;
1669}
1670
1671template <class LHS_TYPE, class RHS_TYPE>
1672inline
1673bool bdlb::operator>(const LHS_TYPE& lhs,
1674 const NullableAllocatedValue<RHS_TYPE>& rhs)
1675{
1676 return rhs.isNull() ? true : lhs > rhs.value();
1677}
1678
1679template <class LHS_TYPE, class RHS_TYPE>
1680inline
1681bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1682 const NullableAllocatedValue<RHS_TYPE>& rhs)
1683{
1684 if (rhs.isNull()) {
1685 return true; // RETURN
1686 }
1687
1688 return lhs.isNull() ? false : lhs.value() >= rhs.value();
1689}
1690
1691template <class LHS_TYPE, class RHS_TYPE>
1692inline
1693bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1694 const RHS_TYPE& rhs)
1695{
1696 return lhs.isNull() ? false : lhs.value() >= rhs;
1697}
1698
1699template <class LHS_TYPE, class RHS_TYPE>
1700inline
1701bool bdlb::operator>=(const LHS_TYPE& lhs,
1702 const NullableAllocatedValue<RHS_TYPE>& rhs)
1703{
1704 return rhs.isNull() ? true : lhs >= rhs.value();
1705}
1706
1707template <class TYPE>
1708inline
1709bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
1710 const NullableAllocatedValue<TYPE>& object)
1711{
1712 return object.print(stream, 0, -1);
1713}
1714
1715 //--------------------------------
1716 // Comparisons with bsl::nullopt_t
1717 //--------------------------------
1718
1719template <class TYPE>
1720inline
1721bool bdlb::operator==(const NullableAllocatedValue<TYPE>& lhs,
1723{
1724 return !lhs.has_value();
1725}
1726
1727template <class TYPE>
1728inline
1729bool bdlb::operator==(
1730 const bsl::nullopt_t&,
1731 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1732{
1733 return !rhs.has_value();
1734}
1735
1736template <class TYPE>
1737inline bool bdlb::operator!=(const NullableAllocatedValue<TYPE>& lhs,
1739{
1740 return lhs.has_value();
1741}
1742
1743template <class TYPE>
1744inline
1745bool bdlb::operator!=(
1746 const bsl::nullopt_t&,
1747 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1748{
1749 return rhs.has_value();
1750}
1751
1752template <class TYPE>
1753inline
1754bool bdlb::operator<(const NullableAllocatedValue<TYPE>&,
1756{
1757 return false;
1758}
1759
1760template <class TYPE>
1761inline
1762bool bdlb::operator<(
1763 const bsl::nullopt_t&,
1764 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1765{
1766 return rhs.has_value();
1767}
1768
1769template <class TYPE>
1770inline
1771bool bdlb::operator>(const NullableAllocatedValue<TYPE>& lhs,
1773{
1774 return lhs.has_value();
1775}
1776
1777template <class TYPE>
1778inline
1780 const NullableAllocatedValue<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1781{
1782 return false;
1783}
1784
1785template <class TYPE>
1786inline
1787bool bdlb::operator<=(const NullableAllocatedValue<TYPE>& lhs,
1789{
1790 return !lhs.has_value();
1791}
1792
1793template <class TYPE>
1794inline
1795bool bdlb::operator<=(
1796 const bsl::nullopt_t&,
1797 const NullableAllocatedValue<TYPE>&) BSLS_KEYWORD_NOEXCEPT
1798{
1799 return true;
1800}
1801
1802template <class TYPE>
1803inline
1804bool bdlb::operator>=(const NullableAllocatedValue<TYPE>&,
1806{
1807 return true;
1808}
1809
1810template <class TYPE>
1811inline
1812bool bdlb::operator>=(
1813 const bsl::nullopt_t&,
1814 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
1815{
1816 return !rhs.has_value();
1817}
1818
1819 //-------------------------------
1820 // Comparisons with bsl::optional
1821 //-------------------------------
1822
1823template <class LHS_TYPE, class RHS_TYPE>
1824inline
1825bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
1826 const bsl::optional<RHS_TYPE>& rhs)
1827{
1828 if (lhs.has_value() != rhs.has_value())
1829 return false; // RETURN
1830 return lhs.has_value () ? lhs.value() == rhs.value () : true;
1831}
1832
1833template <class LHS_TYPE, class RHS_TYPE>
1834inline
1836 const NullableAllocatedValue<RHS_TYPE>& rhs)
1837{
1838 if (lhs.has_value() != rhs.has_value())
1839 return false; // RETURN
1840 return lhs.has_value () ? lhs.value() == rhs.value () : true;
1841}
1842
1843template <class LHS_TYPE, class RHS_TYPE>
1844inline
1845bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1846 const bsl::optional<RHS_TYPE>& rhs)
1847{
1848 if (lhs.has_value() != rhs.has_value())
1849 return true; // RETURN
1850 return lhs.has_value () ? lhs.value() != rhs.value () : false;
1851}
1852
1853template <class LHS_TYPE, class RHS_TYPE>
1854inline
1856 const NullableAllocatedValue<RHS_TYPE>& rhs)
1857{
1858 if (lhs.has_value() != rhs.has_value())
1859 return true; // RETURN
1860 return lhs.has_value () ? lhs.value() != rhs.value () : false;
1861}
1862
1863template <class LHS_TYPE, class RHS_TYPE>
1864inline
1865bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
1866 const bsl::optional<RHS_TYPE>& rhs)
1867{
1868 if (lhs.has_value() != rhs.has_value())
1869 return rhs.has_value(); // RETURN
1870 return lhs.has_value () ? lhs.value() < rhs.value () : false;
1871}
1872
1873template <class LHS_TYPE, class RHS_TYPE>
1874inline
1876 const NullableAllocatedValue<RHS_TYPE>& rhs)
1877{
1878 if (lhs.has_value() != rhs.has_value())
1879 return rhs.has_value(); // RETURN
1880 return lhs.has_value () ? lhs.value() < rhs.value () : false;
1881}
1882
1883
1884template <class LHS_TYPE, class RHS_TYPE>
1885inline
1886bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
1887 const bsl::optional<RHS_TYPE>& rhs)
1888{
1889 if (lhs.has_value() != rhs.has_value())
1890 return lhs.has_value(); // RETURN
1891 return lhs.has_value () ? lhs.value() > rhs.value () : false;
1892}
1893
1894template <class LHS_TYPE, class RHS_TYPE>
1895inline
1897 const NullableAllocatedValue<RHS_TYPE>& rhs)
1898{
1899 if (lhs.has_value() != rhs.has_value())
1900 return lhs.has_value(); // RETURN
1901 return lhs.has_value () ? lhs.value() > rhs.value () : false;
1902}
1903
1904template <class LHS_TYPE, class RHS_TYPE>
1905inline
1906bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1907 const bsl::optional<RHS_TYPE>& rhs)
1908{
1909 if (lhs.has_value() != rhs.has_value())
1910 return rhs.has_value(); // RETURN
1911 return lhs.has_value () ? lhs.value() <= rhs.value () : true;
1912}
1913
1914template <class LHS_TYPE, class RHS_TYPE>
1915inline
1917 const NullableAllocatedValue<RHS_TYPE>& rhs)
1918{
1919 if (lhs.has_value() != rhs.has_value())
1920 return rhs.has_value(); // RETURN
1921 return lhs.has_value () ? lhs.value() <= rhs.value () : true;
1922}
1923
1924template <class LHS_TYPE, class RHS_TYPE>
1925inline
1926bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
1927 const bsl::optional<RHS_TYPE>& rhs)
1928{
1929 if (lhs.has_value() != rhs.has_value())
1930 return lhs.has_value(); // RETURN
1931 return lhs.has_value () ? lhs.value() >= rhs.value () : true;
1932}
1933
1934template <class LHS_TYPE, class RHS_TYPE>
1935inline
1937 const NullableAllocatedValue<RHS_TYPE>& rhs)
1938{
1939 if (lhs.has_value() != rhs.has_value())
1940 return lhs.has_value(); // RETURN
1941 return lhs.has_value () ? lhs.value() >= rhs.value () : true;
1942}
1943
1944
1945// FREE FUNCTIONS
1946template <class HASHALG, class TYPE>
1947void bdlb::hashAppend(HASHALG& hashAlg,
1948 const NullableAllocatedValue<TYPE>& input)
1949{
1950 using ::BloombergLP::bslh::hashAppend;
1951
1952 if (!input.isNull()) {
1953 hashAppend(hashAlg, true);
1954 hashAppend(hashAlg, input.value());
1955 }
1956 else {
1957 hashAppend(hashAlg, false);
1958 }
1959}
1960
1961template <class TYPE>
1962void bdlb::swap(NullableAllocatedValue<TYPE>& a,
1963 NullableAllocatedValue<TYPE>& b)
1964{
1965 if (a.allocator() == b.allocator()) {
1966 a.swap(b);
1967
1968 return; // RETURN
1969 }
1970
1971 NullableAllocatedValue<TYPE> futureA(b, a.allocator());
1972 NullableAllocatedValue<TYPE> futureB(a, b.allocator());
1973
1974 futureA.swap(a);
1975 futureB.swap(b);
1976}
1977
1978
1979
1980#endif // End C++11 code
1981
1982#endif
1983
1984// ----------------------------------------------------------------------------
1985// Copyright 2015 Bloomberg Finance L.P.
1986//
1987// Licensed under the Apache License, Version 2.0 (the "License");
1988// you may not use this file except in compliance with the License.
1989// You may obtain a copy of the License at
1990//
1991// http://www.apache.org/licenses/LICENSE-2.0
1992//
1993// Unless required by applicable law or agreed to in writing, software
1994// distributed under the License is distributed on an "AS IS" BASIS,
1995// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1996// See the License for the specific language governing permissions and
1997// limitations under the License.
1998// ----------------------------- END-OF-FILE ----------------------------------
1999
2000/** @} */
2001/** @} */
2002/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:99
Definition bdlb_nullableallocatedvalue.h:180
const TYPE & value() const
Definition bdlb_nullableallocatedvalue.h:1489
char d_buffer[sizeof(TYPE *)]
Definition bdlb_nullableallocatedvalue.h:189
TYPE * d_pointer_p
Definition bdlb_nullableallocatedvalue.h:188
void reset()
Definition bdlb_nullableallocatedvalue.h:1148
TYPE ValueType
Definition bdlb_nullableallocatedvalue.h:258
TYPE value_or(const ANY_TYPE &default_value) const
Definition bdlb_nullableallocatedvalue.h:1440
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1393
TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)...)
NullableAllocatedValue()
Definition bdlb_nullableallocatedvalue.h:928
bsl::allocator< char > get_allocator() const
Definition bdlb_nullableallocatedvalue.h:1385
TYPE & makeValue()
Definition bdlb_nullableallocatedvalue.h:1114
NullableAllocatedValue< TYPE > & operator=(const NullableAllocatedValue &rhs)
Definition bdlb_nullableallocatedvalue.h:1031
~NullableAllocatedValue()
Destroy this object.
Definition bdlb_nullableallocatedvalue.h:1010
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlb_nullableallocatedvalue.h:1064
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlb_nullableallocatedvalue.h:1472
TYPE * operator->()
Definition bdlb_nullableallocatedvalue.h:1191
BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace", "Use 'emplace' instead") TYPE &makeValueInplace(ARGS &&... args)
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1400
BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::addressOr", "Use 'has_value() ? &value() : address' instead") const TYPE *addressOr(const TYPE *address) const
void swap(NullableAllocatedValue &other)
Definition bdlb_nullableallocatedvalue.h:1162
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlb_nullableallocatedvalue.h:1369
TYPE & value()
Definition bdlb_nullableallocatedvalue.h:1183
BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::valueOr", "Use 'value_or' instead") TYPE valueOr(const TYPE &otherValue) const
const TYPE * operator->() const
Definition bdlb_nullableallocatedvalue.h:1447
int maxSupportedBdexVersion() const
Definition bdlb_nullableallocatedvalue.h:1431
TYPE & operator*()
Definition bdlb_nullableallocatedvalue.h:1199
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlb_nullableallocatedvalue.h:1465
TYPE & makeValue(const TYPE &val)
Definition bdlb_nullableallocatedvalue.h:1087
const TYPE & operator*() const
Definition bdlb_nullableallocatedvalue.h:1455
Definition bslma_bslallocator.h:588
Definition bslstl_optional.h:2043
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:182
Definition bslma_allocator.h:545
virtual void * allocate(size_type size)=0
Definition bslma_deallocatorproctor.h:312
void release()
Definition bslma_deallocatorproctor.h:389
void setFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:283
void clearFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:272
bool readFlag(unsigned idx) const
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:262
t_TYPE * getPointer() const
Return the held pointer.
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:254
#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_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
bool isNull(const TYPE &object)
void makeValue(TYPE *object)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:725
Definition bdlb_algorithmworkaroundutil.h:74
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const BigEndianInt16 &integer)
bool operator>=(const Guid &lhs, const Guid &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
void swap(NullableAllocatedValue< TYPE > &a, NullableAllocatedValue< TYPE > &b)
bool operator<=(const Guid &lhs, const Guid &rhs)
bool operator>(const Guid &lhs, const Guid &rhs)
bool operator<(const Guid &lhs, const Guid &rhs)
bool operator==(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
Definition bdlat_valuetypefunctions.h:939
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
STREAM & bdexStreamIn(STREAM &stream, VALUE_TYPE &variable)
Definition bslx_instreamfunctions.h:1263
STREAM & bdexStreamOut(STREAM &stream, const TYPE &value)
Definition bslx_outstreamfunctions.h:1004
int maxSupportedBdexVersion(const TYPE *, int versionSelector)
Definition bslx_versionfunctions.h:531
Definition bdlb_printmethods.h:306
Definition bslstl_optional.h:522
static void defaultConstruct(TARGET_TYPE *address, bslma::Allocator *allocator)
Definition bslalg_scalarprimitives.h:1577
static void copyConstruct(TARGET_TYPE *address, const TARGET_TYPE &original, bslma::Allocator *allocator)
Definition bslalg_scalarprimitives.h:1617
Definition bslmf_isbitwisemoveable.h:718
Definition bsls_alignmentfromtype.h:378