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