BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_nullableallocatedvalue_cpp03.h
Go to the documentation of this file.
1/// @file bdlb_nullableallocatedvalue_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullableallocatedvalue_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_CPP03
12#define INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_CPP03
13
14/// @defgroup bdlb_nullableallocatedvalue_cpp03 bdlb_nullableallocatedvalue_cpp03
15/// @brief Provide C++03 implementation for bdlb_nullableallocatedvalue.h
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_nullableallocatedvalue_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_nullableallocatedvalue_cpp03-purpose"> Purpose</a>
25/// * <a href="#bdlb_nullableallocatedvalue_cpp03-classes"> Classes </a>
26/// * <a href="#bdlb_nullableallocatedvalue_cpp03-description"> Description </a>
27///
28/// # Purpose {#bdlb_nullableallocatedvalue_cpp03-purpose}
29/// Provide C++03 implementation for bdlb_nullableallocatedvalue.h
30///
31/// # Classes {#bdlb_nullableallocatedvalue_cpp03-classes}
32/// See bdlb_nullableallocatedvalue.h for list of classes
33///
34/// @see bdlb_nullableallocatedvalue
35///
36/// # Description {#bdlb_nullableallocatedvalue_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Wed Sep 4 19:02:35 2024
48/// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bdl
54 * @{
55 */
56/** @addtogroup bdlb
57 * @{
58 */
59/** @addtogroup bdlb_nullableallocatedvalue_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BDLB_NULLABLEALLOCATEDVALUE_H
64
65
66namespace bdlb {
67
68 // ==================================
69 // class NullableAllocatedValue<TYPE>
70 // ==================================
71
72/// This template class extends the set of values of its value-semantic
73/// `TYPE` parameter to include the notion of a "null" value. If `TYPE` is
74/// fully value-semantic, then the augmented type
75/// `NullableAllocatedValue<TYPE>` will be as well. In addition to
76/// supporting all homogeneous value-semantic operations, conversions
77/// between comparable underlying value types is also supported. Two
78/// nullable objects with different underlying types compare equal if their
79/// underlying types are comparable and either (1) both objects are null or
80/// (2) the non-null values compare equal. Attempts to copy construct, copy
81/// assign, or compare incompatible values types will fail to compile. The
82/// `NullableAllocatedValue` template can be instantiated on an incomplete
83/// type, but it cannot be instantiated on a type that overloads
84/// `operator&`.
85///
86/// See @ref bdlb_nullableallocatedvalue_cpp03
87template <class TYPE>
88class NullableAllocatedValue {
89
90 enum { k_HAS_VALUE = 0 };
91 // flag for checking if the value is present
92
93 // DATA
94 NullableAllocatedValue_PointerBitsPair<bslma::Allocator, 1> d_allocator;
95 union {
96 TYPE *d_pointer_p;
97 char d_buffer[sizeof(TYPE *)];
98 } d_storage;
99
100 // PRIVATE TYPES
101# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
102 // UNSPECIFIED BOOL
103
104 /// This type is needed only in C++03 mode, where `explicit` conversion
105 /// operators are not supported. A `NullableAllocatedValue` is implicitly
106 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
107 /// implicitly convertible to `bool`.
108 typedef BloombergLP::bsls::UnspecifiedBool<NullableAllocatedValue>
109 UnspecifiedBoolUtil;
110 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
111# endif
112
113 // PRIVATE CLASS METHODS
114
115 /// Returns `true` if an object of the template parameter `TYPE` can be
116 /// stored locally, instead of being allocated on the heap.
117 static bool isLocal() BSLS_KEYWORD_NOEXCEPT;
118
119 // PRIVATE ACCESSORS
120
121 /// return a pointer to the held value. If the value does not exist and
122 /// the storage is local, then return a pointer to storage suitable for
123 /// constructing the held value. If the value does not exist and the
124 /// storage is not local, return NULL.
125 TYPE *getAddress();
126 const TYPE *getAddress() const;
127
128 // PRIVATE MANIPULATORS
129
130 /// Clear the flag in the `d_allocator` field that indicates that this
131 /// object does not hold a value.
132 void clearHasValueFlag() BSLS_KEYWORD_NOEXCEPT;
133
134 /// Set the flag in the `d_allocator` field that indicates that this
135 /// object holds a value.
136 void setHasValueFlag() BSLS_KEYWORD_NOEXCEPT;
137
138 /// Set the value of the pointer to the held value to the specified
139 /// `newPtr`. The behavior is undefined if the storage is local.
140 void setRemoteAddress(TYPE *newPtr);
141
142 /// Efficiently exchange the value of this object with the value of the
143 /// specified `other` object. At least one of `this` or `other` is not
144 /// empty, and the values are stored locally. This method provides the
145 /// no-throw exception-safety guarantee. The behavior is undefined
146 /// unless this object was created with the same allocator as `other`.
147 void swapLocal(NullableAllocatedValue& other);
148
149 /// Efficiently exchange the value of this object with the value of the
150 /// specified `other` object. At least one of `this` or `other` is not
151 /// empty, and the values are stored remotely. This method provides the
152 /// no-throw exception-safety guarantee. The behavior is undefined
153 /// unless this object was created with the same allocator as `other`.
154 void swapRemote(NullableAllocatedValue& other);
155
156
157 public:
158 // TYPES
159
160 /// `ValueType` is an alias for the underlying `TYPE` upon which this
161 /// template class is instantiated, and represents the type of the
162 /// managed object.
163 typedef TYPE ValueType;
164
165 // TRAITS
167 bslma::UsesBslmaAllocator);
169 bslmf::IsBitwiseMoveable);
171 bdlb::HasPrintMethod);
172
173 // CREATORS
174
175 /// Create a nullable object having the null value. Use the currently
176 /// installed default allocator to supply memory.
178
179 /// Create a nullable object that has the null value and that uses the
180 /// mechanism of the specified `allocator` to supply memory.
181 explicit NullableAllocatedValue(const bsl::allocator<char>& allocator);
182
183 /// Create a nullable object having the null value. Use the currently
184 /// installed default allocator to supply memory.
185 NullableAllocatedValue(const bsl::nullopt_t&); // IMPLICIT
186
187 /// Create a nullable object that has the null value and that uses the
188 /// mechanism of the specified `allocator` to supply memory.
189 NullableAllocatedValue(const bsl::nullopt_t&,
190 const bsl::allocator<char>& allocator);
191
192 /// Create a nullable object having the value of the specified
193 /// `original` object. Use the currently installed default allocator
194 /// to supply memory.
196
197 /// Create a nullable object having the value of the specified
198 /// `original` object and that uses the mechanism of the specified
199 /// `allocator` to supply memory.
201 const bsl::allocator<char>& allocator);
202
203 /// Create a nullable object having the specified `value`. Use the
204 /// currently installed default allocator to supply memory.
205 NullableAllocatedValue(const TYPE& value); // IMPLICIT
206
207 /// Create a nullable object having the specified `value` and that uses
208 /// the mechanism of specified `allocator` to supply memory.
209 NullableAllocatedValue(const TYPE& value,
210 const bsl::allocator<char>& allocator);
211
212 /// Destroy this object.
214
215 // MANIPULATORS
216
217 /// Assign to this object the value of the specified `rhs`, and return a
218 /// reference providing modifiable access to this object.
219 NullableAllocatedValue<TYPE>& operator=(const NullableAllocatedValue& rhs);
220
221 /// Reset this object to the default constructed state (i.e., to have
222 /// the null value).
223 NullableAllocatedValue<TYPE>& operator=(const bsl::nullopt_t&);
224
225 /// Assign to this object the value of the specified `rhs`, and return a
226 /// reference providing modifiable access to the underlying `TYPE`
227 /// object.
228 NullableAllocatedValue<TYPE>& operator=(const TYPE& rhs);
229
230 /// Return a pointer providing modifiable access to the underlying
231 /// `TYPE` object. The behavior is undefined if the object has no
232 /// value.
233 TYPE *operator->();
234
235 /// Return a reference providing modifiable access to the underlying
236 /// `TYPE` object. The behavior is undefined if the object has no
237 /// value.
238 TYPE& operator*();
239
240#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
241// {{{ BEGIN GENERATED CODE
242// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
243#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
244#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT 5
245#endif
246#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A
247#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
248#endif
249#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 0
250 TYPE& emplace();
251#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 0
252
253#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 1
254 template <class ARGS_1>
256#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 1
257
258#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 2
259 template <class ARGS_1,
260 class ARGS_2>
263#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 2
264
265#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 3
266 template <class ARGS_1,
267 class ARGS_2,
268 class ARGS_3>
272#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 3
273
274#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 4
275 template <class ARGS_1,
276 class ARGS_2,
277 class ARGS_3,
278 class ARGS_4>
283#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 4
284
285#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 5
286 template <class ARGS_1,
287 class ARGS_2,
288 class ARGS_3,
289 class ARGS_4,
290 class ARGS_5>
296#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 5
297
298
299# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
300#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 0
301 template <class INIT_LIST_TYPE>
302 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il);
303#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 0
304
305#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 1
306 template <class INIT_LIST_TYPE, class ARGS_1>
307 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
309#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 1
310
311#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 2
312 template <class INIT_LIST_TYPE, class ARGS_1,
313 class ARGS_2>
314 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
317#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 2
318
319#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 3
320 template <class INIT_LIST_TYPE, class ARGS_1,
321 class ARGS_2,
322 class ARGS_3>
323 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
327#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 3
328
329#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 4
330 template <class INIT_LIST_TYPE, class ARGS_1,
331 class ARGS_2,
332 class ARGS_3,
333 class ARGS_4>
334 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
339#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 4
340
341#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 5
342 template <class INIT_LIST_TYPE, class ARGS_1,
343 class ARGS_2,
344 class ARGS_3,
345 class ARGS_4,
346 class ARGS_5>
347 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
353#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_A >= 5
354
355
356# endif
357#else
358// The generated code below is a workaround for the absence of perfect
359// forwarding in some compilers.
360 template <class... ARGS>
362
363# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
364 template <class INIT_LIST_TYPE, class... ARGS>
365 TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il,
367
368# endif
369// }}} END GENERATED CODE
370#endif
371
372 /// Assign to this object the value read from the specified input
373 /// `stream` using the specified `version` format, and return a
374 /// reference to `stream`. If `stream` is initially invalid, this
375 /// operation has no effect. If `version` is not supported, this object
376 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
377 /// If `version` is supported but `stream` becomes invalid during this
378 /// operation, this object has an undefined, but valid, state. Note
379 /// that no version is read from `stream`. See the `bslx` package-level
380 /// documentation for more information on BDEX streaming of
381 /// value-semantic types and containers.
382 template <class STREAM>
383 STREAM& bdexStreamIn(STREAM& stream, int version);
384
385 /// Assign to this object the specified `val`, and return a reference
386 /// providing modifiable access to the underlying `TYPE` object.
387 TYPE& makeValue(const TYPE& val);
388
389 /// Assign to this object the default value for `TYPE`, and return a
390 /// reference providing modifiable access to the underlying `TYPE`
391 /// object.
392 TYPE& makeValue();
393
394 /// Reset this object to the default constructed state (i.e., to have
395 /// the null value).
396 void reset();
397
398 /// Efficiently exchange the value of this object with the value of the
399 /// specified `other` object. This method provides the no-throw
400 /// exception-safety guarantee. The behavior is undefined unless this
401 /// object was created with the same allocator as `other`.
402 void swap(NullableAllocatedValue& other);
403
404 /// Return a reference providing modifiable access to the underlying
405 /// `TYPE` object. The behavior is undefined unless this object is
406 /// non-null.
407 TYPE& value();
408
409 // ACCESSORS
410
411 /// Write the value of this object, using the specified `version`
412 /// format, to the specified output `stream`, and return a reference to
413 /// `stream`. If `stream` is initially invalid, this operation has no
414 /// effect. If `version` is not supported, `stream` is invalidated, but
415 /// otherwise unmodified. Note that `version` is not written to
416 /// `stream`. See the `bslx` package-level documentation for more
417 /// information on BDEX streaming of value-semantic types and
418 /// containers.
419 template <class STREAM>
420 STREAM& bdexStreamOut(STREAM& stream, int version) const;
421
422 /// Return a `bsl::allocator` constructed from the `bslma::Allocator`
423 /// used by this object to supply memory. Note that if no allocator was
424 /// supplied at construction the default allocator in effect at
425 /// construction is used.
427
428 /// Return `true` if this object contains a value, and `false`
429 /// otherwise.
430 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
431
432 /// Return `false` if this object contains a value, and `true`
433 /// otherwise. Note that this is the opposite of @ref has_value .
434 bool isNull() const BSLS_KEYWORD_NOEXCEPT;
435
436 /// Return the maximum valid BDEX format version, as indicated by the
437 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
438 /// method. 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.)
451 int maxSupportedBdexVersion() const;
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
456 /// otherwise. Note that this method returns *by* *value*, so may be
457 /// inefficient in some contexts.
458 template <class ANY_TYPE>
459 TYPE value_or(const ANY_TYPE& default_value) const;
460
461 /// Return a pointer providing non-modifiable access to the underlying
462 /// `TYPE` object. The behavior is undefined if the object has no
463 /// value.
464 const TYPE *operator->() const;
465
466 /// Return a reference providing non-modifiable access to the underlying
467 /// `TYPE` object. The behavior is undefined if the object has no
468 /// value.
469 const TYPE& operator*() const;
470
471
472# ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
473 /// Return `true` if this object is contains a value, and `true`
474 /// otherwise.
475 BSLS_KEYWORD_EXPLICIT operator bool() const BSLS_KEYWORD_NOEXCEPT;
476# else // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
477 /// Simulation of explicit conversion to bool. Inlined to work around xlC
478 /// bug when out-of-line.
479 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
480 {
481 return UnspecifiedBoolUtil::makeValue(has_value());
482 }
483# endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
484
485 // Aspects
486
487 /// Return the allocator used by this object to supply memory.
489
490 /// Format this object to the specified output `stream` at the (absolute
491 /// value of) the optionally specified indentation `level` and return a
492 /// reference to `stream`. If `level` is specified, optionally specify
493 /// `spacesPerLevel`, the number of spaces per indentation level for
494 /// this and all of its nested objects. If `level` is negative,
495 /// suppress indentation of the first line. If `spacesPerLevel` is
496 /// negative, format the entire output on one line, suppressing all but
497 /// the initial indentation (as governed by `level`). If `stream` is
498 /// not valid on entry, this operation has no effect.
499 bsl::ostream& print(bsl::ostream& stream,
500 int level = 0,
501 int spacesPerLevel = 4) const;
502
503 /// Return a reference providing non-modifiable access to the underlying
504 /// `TYPE` object. The behavior is undefined unless this object is
505 /// non-null.
506 const TYPE& value() const;
507
508 // DEPRECATED FUNCTIONS
509 // provided for compatibility with NullableValue
510
511 /// Return an address providing non-modifiable access to the underlying
512 /// object of a (template parameter) `TYPE` if this object is non-null,
513 /// and the specified `address` otherwise.
514 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::addressOr",
515 "Use 'has_value() ? &value() : address' instead")
516 const TYPE *addressOr(const TYPE *address) const;
517
518#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
519// {{{ BEGIN GENERATED CODE
520// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
521#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
522#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT 5
523#endif
524#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B
525#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
526#endif
527
528#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 0
529 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
530 "Use 'emplace' instead")
531 TYPE& makeValueInplace();
532#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 0
533
534#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 1
535 template <class ARGS_1>
536 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
537 "Use 'emplace' instead")
538 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1);
539#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 1
540
541#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 2
542 template <class ARGS_1,
543 class ARGS_2>
544 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
545 "Use 'emplace' instead")
546 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
547 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2);
548#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 2
549
550#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 3
551 template <class ARGS_1,
552 class ARGS_2,
553 class ARGS_3>
554 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
555 "Use 'emplace' instead")
556 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
558 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3);
559#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 3
560
561#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 4
562 template <class ARGS_1,
563 class ARGS_2,
564 class ARGS_3,
565 class ARGS_4>
566 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
567 "Use 'emplace' instead")
568 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
571 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4);
572#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 4
573
574#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 5
575 template <class ARGS_1,
576 class ARGS_2,
577 class ARGS_3,
578 class ARGS_4,
579 class ARGS_5>
580 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
581 "Use 'emplace' instead")
582 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
586 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5);
587#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_B >= 5
588
589#else
590// The generated code below is a workaround for the absence of perfect
591// forwarding in some compilers.
592
593 template <class... ARGS>
594 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::makeValueInplace",
595 "Use 'emplace' instead")
596 TYPE& makeValueInplace(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
597// }}} END GENERATED CODE
598#endif
599
600 /// Return the value of the underlying object of a (template parameter)
601 /// `TYPE` if this object is non-null, and the specified `otherValue`
602 /// otherwise. Note that this method returns *by* *value*, so may be
603 /// inefficient in some contexts.
604 BSLS_DEPRECATE_FEATURE("bdl", "NullableAllocatedValue::valueOr",
605 "Use 'value_or' instead")
606 TYPE valueOr(const TYPE& otherValue) const;
607
608 /// Return an address providing non-modifiable access to the underlying
609 /// object of a (template parameter) `TYPE` if this object is non-null,
610 /// and 0 otherwise.
612 "Use 'has_value() ? &value() : NULL' instead")
613 const TYPE *valueOrNull() const;
614
615};
616
617// FREE OPERATORS
618
619/// Return `true` if the specified `lhs` and `rhs` nullable objects have the
620/// same value, and `false` otherwise. Two nullable objects have the same
621/// value if both are null, or if both are non-null and the values of their
622/// underlying objects compare equal. Note that this function will fail to
623/// compile if `LHS_TYPE` and `RHS_TYPE` are not compatible.
624template <class LHS_TYPE, class RHS_TYPE>
625bool operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
626 const NullableAllocatedValue<RHS_TYPE>& rhs);
627
628/// Return `true` if the specified `lhs` and `rhs` objects have the same
629/// value, and `false` otherwise. A nullable object and a value of some
630/// type have the same value if the nullable object is non-null and its
631/// underlying value compares equal to the other value. Note that this
632/// function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are not
633/// compatible.
634template <class LHS_TYPE, class RHS_TYPE>
635bool operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
636 const RHS_TYPE& rhs);
637template <class LHS_TYPE, class RHS_TYPE>
638bool operator==(const LHS_TYPE& lhs,
639 const NullableAllocatedValue<RHS_TYPE>& rhs);
640
641/// Return `true` if the specified `lhs` and `rhs` nullable objects do not
642/// have the same value, and `false` otherwise. Two nullable objects do not
643/// have the same value if one is null and the other is non-null, or if both
644/// are non-null and the values of their underlying objects do not compare
645/// equal. Note that this function will fail to compile if `LHS_TYPE` and
646/// `RHS_TYPE` are not compatible.
647template <class LHS_TYPE, class RHS_TYPE>
648bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
649 const NullableAllocatedValue<RHS_TYPE>& rhs);
650
651/// Return `true` if the specified `lhs` and `rhs` objects do not have the
652/// same value, and `false` otherwise. A nullable object and a value of
653/// some type do not have the same value if either the nullable object is
654/// null, or its underlying value does not compare equal to the other value.
655/// Note that this function will fail to compile if `LHS_TYPE` and
656/// `RHS_TYPE` are not compatible.
657template <class LHS_TYPE, class RHS_TYPE>
658bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
659 const RHS_TYPE& rhs);
660template <class LHS_TYPE, class RHS_TYPE>
661bool operator!=(const LHS_TYPE& lhs,
662 const NullableAllocatedValue<RHS_TYPE>& rhs);
663
664/// Return `true` if the specified `lhs` nullable object is ordered before
665/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
666/// ordered before `rhs` if `lhs` is null and `rhs` is non-null or if both
667/// are non-null and `lhs.value()` is ordered before `rhs.value()`. Note
668/// that this function will fail to compile if `LHS_TYPE` and `RHS_TYPE` are
669/// not compatible.
670template <class LHS_TYPE, class RHS_TYPE>
671bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
672 const NullableAllocatedValue<RHS_TYPE>& rhs);
673
674/// Return `true` if the specified `lhs` nullable object is ordered before
675/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
676/// `rhs` if `lhs` is null or `lhs.value()` is ordered before `rhs`.
677template <class LHS_TYPE, class RHS_TYPE>
678bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
679 const RHS_TYPE& rhs);
680
681/// Return `true` if the specified `lhs` is ordered before the specified
682/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered before
683/// `rhs` if `rhs` is not null and `lhs` is ordered before `rhs.value()`.
684template <class LHS_TYPE, class RHS_TYPE>
685bool operator<(const LHS_TYPE& lhs,
686 const NullableAllocatedValue<RHS_TYPE>& rhs);
687
688
689/// Return `true` if the specified `lhs` nullable object is ordered before
690/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
691/// value, and `false` otherwise. (See `operator<` and `operator==`.) Note
692/// that this operator returns `!(rhs < lhs)` when both operands are of
693/// `NullableValue` type. Also note that this function will fail to compile
694/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
695template <class LHS_TYPE, class RHS_TYPE>
696bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
697 const NullableAllocatedValue<RHS_TYPE>& rhs);
698
699/// Return `true` if the specified `lhs` nullable object is ordered before
700/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
701/// otherwise. (See `operator<` and `operator==`.) Note that this operator
702/// returns `!(rhs < lhs)`.
703template <class LHS_TYPE, class RHS_TYPE>
704bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
705 const RHS_TYPE& rhs);
706
707/// Return `true` if the specified `lhs` is ordered before the specified
708/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
709/// `false` otherwise. (See `operator<` and `operator==`.) Note that this
710/// operator returns `!(rhs < lhs)`.
711template <class LHS_TYPE, class RHS_TYPE>
712bool operator<=(const LHS_TYPE& lhs,
713 const NullableAllocatedValue<RHS_TYPE>& rhs);
714
715/// Return `true` if the specified `lhs` nullable object is ordered after
716/// the specified `rhs` nullable object, and `false` otherwise. `lhs` is
717/// ordered after `rhs` if `lhs` is non-null and `rhs` is null or if both
718/// are non-null and `lhs.value()` is ordered after `rhs.value()`. Note
719/// that this operator returns `rhs < lhs` when both operands are of
720/// `NullableValue` type. Also note that this function will fail to compile
721/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
722template <class LHS_TYPE, class RHS_TYPE>
723bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
724 const NullableAllocatedValue<RHS_TYPE>& rhs);
725
726/// Return `true` if the specified `lhs` nullable object is ordered after
727/// the specified `rhs`, and `false` otherwise. `lhs` is ordered after
728/// `rhs` if `lhs` is not null and `lhs.value()` is ordered after `rhs`.
729/// Note that this operator returns `rhs < lhs`.
730template <class LHS_TYPE, class RHS_TYPE>
731bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
732 const RHS_TYPE& rhs);
733
734/// Return `true` if the specified `lhs` is ordered after the specified
735/// `rhs` nullable object, and `false` otherwise. `lhs` is ordered after
736/// `rhs` if `rhs` is null or `lhs` is ordered after `rhs.value()`. Note
737/// that this operator returns `rhs < lhs`.
738template <class LHS_TYPE, class RHS_TYPE>
739bool operator>(const LHS_TYPE& lhs,
740 const NullableAllocatedValue<RHS_TYPE>& rhs);
741
742/// Return `true` if the specified `lhs` nullable object is ordered after
743/// the specified `rhs` nullable object or `lhs` and `rhs` have the same
744/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
745/// that this operator returns `!(lhs < rhs)` when both operands are of
746/// `NullableValue` type. Also note that this function will fail to compile
747/// if `LHS_TYPE` and `RHS_TYPE` are not compatible.
748template <class LHS_TYPE, class RHS_TYPE>
749bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
750 const NullableAllocatedValue<RHS_TYPE>& rhs);
751
752/// Return `true` if the specified `lhs` nullable object is ordered after
753/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
754/// otherwise. (See `operator>` and `operator==`.) Note that this operator
755/// returns `!(lhs < rhs)`.
756template <class LHS_TYPE, class RHS_TYPE>
757bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
758 const RHS_TYPE& rhs);
759
760/// Return `true` if the specified `lhs` is ordered after the specified
761/// `rhs` nullable object or `lhs` and `rhs` have the same value, and
762/// `false` otherwise. (See `operator>` and `operator==`.) Note that this
763/// operator returns `!(lhs < rhs)`.
764template <class LHS_TYPE, class RHS_TYPE>
765bool operator>=(const LHS_TYPE& lhs,
766 const NullableAllocatedValue<RHS_TYPE>& rhs);
767
768/// Write the value of the specified `object` to the specified output
769/// `stream` in a single-line format, and return a reference to `stream`.
770/// If `stream` is not valid on entry, this operation has no effect. Note
771/// that this human-readable format is not fully specified, can change
772/// without notice, and is logically equivalent to:
773/// @code
774/// print(stream, 0, -1);
775/// @endcode
776template <class TYPE>
777bsl::ostream& operator<<(bsl::ostream& stream,
778 const NullableAllocatedValue<TYPE>& object);
779
780 //================================
781 // Comparisons with bsl::nullopt_t
782 //================================
783
784/// Return `true` if the specified `lhs` is null, and `false` otherwise.
785template <class TYPE>
786bool operator==(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
788
789/// Return `true` if the specified `rhs` is null, and `false` otherwise.
790template <class TYPE>
791bool operator==(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
793
794/// Return `true` if the specified `lhs` is not null, and `false` otherwise.
795template <class TYPE>
796bool operator!=(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
798
799/// Return `true` if the specified `rhs` is not null, and `false`
800/// otherwise.
801template <class TYPE>
802bool operator!=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
804
805/// Return `false`. Note that `bsl::nullopt` never orders after a
806/// `NullableAllocatedValue`.
807template <class TYPE>
808bool operator<(const NullableAllocatedValue<TYPE>&, const bsl::nullopt_t&)
810
811/// Return `true` if the specified `rhs` is not null, and `false` otherwise.
812/// Note that `bsl::nullopt` is ordered before any `NullableAllocatedValue`
813/// that is not null.
814template <class TYPE>
815bool operator<(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
817
818/// Return `true` if the specified `lhs` is not null, and `false`
819/// otherwise.
820template <class TYPE>
821bool operator>(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
823
824/// Return `false`. Note that `bsl::nullopt` never orders after a
825/// `NullableAllocatedValue`.
826template <class TYPE>
827bool operator>(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>&)
829
830/// Return `true` if the specified `lhs` is null, and `false` otherwise.
831template <class TYPE>
832bool operator<=(const NullableAllocatedValue<TYPE>& lhs, const bsl::nullopt_t&)
834
835/// Return `true`.
836template <class TYPE>
837bool operator<=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>&)
839
840/// Return `true`.
841template <class TYPE>
842bool operator>=(const NullableAllocatedValue<TYPE>&, const bsl::nullopt_t&)
844
845/// Return `true` if the specified `rhs` is null, and `false` otherwise.
846template <class TYPE>
847bool operator>=(const bsl::nullopt_t&, const NullableAllocatedValue<TYPE>& rhs)
849
850 //===============================
851 // Comparisons with bsl::optional
852 //===============================
853
854/// If neither of the specified `lhs` and `rhs` contain a value, return
855/// `true`. If one contains a value, and the other does not, return
856/// `false`. 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);
860template <class LHS_TYPE, class RHS_TYPE>
861bool operator==(const bsl::optional<LHS_TYPE>& lhs,
862 const NullableAllocatedValue<RHS_TYPE>& rhs);
863
864/// If neither of the specified `lhs` and `rhs` contain a value, return
865/// `false`. If one contains a value, and the other does not, return
866/// `true`. Otherwise, return `lhs.value != rhs.value()`.
867template <class LHS_TYPE, class RHS_TYPE>
868bool operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
869 const bsl::optional<RHS_TYPE>& rhs);
870template <class LHS_TYPE, class RHS_TYPE>
871bool operator!=(const bsl::optional<LHS_TYPE>& lhs,
872 const NullableAllocatedValue<RHS_TYPE>& rhs);
873
874/// If neither of the specified `lhs` and `rhs` contain a value, return
875/// `false`. If `lhs` contains a value, and `rhs` does not, return `false`.
876/// If `lhs` does not contains a value, `rhs` does, return `true`.
877/// Otherwise, return `lhs.value < rhs.value()`.
878template <class LHS_TYPE, class RHS_TYPE>
879bool operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
880 const bsl::optional<RHS_TYPE>& rhs);
881
882/// If neither of the specified `lhs` and `rhs` contain a value, return
883/// `false`. If `lhs` contains a value, and `rhs` does not, return `false`.
884/// If `lhs` does not contains a value, `rhs` does, return `true`.
885/// Otherwise, return `lhs.value < rhs.value()`.
886template <class LHS_TYPE, class RHS_TYPE>
887bool operator<(const bsl::optional<LHS_TYPE>& lhs,
888 const NullableAllocatedValue<RHS_TYPE>& rhs);
889
890/// If neither of the specified `lhs` and `rhs` contain a value, return
891/// `false`. If `lhs` contains a value, and `rhs` does not, return `true`.
892/// If `lhs` does not contains a value, `rhs` does, return `false`.
893/// Otherwise, return `lhs.value > rhs.value()`.
894template <class LHS_TYPE, class RHS_TYPE>
895bool operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
896 const bsl::optional<RHS_TYPE>& rhs);
897
898/// If neither of the specified `lhs` and `rhs` contain a value, return
899/// `false`. If `lhs` contains a value, and `rhs` does not, return `true`.
900/// If `lhs` does not contains a value, `rhs` does, return `false`.
901/// Otherwise, return `lhs.value > rhs.value()`.
902template <class LHS_TYPE, class RHS_TYPE>
903bool operator>(const bsl::optional<LHS_TYPE>& lhs,
904 const NullableAllocatedValue<RHS_TYPE>& rhs);
905
906/// If neither of the specified `lhs` and `rhs` contain a value, return
907/// `true`. If `lhs` contains a value, and `rhs` does not, return `false`.
908/// If `lhs` does not contains a value, `rhs` does, return `true`.
909/// Otherwise, return `lhs.value <= rhs.value()`.
910template <class LHS_TYPE, class RHS_TYPE>
911bool operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
912 const bsl::optional<RHS_TYPE>& rhs);
913
914/// If neither of the specified `lhs` and `rhs` contain a value, return
915/// `true`. If `lhs` contains a value, and `rhs` does not, return `false`.
916/// If `lhs` does not contains a value, `rhs` does, return `true`.
917/// Otherwise, return `lhs.value <= rhs.value()`.
918template <class LHS_TYPE, class RHS_TYPE>
919bool operator<=(const bsl::optional<LHS_TYPE>& lhs,
920 const NullableAllocatedValue<RHS_TYPE>& rhs);
921
922/// If neither of the specified `lhs` and `rhs` contain a value, return
923/// `true`. If `lhs` contains a value, and `rhs` does not, return `true`.
924/// If `lhs` does not contains a value, `rhs` does, return `false`.
925/// Otherwise, return `lhs.value >= rhs.value()`.
926template <class LHS_TYPE, class RHS_TYPE>
927bool operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
928 const bsl::optional<RHS_TYPE>& rhs);
929
930/// If neither of the specified `lhs` and `rhs` contain a value, return
931/// `true`. If `lhs` contains a value, and `rhs` does not, return `true`.
932/// If `lhs` does not contains a value, `rhs` does, return `false`.
933/// Otherwise, return `lhs.value >= rhs.value()`.
934template <class LHS_TYPE, class RHS_TYPE>
935bool operator>=(const bsl::optional<LHS_TYPE>& lhs,
936 const NullableAllocatedValue<RHS_TYPE>& rhs);
937
938// FREE FUNCTIONS
939
940/// Pass the boolean value of whether the specified `input` contains a value
941/// to the specified `hashAlg` hashing algorithm of (template parameter)
942/// type `HASHALG`. If `input` contains a value, additionally pass that
943/// value to `hashAlg`.
944template <class HASHALG, class TYPE>
945void hashAppend(HASHALG& hashAlg, const NullableAllocatedValue<TYPE>& input);
946
947/// Exchange the values of the specified `a` and `b` objects. This function
948/// provides the no-throw exception-safety guarantee if the two objects were
949/// created with the same allocator and the basic guarantee otherwise.
950template <class TYPE>
951void swap(NullableAllocatedValue<TYPE>& a,
952 NullableAllocatedValue<TYPE>& b);
953
954// ============================================================================
955// INLINE DEFINITIONS
956// ============================================================================
957
958 // ----------------------------------
959 // class NullableAllocatedValue<TYPE>
960 // ----------------------------------
961
962// CREATORS
963template <class TYPE>
964inline
966: d_allocator(bslma::Default::defaultAllocator())
967{
968 d_storage.d_pointer_p = 0;
969}
970
971template <class TYPE>
972inline
973NullableAllocatedValue<TYPE>
974::NullableAllocatedValue(const bsl::allocator<char>& allocator)
975: d_allocator(allocator.mechanism())
976{
977 d_storage.d_pointer_p = 0;
978}
979
980template <class TYPE>
981inline
982NullableAllocatedValue<TYPE>::NullableAllocatedValue(const bsl::nullopt_t&)
983: d_allocator(bslma::Default::defaultAllocator())
984{
985 d_storage.d_pointer_p = 0;
986}
987
988template <class TYPE>
989inline
990NullableAllocatedValue<TYPE>
991::NullableAllocatedValue(const bsl::nullopt_t&,
992 const bsl::allocator<char>& allocator)
993: d_allocator(allocator.mechanism())
994{
995 d_storage.d_pointer_p = 0;
996}
997
998template <class TYPE>
999inline
1000NullableAllocatedValue<TYPE>
1001::NullableAllocatedValue(const NullableAllocatedValue<TYPE>& original)
1002: d_allocator(bslma::Default::defaultAllocator())
1003{
1004 if (original.has_value()) {
1005 makeValue(original.value());
1006 }
1007 else {
1008 d_storage.d_pointer_p = 0;
1009 }
1010}
1011
1012template <class TYPE>
1013inline
1014NullableAllocatedValue<TYPE>
1015::NullableAllocatedValue(const NullableAllocatedValue<TYPE>& original,
1016 const bsl::allocator<char>& allocator)
1017: d_allocator(allocator.mechanism())
1018{
1019 if (original.has_value()) {
1020 makeValue(original.value());
1021 }
1022 else {
1023 d_storage.d_pointer_p = 0;
1024 }
1025}
1026
1027template <class TYPE>
1028inline
1029NullableAllocatedValue<TYPE>::NullableAllocatedValue(const TYPE& value)
1030: d_allocator(bslma::Default::defaultAllocator())
1031{
1032 makeValue(value);
1033}
1034
1035template <class TYPE>
1036inline
1037NullableAllocatedValue<TYPE>::NullableAllocatedValue(
1038 const TYPE& value,
1039 const bsl::allocator<char>& allocator)
1040: d_allocator(allocator.mechanism())
1041{
1042 makeValue(value);
1043}
1044
1045template <class TYPE>
1046inline
1047NullableAllocatedValue<TYPE>::~NullableAllocatedValue()
1048{
1049 reset();
1050}
1051
1052// PRIVATE CLASS METHODS
1053template <class TYPE>
1054bool NullableAllocatedValue<TYPE>::isLocal() BSLS_KEYWORD_NOEXCEPT
1055{
1056// we can store it locally if it will fit into a pointer, and it doesn't have
1057// an exceptionally large alignment requirement.
1058 return (sizeof(TYPE) <= sizeof(TYPE *)) &&
1060 (static_cast<bsl::size_t>(bsls::AlignmentFromType<TYPE >::VALUE) <=
1061 static_cast<bsl::size_t>(bsls::AlignmentFromType<TYPE *>::VALUE));
1062}
1063
1064// MANIPULATORS
1065template <class TYPE>
1066inline
1067NullableAllocatedValue<TYPE>&
1068NullableAllocatedValue<TYPE>::operator=(
1069 const NullableAllocatedValue<TYPE>& rhs)
1070{
1071 if (rhs.has_value()) {
1072 makeValue(rhs.value());
1073 }
1074 else {
1075 reset();
1076 }
1077
1078 return *this;
1079}
1080
1081template <class TYPE>
1082inline
1083NullableAllocatedValue<TYPE>&
1084NullableAllocatedValue<TYPE>::operator=(const bsl::nullopt_t&)
1085{
1086 reset();
1087 return *this;
1088}
1089
1090template <class TYPE>
1091inline
1092NullableAllocatedValue<TYPE>&
1093NullableAllocatedValue<TYPE>::operator=(const TYPE& rhs)
1094{
1095 makeValue(rhs);
1096 return *this;
1097}
1098
1099template <class TYPE>
1100template <class STREAM>
1101STREAM& NullableAllocatedValue<TYPE>::bdexStreamIn(STREAM& stream, int version)
1102{
1104
1105 char isNullFlag = 0; // Redundant initialization to suppress -Werror.
1106
1107 stream.getInt8(isNullFlag);
1108
1109 if (stream) {
1110 if (!isNullFlag) {
1111 makeValue();
1112 bdexStreamIn(stream, value(), version);
1113 }
1114 else {
1115 reset();
1116 }
1117 }
1118
1119 return stream;
1120}
1121
1122template <class TYPE>
1123inline
1124TYPE& NullableAllocatedValue<TYPE>::makeValue(const TYPE& val)
1125{
1126 if (has_value()) {
1127 TYPE &v = value();
1128 v = val;
1129 return v; // RETURN
1130 }
1131
1132 bslma::Allocator *alloc = allocator();
1133 if (isLocal()) {
1134 bslalg::ScalarPrimitives::copyConstruct(getAddress(), val, alloc);
1135 }
1136 else {
1137 TYPE *tmpPtr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1138
1139 bslma::DeallocatorProctor<bslma::Allocator> proctor(tmpPtr, alloc);
1140 bslalg::ScalarPrimitives::copyConstruct(tmpPtr, val, alloc);
1141 proctor.release();
1142 setRemoteAddress(tmpPtr);
1143 }
1144
1145 setHasValueFlag();
1146 return value();
1147}
1148
1149template <class TYPE>
1150inline
1151TYPE& NullableAllocatedValue<TYPE>::makeValue()
1152{
1153 reset();
1154
1155 // Note that this alternative implementation, instead of 'reset()',
1156 // provides stronger exception-safety, but it breaks some client code that
1157 // uses 'NullableAllocatedValue' with a non-value-semantic 'TYPE'.
1158 //..
1159 // if (d_value_p) {
1160 // *d_value_p = TYPE(allocator());
1161 // return *d_value_p; // RETURN
1162 // }
1163 //..
1164
1165 bslma::Allocator *alloc = allocator();
1166 if (isLocal()) {
1167 bslalg::ScalarPrimitives::defaultConstruct(getAddress(), alloc);
1168 }
1169 else {
1170 TYPE *tmpPtr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1171
1172 bslma::DeallocatorProctor<bslma::Allocator> proctor(tmpPtr, alloc);
1174 proctor.release();
1175 setRemoteAddress(tmpPtr);
1176 }
1177
1178 setHasValueFlag();
1179
1180 return value();
1181}
1182
1183template <class TYPE>
1184inline
1185void NullableAllocatedValue<TYPE>::reset()
1186{
1187 if (has_value()) {
1188 TYPE *p = getAddress();
1189 BSLS_ASSERT(p);
1190 p->~TYPE();
1191 if (!isLocal()) {
1192 allocator()->deallocate(p);
1193 }
1194 clearHasValueFlag();
1195 }
1196}
1197
1198template <class TYPE>
1199void NullableAllocatedValue<TYPE>::swap(NullableAllocatedValue& other)
1200{
1201 // Member 'swap' is undefined for non-equal allocators.
1202
1203 BSLS_ASSERT(allocator() == other.allocator());
1204
1205 // Nothing to do if both objects are null.
1206 if (isNull() && other.isNull()) {
1207 return; // RETURN
1208 }
1209
1210 if (isLocal()) {
1211 swapLocal(other);
1212 }
1213 else {
1214 swapRemote(other);
1215 }
1216}
1217
1218template <class TYPE>
1219inline
1220TYPE& NullableAllocatedValue<TYPE>::value()
1221{
1222 BSLS_ASSERT(has_value());
1223 return *getAddress();
1224}
1225
1226template <class TYPE>
1227inline
1228TYPE *NullableAllocatedValue<TYPE>::operator->()
1229{
1230 BSLS_ASSERT(has_value());
1231 return getAddress();
1232}
1233
1234template <class TYPE>
1235inline
1236TYPE& NullableAllocatedValue<TYPE>::operator*()
1237{
1238 BSLS_ASSERT(has_value());
1239 return value();
1240}
1241
1242#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1243// {{{ BEGIN GENERATED CODE
1244// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
1245#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
1246#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT 5
1247#endif
1248#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C
1249#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
1250#endif
1251#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 0
1252template <class TYPE>
1253inline
1254TYPE& NullableAllocatedValue<TYPE>::emplace(
1255 )
1256{
1257 bslma::Allocator *alloc = allocator();
1258 TYPE *ptr = getAddress();
1259 if (has_value()) {
1260 BSLS_ASSERT(ptr);
1261 ptr->~TYPE();
1262 clearHasValueFlag();
1263 }
1264 else if (!isLocal()) {
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 }
1274 else {
1276 BloombergLP::bslma::ConstructionUtil::construct(
1277 ptr,
1278 alloc);
1279 proctor.release();
1280 }
1281 setHasValueFlag();
1282 return value();
1283}
1284#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 0
1285
1286#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 1
1287template <class TYPE>
1288template <class ARGS_1>
1289inline
1290TYPE& NullableAllocatedValue<TYPE>::emplace(
1291 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
1292{
1293 bslma::Allocator *alloc = allocator();
1294 TYPE *ptr = getAddress();
1295 if (has_value()) {
1296 BSLS_ASSERT(ptr);
1297 ptr->~TYPE();
1298 clearHasValueFlag();
1299 }
1300 else if (!isLocal()) {
1301 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1302 setRemoteAddress(ptr);
1303 }
1304
1305 if (isLocal()) {
1306 BloombergLP::bslma::ConstructionUtil::construct(
1307 ptr,
1308 alloc,
1309 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1310 }
1311 else {
1313 BloombergLP::bslma::ConstructionUtil::construct(
1314 ptr,
1315 alloc,
1316 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1317 proctor.release();
1318 }
1319 setHasValueFlag();
1320 return value();
1321}
1322#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 1
1323
1324#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 2
1325template <class TYPE>
1326template <class ARGS_1,
1327 class ARGS_2>
1328inline
1329TYPE& NullableAllocatedValue<TYPE>::emplace(
1330 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1331 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
1332{
1333 bslma::Allocator *alloc = allocator();
1334 TYPE *ptr = getAddress();
1335 if (has_value()) {
1336 BSLS_ASSERT(ptr);
1337 ptr->~TYPE();
1338 clearHasValueFlag();
1339 }
1340 else if (!isLocal()) {
1341 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1342 setRemoteAddress(ptr);
1343 }
1344
1345 if (isLocal()) {
1346 BloombergLP::bslma::ConstructionUtil::construct(
1347 ptr,
1348 alloc,
1349 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1350 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1351 }
1352 else {
1354 BloombergLP::bslma::ConstructionUtil::construct(
1355 ptr,
1356 alloc,
1357 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1358 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1359 proctor.release();
1360 }
1361 setHasValueFlag();
1362 return value();
1363}
1364#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 2
1365
1366#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 3
1367template <class TYPE>
1368template <class ARGS_1,
1369 class ARGS_2,
1370 class ARGS_3>
1371inline
1372TYPE& NullableAllocatedValue<TYPE>::emplace(
1373 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1374 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1375 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
1376{
1377 bslma::Allocator *alloc = allocator();
1378 TYPE *ptr = getAddress();
1379 if (has_value()) {
1380 BSLS_ASSERT(ptr);
1381 ptr->~TYPE();
1382 clearHasValueFlag();
1383 }
1384 else if (!isLocal()) {
1385 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1386 setRemoteAddress(ptr);
1387 }
1388
1389 if (isLocal()) {
1390 BloombergLP::bslma::ConstructionUtil::construct(
1391 ptr,
1392 alloc,
1393 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1394 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1395 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1396 }
1397 else {
1399 BloombergLP::bslma::ConstructionUtil::construct(
1400 ptr,
1401 alloc,
1402 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1403 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1404 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1405 proctor.release();
1406 }
1407 setHasValueFlag();
1408 return value();
1409}
1410#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 3
1411
1412#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 4
1413template <class TYPE>
1414template <class ARGS_1,
1415 class ARGS_2,
1416 class ARGS_3,
1417 class ARGS_4>
1418inline
1419TYPE& NullableAllocatedValue<TYPE>::emplace(
1420 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1421 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1422 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1423 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
1424{
1425 bslma::Allocator *alloc = allocator();
1426 TYPE *ptr = getAddress();
1427 if (has_value()) {
1428 BSLS_ASSERT(ptr);
1429 ptr->~TYPE();
1430 clearHasValueFlag();
1431 }
1432 else if (!isLocal()) {
1433 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1434 setRemoteAddress(ptr);
1435 }
1436
1437 if (isLocal()) {
1438 BloombergLP::bslma::ConstructionUtil::construct(
1439 ptr,
1440 alloc,
1441 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1442 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1443 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1444 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1445 }
1446 else {
1448 BloombergLP::bslma::ConstructionUtil::construct(
1449 ptr,
1450 alloc,
1451 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1452 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1453 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1454 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1455 proctor.release();
1456 }
1457 setHasValueFlag();
1458 return value();
1459}
1460#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 4
1461
1462#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 5
1463template <class TYPE>
1464template <class ARGS_1,
1465 class ARGS_2,
1466 class ARGS_3,
1467 class ARGS_4,
1468 class ARGS_5>
1469inline
1470TYPE& NullableAllocatedValue<TYPE>::emplace(
1471 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1472 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1473 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1474 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
1475 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
1476{
1477 bslma::Allocator *alloc = allocator();
1478 TYPE *ptr = getAddress();
1479 if (has_value()) {
1480 BSLS_ASSERT(ptr);
1481 ptr->~TYPE();
1482 clearHasValueFlag();
1483 }
1484 else if (!isLocal()) {
1485 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1486 setRemoteAddress(ptr);
1487 }
1488
1489 if (isLocal()) {
1490 BloombergLP::bslma::ConstructionUtil::construct(
1491 ptr,
1492 alloc,
1493 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1494 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1495 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1496 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1497 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1498 }
1499 else {
1501 BloombergLP::bslma::ConstructionUtil::construct(
1502 ptr,
1503 alloc,
1504 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1505 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1506 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1507 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1508 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1509 proctor.release();
1510 }
1511 setHasValueFlag();
1512 return value();
1513}
1514#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 5
1515
1516
1517# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1518#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 0
1519template <class TYPE>
1520template <class INIT_LIST_TYPE>
1521TYPE& NullableAllocatedValue<TYPE>::emplace(
1522 std::initializer_list<INIT_LIST_TYPE> il)
1523{
1524 bslma::Allocator *alloc = allocator();
1525 TYPE *ptr = getAddress();
1526 if (has_value()) {
1527 BSLS_ASSERT(ptr);
1528 ptr->~TYPE();
1529 clearHasValueFlag();
1530 }
1531 else if (!isLocal()) {
1532 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1533 setRemoteAddress(ptr);
1534 }
1535
1536 if (isLocal()) {
1537 BloombergLP::bslma::ConstructionUtil::construct(
1538 ptr,
1539 alloc,
1540 il);
1541 }
1542 else {
1544 BloombergLP::bslma::ConstructionUtil::construct(
1545 ptr,
1546 alloc,
1547 il);
1548 proctor.release();
1549 }
1550 setHasValueFlag();
1551 return value();
1552}
1553#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 0
1554
1555#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 1
1556template <class TYPE>
1557template <class INIT_LIST_TYPE, class ARGS_1>
1558TYPE& NullableAllocatedValue<TYPE>::emplace(
1559 std::initializer_list<INIT_LIST_TYPE> il,
1560 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
1561{
1562 bslma::Allocator *alloc = allocator();
1563 TYPE *ptr = getAddress();
1564 if (has_value()) {
1565 BSLS_ASSERT(ptr);
1566 ptr->~TYPE();
1567 clearHasValueFlag();
1568 }
1569 else if (!isLocal()) {
1570 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1571 setRemoteAddress(ptr);
1572 }
1573
1574 if (isLocal()) {
1575 BloombergLP::bslma::ConstructionUtil::construct(
1576 ptr,
1577 alloc,
1578 il,
1579 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1580 }
1581 else {
1583 BloombergLP::bslma::ConstructionUtil::construct(
1584 ptr,
1585 alloc,
1586 il,
1587 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
1588 proctor.release();
1589 }
1590 setHasValueFlag();
1591 return value();
1592}
1593#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 1
1594
1595#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 2
1596template <class TYPE>
1597template <class INIT_LIST_TYPE, class ARGS_1,
1598 class ARGS_2>
1599TYPE& NullableAllocatedValue<TYPE>::emplace(
1600 std::initializer_list<INIT_LIST_TYPE> il,
1601 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1602 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
1603{
1604 bslma::Allocator *alloc = allocator();
1605 TYPE *ptr = getAddress();
1606 if (has_value()) {
1607 BSLS_ASSERT(ptr);
1608 ptr->~TYPE();
1609 clearHasValueFlag();
1610 }
1611 else if (!isLocal()) {
1612 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1613 setRemoteAddress(ptr);
1614 }
1615
1616 if (isLocal()) {
1617 BloombergLP::bslma::ConstructionUtil::construct(
1618 ptr,
1619 alloc,
1620 il,
1621 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1622 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1623 }
1624 else {
1626 BloombergLP::bslma::ConstructionUtil::construct(
1627 ptr,
1628 alloc,
1629 il,
1630 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1631 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
1632 proctor.release();
1633 }
1634 setHasValueFlag();
1635 return value();
1636}
1637#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 2
1638
1639#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 3
1640template <class TYPE>
1641template <class INIT_LIST_TYPE, class ARGS_1,
1642 class ARGS_2,
1643 class ARGS_3>
1644TYPE& NullableAllocatedValue<TYPE>::emplace(
1645 std::initializer_list<INIT_LIST_TYPE> il,
1646 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1647 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1648 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
1649{
1650 bslma::Allocator *alloc = allocator();
1651 TYPE *ptr = getAddress();
1652 if (has_value()) {
1653 BSLS_ASSERT(ptr);
1654 ptr->~TYPE();
1655 clearHasValueFlag();
1656 }
1657 else if (!isLocal()) {
1658 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1659 setRemoteAddress(ptr);
1660 }
1661
1662 if (isLocal()) {
1663 BloombergLP::bslma::ConstructionUtil::construct(
1664 ptr,
1665 alloc,
1666 il,
1667 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1668 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1669 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1670 }
1671 else {
1673 BloombergLP::bslma::ConstructionUtil::construct(
1674 ptr,
1675 alloc,
1676 il,
1677 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1678 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1679 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
1680 proctor.release();
1681 }
1682 setHasValueFlag();
1683 return value();
1684}
1685#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 3
1686
1687#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 4
1688template <class TYPE>
1689template <class INIT_LIST_TYPE, class ARGS_1,
1690 class ARGS_2,
1691 class ARGS_3,
1692 class ARGS_4>
1693TYPE& NullableAllocatedValue<TYPE>::emplace(
1694 std::initializer_list<INIT_LIST_TYPE> il,
1695 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1696 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1697 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1698 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
1699{
1700 bslma::Allocator *alloc = allocator();
1701 TYPE *ptr = getAddress();
1702 if (has_value()) {
1703 BSLS_ASSERT(ptr);
1704 ptr->~TYPE();
1705 clearHasValueFlag();
1706 }
1707 else if (!isLocal()) {
1708 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1709 setRemoteAddress(ptr);
1710 }
1711
1712 if (isLocal()) {
1713 BloombergLP::bslma::ConstructionUtil::construct(
1714 ptr,
1715 alloc,
1716 il,
1717 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1718 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1719 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1720 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1721 }
1722 else {
1724 BloombergLP::bslma::ConstructionUtil::construct(
1725 ptr,
1726 alloc,
1727 il,
1728 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1729 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1730 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1731 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
1732 proctor.release();
1733 }
1734 setHasValueFlag();
1735 return value();
1736}
1737#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 4
1738
1739#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 5
1740template <class TYPE>
1741template <class INIT_LIST_TYPE, class ARGS_1,
1742 class ARGS_2,
1743 class ARGS_3,
1744 class ARGS_4,
1745 class ARGS_5>
1746TYPE& NullableAllocatedValue<TYPE>::emplace(
1747 std::initializer_list<INIT_LIST_TYPE> il,
1748 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
1749 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
1750 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
1751 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
1752 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
1753{
1754 bslma::Allocator *alloc = allocator();
1755 TYPE *ptr = getAddress();
1756 if (has_value()) {
1757 BSLS_ASSERT(ptr);
1758 ptr->~TYPE();
1759 clearHasValueFlag();
1760 }
1761 else if (!isLocal()) {
1762 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1763 setRemoteAddress(ptr);
1764 }
1765
1766 if (isLocal()) {
1767 BloombergLP::bslma::ConstructionUtil::construct(
1768 ptr,
1769 alloc,
1770 il,
1771 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1772 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1773 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1774 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1775 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1776 }
1777 else {
1779 BloombergLP::bslma::ConstructionUtil::construct(
1780 ptr,
1781 alloc,
1782 il,
1783 BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
1784 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
1785 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
1786 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
1787 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
1788 proctor.release();
1789 }
1790 setHasValueFlag();
1791 return value();
1792}
1793#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_C >= 5
1794
1795# endif
1796#else
1797// The generated code below is a workaround for the absence of perfect
1798// forwarding in some compilers.
1799template <class TYPE>
1800template <class... ARGS>
1801inline
1802TYPE& NullableAllocatedValue<TYPE>::emplace(
1804{
1805 bslma::Allocator *alloc = allocator();
1806 TYPE *ptr = getAddress();
1807 if (has_value()) {
1808 BSLS_ASSERT(ptr);
1809 ptr->~TYPE();
1810 clearHasValueFlag();
1811 }
1812 else if (!isLocal()) {
1813 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1814 setRemoteAddress(ptr);
1815 }
1816
1817 if (isLocal()) {
1818 BloombergLP::bslma::ConstructionUtil::construct(
1819 ptr,
1820 alloc,
1821 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1822 }
1823 else {
1825 BloombergLP::bslma::ConstructionUtil::construct(
1826 ptr,
1827 alloc,
1828 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1829 proctor.release();
1830 }
1831 setHasValueFlag();
1832 return value();
1833}
1834
1835# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1836template <class TYPE>
1837template <class INIT_LIST_TYPE, class... ARGS>
1838TYPE& NullableAllocatedValue<TYPE>::emplace(
1839 std::initializer_list<INIT_LIST_TYPE> il,
1841{
1842 bslma::Allocator *alloc = allocator();
1843 TYPE *ptr = getAddress();
1844 if (has_value()) {
1845 BSLS_ASSERT(ptr);
1846 ptr->~TYPE();
1847 clearHasValueFlag();
1848 }
1849 else if (!isLocal()) {
1850 ptr = reinterpret_cast<TYPE *>(alloc->allocate(sizeof(TYPE)));
1851 setRemoteAddress(ptr);
1852 }
1853
1854 if (isLocal()) {
1855 BloombergLP::bslma::ConstructionUtil::construct(
1856 ptr,
1857 alloc,
1858 il,
1859 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1860 }
1861 else {
1863 BloombergLP::bslma::ConstructionUtil::construct(
1864 ptr,
1865 alloc,
1866 il,
1867 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
1868 proctor.release();
1869 }
1870 setHasValueFlag();
1871 return value();
1872}
1873# endif
1874// }}} END GENERATED CODE
1875#endif
1876
1877// PRIVATE ACCESSORS
1878template <class TYPE>
1879inline
1880TYPE *NullableAllocatedValue<TYPE>::getAddress() {
1881 if (isLocal()) {
1882 return reinterpret_cast<TYPE *>(
1883 static_cast<void *>(d_storage.d_buffer)); // RETURN
1884 }
1885 else {
1886 return d_storage.d_pointer_p; // RETURN
1887 }
1888}
1889
1890template <class TYPE>
1891inline
1892const TYPE *NullableAllocatedValue<TYPE>::getAddress() const {
1893 if (isLocal()) {
1894 return reinterpret_cast<const TYPE *>(
1895 static_cast<const void *>(d_storage.d_buffer)); // RETURN
1896 }
1897 else {
1898 return d_storage.d_pointer_p; // RETURN
1899 }
1900}
1901
1902// PRIVATE MANIPULATORS
1903template <class TYPE>
1904inline
1905void NullableAllocatedValue<TYPE>::clearHasValueFlag() BSLS_KEYWORD_NOEXCEPT
1906{
1907 d_allocator.clearFlag(k_HAS_VALUE);
1908}
1909
1910template <class TYPE>
1911inline
1912void NullableAllocatedValue<TYPE>::setHasValueFlag() BSLS_KEYWORD_NOEXCEPT
1913{
1914 d_allocator.setFlag(k_HAS_VALUE);
1915}
1916
1917template <class TYPE>
1918inline
1919void NullableAllocatedValue<TYPE>::setRemoteAddress(TYPE *newPtr) {
1920 BSLS_ASSERT(!isLocal());
1921 d_storage.d_pointer_p = newPtr;
1922}
1923
1924template <class TYPE>
1925inline
1926void NullableAllocatedValue<TYPE>::swapLocal(NullableAllocatedValue& other)
1927{
1928// At most one of 'isNull()' and 'other.isNull()' is true
1929// Swapping the 'd_allocator's would be wrong here.
1930 if (isNull()) {
1931 makeValue(other.value());
1932 other.reset();
1933 }
1934 else if (other.isNull()) {
1935 other.makeValue(value());
1936 reset();
1937 }
1938 else {
1939 bslalg::SwapUtil::swap(getAddress(), other.getAddress());
1940 }
1941}
1942
1943template <class TYPE>
1944inline
1945void NullableAllocatedValue<TYPE>::swapRemote(NullableAllocatedValue& other)
1946{
1947 bslalg::SwapUtil::swap(&d_allocator, &other.d_allocator);
1948 bslalg::SwapUtil::swap(& d_storage.d_pointer_p,
1949 &other.d_storage.d_pointer_p);
1950}
1951
1952// ACCESSORS
1953template <class TYPE>
1954template <class STREAM>
1955STREAM& NullableAllocatedValue<TYPE>::bdexStreamOut(STREAM& stream,
1956 int version) const
1957{
1959
1960 stream.putInt8(has_value() ? 0 : 1);
1961
1962 if (has_value()) {
1963 bdexStreamOut(stream, value(), version);
1964 }
1965
1966 return stream;
1967}
1968
1969template <class TYPE>
1970inline
1971bsl::allocator<char> NullableAllocatedValue<TYPE>::get_allocator() const
1972{
1973 return allocator();
1974}
1975
1976
1977template <class TYPE>
1978inline
1979bool NullableAllocatedValue<TYPE>::has_value() const BSLS_KEYWORD_NOEXCEPT
1980{
1981 return d_allocator.readFlag(k_HAS_VALUE);
1982}
1983
1984template <class TYPE>
1985inline
1986bool NullableAllocatedValue<TYPE>::isNull() const BSLS_KEYWORD_NOEXCEPT
1987{
1988 return !has_value();
1989}
1990
1991# ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1992template <class TYPE>
1993NullableAllocatedValue<TYPE>::operator bool() const BSLS_KEYWORD_NOEXCEPT
1994{
1995 return has_value();
1996}
1997# endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1998
1999template <class TYPE>
2000inline
2001int NullableAllocatedValue<TYPE>::maxSupportedBdexVersion(
2002 int versionSelector) const
2003{
2005
2006 // We need to call the 'bslx::VersionFunctions' helper function, because we
2007 // cannot guarantee that 'TYPE' implements 'maxSupportedBdexVersion' as a
2008 // class method.
2009
2010 return maxSupportedBdexVersion(reinterpret_cast<TYPE *>(0),
2011 versionSelector);
2012}
2013
2014#ifndef BDE_OMIT_INTERNAL_DEPRECATED
2015template <class TYPE>
2016inline
2017int NullableAllocatedValue<TYPE>::maxSupportedBdexVersion() const
2018{
2019 return maxSupportedBdexVersion(0);
2020}
2021#endif // BDE_OMIT_INTERNAL_DEPRECATED
2022
2023template <class TYPE>
2024template <class ANY_TYPE>
2025inline TYPE
2026NullableAllocatedValue<TYPE>::value_or(const ANY_TYPE& default_value) const
2027{
2028 return has_value() ? value() : static_cast<TYPE>(default_value);
2029}
2030
2031template <class TYPE>
2032inline
2033const TYPE *NullableAllocatedValue<TYPE>::operator->() const
2034{
2035 BSLS_ASSERT(has_value());
2036 return &value();
2037}
2038
2039template <class TYPE>
2040inline
2041const TYPE& NullableAllocatedValue<TYPE>::operator*() const
2042{
2043 BSLS_ASSERT(has_value());
2044 return value();
2045}
2046
2047 // Aspects
2048
2049template <class TYPE>
2050inline
2051bslma::Allocator *NullableAllocatedValue<TYPE>::allocator() const
2052{
2053 return d_allocator.getPointer();
2054}
2055
2056template <class TYPE>
2057inline
2058bsl::ostream& NullableAllocatedValue<TYPE>::print(
2059 bsl::ostream& stream,
2060 int level,
2061 int spacesPerLevel) const
2062{
2063 if (!has_value()) {
2064 return bdlb::PrintMethods::print(stream,
2065 "NULL",
2066 level,
2067 spacesPerLevel); // RETURN
2068 }
2069
2070 return bdlb::PrintMethods::print(stream, value(), level, spacesPerLevel);
2071}
2072
2073template <class TYPE>
2074inline
2075const TYPE& NullableAllocatedValue<TYPE>::value() const
2076{
2077#ifndef BDE_OMIT_INTERNAL_DEPRECATED
2078 // TBD: The assert below was commented out because a call to this function
2079 // is sometimes used as an argument to a template function that only looks
2080 // at the value type (and does not access the value).
2081
2082 // BSLS_REVIEW(has_value());
2083#else
2084 BSLS_ASSERT(has_value());
2085#endif
2086
2087 return *getAddress();
2088}
2089
2090// DEPRECATED FUNCTIONS
2091
2092template <class TYPE>
2093inline
2094const TYPE *NullableAllocatedValue<TYPE>::addressOr(const TYPE *address) const
2095{
2096 return has_value() ? &value() : address;
2097}
2098
2099#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
2100// {{{ BEGIN GENERATED CODE
2101// Command line: sim_cpp11_features.pl bdlb_nullableallocatedvalue.h
2102#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
2103#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT 5
2104#endif
2105#ifndef BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D
2106#define BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT
2107#endif
2108#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 0
2109template <class TYPE>
2110inline
2111TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2112 )
2113{
2114 return emplace();
2115}
2116#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 0
2117
2118#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 1
2119template <class TYPE>
2120template <class ARGS_1>
2121inline
2122TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2123 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1)
2124{
2125 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1));
2126}
2127#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 1
2128
2129#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 2
2130template <class TYPE>
2131template <class ARGS_1,
2132 class ARGS_2>
2133inline
2134TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2135 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
2136 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
2137{
2138 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
2139 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2));
2140}
2141#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 2
2142
2143#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 3
2144template <class TYPE>
2145template <class ARGS_1,
2146 class ARGS_2,
2147 class ARGS_3>
2148inline
2149TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2150 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
2151 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
2152 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
2153{
2154 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
2155 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
2156 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3));
2157}
2158#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 3
2159
2160#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 4
2161template <class TYPE>
2162template <class ARGS_1,
2163 class ARGS_2,
2164 class ARGS_3,
2165 class ARGS_4>
2166inline
2167TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2168 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
2169 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
2170 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
2171 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
2172{
2173 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
2174 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
2175 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
2176 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4));
2177}
2178#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 4
2179
2180#if BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 5
2181template <class TYPE>
2182template <class ARGS_1,
2183 class ARGS_2,
2184 class ARGS_3,
2185 class ARGS_4,
2186 class ARGS_5>
2187inline
2188TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2189 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
2190 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
2191 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
2192 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
2193 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
2194{
2195 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS_1, args_1),
2196 BSLS_COMPILERFEATURES_FORWARD(ARGS_2, args_2),
2197 BSLS_COMPILERFEATURES_FORWARD(ARGS_3, args_3),
2198 BSLS_COMPILERFEATURES_FORWARD(ARGS_4, args_4),
2199 BSLS_COMPILERFEATURES_FORWARD(ARGS_5, args_5));
2200}
2201#endif // BDLB_NULLABLEALLOCATEDVALUE_VARIADIC_LIMIT_D >= 5
2202
2203#else
2204// The generated code below is a workaround for the absence of perfect
2205// forwarding in some compilers.
2206template <class TYPE>
2207template <class... ARGS>
2208inline
2209TYPE& NullableAllocatedValue<TYPE>::makeValueInplace(
2211{
2212 return emplace(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
2213}
2214// }}} END GENERATED CODE
2215#endif
2216
2217template <class TYPE>
2218inline
2219TYPE NullableAllocatedValue<TYPE>::valueOr(const TYPE& otherValue) const
2220{
2221 return has_value() ? value() : otherValue;
2222}
2223
2224template <class TYPE>
2225inline
2226const TYPE *NullableAllocatedValue<TYPE>::valueOrNull() const {
2227 return has_value() ? &value() : NULL;
2228}
2229
2230} // close package namespace
2231
2232// FREE OPERATORS
2233template <class LHS_TYPE, class RHS_TYPE>
2234inline
2235bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
2236 const NullableAllocatedValue<RHS_TYPE>& rhs)
2237{
2238 if (lhs.isNull()) {
2239 return rhs.isNull(); // RETURN
2240 }
2241
2242 return rhs.isNull() ? false : lhs.value() == rhs.value();
2243}
2244
2245template <class LHS_TYPE, class RHS_TYPE>
2246inline
2247bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
2248 const RHS_TYPE& rhs)
2249{
2250 return lhs.isNull() ? false : lhs.value() == rhs;
2251}
2252
2253template <class LHS_TYPE, class RHS_TYPE>
2254inline
2255bool bdlb::operator==(const LHS_TYPE& lhs,
2256 const NullableAllocatedValue<RHS_TYPE>& rhs)
2257{
2258 return rhs.isNull() ? false : lhs == rhs.value();
2259}
2260
2261template <class LHS_TYPE, class RHS_TYPE>
2262inline
2263bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2264 const NullableAllocatedValue<RHS_TYPE>& rhs)
2265{
2266 if (lhs.isNull()) {
2267 return !rhs.isNull(); // RETURN
2268 }
2269
2270 return rhs.isNull() ? true : lhs.value() != rhs.value();
2271}
2272
2273template <class LHS_TYPE, class RHS_TYPE>
2274inline
2275bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2276 const RHS_TYPE& rhs)
2277{
2278 return lhs.isNull() ? true : lhs.value() != rhs;
2279}
2280
2281template <class LHS_TYPE, class RHS_TYPE>
2282inline
2283bool bdlb::operator!=(const LHS_TYPE& lhs,
2284 const NullableAllocatedValue<RHS_TYPE>& rhs)
2285{
2286 return rhs.isNull() ? true : lhs != rhs.value();
2287}
2288
2289template <class LHS_TYPE, class RHS_TYPE>
2290inline
2291bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
2292 const NullableAllocatedValue<RHS_TYPE>& rhs)
2293{
2294 if (rhs.isNull()) {
2295 return false; // RETURN
2296 }
2297
2298 return lhs.isNull() ? true : lhs.value() < rhs.value();
2299}
2300
2301template <class LHS_TYPE, class RHS_TYPE>
2302inline
2303bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
2304 const RHS_TYPE& rhs)
2305{
2306 return lhs.isNull() ? true : lhs.value() < rhs;
2307}
2308
2309template <class LHS_TYPE, class RHS_TYPE>
2310inline
2311bool bdlb::operator<(const LHS_TYPE& lhs,
2312 const NullableAllocatedValue<RHS_TYPE>& rhs)
2313{
2314 return rhs.isNull() ? false : lhs < rhs.value();
2315}
2316
2317template <class LHS_TYPE, class RHS_TYPE>
2318inline
2319bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2320 const NullableAllocatedValue<RHS_TYPE>& rhs)
2321{
2322 if (lhs.isNull()) {
2323 return true; // RETURN
2324 }
2325
2326 return rhs.isNull() ? false : lhs.value() <= rhs.value();
2327}
2328
2329template <class LHS_TYPE, class RHS_TYPE>
2330inline
2331bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2332 const RHS_TYPE& rhs)
2333{
2334 return lhs.isNull() ? true : lhs.value() <= rhs;
2335}
2336
2337template <class LHS_TYPE, class RHS_TYPE>
2338inline
2339bool bdlb::operator<=(const LHS_TYPE& lhs,
2340 const NullableAllocatedValue<RHS_TYPE>& rhs)
2341{
2342 return rhs.isNull() ? false : lhs <= rhs.value();
2343}
2344
2345template <class LHS_TYPE, class RHS_TYPE>
2346inline
2347bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
2348 const NullableAllocatedValue<RHS_TYPE>& rhs)
2349{
2350 if (lhs.isNull()) {
2351 return false; // RETURN
2352 }
2353
2354 return rhs.isNull() ? true : lhs.value() > rhs.value();
2355}
2356
2357template <class LHS_TYPE, class RHS_TYPE>
2358inline
2359bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
2360 const RHS_TYPE& rhs)
2361{
2362 return lhs.isNull() ? false : lhs.value() > rhs;
2363}
2364
2365template <class LHS_TYPE, class RHS_TYPE>
2366inline
2367bool bdlb::operator>(const LHS_TYPE& lhs,
2368 const NullableAllocatedValue<RHS_TYPE>& rhs)
2369{
2370 return rhs.isNull() ? true : lhs > rhs.value();
2371}
2372
2373template <class LHS_TYPE, class RHS_TYPE>
2374inline
2375bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2376 const NullableAllocatedValue<RHS_TYPE>& rhs)
2377{
2378 if (rhs.isNull()) {
2379 return true; // RETURN
2380 }
2381
2382 return lhs.isNull() ? false : lhs.value() >= rhs.value();
2383}
2384
2385template <class LHS_TYPE, class RHS_TYPE>
2386inline
2387bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2388 const RHS_TYPE& rhs)
2389{
2390 return lhs.isNull() ? false : lhs.value() >= rhs;
2391}
2392
2393template <class LHS_TYPE, class RHS_TYPE>
2394inline
2395bool bdlb::operator>=(const LHS_TYPE& lhs,
2396 const NullableAllocatedValue<RHS_TYPE>& rhs)
2397{
2398 return rhs.isNull() ? true : lhs >= rhs.value();
2399}
2400
2401template <class TYPE>
2402inline
2403bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
2404 const NullableAllocatedValue<TYPE>& object)
2405{
2406 return object.print(stream, 0, -1);
2407}
2408
2409 //--------------------------------
2410 // Comparisons with bsl::nullopt_t
2411 //--------------------------------
2412
2413template <class TYPE>
2414inline
2415bool bdlb::operator==(const NullableAllocatedValue<TYPE>& lhs,
2417{
2418 return !lhs.has_value();
2419}
2420
2421template <class TYPE>
2422inline
2423bool bdlb::operator==(
2424 const bsl::nullopt_t&,
2425 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2426{
2427 return !rhs.has_value();
2428}
2429
2430template <class TYPE>
2431inline bool bdlb::operator!=(const NullableAllocatedValue<TYPE>& lhs,
2433{
2434 return lhs.has_value();
2435}
2436
2437template <class TYPE>
2438inline
2439bool bdlb::operator!=(
2440 const bsl::nullopt_t&,
2441 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2442{
2443 return rhs.has_value();
2444}
2445
2446template <class TYPE>
2447inline
2448bool bdlb::operator<(const NullableAllocatedValue<TYPE>&,
2450{
2451 return false;
2452}
2453
2454template <class TYPE>
2455inline
2456bool bdlb::operator<(
2457 const bsl::nullopt_t&,
2458 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2459{
2460 return rhs.has_value();
2461}
2462
2463template <class TYPE>
2464inline
2465bool bdlb::operator>(const NullableAllocatedValue<TYPE>& lhs,
2467{
2468 return lhs.has_value();
2469}
2470
2471template <class TYPE>
2472inline
2474 const NullableAllocatedValue<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2475{
2476 return false;
2477}
2478
2479template <class TYPE>
2480inline
2481bool bdlb::operator<=(const NullableAllocatedValue<TYPE>& lhs,
2483{
2484 return !lhs.has_value();
2485}
2486
2487template <class TYPE>
2488inline
2489bool bdlb::operator<=(
2490 const bsl::nullopt_t&,
2491 const NullableAllocatedValue<TYPE>&) BSLS_KEYWORD_NOEXCEPT
2492{
2493 return true;
2494}
2495
2496template <class TYPE>
2497inline
2498bool bdlb::operator>=(const NullableAllocatedValue<TYPE>&,
2500{
2501 return true;
2502}
2503
2504template <class TYPE>
2505inline
2506bool bdlb::operator>=(
2507 const bsl::nullopt_t&,
2508 const NullableAllocatedValue<TYPE>& rhs) BSLS_KEYWORD_NOEXCEPT
2509{
2510 return !rhs.has_value();
2511}
2512
2513 //-------------------------------
2514 // Comparisons with bsl::optional
2515 //-------------------------------
2516
2517template <class LHS_TYPE, class RHS_TYPE>
2518inline
2519bool bdlb::operator==(const NullableAllocatedValue<LHS_TYPE>& lhs,
2520 const bsl::optional<RHS_TYPE>& rhs)
2521{
2522 if (lhs.has_value() != rhs.has_value())
2523 return false; // RETURN
2524 return lhs.has_value () ? lhs.value() == rhs.value () : true;
2525}
2526
2527template <class LHS_TYPE, class RHS_TYPE>
2528inline
2530 const NullableAllocatedValue<RHS_TYPE>& rhs)
2531{
2532 if (lhs.has_value() != rhs.has_value())
2533 return false; // RETURN
2534 return lhs.has_value () ? lhs.value() == rhs.value () : true;
2535}
2536
2537template <class LHS_TYPE, class RHS_TYPE>
2538inline
2539bool bdlb::operator!=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2540 const bsl::optional<RHS_TYPE>& rhs)
2541{
2542 if (lhs.has_value() != rhs.has_value())
2543 return true; // RETURN
2544 return lhs.has_value () ? lhs.value() != rhs.value () : false;
2545}
2546
2547template <class LHS_TYPE, class RHS_TYPE>
2548inline
2550 const NullableAllocatedValue<RHS_TYPE>& rhs)
2551{
2552 if (lhs.has_value() != rhs.has_value())
2553 return true; // RETURN
2554 return lhs.has_value () ? lhs.value() != rhs.value () : false;
2555}
2556
2557template <class LHS_TYPE, class RHS_TYPE>
2558inline
2559bool bdlb::operator<(const NullableAllocatedValue<LHS_TYPE>& lhs,
2560 const bsl::optional<RHS_TYPE>& rhs)
2561{
2562 if (lhs.has_value() != rhs.has_value())
2563 return rhs.has_value(); // RETURN
2564 return lhs.has_value () ? lhs.value() < rhs.value () : false;
2565}
2566
2567template <class LHS_TYPE, class RHS_TYPE>
2568inline
2570 const NullableAllocatedValue<RHS_TYPE>& rhs)
2571{
2572 if (lhs.has_value() != rhs.has_value())
2573 return rhs.has_value(); // RETURN
2574 return lhs.has_value () ? lhs.value() < rhs.value () : false;
2575}
2576
2577
2578template <class LHS_TYPE, class RHS_TYPE>
2579inline
2580bool bdlb::operator>(const NullableAllocatedValue<LHS_TYPE>& lhs,
2581 const bsl::optional<RHS_TYPE>& rhs)
2582{
2583 if (lhs.has_value() != rhs.has_value())
2584 return lhs.has_value(); // RETURN
2585 return lhs.has_value () ? lhs.value() > rhs.value () : false;
2586}
2587
2588template <class LHS_TYPE, class RHS_TYPE>
2589inline
2591 const NullableAllocatedValue<RHS_TYPE>& rhs)
2592{
2593 if (lhs.has_value() != rhs.has_value())
2594 return lhs.has_value(); // RETURN
2595 return lhs.has_value () ? lhs.value() > rhs.value () : false;
2596}
2597
2598template <class LHS_TYPE, class RHS_TYPE>
2599inline
2600bool bdlb::operator<=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2601 const bsl::optional<RHS_TYPE>& rhs)
2602{
2603 if (lhs.has_value() != rhs.has_value())
2604 return rhs.has_value(); // RETURN
2605 return lhs.has_value () ? lhs.value() <= rhs.value () : true;
2606}
2607
2608template <class LHS_TYPE, class RHS_TYPE>
2609inline
2611 const NullableAllocatedValue<RHS_TYPE>& rhs)
2612{
2613 if (lhs.has_value() != rhs.has_value())
2614 return rhs.has_value(); // RETURN
2615 return lhs.has_value () ? lhs.value() <= rhs.value () : true;
2616}
2617
2618template <class LHS_TYPE, class RHS_TYPE>
2619inline
2620bool bdlb::operator>=(const NullableAllocatedValue<LHS_TYPE>& lhs,
2621 const bsl::optional<RHS_TYPE>& rhs)
2622{
2623 if (lhs.has_value() != rhs.has_value())
2624 return lhs.has_value(); // RETURN
2625 return lhs.has_value () ? lhs.value() >= rhs.value () : true;
2626}
2627
2628template <class LHS_TYPE, class RHS_TYPE>
2629inline
2631 const NullableAllocatedValue<RHS_TYPE>& rhs)
2632{
2633 if (lhs.has_value() != rhs.has_value())
2634 return lhs.has_value(); // RETURN
2635 return lhs.has_value () ? lhs.value() >= rhs.value () : true;
2636}
2637
2638
2639// FREE FUNCTIONS
2640template <class HASHALG, class TYPE>
2641void bdlb::hashAppend(HASHALG& hashAlg,
2642 const NullableAllocatedValue<TYPE>& input)
2643{
2644 using ::BloombergLP::bslh::hashAppend;
2645
2646 if (!input.isNull()) {
2647 hashAppend(hashAlg, true);
2648 hashAppend(hashAlg, input.value());
2649 }
2650 else {
2651 hashAppend(hashAlg, false);
2652 }
2653}
2654
2655template <class TYPE>
2656void bdlb::swap(NullableAllocatedValue<TYPE>& a,
2657 NullableAllocatedValue<TYPE>& b)
2658{
2659 if (a.allocator() == b.allocator()) {
2660 a.swap(b);
2661
2662 return; // RETURN
2663 }
2664
2665 NullableAllocatedValue<TYPE> futureA(b, a.allocator());
2666 NullableAllocatedValue<TYPE> futureB(a, b.allocator());
2667
2668 futureA.swap(a);
2669 futureB.swap(b);
2670}
2671
2672
2673
2674#else // if ! defined(DEFINED_BDLB_NULLABLEALLOCATEDVALUE_H)
2675# error Not valid except when included from bdlb_nullableallocatedvalue.h
2676#endif // ! defined(COMPILING_BDLB_NULLABLEALLOCATEDVALUE_H)
2677
2678#endif // ! defined(INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_CPP03)
2679
2680// ----------------------------------------------------------------------------
2681// Copyright 2015 Bloomberg Finance L.P.
2682//
2683// Licensed under the Apache License, Version 2.0 (the "License");
2684// you may not use this file except in compliance with the License.
2685// You may obtain a copy of the License at
2686//
2687// http://www.apache.org/licenses/LICENSE-2.0
2688//
2689// Unless required by applicable law or agreed to in writing, software
2690// distributed under the License is distributed on an "AS IS" BASIS,
2691// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2692// See the License for the specific language governing permissions and
2693// limitations under the License.
2694// ----------------------------- END-OF-FILE ----------------------------------
2695
2696/** @} */
2697/** @} */
2698/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
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
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
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1356
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
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
Definition bslma_bslallocator.h:580
void deallocate(TYPE *p, std::size_t n=1)
Definition bslma_bslallocator.h:1039
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
#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_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
STREAM & bdexStreamOut(STREAM &stream, const DayCountConvention::Enum &value, int version)
int maxSupportedBdexVersion(const DayCountConvention::Enum *, int versionSelector)
STREAM & bdexStreamIn(STREAM &stream, DayCountConvention::Enum &variable, int version)
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 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