BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_optional.h
Go to the documentation of this file.
1/// @file bslstl_optional.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_optional.h -*-C++-*-
8
9#ifndef INCLUDED_BSLSTL_OPTIONAL
10#define INCLUDED_BSLSTL_OPTIONAL
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslstl_optional bslstl_optional
16/// @brief Provide a standard-compliant allocator aware optional type.
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslstl
20/// @{
21/// @addtogroup bslstl_optional
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslstl_optional-purpose"> Purpose</a>
26/// * <a href="#bslstl_optional-classes"> Classes </a>
27/// * <a href="#bslstl_optional-description"> Description </a>
28/// * <a href="#bslstl_optional-sections"> Sections: </a>
29/// * <a href="#bslstl_optional-usage"> Usage </a>
30/// * <a href="#bslstl_optional-known-limitations"> Known limitations </a>
31///
32/// # Purpose {#bslstl_optional-purpose}
33/// Provide a standard-compliant allocator aware optional type.
34///
35/// # Classes {#bslstl_optional-classes}
36///
37/// - bsl::optional: template class for optional objects
38///
39/// **Canonical header:** bsl_optional.h
40///
41/// # Description {#bslstl_optional-description}
42/// This component provides a template class,
43/// `bsl::optional<TYPE>`, that implements a notion of object that may or may
44/// not contain a `TYPE` value. This template class also provides an interface
45/// to check if the optional object contains a value or not, as well as a
46/// contextual conversion to `bool`. If an optional object is engaged, i.e.
47/// contains a value, it will evaluate to `true` when converted to `bool`;
48/// otherwise, it will evaluate to `false` when converted to `bool`.
49///
50/// An optional object is engaged if it has been initialized with, or assigned
51/// from an object of `TYPE` or another engaged optional object, or if the value
52/// was created using the `emplace` method. Other types of assignment and
53/// initialization (including default initialization), as well as calling
54/// `reset` method will result in the optional object being disengaged.
55///
56/// If the underlying `TYPE` has value-semantics, then so will the type
57/// `bsl::optional<TYPE>`. Two homogeneous optional objects have the same value
58/// if their underlying (non-null) `TYPE` values are the same, or both are null.
59///
60/// Note that the object of template parameter `TYPE` that is managed by a
61/// `bsl::optional<TYPE>` object is created *in*-*place*. Consequently, the
62/// template parameter `TYPE` must be a complete type when the class is
63/// instantiated.
64///
65/// In addition to the standard homogeneous, value-semantic, operations such as
66/// copy/move construction, copy/move assignment, equality comparison, and
67/// relational operators, `bsl::optional` also supports conversion between
68/// optional types for which the underlying types are convertible, i.e., for
69/// heterogeneous copy construction, copy assignment, and equality comparison
70/// (e.g., between `int` and `double`); attempts at conversion between
71/// incompatible types, such as `int` and `bsl::string`, will fail to compile.
72///
73/// For allocator-aware types, bsl::optional uses the same allocator for all
74/// `value_type` objects it manages during its lifetime.
75///
76/// ## Sections: {#bslstl_optional-sections}
77///
78///
79/// This file is very complex, a navigation map of this file can be obtained by:
80/// `$ grep -n Section: bslstl_optional.h`
81///
82/// ## Usage {#bslstl_optional-usage}
83///
84///
85/// The following snippets of code illustrate use of this component:
86///
87/// First, create a `optional` `int` object:
88/// @code
89/// bsl::optional<int> optionalInt;
90/// assert(!optionalInt.has_value());
91/// @endcode
92/// Next, give the `int` object the value 123 (making it non-null):
93/// @code
94/// optionalInt.emplace(123);
95/// assert( optionalInt.has_value());
96/// assert(123 == optionalInt.value());
97/// @endcode
98/// Finally, reset the object to its default constructed state (i.e., null):
99/// @code
100/// optionalInt.reset();
101/// assert(!optionalInt.has_value());
102/// @endcode
103///
104/// ## Known limitations {#bslstl_optional-known-limitations}
105///
106///
107/// * For assignment/construction constraints, we use `is_constructible` but
108/// the exact creation will be done using allocation construction that will
109/// invoke an allocator-extended constructor for allocator-aware types.
110/// If the `value_type` is constructible from the assignment/constructor
111/// argument, but doesn't have a corresponding allocator-extended
112/// constructor, the overload selection may not be be correct.
113/// * `optional<const TYPE>` is fully supported in C++11 and onwards. However,
114/// due to limitations of `MovableRef<const TYPE>`, C++03 support for const
115/// `value_type`s is limited and move semantics of such an `optional` in
116/// C++03 will not work.
117/// @}
118/** @} */
119/** @} */
120
121/** @addtogroup bsl
122 * @{
123 */
124/** @addtogroup bslstl
125 * @{
126 */
127/** @addtogroup bslstl_optional
128 * @{
129 */
130
131#include <bslscm_version.h>
132
134#include <bslstl_compare.h>
135#include <bslstl_hash.h>
136#include <bslstl_inplace.h>
137
138#include <bslalg_swaputil.h>
139
141#include <bslma_default.h>
143#include <bslma_bslallocator.h>
145
146#include <bslmf_allocatorargt.h>
147#include <bslmf_decay.h>
152#include <bslmf_isconvertible.h>
155#include <bslmf_issame.h>
156#include <bslmf_movableref.h>
158#include <bslmf_removeconst.h>
159#include <bslmf_removecvref.h>
160#include <bslmf_util.h> // 'forward(V)'
161
162#include <bsls_assert.h>
164#include <bsls_exceptionutil.h>
165#include <bsls_keyword.h>
166#include <bsls_libraryfeatures.h>
167#include <bsls_objectbuffer.h>
168#include <bsls_platform.h>
169#include <bsls_unspecifiedbool.h>
170#include <bsls_util.h> // 'forward<T>(V)'
171
172#include <stddef.h>
173
174#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
175# include <bslmf_if.h>
176#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
177
178#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
179# include <type_traits>
180#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
181
182#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
183//In C++17, bsl::optional for non-aa types inherits from std::optional
184# include <optional>
185#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
186
187#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
188# include <initializer_list>
189#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
190
191#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
192// Include version that can be compiled with C++03
193// Generated on Mon Jan 30 15:27:01 2023
194// Command line: sim_cpp11_features.pl bslstl_optional.h
195# define COMPILING_BSLSTL_OPTIONAL_H
196# include <bslstl_optional_cpp03.h>
197# undef COMPILING_BSLSTL_OPTIONAL_H
198#else
199
200// ============================================================================
201// Section: BSLSTL_OPTIONAL_* Macros
202// ============================================================================
203
204# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
205
206// This macro is defined as 'std::is_constructible<U, V>::value' in C++11 and
207// later, and as 'DEFAULT' in C++03 with the value of 'DEFAULT' typically
208// chosen to not affect the constraint this macro appears in. Note that
209// 'is_constructible', unlike 'is_convertible', is 'true' for both implicitly
210// and explicitly constructible conversions.
211#define BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(U, V, DEFAULT) \
212 std::is_constructible<U, V>::value
213
214// This macro is defined as 'std::is_assignable<U, V>::value' in C++11 and
215// later, and as 'DEFAULT' in C++03 with the value of 'DEFAULT' typically
216// chosen to not affect the constraint this macro appears in.
217#define BSLSTL_OPTIONAL_IS_ASSIGNABLE(U, V, DEFAULT) \
218 std::is_assignable<U, V>::value
219
220# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
221
222#define BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(U, V, DEFAULT) DEFAULT
223
224#define BSLSTL_OPTIONAL_IS_ASSIGNABLE(U, V, DEFAULT) DEFAULT
225
226# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
227
228// As in 'std' implementation, if the 'TYPE' converts from any value category
229// of an optional type 'OPT_TYPE', we consider it convertible from that
230// optional type.
231#define BSLSTL_OPTIONAL_CONVERTS_FROM(TYPE, OPT_TYPE) \
232 (bsl::is_convertible<const OPT_TYPE&, TYPE>::value || \
233 bsl::is_convertible<OPT_TYPE&, TYPE>::value || \
234 bsl::is_convertible<const OPT_TYPE, TYPE>::value || \
235 bsl::is_convertible<OPT_TYPE, TYPE>::value || \
236 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, const OPT_TYPE&, false) || \
237 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, OPT_TYPE&, false) || \
238 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, const OPT_TYPE, false) || \
239 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, OPT_TYPE, false))
240
241// As in 'std' implementation, if the 'TYPE' can be assigned to from any value
242// category of an optional type 'OPT_TYPE', we consider it convertible from
243// that optional type.
244# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
245#define BSLSTL_OPTIONAL_ASSIGNS_FROM(TYPE, OPT_TYPE) \
246 (std::is_assignable<TYPE&, const OPT_TYPE&>::value || \
247 std::is_assignable<TYPE&, OPT_TYPE&>::value || \
248 std::is_assignable<TYPE&, const OPT_TYPE>::value || \
249 std::is_assignable<TYPE&, OPT_TYPE>::value)
250
251# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
252// The value of this macro is chosen so it does not affect the disjunction-form
253// constraint this macro appears in.
254#define BSLSTL_OPTIONAL_ASSIGNS_FROM(TYPE, OPT_TYPE) false
255# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
256
257#define BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
258 BSLSTL_OPTIONAL_CONVERTS_FROM( \
259 TYPE, \
260 bsl::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
261
262#define BSLSTL_OPTIONAL_ASSIGNS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
263 BSLSTL_OPTIONAL_ASSIGNS_FROM( \
264 TYPE, \
265 bsl::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
266
267# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
268#define BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
269 BSLSTL_OPTIONAL_CONVERTS_FROM( \
270 TYPE, \
271 std::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
272
273#define BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
274 BSLSTL_OPTIONAL_ASSIGNS_FROM( \
275 TYPE, \
276 std::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
277# else // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
278// The value of these macros is chosen to not affect the constraints these
279// macros appears in.
280#define BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) false
281#define BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) false
282
283# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY else
284
285// Macros to define common constraints that enable a constructor or assignment
286// operator.
287#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, \
288 ANY_TYPE) \
289 typename bsl::enable_if< \
290 !bsl::is_same<TYPE, ANY_TYPE>::value && \
291 !BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) && \
292 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true), \
293 BloombergLP::bslstl::Optional_OptNoSuchType>::type
294
295#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, \
296 ANY_TYPE) \
297 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL( \
298 TYPE, \
299 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
300
301#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, \
302 ANY_TYPE) \
303 typename bsl::enable_if< \
304 !BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) && \
305 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true), \
306 BloombergLP::bslstl::Optional_OptNoSuchType>::type
307
308#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, \
309 ANY_TYPE) \
310 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL( \
311 TYPE, \
312 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
313
314#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, \
315 ANY_TYPE) \
316 typename bsl::enable_if< \
317 BloombergLP::bslstl::Optional_PropagatesAllocator<TYPE, \
318 ANY_TYPE>::value, \
319 BloombergLP::bslstl::Optional_OptNoSuchType>::type
320
321#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, \
322 ANY_TYPE) \
323 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR( \
324 TYPE, \
325 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
326
327#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
328 TYPE, ANY_TYPE) \
329 typename bsl::enable_if< \
330 !BloombergLP::bslstl::Optional_PropagatesAllocator<TYPE, \
331 ANY_TYPE>::value, \
332 BloombergLP::bslstl::Optional_OptNoSuchType>::type
333
334#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
335 TYPE, ANY_TYPE) \
336 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
337 TYPE, \
338 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
339
340#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE) \
341 typename bsl::enable_if< \
342 BloombergLP::bslstl::Optional_ConstructsFromType<TYPE, \
343 ANY_TYPE>::value, \
344 BloombergLP::bslstl::Optional_OptNoSuchType>::type
345
346#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE) \
347 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM( \
348 TYPE, \
349 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
350
351#define BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED) \
352 typename bsl::enable_if< \
353 BloombergLP::bslmf::IsAccessibleBaseOf<optional, DERIVED>::value && \
354 !bsl::is_const<DERIVED>::value, \
355 BloombergLP::bslstl::Optional_OptNoSuchType>::type
356
357#define BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(DERIVED) \
358 BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED) = \
359 BloombergLP::bslstl::Optional_OptNoSuchType(0)
360
361#define BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(U, V) \
362 typename bsl::enable_if< \
363 !bsl::is_convertible<V, U>::value, \
364 BloombergLP::bslstl::Optional_OptNoSuchType>::type
365
366#define BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(U, V) \
367 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT( \
368 U, \
369 V) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
370
371#define BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT(U, V) \
372 typename bsl::enable_if< \
373 bsl::is_convertible<V, U>::value, \
374 BloombergLP::bslstl::Optional_OptNoSuchType>::type
375
376#define BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(U, V) \
377 BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT( \
378 U, \
379 V) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
380
381#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
382 typename bsl::enable_if< \
383 !BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) && \
384 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true) && \
385 BSLSTL_OPTIONAL_IS_ASSIGNABLE(TYPE&, ANY_TYPE, true) && \
386 !BSLSTL_OPTIONAL_ASSIGNS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE), \
387 optional<TYPE> >::type
388
389#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
390 typename bsl::enable_if< \
391 !BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) && \
392 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true) && \
393 BSLSTL_OPTIONAL_IS_ASSIGNABLE(TYPE&, ANY_TYPE, true) && \
394 !BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE), \
395 optional<TYPE> >::type
396
397# if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
398# define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED(TYPE, DERIVED) \
399 typename bsl::enable_if< \
400 BloombergLP::bslmf::IsAccessibleBaseOf<bsl::optional<TYPE>, \
401 DERIVED>::value && \
402 !bsl::is_same<bsl::optional<TYPE>, DERIVED>::value, \
403 optional<TYPE> >::type
404# endif
405
406#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_FORWARD_REF(TYPE, ANY_TYPE) \
407 typename bsl::enable_if< \
408 !bsl::is_same<bsl::optional<TYPE>, \
409 typename bsl::remove_cvref<ANY_TYPE>::type>::value && \
410 !(bsl::is_same<TYPE, \
411 typename bsl::decay<ANY_TYPE>::type>::value && \
412 std::is_scalar<TYPE>::value) && \
413 std::is_constructible<TYPE, ANY_TYPE>::value && \
414 std::is_assignable<TYPE, ANY_TYPE>::value, \
415 optional<TYPE> >::type
416
417#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(TYPE, ANY_TYPE) \
418 typename bsl::enable_if< \
419 !::BloombergLP::bslmf::IsAccessibleBaseOf< \
420 bsl::optional<TYPE>, \
421 typename bsl::remove_cv< \
422 typename ::BloombergLP::bslmf::MovableRefUtil:: \
423 RemoveReference<ANY_TYPE>::type>::type>::value, \
424 optional<TYPE> >::type
425
426#define BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG(ARG) \
427 typename bsl::enable_if< \
428 !bsl::is_same< \
429 typename bsl::remove_cvref<ARG>::type, \
430 bsl::allocator_arg_t>::value, \
431 optional<t_TYPE> >::type
432
433#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS
434 #define BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(ARG) = ARG
435#else
436 #define BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(ARG)
437#endif
438
439#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
440 #define BSLSTL_OPTIONAL_REQUIRES(EXPR) requires(EXPR)
441#else
442 #define BSLSTL_OPTIONAL_REQUIRES(EXPR)
443#endif
444
445
446namespace bslstl {
447/// This trivial tag type is used to create `nullopt_t` objects prior to
448/// C++17.
451} // close package namespace
452
453
454namespace bsl {
455
456# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
457
458using nullopt_t = std::nullopt_t;
459using std::nullopt;
460
461# else // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
462
463 // ================
464 // struct nullopt_t
465 // ================
466
467struct nullopt_t {
468 // This trivial tag type is used to create 'optional' objects in a
469 // disengaged state. It uses a constructor template to avoid being
470 // constructible from any braced list. See implementation notes for more
471 // information.
472
473 // CREATORS
474 template <class t_TYPE>
476 t_TYPE,
477 typename enable_if<is_same<t_TYPE,
478 BloombergLP::bslstl::
479 Optional_NulloptConstructToken>::value,
480 int>::type = 0) BSLS_KEYWORD_NOEXCEPT
481 // Create a 'nullopt_t' object. Note that the argument is not used.
482 {
483 }
484};
485
486# if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES)
487inline constexpr
488nullopt_t nullopt(BloombergLP::bslstl::Optional_NulloptConstructToken{});
489# else
490extern const nullopt_t nullopt;
491# endif
492 // Value of type 'nullopt_t' used as an argument to functions that take a
493 // 'nullopt_t' argument.
494
495# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
496
497template <class t_TYPE>
498class optional;
499
500} // close namespace bsl
501
502// ============================================================================
503// Section: bslstl::Optional_* Utility Classes
504// ============================================================================
505
506
507namespace bslstl {
508
509 // =======================================
510 // struct Optional_IsTriviallyDestructible
511 // =======================================
512
513# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
514
515/// This metafunction is derived from
516/// `std::is_trivially_destructible<t_TYPE>` in C++11 and later. In C++03,
517/// the metafunction is derived from `bsl::is_trivially_copyable`, a trait
518/// that implies the type is also trivially destructible.
519template <class t_TYPE>
521: std::is_trivially_destructible<t_TYPE> {
522};
523
524# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
525
526template <class t_TYPE>
528 // C++03 does not provide a trivially destructible trait. Instead we use
529 // 'bslmf::IsBitwiseCopyable' which implies the type is also trivially
530 // destructible.
531 //
532 // Note that we use 'bslmf::IsBitwiseCopyable' here and not
533 // 'bsl::is_trivially_copyable' because on some platforms, the native
534 // 'std::is_trivially_copyable<Optional_Data<t_TYPE, true>>' is 'false'
535 // even though it has no d'tor and 'TYPE' is trivally copyable.
536};
537
538# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
539
540 // ============================
541 // class Optional_OptNoSuchType
542 // ============================
543
544/// This component-private trivial tag type is used to distinguish between
545/// arguments passed by a user, and an `enable_if` argument. It is not
546/// default constructible so the following construction never invokes a
547/// constrained single parameter constructor:
548/// @code
549/// optional<SomeType> o(int, {});
550/// @endcode
552
553 // CREATORS
554
555 /// Create an `Optional_OptNoSuchType` object. Note that the argument
556 /// is not used.
559};
560
561// CREATORS
562inline
567
568 // ==================================
569 // class Optional_PropagatesAllocator
570 // ==================================
571
572/// This metafunction is derived from `bsl::true_type` if `t_TYPE` is an
573/// allocator-aware const type, and if `t_ANY_TYPE` is the same as `t_TYPE`,
574/// minus the cv qualification. This trait is used to enable a constructor
575/// overload for a const qualified allocator-aware `ValueType` taking an
576/// rvalue of Optional_Base of the non-const qualified `ValueType`. Such an
577/// overload needs to propagate the allocator.
578template <class t_TYPE, class t_ANY_TYPE>
581 bool,
582 bslma::UsesBslmaAllocator<t_TYPE>::value &&
583 bsl::is_const<t_TYPE>::value &&
584 bsl::is_same<t_ANY_TYPE,
585 typename bsl::remove_cv<t_TYPE>::type>::value> {
586};
587
588/// This metafunction is derived from `bsl::true_type` if `t_ANY_TYPE` is
589/// not derived from `bsl::optional<t_TYPE>`, `t_ANY_TYPE` is not a tag
590/// type, and `t_TYPE` is constructible from `t_ANY_TYPE`.
591template <class t_TYPE, class t_ANY_TYPE>
594 bool,
595 !bslmf::IsAccessibleBaseOf<
596 bsl::optional<t_TYPE>,
597 typename bsl::remove_cvref<t_ANY_TYPE>::type>::value &&
598 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
599 bsl::nullopt_t>::value &&
600 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
601 bsl::in_place_t>::value &&
602 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
603 bsl::allocator_arg_t>::value &&
604 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(t_TYPE, t_ANY_TYPE, true)> {
605};
606
607 // ===========================
608 // Component-Private Tag Types
609 // ===========================
610
611// The types defined in this section are used to select particular templated
612// constructors of 'class Optional_Base'. This avoids the need to duplicate
613// constraints between 'optional' and 'Optional_Base'.
614
620
621 // ======================
622 // class Optional_DataImp
623 // ======================
624
625/// This component-private `struct` manages a `value_type` object in an
626/// `Optional_Base` object. This class provides an abstraction for `const`
627/// value type. An `Optional_Base` object may contain an object of `const`
628/// type. An assignment to such an `Optional_Base` object should not
629/// succeed. However, unless the `Optional_Base` object itself is `const`,
630/// it should be possible to change the value of the `Optional_Base` object
631/// using `emplace`. In order to allow for that, this class manages a
632/// non-const object of `value_type`, but all the accessors return a `const`
633/// adjusted reference to the managed object.
634template <class t_TYPE>
636
637 private:
638 // PRIVATE TYPES
639 typedef typename bsl::remove_const<t_TYPE>::type StoredType;
640
641 // DATA
642
643 // in-place `TYPE` object
645
646 // `true` if object has a value, and `false` otherwise
647 bool d_hasValue;
648
649 public:
650 // CREATORS
651
652 /// Create an empty `Optional_DataImp` object.
654
655 // MANIPULATORS
656#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
657 /// Create an object of `StoredType` in `d_buffer` using the specified
658 /// `allocator` and `args` and return a reference providing modifiable
659 /// access to the underlying `t_TYPE` object.
660 template <class... t_ARGS>
661 t_TYPE& emplace(bslma::Allocator *allocator,
662 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
663
664# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
665 /// Create an object of `StoredType` in `d_buffer` using the specified
666 /// `allocator`, @ref initializer_list , and `args`, and return a reference
667 /// providing modifiable access to the underlying `t_TYPE` object.
668 template <class t_INIT_LIST_TYPE, class... t_ARGS>
669 t_TYPE& emplace(
670 bslma::Allocator *allocator,
671 std::initializer_list<t_INIT_LIST_TYPE> initializer_list,
672 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
673# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
674#endif
675
676 /// Destroy the `value_type` object in `d_buffer`, if any.
678
679# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
680 /// Return the `value_type` object in `d_buffer` with const
681 /// qualification adjusted to match that of `t_TYPE`. The behavior is
682 /// undefined unless `this->hasValue() == true`.
683 t_TYPE& value() &;
684 t_TYPE&& value() &&;
685# else
686 t_TYPE& value();
687 // Return the 'value_type' object in 'd_buffer' with const
688 // qualification adjusted to match that of 't_TYPE'. The behavior is
689 // undefined unless 'this->hasValue() == true'.
690# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
691
692 // ACCESSORS
693
694 /// Return `true` if this objects has a value, and `false` otherwise.
695 bool hasValue() const BSLS_KEYWORD_NOEXCEPT;
696
697# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
698 /// Return the `value_type` object in `d_buffer` with const
699 /// qualification adjusted to match that of `t_TYPE`. The behavior is
700 /// undefined unless `this->hasValue() == true`.
701 const t_TYPE& value() const &;
702 const t_TYPE&& value() const &&;
703
704# else
705 const t_TYPE& value() const;
706 // Return the 'value_type' object in 'd_buffer' with const
707 // qualification adjusted to match that of 't_TYPE'. The behavior is
708 // undefined unless 'this->hasValue() == true'.
709# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
710};
711
712 // ===================
713 // class Optional_Data
714 // ===================
715
716/// This component-private `struct` manages a `value_type` object in
717/// `Optional_Base` by inheriting from `Optional_DataImp`. In addition,
718/// this primary template properly destroys the owned instance of `t_TYPE`
719/// in its destructor.
720template <
721 class t_TYPE,
722 bool t_IS_TRIVIALLY_DESTRUCTIBLE =
724struct Optional_Data : public Optional_DataImp<t_TYPE> {
725
726 public:
727 // CREATORS
728
729 /// Destroy the managed `value_type` object, if it exists.
731};
732
733 // ===================
734 // class Optional_Data
735 // ===================
736
737/// This partial specialization manages a trivially destructible
738/// `value_type` in Optional_Base. It does not have a user-provided
739/// destructor, which makes it `is_trivially_destructible` itself.
740template <class t_TYPE>
748
749 // ==========================
750 // Component-private concepts
751 // ==========================
752
753#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
754template <class t_TYPE>
755void optional_acceptsBslOptional(const bsl::optional<t_TYPE>&);
756
757template <class t_TYPE>
758void optional_acceptsStdOptional(const std::optional<t_TYPE>&);
759
760template <class t_TYPE>
761concept Optional_ConvertibleToBool =
762 // This component-private concept models the Standard's exposition-only
763 // 'boolean-testable' concept.
764 bsl::is_convertible_v<t_TYPE, bool>;
765
766template <class t_TYPE>
767concept Optional_DerivedFromBslOptional =
768 // This component-private concept is used in the subsequent implementation
769 // of the component-private concept 'Optional_DerivedFromOptional'.
770 requires (const t_TYPE& t) { optional_acceptsBslOptional(t); };
771
772template <class t_TYPE>
773concept Optional_DerivedFromStdOptional =
774 // This component-private concept is used in the subsequent implementation
775 // of the component-private concept 'Optional_DerivedFromOptional'.
776 requires (const t_TYPE& t) { optional_acceptsStdOptional(t); };
777
778template <class t_TYPE>
779concept Optional_DerivedFromOptional =
780 // This component-private concept models whether a type is derived from one
781 // of 'std::optional' or 'bsl::optional'.
782 Optional_DerivedFromBslOptional<t_TYPE> ||
783 Optional_DerivedFromStdOptional<t_TYPE>;
784#endif
785
786// ============================================================================
787// Section: Definition of Allocator-Aware 'Optional_Base'
788// ============================================================================
789
790 // ===================
791 // class Optional_Base
792 // ===================
793
794/// This component-private class template implements the functionality of
795/// `bsl::optional`. The primary template is instantiated when `TYPE` is
796/// allocator-aware, and holds the allocator that is used to create the
797/// stored object.
798///
799/// See @ref bslstl_optional
800template <class t_TYPE,
801 bool t_USES_BSLMA_ALLOC =
802 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>
804
805 public:
806 // TYPES
807
808 /// `value_type` is an alias for the underlying `TYPE` upon which this
809 /// template class is instantiated, and represents the type of the
810 /// managed object. The name is chosen so it is compatible with the
811 /// `std::optional` implementation.
812 typedef t_TYPE value_type;
813
815
816 protected:
817 // PROTECTED TYPES
819
820 private:
821 // PRIVATE TYPES
822 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
823
824# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
825 // UNSPECIFIED BOOL
826
827 // This type is needed only in C++03 mode, where 'explicit' conversion
828 // operators are not supported. An 'optional' object is contextually
829 // converted to 'UnspecifiedBool' when used in 'if' statements, but is not
830 // implicitly convertible to 'bool'.
831 typedef BloombergLP::bsls::UnspecifiedBool<Optional_Base>
832 UnspecifiedBoolUtil;
833 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
834# endif
835
836 // DATA
837
838 // in-place `TYPE` object
839 BloombergLP::bslstl::Optional_Data<t_TYPE> d_value;
840
841 // allocator to be used for all in-place `TYPE` objects
842 allocator_type d_allocator;
843
844 protected:
845 // PROTECTED CREATORS
846
847 /// Create a disengaged `Optional_Base` object. Use the currently
848 /// installed default allocator to supply memory.
850
851 /// Create a disengaged `Optional_Base` object. Use the currently
852 /// installed default allocator to supply memory.
853 Optional_Base(bsl::nullopt_t); // IMPLICIT
854
855 Optional_Base(const Optional_Base& original);
856 /// Create an `Optional_Base` object having the value of the specified
857 /// `original` object. Use the currently installed default allocator to
858 /// supply memory.
859
860 Optional_Base(BloombergLP::bslmf::MovableRef<Optional_Base> original)
863 // Create an 'Optional_Base' object having the same value as the
864 // specified 'original' object by moving the contents of 'original' to
865 // the newly-created object. The allocator associated with 'original'
866 // is propagated for use in the newly-created object. 'original' is
867 // left in a valid, but unspecified state.
868
869 /// Create an `Optional_Base` object whose contained value is
870 /// initialized by forwarding from the specified `value`. Use the
871 /// currently installed default allocator to supply memory.
872 template <class t_ANY_TYPE>
873 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
875
876 /// Create a disengaged `Optional_Base` object if the specified
877 /// `original` object is disengaged, and an `Optional_Base` object with
878 /// the value of `original.value()` converted to `t_TYPE` otherwise.
879 /// Use the currently installed default allocator to supply memory.
880 template <class t_ANY_TYPE>
881 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
882 const Optional_Base<t_ANY_TYPE>& original);
883
884 /// Create a disengaged `Optional_Base` object if the specified
885 /// `original` object is disengaged, and an `Optional_Base` object with
886 /// the value of `original.value()` converted to `t_TYPE` otherwise.
887 /// Use the currently installed default allocator to supply memory.
888 /// `original` is left in a valid but unspecified state.
889 template <class t_ANY_TYPE>
891 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
894 t_TYPE,
895 t_ANY_TYPE));
896
897 /// Create a disengaged `Optional_Base` object if the specified
898 /// `original` object is disengaged, and an `Optional_Base` object with
899 /// the value of `original.value()` otherwise. This is a special case
900 /// constructor where `t_ANY_TYPE` is a non-const version of `t_TYPE`
901 /// and we use the allocator from `original` to supply memory.
902 /// `original` is left in a valid but unspecified state.
903 template <class t_ANY_TYPE>
905 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
908 t_ANY_TYPE));
909
910# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
911 /// Create a disengaged `Optional_Base` object if the specified
912 /// `original` object is disengaged, and an `Optional_Base` object with
913 /// the value of `original.value()` converted to `t_TYPE` otherwise.
914 /// Use the currently installed default allocator to supply memory.
915 template <class t_ANY_TYPE>
916 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
917 const std::optional<t_ANY_TYPE>& original);
918
919 /// Create a disengaged `Optional_Base` object if the specified
920 /// `original` object is disengaged, and an `Optional_Base` object with
921 /// the value of `original.value()` converted to `t_TYPE` otherwise.
922 /// Use the currently installed default allocator to supply memory.
923 template <class t_ANY_TYPE>
924 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
925 std::optional<t_ANY_TYPE>&& original);
926# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
927
928#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
929 /// Create an `Optional_Base` object having the value of the (template
930 /// parameter) `t_TYPE` created in place using the specified `args`.
931 /// Use the currently installed default allocator to supply memory.
932 template <class... t_ARGS>
934 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
935# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
936 /// Create an `Optional_Base` object having the value of the (template
937 /// parameter) `t_TYPE` created in place using the specified `il` and
938 /// specified `args`. Use the currently installed default allocator to
939 /// supply memory.
940 template <class t_INIT_LIST_TYPE, class... t_ARGS>
942 std::initializer_list<t_INIT_LIST_TYPE> il,
943 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
944# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
945#endif
946
947 // allocator-extended constructors
948
949 /// Create a disengaged `Optional_Base` object. Use the specified
950 /// `allocator` to supply memory.
951 Optional_Base(bsl::allocator_arg_t, allocator_type allocator);
952
953 /// Create a disengaged `Optional_Base` object. Use the specified
954 /// `allocator` to supply memory.
955 Optional_Base(bsl::allocator_arg_t,
956 allocator_type allocator,
958
959 /// If the specified `original` contains a value, create an
960 /// `Optional_Base` object whose contained value is initialized from
961 /// `*original`. Otherwise, create a disengaged `Optional_Base` object.
962 /// Use the specified `allocator` to supply memory.
963 Optional_Base(bsl::allocator_arg_t,
964 allocator_type allocator,
965 const Optional_Base& original);
966
967 /// If the specified `original` contains a value, create an
968 /// `Optional_Base` object whose contained value is initialized by
969 /// moving `*original`. Otherwise, create a disengaged `Optional_Base`
970 /// object. Use the specified `allocator` to supply memory. `original`
971 /// is left in a valid but unspecified state.
972 Optional_Base(bsl::allocator_arg_t,
973 allocator_type allocator,
974 BloombergLP::bslmf::MovableRef<Optional_Base> original);
975
976 /// Create an `Optional_Base` object whose contained value is
977 /// initialized by forwarding from the specified `value`. Use the
978 /// specified `allocator` to supply memory.
979 template <class t_ANY_TYPE>
980 Optional_Base(bsl::allocator_arg_t,
981 allocator_type allocator,
982 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
984
985 /// If the specified `original` contains a value, create an
986 /// `Optional_Base` object whose contained value is initialized from
987 /// `*original`, converted to `t_TYPE`. Otherwise, create a disengaged
988 /// `Optional_Base`. Use the specified `allocator` to supply memory.
989 template <class t_ANY_TYPE>
990 Optional_Base(bsl::allocator_arg_t,
991 allocator_type allocator,
992 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
993 const Optional_Base<t_ANY_TYPE>& original);
994
995 /// If the specified `original` contains a value, create an
996 /// `Optional_Base` object whose contained value is initialized by
997 /// moving from `*original` and converting to `t_TYPE`. Otherwise,
998 /// create a disengaged `Optional_Base`. Use the specified `allocator`
999 /// to supply memory. `original` is left in a valid but unspecified
1000 /// state.
1001 template <class t_ANY_TYPE>
1002 Optional_Base(bsl::allocator_arg_t,
1003 allocator_type allocator,
1004 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1006
1007# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1008 /// If the specified `original` contains a value, create an
1009 /// `Optional_Base` object whose contained value is initialized from
1010 /// `*original`, converted to `t_TYPE`. Otherwise, create a disengaged
1011 /// `Optional_Base` object. Use the specified `allocator` to supply
1012 /// memory.
1013 template <class t_ANY_TYPE>
1014 Optional_Base(bsl::allocator_arg_t,
1015 allocator_type allocator,
1016 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1017 const std::optional<t_ANY_TYPE>& original);
1018
1019 /// If the specified `original` contains a value, create an
1020 /// `Optional_Base` object whose contained value is initialized from
1021 /// moving from `*original` and converting to `t_TYPE`. Otherwise,
1022 /// create a disengaged `Optional_Base`. Use the specified `allocator`
1023 /// to supply memory. `original` is left in a valid but unspecified
1024 /// state.
1025 template <class t_ANY_TYPE>
1026 Optional_Base(bsl::allocator_arg_t,
1027 allocator_type allocator,
1028 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1029 std::optional<t_ANY_TYPE>&& original);
1030# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1031
1032#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1033 /// Create an `Optional_Base` object whose contained value is
1034 /// initialized from the specified `args`. Use the specified
1035 /// `allocator` to supply memory.
1036 template <class... t_ARGS>
1037 Optional_Base(bsl::allocator_arg_t,
1038 allocator_type allocator,
1040 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1041
1042# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1043 /// Create an `Optional_Base` object whose contained value is
1044 /// initialized from the specified `il` and `args`. Use the specified
1045 /// `allocator` to supply memory.
1046 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1047 Optional_Base(bsl::allocator_arg_t,
1048 allocator_type allocator,
1050 std::initializer_list<t_INIT_LIST_TYPE> il,
1051 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1052# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1053#endif
1054
1055 // PROTECTED MANIPULATORS
1056
1057 /// If `*this` holds an object, assign to that object the value of the
1058 /// specified `rhs`, converted to `t_TYPE`. Otherwise, construct a held
1059 /// object from `rhs`, converted to `t_TYPE`. The allocators of `*this`
1060 /// and `rhs` remain unchanged.
1061 template <class t_ANY_TYPE>
1063
1064# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1065 /// Return a reference providing modifiable access to the underlying
1066 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1067 /// object is disengaged. Note that this function is only intended to
1068 /// be called by `bdlb::NullableValue::value` during transition of its
1069 /// implementation to use 'bsl::Optional_Base. Note that ref-qualified
1070 /// versions of `value()` are not provided because `NullableValue` does
1071 /// not require them.
1072 t_TYPE& dereferenceRaw();
1073
1074 // PROTECTED ACCESSORS
1075
1076 /// Return a reference providing non-modifiable access to the underlying
1077 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1078 /// object is disengaged. Note that this function is only intended to
1079 /// be called by `bdlb::NullableValue::value` during transition of its
1080 /// implementation to use 'bsl::Optional_Base. Note that ref-qualified
1081 /// versions of `value()` are not provided because `NullableValue` does
1082 /// not require them.
1083 const t_TYPE& dereferenceRaw() const;
1084# endif // BDE_OMIT_INTERNAL_DEPRECATED
1085
1086 public:
1087 // TRAITS
1089 BloombergLP::bslma::UsesBslmaAllocator);
1091 BloombergLP::bslmf::UsesAllocatorArgT);
1094 BloombergLP::bslmf::IsBitwiseMoveable,
1095 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1098 BloombergLP::bslmf::IsBitwiseCopyable,
1099 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1100
1101 // MANIPULATORS
1102#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1103 /// Assign to this `Optional_Base` object the value of the (template
1104 /// parameter) `t_TYPE` created in place using the specified `args` and
1105 /// return a reference providing modifiable access to the underlying
1106 /// `t_TYPE` object. If this `Optional_Base` object already contains an
1107 /// object (`true == hasValue()`), that object is destroyed before the
1108 /// new object is created. The allocator specified at the construction
1109 /// of this `Optional_Base` object is used to supply memory to the value
1110 /// object. Attempts to explicitly specify via `args` another allocator
1111 /// to supply memory to the created (value) object are disallowed by the
1112 /// compiler. Note that if the constructor of `t_TYPE` throws an
1113 /// exception this object is left in a disengaged state.
1114 template <class... t_ARGS>
1115 t_TYPE& emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1116
1117# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1118 /// Assign to this `Optional_Base` object the value of the (template
1119 /// parameter) `t_TYPE` created in place using the specified `il` and
1120 /// specified `args` and return a reference providing modifiable access
1121 /// to the underlying `t_TYPE` object. If this `Optional_Base` object
1122 /// already contains an object (`true == hasValue()`), that object is
1123 /// destroyed before the new object is created. The allocator specified
1124 /// at the construction of this `Optional_Base` object is used to supply
1125 /// memory to the value object. Attempts to explicitly specify via
1126 /// `args` another allocator to supply memory to the created (value)
1127 /// object are disallowed by the compiler. Note that if the constructor
1128 /// of `t_TYPE` throws an exception this object is left in a disengaged
1129 /// state.
1130 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1131 t_TYPE& emplace(std::initializer_list<t_INIT_LIST_TYPE> il,
1132 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1133
1134# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1135#endif
1136 /// Reset this object to the default constructed state (i.e., to a
1137 /// disengaged state).
1139
1141 bsl::is_nothrow_move_constructible<t_TYPE>::value &&
1142 bsl::is_nothrow_swappable<t_TYPE>::value);
1143 // Efficiently exchange the value of this object with the value of the
1144 // specified 'other' object. This method provides the no-throw
1145 // exception-safety guarantee if the template parameter 't_TYPE'
1146 // provides that guarantee and the result of the 'hasValue' method for
1147 // the two objects being swapped is the same. The behavior is
1148 // undefined unless this object was created with the same allocator as
1149 // 'other'.
1150
1151# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1152 /// Return a reference providing modifiable access to the underlying
1153 /// `t_TYPE` object if `true == has_value()` and throw
1154 /// `bsl::bad_optional_access` otherwise.
1155 t_TYPE& value() &;
1156 t_TYPE&& value() &&;
1157# else
1158 t_TYPE& value();
1159 // Return a reference providing modifiable access to the underlying
1160 // 't_TYPE' object. Throws a 'bsl::bad_optional_access' if the
1161 // 'Optional_Base' object is disengaged.
1162# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1163
1164# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1165 /// Return a copy of the underlying object of a (template parameter)
1166 /// `t_TYPE` if this object is non-null, and the specified `value`
1167 /// converted to `t_TYPE` otherwise. Note that this method returns *by*
1168 /// *value*, so may be inefficient in some contexts.
1169 template <class t_ANY_TYPE>
1170 t_TYPE value_or(t_ANY_TYPE&& value) &&;
1171# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1172 /// If this object is non-null, return a copy of the underlying object
1173 /// of a (template parameter) `t_TYPE` created using the provided
1174 /// allocator, and the specified `value` converted to `t_TYPE` using the
1175 /// specified `allocator` otherwise. Note that this method returns *by*
1176 /// *value*, so may be inefficient in some contexts.
1177 template <class t_ANY_TYPE>
1178 t_TYPE value_or(bsl::allocator_arg_t,
1180 t_ANY_TYPE&& value) &&;
1181# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1182# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1183
1184 /// Assign to this object the value of the specified `rhs` object, and
1185 /// return a non-`const` reference to this object.
1187
1188 /// Assign to this object the value of the specified `rhs` object, and
1189 /// return a non-`const` reference to this object. The allocators of
1190 /// this object and `rhs` both remain unchanged. The contents of `rhs`
1191 /// are either move-constructed into or move-assigned to this object.
1192 /// `rhs` is left in a valid but unspecified state.
1194 BloombergLP::bslmf::MovableRef<Optional_Base> rhs);
1195
1196 /// Return a pointer providing modifiable access to the underlying
1197 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1198 /// object is disengaged.
1199 t_TYPE *operator->();
1200
1201# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1202 /// Return a reference providing modifiable access to the underlying
1203 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1204 /// object is disengaged.
1205 t_TYPE& operator*() &;
1206 t_TYPE&& operator*() &&;
1207# else
1208 t_TYPE& operator*();
1209 // Return a reference providing modifiable access to the underlying
1210 // 't_TYPE' object. The behavior is undefined if the 'Optional_Base'
1211 // object is disengaged.
1212
1213# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1214
1215 // ACCESSORS
1216
1217 /// Return allocator used for construction of `value_type`.
1219
1220 /// Return `false` if this object is disengaged, and `true` otherwise.
1221 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
1222
1223# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1224 /// Return a reference providing non-modifiable access to the underlying
1225 /// `t_TYPE` object if `true == has_value()` and throw
1226 /// `bsl::bad_optional_access` otherwise.
1227 const t_TYPE& value() const &;
1228 const t_TYPE&& value() const &&;
1229# else
1230
1231 const t_TYPE& value() const;
1232 // Return a reference providing non-modifiable access to the underlying
1233 // 't_TYPE' object. Throws a 'bsl::bad_optional_access' if the
1234 // 'Optional_Base' object is disengaged.
1235
1236# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1237
1238 /// Return a pointer providing non-modifiable access to the underlying
1239 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1240 /// object is disengaged.
1241 const t_TYPE *operator->() const;
1242
1243# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1244
1245 /// Return a reference providing non-modifiable access to the underlying
1246 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1247 /// object is disengaged.
1248 const t_TYPE& operator*() const &;
1249 const t_TYPE&& operator*() const &&;
1250
1251# else
1252
1253 const t_TYPE& operator*() const;
1254 // Return a reference providing non-modifiable access to the underlying
1255 // 't_TYPE' object. The behavior is undefined if the 'Optional_Base'
1256 // object is disengaged.
1257
1258# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1259
1260# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1261 /// Return a copy of the underlying object of a (template parameter)
1262 /// `t_TYPE` if this object is non-null, and the specified `value`
1263 /// converted to `t_TYPE` otherwise. Note that this method returns *by*
1264 /// *value*, so may be inefficient in some contexts.
1265 template <class t_ANY_TYPE>
1266 t_TYPE value_or(
1267 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1268# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1269 /// If this object is non-null, return a copy of the underlying object
1270 /// of a (template parameter) `t_TYPE` created using the provided
1271 /// allocator, and the specified `value` converted to `t_TYPE` using the
1272 /// specified `allocator` otherwise. Note that this method returns *by*
1273 /// *value*, so may be inefficient in some contexts.
1274 template <class t_ANY_TYPE>
1275 t_TYPE value_or(
1276 bsl::allocator_arg_t,
1278 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1279# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1280# else
1281 template <class t_ANY_TYPE>
1282 t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1283 // Return a copy of the underlying object of a (template parameter)
1284 // 't_TYPE' if this object is non-null, and the specified 'value'
1285 // converted to 't_TYPE' otherwise. Note that this method returns *by*
1286 // *value*, so may be inefficient in some contexts.
1287# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1288 template <class t_ANY_TYPE>
1289 t_TYPE value_or(bsl::allocator_arg_t,
1291 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1292 // If this object is non-null, return a copy of the underlying object
1293 // of a (template parameter) 't_TYPE' created using the provided
1294 // allocator, and the specified 'value' converted to 't_TYPE' using the
1295 // specified 'allocator' otherwise. Note that this method returns *by*
1296 // *value*, so may be inefficient in some contexts.
1297# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1298# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1299
1300#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1301 /// Return `false` if this object is disengaged, and `true` otherwise.
1302 explicit operator bool() const BSLS_KEYWORD_NOEXCEPT;
1303#else
1304 // Simulation of explicit conversion to bool. Inlined to work around xlC
1305 // bug when out-of-line.
1306 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
1307 {
1308 return UnspecifiedBoolUtil::makeValue(has_value());
1309 }
1310#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
1311};
1312
1313// ============================================================================
1314// Section: Definition of C++17 Allocator-Unaware 'Optional_Base'
1315// ============================================================================
1316
1317 // ==================================
1318 // class Optional_Base<t_TYPE, false>
1319 // ==================================
1320
1321# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1322/// Specialization of `Optional_Base` for `value_type` that is not
1323/// allocator-aware when `std::optional` is available.
1324template <class t_TYPE>
1325class Optional_Base<t_TYPE, false> : public std::optional<t_TYPE> {
1326
1327 private:
1328 // PRIVATE TYPES
1329 typedef std::optional<t_TYPE> StdOptionalBase;
1330
1331 protected:
1332 // PROTECTED TYPES
1333 struct AllocType {
1334 private:
1335 // NOT IMPLEMENTED
1336
1337 /// This constructor prevents `AllocType` from being an aggregate.
1338 explicit AllocType(int) = delete;
1339 };
1340
1341 // PROTECTED CREATORS
1342
1343 /// Create a disengaged `Optional_Base` object.
1344 Optional_Base();
1345
1346 /// Create a disengaged `Optional_Base` object.
1347 Optional_Base(bsl::nullopt_t); // IMPLICIT
1348
1349 /// Create an `Optional_Base` object whose contained value is
1350 /// initialized by forwarding from the specified `value`.
1351 template <class t_ANY_TYPE>
1352 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1353 t_ANY_TYPE&& value);
1354
1355 /// Create a disengaged `Optional_Base` object if the specified
1356 /// `original` object is disengaged, and an `Optional_Base` object with
1357 /// the value of `original.value()` (of `t_ANY_TYPE`) converted to
1358 /// `t_TYPE` otherwise.
1359 template <class t_ANY_TYPE>
1360 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1361 const Optional_Base<t_ANY_TYPE>& original);
1362
1363 /// Create a disengaged `Optional_Base` object if the specified
1364 /// `original` object is disengaged, and an `Optional_Base` object with
1365 /// the value of `original.value()` (of `t_ANY_TYPE`) converted to
1366 /// `t_TYPE` otherwise. `original` is left in a valid but unspecified
1367 /// state.
1368 template <class t_ANY_TYPE>
1369 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1370 Optional_Base<t_ANY_TYPE>&& original);
1371
1372 template <class t_ANY_TYPE>
1373 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1374 const std::optional<t_ANY_TYPE>& original);
1375
1376 template <class t_ANY_TYPE>
1377 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1378 std::optional<t_ANY_TYPE>&& original);
1379
1380 /// Create an `Optional_Base` object whose contained value is
1381 /// initialized from the specified `args`.
1382 template <class... t_ARGS>
1383 explicit Optional_Base(bsl::in_place_t, t_ARGS&&... args);
1384
1385 /// Create an `Optional_Base` object whose contained value is
1386 /// initialized from the specified `il` and `args`.
1387 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1389 std::initializer_list<t_INIT_LIST_TYPE> il,
1390 t_ARGS&&... args);
1391
1392 // These allocator-extended constructors cannot be called, and are provided
1393 // only to prevent compilation errors when 'optional' is explicitly
1394 // instantiated.
1395
1396 Optional_Base(bsl::allocator_arg_t, AllocType);
1397
1398 Optional_Base(bsl::allocator_arg_t, AllocType, bsl::nullopt_t);
1399
1400 template <class t_ANY_TYPE>
1401 Optional_Base(bsl::allocator_arg_t,
1402 AllocType,
1403 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1404 t_ANY_TYPE&&);
1405
1406 template <class t_ANY_TYPE>
1407 Optional_Base(bsl::allocator_arg_t,
1408 AllocType,
1409 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1410 const Optional_Base<t_ANY_TYPE>&);
1411
1412 template <class t_ANY_TYPE>
1413 Optional_Base(bsl::allocator_arg_t,
1414 AllocType,
1415 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1416 Optional_Base<t_ANY_TYPE>&&);
1417
1418 template <class t_ANY_TYPE>
1419 Optional_Base(bsl::allocator_arg_t,
1420 AllocType,
1421 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1422 const std::optional<t_ANY_TYPE>&);
1423
1424 template <class t_ANY_TYPE>
1425 Optional_Base(bsl::allocator_arg_t,
1426 AllocType,
1427 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1428 std::optional<t_ANY_TYPE>&&);
1429
1430 template <class... t_ARGS>
1431 Optional_Base(bsl::allocator_arg_t,
1432 AllocType,
1434 t_ARGS&&...);
1435
1436 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1437 Optional_Base(bsl::allocator_arg_t,
1438 AllocType,
1440 std::initializer_list<t_INIT_LIST_TYPE>,
1441 t_ARGS&&...);
1442
1443 // PROTECTED MANIPULATORS
1444
1445 /// If `*this` holds an object, assign to that object the value of the
1446 /// specified `rhs`, converted to `t_TYPE`. Otherwise, construct a held
1447 /// object from `rhs`, converted to `t_TYPE`.
1448 template <class t_ANY_TYPE>
1449 void assignOrEmplace(t_ANY_TYPE&& rhs);
1450
1451# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1452 /// Return a reference providing modifiable access to the underlying
1453 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1454 /// object is disengaged. Note that this function is only intended to
1455 /// be called by `bdlb::NullableValue::value` during transition of its
1456 /// implementation to use 'bsl::Optional_Base. Note that ref-qualified
1457 /// versions of `value()` are not provided because `NullableValue` does
1458 /// not require them.
1459 t_TYPE& dereferenceRaw();
1460
1461 // PROTECTED ACCESSORS
1462
1463 /// Return a reference providing non-modifiable access to the underlying
1464 /// `t_TYPE` object. The behavior is undefined if the `Optional_Base`
1465 /// object is disengaged. Note that this function is only intended to
1466 /// be called by `bdlb::NullableValue::value` during transition of its
1467 /// implementation to use 'bsl::Optional_Base. Note that ref-qualified
1468 /// versions of `value()` are not provided because `NullableValue` does
1469 /// not require them.
1470 const t_TYPE& dereferenceRaw() const;
1471# endif // BDE_OMIT_INTERNAL_DEPRECATED
1472
1473 public:
1474 // TRAITS
1477 BloombergLP::bslmf::IsBitwiseMoveable,
1478 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1481 BloombergLP::bslmf::IsBitwiseCopyable,
1482 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1483};
1484# else // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1485
1486// ============================================================================
1487// Section: Definition of Pre-C++17 Allocator-Unaware 'Optional_Base'
1488// ============================================================================
1489
1490 // ==================================
1491 // class Optional_Base<t_TYPE, false>
1492 // ==================================
1493
1494template <class t_TYPE>
1495class Optional_Base<t_TYPE, false> {
1496 // Specialization of 'Optional_Base' for 'value_type' that is not
1497 // allocator-aware.
1498
1499 private:
1500 // PRIVATE TYPES
1501 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1502
1503# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1504 // UNSPECIFIED BOOL
1505
1506 // This type is needed only in C++03 mode, where 'explicit' conversion
1507 // operators are not supported. An 'optional' object is contextually
1508 // converted to 'UnspecifiedBool' when used in 'if' statements, but is not
1509 // implicitly convertible to 'bool'.
1510 typedef BloombergLP::bsls::UnspecifiedBool<Optional_Base>
1511 UnspecifiedBoolUtil;
1512 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
1513# endif
1514
1515 // DATA
1516 BloombergLP::bslstl::Optional_Data<t_TYPE> d_value;
1517 // in-place 'TYPE' object
1518
1519 protected:
1520 // PROTECTED TYPES
1521 struct AllocType {
1522 private:
1523 // NOT IMPLEMENTED
1524 explicit AllocType(int) BSLS_KEYWORD_DELETED;
1525 // This constructor prevents 'AllocType' from being an aggregate.
1526 };
1527
1528 // PROTECTED CREATORS
1529 Optional_Base();
1530 // Create a disengaged 'Optional_Base' object.
1531
1532 Optional_Base(bsl::nullopt_t); // IMPLICIT
1533 // Create a disengaged 'Optional_Base' object.
1534
1535 Optional_Base(const Optional_Base& original);
1536 // Create an 'Optional_Base' object having the value of the specified
1537 // 'original' object.
1538
1539 Optional_Base(BloombergLP::bslmf::MovableRef<Optional_Base> original)
1542 // Create an 'Optional_Base' object having the same value as the
1543 // specified 'original' object by moving the contents of 'original' to
1544 // the newly-created object. 'original' is left in a valid, but
1545 // unspecified state.
1546
1547 template <class t_ANY_TYPE>
1548 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1550 // Create an 'Optional_Base' object whose contained value is
1551 // initialized by forwarding from the specified 'value'.
1552
1553 template <class t_ANY_TYPE>
1554 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1555 const Optional_Base<t_ANY_TYPE>& original);
1556 // Create a disengaged 'Optional_Base' object if the specified
1557 // 'original' object is disengaged, and an 'Optional_Base' object with
1558 // the value of 'original.value()' converted to 't_TYPE' otherwise.
1559
1560 template <class t_ANY_TYPE>
1561 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1563 // Create a disengaged 'Optional_Base' object if the specified
1564 // 'original' object is disengaged, and an 'Optional_Base' object with
1565 // the value of 'original.value()' converted to 't_TYPE' otherwise.
1566 // 'original' is left in a valid but unspecified state.
1567
1568#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1569 template <class... t_ARGS>
1571 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1572 // Create an 'Optional_Base' object holding an object of type
1573 // Create an 'Optional_Base' object having the value of the (template
1574 // parameter) 't_TYPE' created in place using the specified 'args'.
1575
1576# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1577 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1579 std::initializer_list<t_INIT_LIST_TYPE> il,
1580 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1581 // Create an 'Optional_Base' object having the value of the (template
1582 // parameter) 't_TYPE' created in place using the specified 'il' and
1583 // specified 'args'.
1584# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1585#endif
1586
1587 // These allocator-extended constructors cannot be called, and are provided
1588 // only to prevent compilation errors when 'optional' is explicitly
1589 // instantiated.
1590 Optional_Base(bsl::allocator_arg_t, AllocType);
1591
1592 Optional_Base(bsl::allocator_arg_t, AllocType, bsl::nullopt_t);
1593
1594 Optional_Base(bsl::allocator_arg_t, AllocType, const Optional_Base&);
1595
1596 Optional_Base(bsl::allocator_arg_t,
1597 AllocType,
1598 BloombergLP::bslmf::MovableRef<Optional_Base>);
1599
1600 template <class t_ANY_TYPE>
1601 Optional_Base(bsl::allocator_arg_t,
1602 AllocType,
1603 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1605
1606 template <class t_ANY_TYPE>
1607 Optional_Base(bsl::allocator_arg_t,
1608 AllocType,
1609 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1611
1612 template <class t_ANY_TYPE>
1613 Optional_Base(bsl::allocator_arg_t,
1614 AllocType,
1615 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1617
1618#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1619 template <class... t_ARGS>
1620 Optional_Base(bsl::allocator_arg_t,
1621 AllocType,
1624
1625# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1626 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1627 Optional_Base(bsl::allocator_arg_t,
1628 AllocType,
1630 std::initializer_list<t_INIT_LIST_TYPE>,
1632# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1633#endif
1634
1635 // PROTECTED MANIPULATORS
1636 template <class t_ANY_TYPE>
1638 // If '*this' holds an object, assign to that object the value of
1639 // 'rhs', converted to 't_TYPE'. Otherwise, construct a held object
1640 // from 'rhs', converted to 't_TYPE'.
1641
1642# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1643 t_TYPE& dereferenceRaw();
1644 // Return a reference providing modifiable access to the underlying
1645 // 't_TYPE' object. The behavior is undefined if the 'Optional_Base'
1646 // object is disengaged. Note that this function is only intended to
1647 // be called by 'bdlb::NullableValue::value' during transition of its
1648 // implementation to use 'bsl::Optional_Base. Note that ref-qualified
1649 // versions of 'value()' are not provided because 'NullableValue' does
1650 // not require them.
1651
1652 // PROTECTED ACCESSORS
1653 const t_TYPE& dereferenceRaw() const;
1654 // Return a reference providing non-modifiable access to the underlying
1655 // 't_TYPE' object. The behavior is undefined if the 'Optional_Base'
1656 // object is disengaged. Note that this function is only intended to
1657 // be called by 'bdlb::NullableValue::value' during transition of its
1658 // implementation to use 'bsl::Optional_Base. Note that ref-qualified
1659 // versions of 'value()' are not provided because 'NullableValue' does
1660 // not require them.
1661# endif // !BDE_OMIT_INTERNAL_DEPRECATED
1662
1663 public:
1664 // TYPES
1665 typedef t_TYPE value_type;
1666 // 'value_type' is an alias for the underlying 't_TYPE' upon which this
1667 // template class is instantiated, and represents the type of the
1668 // managed object. The name is chosen so it is compatible with the
1669 // 'std::optional' implementation.
1670
1671 // TRAITS
1674 BloombergLP::bslmf::IsBitwiseMoveable,
1675 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1678 BloombergLP::bslmf::IsBitwiseCopyable,
1679 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1680
1681 // MANIPULATORS
1682#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1683 template <class... t_ARGS>
1684 t_TYPE& emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1685 // Assign to this 'Optional_Base' object the value of the (template
1686 // parameter) 't_TYPE' created in place using the specified 'args' and
1687 // return a reference providing modifiable access to the underlying
1688 // 't_TYPE' object. If this 'Optional_Base' object already contains an
1689 // object ('true == hasValue()'), that object is destroyed before the
1690 // new object is created. Note that if the constructor of 't_TYPE'
1691 // throws an exception this object is left in a disengaged state.
1692
1693# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1694 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1695 t_TYPE& emplace(std::initializer_list<t_INIT_LIST_TYPE> il,
1696 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1697 // Assign to this 'Optional_Base' object the value of the (template
1698 // parameter) 't_TYPE' created in place using the specified 'il' and
1699 // specified 'args' and return a reference providing modifiable access
1700 // to the underlying 't_TYPE' object. If this 'Optional_Base' object
1701 // already contains an object ('true == hasValue()'), that object is
1702 // destroyed before the new object is created. Note that if the
1703 // constructor of 't_TYPE' throws an exception this object is left in a
1704 // disengaged state.
1705
1706# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1707#endif
1708
1710 // Reset this object to the default constructed state (i.e., to be in a
1711 // disengaged state).
1712
1714 bsl::is_nothrow_move_constructible<t_TYPE>::value &&
1715 bsl::is_nothrow_swappable<t_TYPE>::value);
1716 // Efficiently exchange the value of this object with the value of the
1717 // specified 'other' object. This method provides the no-throw
1718 // exception-safety guarantee if the template parameter 't_TYPE'
1719 // provides that guarantee and the result of the 'hasValue' method for
1720 // the two objects being swapped is the same.
1721
1722# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1723 t_TYPE& value() &;
1724 t_TYPE&& value() &&;
1725 // Return a reference providing modifiable access to the underlying
1726 // 't_TYPE' object if 'true == has_value()' and throw
1727 // 'bsl::bad_optional_access' otherwise.
1728
1729# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1730 t_TYPE& value();
1731 // Return a reference providing modifiable access to the underlying
1732 // 't_TYPE' object. Throws a 'bsl::bad_optional_access' if the
1733 // 'Optional_Base' object is disengaged.
1734
1735# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1736
1737# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1738 template <class t_ANY_TYPE>
1739 t_TYPE value_or(t_ANY_TYPE&& value) &&;
1740 // Return a copy of the underlying object of a (template parameter)
1741 // 't_TYPE' if this object is non-null, and the specified 'value'
1742 // converted to 't_TYPE' otherwise. Note that this method returns *by*
1743 // *value*, so may be inefficient in some contexts.
1744# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1745
1747 // Assign to this object the value of the specified 'rhs' object, and
1748 // return a non-'const' reference to this object.
1749
1751 BloombergLP::bslmf::MovableRef<Optional_Base> rhs);
1752 // Assign to this object the value of the specified 'rhs' object, and
1753 // return a non-'const' reference to this object. The allocators of
1754 // this object and 'rhs' both remain unchanged. The contents of 'rhs'
1755 // are either move-constructed into or move-assigned to this object.
1756 // 'rhs' is left in a valid but unspecified state.
1757
1758 t_TYPE *operator->();
1759 // Return a pointer providing modifiable access to the underlying
1760 // 't_TYPE' object. The behavior is undefined if this object is
1761 // disengaged.
1762
1763# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1764
1765 t_TYPE& operator*() &;
1766 t_TYPE&& operator*() &&;
1767 // Return a reference providing modifiable access to the underlying
1768 // 't_TYPE' object. The behavior is undefined if this object is
1769 // disengaged.
1770
1771# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1772
1773 t_TYPE& operator*();
1774 // Return a reference providing modifiable access to the underlying
1775 // 't_TYPE' object. The behavior is undefined if this object is
1776 // disengaged.
1777
1778# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1779
1780 // ACCESSORS
1781 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
1782 // Return 'false' if this object is disengaged, and 'true' otherwise.
1783
1784# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1785 const t_TYPE& value() const &;
1786 const t_TYPE&& value() const &&;
1787 // Return a reference providing non-modifiable access to the underlying
1788 // 't_TYPE' object if 'true == has_value()' and throw
1789 // 'bsl::bad_optional_access' otherwise.
1790# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1791 const t_TYPE& value() const;
1792 // Return a reference providing non-modifiable access to the underlying
1793 // 't_TYPE' object. Throws a 'bsl::bad_optional_access' if the
1794 // 'Optional_Base' object is disengaged.
1795
1796# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1797
1798# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1799 template <class t_ANY_TYPE>
1800 t_TYPE value_or(
1801 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1802 // Return a copy of the underlying object of a (template parameter)
1803 // 't_TYPE' if this object is non-null, and the specified 'value'
1804 // converted to 't_TYPE' otherwise. Note that this method returns *by*
1805 // *value*, so may be inefficient in some contexts.
1806# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1807 template <class t_ANY_TYPE>
1808 t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1809 // Return a copy of the underlying object of a (template parameter)
1810 // 't_TYPE' if this object is non-null, and the specified 'value'
1811 // converted to 't_TYPE' otherwise. Note that this method returns *by*
1812 // *value*, so may be inefficient in some contexts.
1813# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1814
1815 const t_TYPE *operator->() const;
1816 // Return a pointer providing non-modifiable access to the underlying
1817 // 't_TYPE' object. The behavior is undefined if this object is
1818 // disengaged.
1819
1820# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1821 const t_TYPE& operator*() const&;
1822 const t_TYPE&& operator*() const&&;
1823 // Return a reference providing non-modifiable access to the underlying
1824 // 't_TYPE' object. The behavior is undefined if this object is
1825 // disengaged.
1826# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1827 const t_TYPE& operator*() const;
1828 // Return a reference providing non-modifiable access to the underlying
1829 // 't_TYPE' object. The behavior is undefined if this object is
1830 // disengaged.
1831# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1832
1833#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1834 explicit operator bool() const BSLS_KEYWORD_NOEXCEPT;
1835 // Return 'false' if this object is disengaged, and 'true' otherwise.
1836#else
1837 // Simulation of explicit conversion to bool. Inlined to work around xlC
1838 // bug when out-of-line.
1839 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
1840 {
1841 return UnspecifiedBoolUtil::makeValue(has_value());
1842 }
1843#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
1844};
1845# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY else
1846
1847} // close package namespace
1848
1849
1850namespace bsl {
1851
1852// ============================================================================
1853// Section: Definition of Class Template 'optional'
1854// ============================================================================
1855
1856 // ==============
1857 // class optional
1858 // ==============
1859
1860template <class t_TYPE>
1861class optional : public BloombergLP::bslstl::Optional_Base<t_TYPE> {
1862 private:
1863 // PRIVATE TYPES
1864 typedef BloombergLP::bslstl::Optional_Base<t_TYPE> BaseType;
1865
1866 typedef typename BaseType::AllocType AllocType;
1867
1868 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1869
1870 public:
1871 // TRAITS
1873 optional,
1874 BloombergLP::bslma::UsesBslmaAllocator,
1875 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value);
1877 optional,
1878 BloombergLP::bslmf::UsesAllocatorArgT,
1879 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value);
1881 optional,
1882 BloombergLP::bslmf::IsBitwiseMoveable,
1883 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1885 optional,
1886 BloombergLP::bslmf::IsBitwiseCopyable,
1887 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1888
1889 // CREATORS
1890
1891 /// Create a disengaged `optional` object. Use the currently installed
1892 /// default allocator to supply memory.
1894
1895 /// Create a disengaged `optional` object. Use the currently installed
1896 /// default allocator to supply memory.
1898
1899#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1900 template <class t_DERIVED>
1901 optional(BloombergLP::bslmf::MovableRef<t_DERIVED> original,
1905 // If the 'optional' base class of the specified 'original' holds a
1906 // value, create an 'optional' object whose contained value is
1907 // initialized by moving from that value; otherwise, create a
1908 // disengaged 'optional' object. The allocator associated with the
1909 // 'optional' base class of 'original' is propagated for use in the
1910 // newly-created object. 'original' is left in a valid, but
1911 // unspecified state. Note that this constructor does not participate
1912 // in overload resolution unless 'optional' is an accessible base class
1913 // of 't_DERIVED' or 't_DERIVED' is 'optional' itself (in which case
1914 // the instantiation provides the move constructor in C++03; a move
1915 // constructor is implicitly declared in C++11).
1916#endif
1917
1918 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
1922 t_ANY_TYPE));
1923 // IMPLICIT
1924
1925 /// Create an `optional` object whose contained value is initialized by
1926 /// forwarding from the specified `value`. Use the currently installed
1927 /// default allocator to supply memory. Note that this constructor
1928 /// participates in overload resolution only when `t_TYPE` is
1929 /// constructible from `t_ANY_TYPE` and is implicit only when
1930 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`.
1931 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
1932 explicit optional(
1933 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
1936
1937 template <class t_ANY_TYPE>
1939 const optional<t_ANY_TYPE>& original,
1941 t_TYPE,
1942 const t_ANY_TYPE&),
1944 const t_ANY_TYPE&));
1945 // IMPLICIT
1946
1947 /// Create a disengaged `optional` object if the specified `original`
1948 /// object is disengaged, and an `optional` object with the value of
1949 /// `original.value()` converted to `t_TYPE` otherwise. Use the
1950 /// currently installed default allocator to supply memory. Note that
1951 /// this constructor participates in overload resolution only when
1952 /// `t_TYPE` is constructible from an lvalue of `const t_ANY_TYPE`, and
1953 /// is implicit only when an lvalue of `const t_ANY_TYPE` is implicitly
1954 /// convertible to `t_TYPE`.
1955 template <class t_ANY_TYPE>
1956 explicit optional(
1957 const optional<t_ANY_TYPE>& original,
1959 t_TYPE,
1960 const t_ANY_TYPE&),
1962 const t_ANY_TYPE&));
1963
1964 template <class t_ANY_TYPE>
1968 t_ANY_TYPE),
1970 // IMPLICIT
1971
1972 /// Create a disengaged `optional` object if the specified `original`
1973 /// object is disengaged, and an `optional` object with the value of
1974 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
1975 /// the allocator from `original` to supply memory if `t_ANY_TYPE` is a
1976 /// non-const version of `t_TYPE`; otherwise, use the currently
1977 /// installed default allocator. `original` is left in a valid but
1978 /// unspecified state. Note that this constructor participates in
1979 /// overload resolution only when `t_TYPE` is constructible from an
1980 /// xvalue of `t_ANY_TYPE`, and is implicit only when an xvalue of
1981 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`.
1982 template <class t_ANY_TYPE>
1983 explicit optional(
1986 t_ANY_TYPE),
1988
1989# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1990 template <class t_ANY_TYPE>
1991 optional(
1992 const std::optional<t_ANY_TYPE>& original,
1994 t_TYPE,
1995 const t_ANY_TYPE&),
1997 t_ANY_TYPE));
1998 // IMPLICIT
1999
2000 /// Create a disengaged `optional` object if the specified `original`
2001 /// object is disengaged, and an `optional` object with the value of
2002 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2003 /// currently installed default allocator to supply memory. Note that
2004 /// this constructor participates in overload resolution only when
2005 /// `t_TYPE` is constructible from an lvalue of `const t_ANY_TYPE`, and
2006 /// is implicit only when an lvalue of `const t_ANY_TYPE` is implicitly
2007 /// convertible to `t_TYPE`.
2008 template <class t_ANY_TYPE>
2009 explicit optional(
2010 const std::optional<t_ANY_TYPE>& original,
2012 t_TYPE,
2013 const t_ANY_TYPE&),
2015
2016 template <class t_ANY_TYPE>
2017 optional(
2018 std::optional<t_ANY_TYPE>&& original,
2020 t_ANY_TYPE),
2022 // IMPLICIT
2023
2024 /// Create a disengaged `optional` object if the specified `original`
2025 /// object is disengaged, and an `optional` object with the value of
2026 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2027 /// currently installed default allocator to supply memory. Note that
2028 /// this constructor participates in overload resolution only when
2029 /// `t_TYPE` is constructible from an xvalue of `t_ANY_TYPE`, and is
2030 /// implicit only when an xvalue of `t_ANY_TYPE` is implicitly
2031 /// convertible to `t_TYPE`.
2032 template <class t_ANY_TYPE>
2033 explicit optional(
2034 std::optional<t_ANY_TYPE>&& original,
2036 t_ANY_TYPE),
2038# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2039
2040#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2041 /// Create an `optional` object having the value of the (template
2042 /// parameter) `t_TYPE` created in place using the specified `args`.
2043 /// Use the currently installed default allocator to supply memory.
2044 template <class... t_ARGS>
2046 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2047
2048# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2049 /// Create an `optional` object having the value of the (template
2050 /// parameter) `t_TYPE` created in place using the specified `il` and
2051 /// specified `args`. Use the currently installed default allocator to
2052 /// supply memory.
2053 template <class t_INIT_LIST_TYPE, class... t_ARGS>
2054 explicit optional(bsl::in_place_t,
2055 std::initializer_list<t_INIT_LIST_TYPE> il,
2056 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2057#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
2058#endif
2059
2060 // These allocator-extended constructors can be called only when 't_TYPE'
2061 // is allocator-aware.
2062
2063 /// Create a disengaged `optional` object. Use the specified
2064 /// `allocator` to supply memory.
2065 optional(bsl::allocator_arg_t, AllocType allocator);
2066
2067 /// Create a disengaged `optional` object. Use the specified
2068 /// `allocator` to supply memory.
2069 optional(bsl::allocator_arg_t, AllocType allocator, bsl::nullopt_t);
2070
2071 /// If the specified `original` contains a value, create an `optional`
2072 /// object whose contained value is initialized from `*original`;
2073 /// otherwise, create a disengaged `optional` object. Use the specified
2074 /// `allocator` to supply memory.
2075 optional(bsl::allocator_arg_t,
2076 AllocType allocator,
2077 const optional& original);
2078
2079 /// If the `optional` base class of the specified `original` holds a
2080 /// value, create an `optional` object whose contained value is
2081 /// initialized by moving from that value; otherwise, create a
2082 /// disengaged `optional` object. Use the specified `allocator` to
2083 /// supply memory. `original` is left in a valid, but unspecified
2084 /// state. Note that this constructor does not participate in overload
2085 /// resolution unless `optional` is an accessible base class of
2086 /// `t_DERIVED` or `t_DERIVED` is `optional` itself (in which case the
2087 /// instantiation provides the allocator-extended move constructor).
2088 template <class t_DERIVED>
2089 optional(bsl::allocator_arg_t,
2090 AllocType allocator,
2091 BSLMF_MOVABLEREF_DEDUCE(t_DERIVED) original,
2093 typename bsl::remove_reference<t_DERIVED>::type));
2094
2095 /// Create an `optional` object whose contained value is initialized by
2096 /// forwarding from the specified `value`. Use the specified
2097 /// `allocator` to supply memory. Note that this constructor
2098 /// participates in overload resolution only when `t_TYPE` is
2099 /// constructible from `t_ANY_TYPE`, and is implicit only when
2100 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`.
2101 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2102 optional(bsl::allocator_arg_t,
2103 AllocType allocator,
2104 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
2107 t_ANY_TYPE));
2108 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2109 explicit optional(
2110 bsl::allocator_arg_t,
2111 AllocType allocator,
2112 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
2115
2116 /// Create a disengaged `optional` object if the specified `original`
2117 /// object is disengaged, and an `optional` object with the value of
2118 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2119 /// specified `allocator` to supply memory. Note that this constructor
2120 /// participates in overload resolution only when `t_TYPE` is
2121 /// constructible from an lvalue of `const t_ANY_TYPE`, and is implicit
2122 /// only when an lvalue of `const t_ANY_TYPE` is implicitly convertible
2123 /// to `t_TYPE`.
2124 template <class t_ANY_TYPE>
2126 bsl::allocator_arg_t,
2127 AllocType allocator,
2128 const optional<t_ANY_TYPE>& original,
2130 t_TYPE,
2131 const t_ANY_TYPE&),
2133 const t_ANY_TYPE&));
2134 template <class t_ANY_TYPE>
2135 explicit optional(
2136 bsl::allocator_arg_t,
2137 AllocType allocator,
2138 const optional<t_ANY_TYPE>& original,
2140 t_TYPE,
2141 const t_ANY_TYPE&),
2143 const t_ANY_TYPE&));
2144
2145 /// Create a disengaged `optional` object if the specified `original`
2146 /// object is disengaged, and an `optional` object with the value of
2147 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
2148 /// the specified `allocator` to supply memory. `original` is left in a
2149 /// valid but unspecified state. Note that this constructor
2150 /// participates in overload resolution only when `t_TYPE` is
2151 /// constructible from an xvalue of `t_ANY_TYPE`, and is implicit only
2152 /// when an xvalue of `t_ANY_TYPE` is implicitly convertible to
2153 /// `t_TYPE`.
2154 template <class t_ANY_TYPE>
2156 bsl::allocator_arg_t,
2157 AllocType allocator,
2160 t_ANY_TYPE),
2162 template <class t_ANY_TYPE>
2163 explicit optional(
2164 bsl::allocator_arg_t,
2165 AllocType allocator,
2168 t_ANY_TYPE),
2170
2171# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2172 /// Create a disengaged `optional` object if the specified `original`
2173 /// object is disengaged, and an `optional` object with the value of
2174 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2175 /// specified `allocator` to supply memory. Note that this constructor
2176 /// participates in overload resolution only when `t_TYPE` is
2177 /// constructible from an lvalue of `const t_ANY_TYPE`, and is implicit
2178 /// only when an lvalue of `const t_ANY_TYPE` is implicitly convertible
2179 /// to `t_TYPE`.
2180 template <class t_ANY_TYPE>
2181 optional(
2182 bsl::allocator_arg_t,
2183 AllocType allocator,
2184 const std::optional<t_ANY_TYPE>& original,
2186 t_TYPE,
2187 const t_ANY_TYPE&),
2189 const t_ANY_TYPE&));
2190 template <class t_ANY_TYPE>
2191 explicit optional(
2192 bsl::allocator_arg_t,
2193 AllocType allocator,
2194 const std::optional<t_ANY_TYPE>& original,
2196 t_TYPE,
2197 const t_ANY_TYPE&),
2199 const t_ANY_TYPE));
2200
2201 /// Create a disengaged `optional` object if the specified `original`
2202 /// object is disengaged, and an `optional` object with the value of
2203 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
2204 /// the specified `allocator` to supply memory. `original` is left in a
2205 /// valid but unspecified state. Note that this constructor
2206 /// participates in overload resolution only when `t_TYPE` is
2207 /// constructible from an xvalue of `t_ANY_TYPE`, and is implicit only
2208 /// when an xvalue of `t_ANY_TYPE` is implicitly convertible to
2209 /// `t_TYPE`.
2210 template <class t_ANY_TYPE>
2211 optional(
2212 bsl::allocator_arg_t,
2213 AllocType allocator,
2214 std::optional<t_ANY_TYPE>&& original,
2216 t_ANY_TYPE),
2218 template <class t_ANY_TYPE>
2219 explicit optional(
2220 bsl::allocator_arg_t,
2221 AllocType allocator,
2222 std::optional<t_ANY_TYPE>&& original,
2224 t_ANY_TYPE),
2226# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2227
2228#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2229 /// Create an `optional` object having the value of the (template
2230 /// parameter) `t_TYPE` created in place using the specified `args`.
2231 /// Use the specified `allocator` to supply memory.
2232 template <class... t_ARGS>
2233 explicit optional(bsl::allocator_arg_t,
2234 AllocType allocator,
2236 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2237
2238# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2239 /// Create an `optional` object having the value of the (template
2240 /// parameter) `t_TYPE` created in place using the specified `il` and
2241 /// `args`. Use the specified `allocator` to supply memory.
2242 template <class t_INIT_LIST_TYPE, class... t_ARGS>
2243 explicit optional(bsl::allocator_arg_t,
2244 AllocType allocator,
2246 std::initializer_list<t_INIT_LIST_TYPE> il,
2247 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2248# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
2249#endif
2250
2251 // MANIPULATORS
2252
2253 // We implement 'operator=' in the most derived class to avoid having to
2254 // repeat constraints in each of the three implementations of
2255 // 'Optional_Base'.
2256
2257 /// Reset this object to be disengaged and return a reference providing
2258 /// modifiable access to this object.
2260
2261#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2262 template <class t_DERIVED>
2264 operator=(BloombergLP::bslmf::MovableRef<t_DERIVED> rhs);
2265 // If the 'optional' base class of the specified 'rhs' holds a value,
2266 // move-construct or move-assign the contained value of '*this' from
2267 // that value. Otherwise, set '*this' to be disengaged. Return a
2268 // reference providing modifiable access to this object. 'rhs' is left
2269 // in a valid but unspecified state. This method does not participate
2270 // in overload resolution unless 'optional' is an accessible base class
2271 // of 't_DERIVED' or 't_DERIVED' is 'optional' itself (in which case
2272 // the instantiation provides the move assignment operator in C++03; a
2273 // move assignment operator is implicitly declared in C++11).
2274#endif
2275
2276 /// Disengage this object if the specified `rhs` object is disengaged,
2277 /// and assign to this object the value of `rhs.value()` (of
2278 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference
2279 /// providing modifiable access to this object. Note that this method
2280 /// does not participate in overload resolution unless `t_TYPE` and
2281 /// `t_ANY_TYPE` are compatible.
2282 template <class t_ANY_TYPE>
2284 operator=(const optional<t_ANY_TYPE>& rhs);
2285
2286 /// Disengage this object if the specified `rhs` object is disengaged,
2287 /// and move assign to this object the value of `rhs.value()` (of
2288 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference
2289 /// providing modifiable access to this object. Note that this method
2290 /// does not participate in overload resolution unless `t_TYPE` and
2291 /// `t_ANY_TYPE` are compatible.
2292 template <class t_ANY_TYPE>
2295
2296#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2297 /// Assign to this object the value of the specified `rhs` object
2298 /// converted to `t_TYPE`, and return a reference providing modifiable
2299 /// access to this object. Note that this method may invoke assignment
2300 /// from `rhs`, or construction from `rhs`, depending on whether this
2301 /// object is engaged. This assignment operator does not participate in
2302 /// overload resolution if `t_ANY_TYPE` is possibly cv-qualified
2303 /// `bsl::optional<t_TYPE>`. Also note that an assignment of the form
2304 /// `o = {};`, where `o` is of type `optional`, will always assign to
2305 /// `o` the empty state, and never call this overload (see
2306 /// implementation notes).
2307 template <class t_ANY_TYPE = t_TYPE>
2309 operator=(t_ANY_TYPE&& rhs);
2310#else
2311 // The existence of MovableRef in C++11 affects the above functions, and
2312 // they need to be defined in terms of rvalue references and perfect
2313 // forwarding. For C++03, the MovableRef overloads are provided below.
2314
2315 optional& operator=(const t_TYPE& rhs);
2316 // Assign to this object the value of the specified 'rhs', and return a
2317 // reference providing modifiable access to this object.
2318
2319 optional& operator=(BloombergLP::bslmf::MovableRef<t_TYPE> rhs);
2320 // Assign to this object the value of the specified 'rhs', and return a
2321 // reference providing modifiable access to this object. The contents
2322 // of 'rhs' are either move-constructed into or move-assigned to this
2323 // object. 'rhs' is left in a valid but unspecified state.
2324
2325 template <class t_ANY_TYPE>
2327 operator=(const t_ANY_TYPE& rhs);
2328 // Assign to this object the value of the specified 'rhs' object (of
2329 // 'ANY_TYPE') converted to 'TYPE', and return a reference providing
2330 // modifiable access to this object. Note that this method may invoke
2331 // assignment from 'rhs', or construction from 'rhs', depending on
2332 // whether this 'optional' object is engaged.
2333
2334 template <class t_ANY_TYPE>
2336 operator=(BloombergLP::bslmf::MovableRef<t_ANY_TYPE> rhs);
2337#endif // RVALUES else
2338
2339#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2340 /// Disengage this object if the specified `rhs` object is disengaged,
2341 /// and assign to this object the value of `rhs.value()` (of
2342 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference
2343 /// providing modifiable access to this object. Note that this method
2344 /// does not participate in overload resolution unless `t_TYPE` and
2345 /// `t_ANY_TYPE` are compatible.
2346 template <class t_ANY_TYPE = t_TYPE>
2347 BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(t_TYPE, const t_ANY_TYPE&)&
2348 operator=(const std::optional<t_ANY_TYPE>& rhs);
2349
2350 /// Disengage this object if the specified `rhs` object is disengaged,
2351 /// and move assign to this object the value of `rhs.value()` (of
2352 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference
2353 /// providing modifiable access to this object. Note that this method
2354 /// does not participate in overload resolution unless `t_TYPE` and
2355 /// `t_ANY_TYPE` are compatible.
2356 template <class t_ANY_TYPE = t_TYPE>
2358 operator=(std::optional<t_ANY_TYPE>&& rhs);
2359# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2360};
2361
2362} // close namespace bsl
2363
2364// ============================================================================
2365// Section: Type Traits on Allocator-Unaware 'Optional_Base'
2366// ============================================================================
2367
2368
2369namespace bslma {
2370
2371template <class t_TYPE>
2372struct UsesBslmaAllocator<bslstl::Optional_Base<t_TYPE, false> >
2374};
2375
2376template <class t_TYPE>
2377struct UsesBslmaAllocator<bsl::optional<t_TYPE> >
2378: UsesBslmaAllocator<t_TYPE> {
2379};
2380
2381} // close namespace bslma
2382
2383
2384namespace bsl {
2385
2386// ============================================================================
2387// Section: CTAD Constructors
2388// ============================================================================
2389
2390# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2391// CLASS TEMPLATE DEDUCTION GUIDES
2392
2393/// Deduce the specified type `t_TYPE` from the corresponding type supplied
2394/// to the constructor of `optional`.
2395template <class t_TYPE>
2396optional(t_TYPE) -> optional<t_TYPE>;
2397
2398/// Deduce the specified type `t_TYPE` from the corresponding type supplied
2399/// to the constructor of `optional`. This guide does not participate in
2400/// deduction unless the deduced type `t_TYPE` supports the bslma allocator
2401/// model, and the specified `t_ALLOC` can be implicitly converted to
2402/// `bsl::allocator<char>`.
2403template <class t_TYPE,
2404 class t_ALLOC,
2405 class = typename bsl::enable_if_t<
2406 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>,
2407 class = typename bsl::enable_if_t<
2408 bsl::is_convertible_v<t_ALLOC, bsl::allocator<char>>>
2409 >
2410optional(bsl::allocator_arg_t, t_ALLOC, t_TYPE)
2411-> optional<t_TYPE>;
2412
2413/// Deduce the specified type `t_TYPE` from the corresponding template
2414/// parameter type supplied to the constructor of `optional`. This guide
2415/// does not participate in deduction unless the deduced type `t_TYPE`
2416/// supports the bslma allocator model, and the specified `t_ALLOC` can be
2417/// implicitly converted to `bsl::allocator<char>`.
2418template <class t_TYPE,
2419 class t_ALLOC,
2420 class = typename bsl::enable_if_t<
2421 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>,
2422 class = typename bsl::enable_if_t<
2423 bsl::is_convertible_v<t_ALLOC, bsl::allocator<char>>>
2424 >
2425optional(bsl::allocator_arg_t, t_ALLOC, optional<t_TYPE>)
2426-> optional<t_TYPE>;
2427# endif // BSLS_COMPILERFEATURES_SUPPORT_CTAD
2428
2429// ============================================================================
2430// Section: Free Function Declarations
2431// ============================================================================
2432
2433// FREE FUNCTIONS
2434
2435/// Efficiently exchange the values of the specified `lhs` and `rhs`
2436/// objects. This method provides the no-throw exception-safety guarantee
2437/// if the template parameter `t_TYPE` provides that guarantee, `lhs` and
2438/// `rhs` have equal allocators, and `lhs.hasValue() == rhs.hasValue()`.
2439template <class t_TYPE>
2441 void>::type
2443
2444/// Efficiently exchange the values of the specified `lhs` and `rhs`
2445/// objects. This method provides the no-throw exception-safety guarantee
2446/// if the template parameter `t_TYPE` provides that guarantee and the
2447/// result of the `hasValue` method for `lhs` and `rhs` is the same.
2448template <class t_TYPE>
2450 void>::type
2452
2453// HASH SPECIALIZATIONS
2454
2455/// Pass the specified `input` to the specified `hashAlg`, where `hashAlg`
2456/// is a hashing algorithm.
2457template <class t_HASHALG, class t_TYPE>
2458void hashAppend(t_HASHALG& hashAlg, const optional<t_TYPE>& input);
2459
2460// FREE OPERATORS
2461template <class t_LHS_TYPE, class t_RHS_TYPE>
2462bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
2463 const bsl::optional<t_RHS_TYPE>& rhs)
2464 BSLSTL_OPTIONAL_REQUIRES(requires {
2465 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2466 });
2467 // Return 'true' if the specified 'lhs' and 'rhs' 'optional' objects have
2468 // the same value, and 'false' otherwise. Two 'optional' objects have the
2469 // same value if both are disengaged, or if both are engaged and the values
2470 // of their underlying objects compare equal.
2471
2472template <class t_LHS_TYPE, class t_RHS_TYPE>
2473bool operator!=(const bsl::optional<t_LHS_TYPE>& lhs,
2474 const bsl::optional<t_RHS_TYPE>& rhs)
2475 BSLSTL_OPTIONAL_REQUIRES(requires {
2476 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2477 });
2478 // Return 'true' if the specified 'lhs' and 'rhs' 'optional' objects do not
2479 // have the same value, and 'false' otherwise. Two 'optional' objects do
2480 // not have the same value if one is disengaged and the other is engaged,
2481 // or if both are engaged and the values of their underlying objects do not
2482 // compare equal.
2483
2484template <class t_LHS_TYPE, class t_RHS_TYPE>
2485bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
2486 const bsl::optional<t_RHS_TYPE>& rhs)
2487 BSLSTL_OPTIONAL_REQUIRES(requires {
2488 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2489 });
2490 // Return 'true' if the specified 'lhs' 'optional' object is ordered before
2491 // the specified 'rhs' 'optional' object, and 'false' otherwise. 'lhs' is
2492 // ordered before 'rhs' if 'lhs' is disengaged and 'rhs' is engaged or if
2493 // both are engaged and 'lhs.value()' is ordered before 'rhs.value()'.
2494
2495template <class t_LHS_TYPE, class t_RHS_TYPE>
2496bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
2497 const bsl::optional<t_RHS_TYPE>& rhs)
2498 BSLSTL_OPTIONAL_REQUIRES(requires {
2499 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2500 });
2501 // Return 'true' if the specified 'lhs' 'optional' object is ordered after
2502 // the specified 'rhs' 'optional' object, and 'false' otherwise. 'lhs' is
2503 // ordered after 'rhs' if 'lhs' is engaged and 'rhs' is disengaged or if
2504 // both are engaged and 'lhs.value()' is ordered after 'rhs.value()'.
2505
2506template <class t_LHS_TYPE, class t_RHS_TYPE>
2507bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs,
2508 const bsl::optional<t_RHS_TYPE>& rhs)
2509 BSLSTL_OPTIONAL_REQUIRES(requires {
2510 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2511 });
2512 // Return 'true' if the specified 'lhs' 'optional' object is ordered before
2513 // the specified 'rhs' 'optional' object or if 'lhs' and 'rhs' have the
2514 // same value, and 'false' otherwise. (See 'operator<' and 'operator=='.)
2515
2516template <class t_LHS_TYPE, class t_RHS_TYPE>
2517bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs,
2518 const bsl::optional<t_RHS_TYPE>& rhs)
2519 BSLSTL_OPTIONAL_REQUIRES(requires {
2520 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2521 });
2522 // Return 'true' if the specified 'lhs' 'optional' object is ordered after
2523 // the specified 'rhs' 'optional' object or if 'lhs' and 'rhs' have the
2524 // same value, and 'false' otherwise. (See 'operator>' and 'operator=='.)
2525
2526// comparison with 'nullopt_t'
2527
2528template <class t_TYPE>
2529BSLS_KEYWORD_CONSTEXPR bool operator==(
2530 const bsl::optional<t_TYPE>& value,
2532#if !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) && \
2533 defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
2534template <class t_TYPE>
2535BSLS_KEYWORD_CONSTEXPR bool operator==(
2536 const bsl::nullopt_t&,
2537 const bsl::optional<t_TYPE>& value)
2539 // Return 'true' if the specified 'value' is disengaged, and 'false'
2540 // otherwise.
2541
2542template <class t_TYPE>
2543BSLS_KEYWORD_CONSTEXPR bool operator!=(
2544 const bsl::optional<t_TYPE>& value,
2546template <class t_TYPE>
2547BSLS_KEYWORD_CONSTEXPR bool operator!=(
2548 const bsl::nullopt_t&,
2549 const bsl::optional<t_TYPE>& value)
2551 // Return 'true' if the specified 'value' is engaged, and 'false'
2552 // otherwise.
2553
2554template <class t_TYPE>
2555BSLS_KEYWORD_CONSTEXPR bool operator<(
2556 const bsl::optional<t_TYPE>&,
2558 // Return 'false'. Note that 'bsl::nullopt_t' never orders after a
2559 // 'bsl::optional'.
2560
2561template <class t_TYPE>
2562BSLS_KEYWORD_CONSTEXPR bool operator<(
2563 const bsl::nullopt_t&,
2565 // Return 'true' if the specified 'value' is engaged, and 'false'
2566 // otherwise. Note that 'bsl::nullopt_t' is ordered before any
2567 // 'bsl::optional' that is engaged.
2568
2569template <class t_TYPE>
2570BSLS_KEYWORD_CONSTEXPR bool operator>(
2571 const bsl::optional<t_TYPE>& value,
2573 // Return 'true' if the specified 'value' is engaged, and 'false'
2574 // otherwise.
2575
2576template <class t_TYPE>
2577BSLS_KEYWORD_CONSTEXPR bool operator>(
2578 const bsl::nullopt_t&,
2580 // Return 'false'. Note that 'bsl::nullopt_t' never orders after a
2581 // 'bsl::optional'.
2582
2583template <class t_TYPE>
2584BSLS_KEYWORD_CONSTEXPR bool operator<=(
2585 const bsl::optional<t_TYPE>& value,
2587 // Return 'true' if the specified 'value' is disengaged, and 'false'
2588 // otherwise.
2589
2590template <class t_TYPE>
2591BSLS_KEYWORD_CONSTEXPR bool operator<=(
2592 const bsl::nullopt_t&,
2594 // Return 'true'. Note that 'bsl::nullopt_t' is ordered before any
2595 // 'bsl::optional' that is engaged.
2596
2597template <class t_TYPE>
2598BSLS_KEYWORD_CONSTEXPR bool operator>=(
2599 const bsl::optional<t_TYPE>&,
2601 // Return 'true'. Note that 'bsl::nullopt_t' is ordered before any
2602 // 'bsl::optional' that is engaged.
2603
2604template <class t_TYPE>
2605BSLS_KEYWORD_CONSTEXPR bool operator>=(
2606 const bsl::nullopt_t&,
2608 // Return 'true' if the specified 'value' is disengaged, and 'false'
2609 // otherwise.
2610#endif // !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) &&
2611 // defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
2612
2613// comparison with 'value_type'
2614
2615template <class t_LHS_TYPE, class t_RHS_TYPE>
2616bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
2617 const t_RHS_TYPE& rhs)
2619 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2620 && requires {
2621 { *lhs == rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2622 });
2623template <class t_LHS_TYPE, class t_RHS_TYPE>
2624bool operator==(const t_LHS_TYPE& lhs,
2625 const bsl::optional<t_RHS_TYPE>& rhs)
2627 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2628 && requires {
2629 { lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2630 });
2631 // Return 'true' if the specified 'lhs' and 'rhs' objects have the same
2632 // value, and 'false' otherwise. An 'optional' object and a value of some
2633 // type have the same value if the optional object is engaged and its
2634 // underlying value compares equal to the other value.
2635
2636template <class t_LHS_TYPE, class t_RHS_TYPE>
2638 const t_RHS_TYPE& rhs)
2640 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2641 && requires {
2642 { *lhs != rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2643 });
2644template <class t_LHS_TYPE, class t_RHS_TYPE>
2645bool operator!=(const t_LHS_TYPE& lhs,
2646 const bsl::optional<t_RHS_TYPE>& rhs)
2648 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2649 && requires {
2650 { lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2651 });
2652 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
2653 // same value, and 'false' otherwise. An 'optional' object and a value of
2654 // some type do not have the same value if either the optional object is
2655 // disengaged, or its underlying value does not compare equal to the other
2656 // value.
2657
2658template <class t_LHS_TYPE, class t_RHS_TYPE>
2659bool operator<(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
2661 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2662 && requires {
2663 { *lhs < rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2664 });
2665 // Return 'true' if the specified 'lhs' 'optional' object is ordered before
2666 // the specified 'rhs', and 'false' otherwise. 'lhs' is ordered before
2667 // 'rhs' if 'lhs' is disengaged or 'lhs.value()' is ordered before 'rhs'.
2668
2669template <class t_LHS_TYPE, class t_RHS_TYPE>
2670bool operator<(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
2672 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2673 && requires {
2674 { lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2675 });
2676 // Return 'true' if the specified 'lhs' is ordered before the specified
2677 // 'rhs' 'optional' object, and 'false' otherwise. 'lhs' is ordered before
2678 // 'rhs' if 'rhs' is engaged and 'lhs' is ordered before 'rhs.value()'.
2679
2680template <class t_LHS_TYPE, class t_RHS_TYPE>
2681bool operator>(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
2683 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2684 && requires {
2685 { *lhs > rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2686 });
2687 // Return 'true' if the specified 'lhs' 'optional' object is ordered after
2688 // the specified 'rhs', and 'false' otherwise. 'lhs' is ordered after
2689 // 'rhs' if 'lhs' is engaged and 'lhs.value()' is ordered after 'rhs'.
2690
2691template <class t_LHS_TYPE, class t_RHS_TYPE>
2692bool operator>(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
2694 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2695 && requires {
2696 { lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2697 });
2698 // Return 'true' if the specified 'lhs' is ordered after the specified
2699 // 'rhs' 'optional' object, and 'false' otherwise. 'lhs' is ordered after
2700 // 'rhs' if 'rhs' is disengaged or 'lhs' is ordered after 'rhs.value()'.
2701
2702template <class t_LHS_TYPE, class t_RHS_TYPE>
2703bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
2705 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2706 && requires {
2707 { *lhs <= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2708 });
2709 // Return 'true' if the specified 'lhs' 'optional' object is ordered before
2710 // the specified 'rhs' or 'lhs' and 'rhs' have the same value, and 'false'
2711 // otherwise. (See 'operator<' and 'operator=='.)
2712
2713template <class t_LHS_TYPE, class t_RHS_TYPE>
2714bool operator<=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
2716 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2717 && requires {
2718 { lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2719 });
2720 // Return 'true' if the specified 'lhs' is ordered before the specified
2721 // 'rhs' 'optional' object or 'lhs' and 'rhs' have the same value, and
2722 // 'false' otherwise. (See 'operator<' and 'operator=='.)
2723
2724template <class t_LHS_TYPE, class t_RHS_TYPE>
2725bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
2727 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2728 && requires {
2729 { *lhs >= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2730 });
2731 // Return 'true' if the specified 'lhs' 'optional' object is ordered after
2732 // the specified 'rhs' or if 'lhs' and 'rhs' have the same value, and
2733 // 'false' otherwise. (See 'operator>' and 'operator=='.)
2734
2735template <class t_LHS_TYPE, class t_RHS_TYPE>
2736bool operator>=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
2738 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2739 && requires {
2740 { lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2741 });
2742 // Return 'true' if the specified 'lhs' is ordered after the specified
2743 // 'rhs' 'optional' object or if 'lhs' and 'rhs' have the same value, or
2744 // 'false' otherwise. (See 'operator>' and 'operator=='.)
2745
2746#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
2747 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
2748/// Perform a three-way comparison of the specified `lhs` and the specified
2749/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
2750/// return the result of that comparison.
2751template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
2752constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
2753 const bsl::optional<t_LHS>& lhs,
2754 const bsl::optional<t_RHS>& rhs);
2755
2756/// Perform a three-way comparison of the specified `lhs` and the specified
2757/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
2758/// return the result of that comparison.
2759template <class t_LHS, class t_RHS>
2760requires (!BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS>) &&
2761 three_way_comparable_with<t_LHS, t_RHS>
2762constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
2763 const bsl::optional<t_LHS>& lhs,
2764 const t_RHS& rhs);
2765
2766/// Perform a three-way comparison of the specified `value` and `nullopt`;
2767/// return the result of that comparison.
2768template <class t_TYPE>
2769constexpr strong_ordering operator<=>(
2770 const bsl::optional<t_TYPE>& value,
2772
2773/// Perform a three-way comparison of the specified `lhs` and the specified
2774/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
2775/// return the result of that comparison.
2776template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
2777constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
2778 const bsl::optional<t_LHS>& lhs,
2779 const std::optional<t_RHS>& rhs);
2780#endif
2781
2782# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2783/// Efficiently exchange the values of the specified `lhs` and `rhs`
2784/// objects. This method provides the no-throw exception-safety guarantee
2785/// if the template parameter `t_TYPE` provides that guarantee and the
2786/// result of the `hasValue` method for `lhs` and `rhs` is the same.
2787template <class t_TYPE>
2789 void>::type
2790swap(bsl::optional<t_TYPE>& lhs, std::optional<t_TYPE>& rhs);
2791template <class t_TYPE>
2793 void>::type
2794swap(std::optional<t_TYPE>& lhs, bsl::optional<t_TYPE>& rhs);
2795
2796// comparison with 'std::optional'
2797
2798/// Return `true` if the specified `lhs` and `rhs` optional objects have the
2799/// same value, and `false` otherwise. Two optional objects have the same
2800/// value if both are disengaged, or if both are engaged and the values of
2801/// their underlying objects compare equal. Note that this function will
2802/// fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE` are not compatible.
2803template <class t_LHS_TYPE, class t_RHS_TYPE>
2804bool operator==(const std::optional<t_LHS_TYPE>& lhs,
2805 const bsl::optional<t_RHS_TYPE>& rhs);
2806template <class t_LHS_TYPE, class t_RHS_TYPE>
2808 const std::optional<t_RHS_TYPE>& rhs);
2809
2810/// Return `true` if the specified `lhs` and `rhs` optional objects do not
2811/// have the same value, and `false` otherwise. Two optional objects do not
2812/// have the same value if one is disengaged and the other is engaged, or if
2813/// both are engaged and the values of their underlying objects do not
2814/// compare equal. Note that this function will fail to compile if
2815/// `t_LHS_TYPE` and `t_RHS_TYPE` are not compatible.
2816template <class t_LHS_TYPE, class t_RHS_TYPE>
2818 const std::optional<t_RHS_TYPE>& rhs);
2819template <class t_LHS_TYPE, class t_RHS_TYPE>
2820bool operator!=(const std::optional<t_LHS_TYPE>& lhs,
2821 const bsl::optional<t_RHS_TYPE>& rhs);
2822
2823/// Return `true` if the specified `lhs` optional object is ordered before
2824/// the specified `rhs` optional object, and `false` otherwise. `lhs` is
2825/// ordered before `rhs` if `lhs` is disengaged and `rhs` is engaged or if
2826/// both are engaged and `lhs.value()` is ordered before `rhs.value()`.
2827/// Note that this function will fail to compile if `t_LHS_TYPE` and
2828/// `t_RHS_TYPE` are not compatible.
2829template <class t_LHS_TYPE, class t_RHS_TYPE>
2830bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
2831 const std::optional<t_RHS_TYPE>& rhs);
2832template <class t_LHS_TYPE, class t_RHS_TYPE>
2833bool operator<(const std::optional<t_LHS_TYPE>& lhs,
2834 const bsl::optional<t_RHS_TYPE>& rhs);
2835
2836/// Return `true` if the specified `lhs` optional object is ordered after
2837/// the specified `rhs` optional object, and `false` otherwise. `lhs` is
2838/// ordered after `rhs` if `lhs` is engaged and `rhs` is disengaged or if
2839/// both are engaged and `lhs.value()` is ordered after `rhs.value()`. Note
2840/// that this function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE`
2841/// are not compatible.
2842template <class t_LHS_TYPE, class t_RHS_TYPE>
2843bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
2844 const std::optional<t_RHS_TYPE>& rhs);
2845template <class t_LHS_TYPE, class t_RHS_TYPE>
2846bool operator>(const std::optional<t_LHS_TYPE>& lhs,
2847 const bsl::optional<t_RHS_TYPE>& rhs);
2848
2849/// Return `true` if the specified `lhs` is ordered before the specified
2850/// `rhs` optional object or `lhs` and `rhs` have the same value, and
2851/// `false` otherwise. (See `operator<` and `operator==`.) Note that this
2852/// function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE` are not
2853/// compatible.
2854template <class t_LHS_TYPE, class t_RHS_TYPE>
2856 const std::optional<t_RHS_TYPE>& rhs);
2857template <class t_LHS_TYPE, class t_RHS_TYPE>
2858bool operator<=(const std::optional<t_LHS_TYPE>& lhs,
2859 const bsl::optional<t_RHS_TYPE>& rhs);
2860
2861/// Return `true` if the specified `lhs` optional object is ordered after
2862/// the specified `rhs` optional object or `lhs` and `rhs` have the same
2863/// value, and `false` otherwise. (See `operator>` and `operator==`.) Note
2864/// that this function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE`
2865/// are not compatible.
2866template <class t_LHS_TYPE, class t_RHS_TYPE>
2868 const std::optional<t_RHS_TYPE>& rhs);
2869template <class t_LHS_TYPE, class t_RHS_TYPE>
2870bool operator>=(const std::optional<t_LHS_TYPE>& lhs,
2871 const bsl::optional<t_RHS_TYPE>& rhs);
2872#endif
2873
2874/// Return an `optional` object containing a `t_TYPE` object created by
2875/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
2876/// with the specified `alloc` as the allocator argument, and specified
2877/// `rhs` as the constructor argument. Note that this function will fail to
2878/// compile if `t_TYPE` doesn't use allocators.
2879template <class t_TYPE>
2881make_optional(bsl::allocator_arg_t,
2882 const typename bsl::optional<
2883 typename bsl::decay<t_TYPE>::type>::allocator_type& alloc,
2885
2886#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2887/// Return an `optional` object containing a `t_TYPE` object created by
2888/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
2889/// with the specified `alloc` as the allocator argument, and specified
2890/// `args` as constructor arguments. Note that this function will fail to
2891/// compile if `t_TYPE` doesn't use allocators.
2892template <class t_TYPE, class... t_ARGS>
2894 bsl::allocator_arg_t,
2895 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
2896 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2897
2898# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) && \
2899 !(defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
2900// MSVC2013 has a bug that causes deduction issues in free template functions
2901// that have an 'std::initializer_list' argument where the
2902// 'std::initializer_list' element type is deduced.
2903
2904/// Return an `optional` object containing a `t_TYPE` object created by
2905/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
2906/// with the specified `alloc` as the allocator argument, and specified `il`
2907/// and `args` as the constructor arguments. Note that this function will
2908/// fail to compile if `t_TYPE` doesn't use allocators.
2909template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
2911 bsl::allocator_arg_t,
2912 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
2913 std::initializer_list<t_INIT_LIST_TYPE> il,
2914 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2915# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2916#endif
2917
2918/// Return an `optional` object containing a `t_TYPE` object created by
2919/// invoking a `bsl::optional` constructor with the specified `rhs` as the
2920/// constructor argument. If `t_TYPE` uses an allocator, the default
2921/// allocator will be used for the `optional` object.
2922template <class t_TYPE>
2925
2926/// Return an `optional` object containing a value-initialized `t_TYPE`
2927/// object. If `t_TYPE` uses an allocator, the default allocator will be
2928/// used for the `optional` object.
2929template <class t_TYPE>
2931
2932#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2933/// Return an `optional` object containing a `TYPE` object created by
2934/// invoking a `bsl::optional` `in_place_t` constructor with the specified
2935/// `arg` and `args` as the constructor arguments. If `t_TYPE` uses an
2936/// allocator, the default allocator will be used for the `optional` object.
2937template <class t_TYPE, class t_ARG, class... t_ARGS>
2940 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2941
2942# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) && \
2943 !(defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
2944// MSVC2013 has a bug that causes deduction issues in free template functions
2945// that have an 'std::initializer_list' argument where the
2946// 'std::initializer_list' element type is deduced.
2947
2948/// Return an `optional` object containing a `t_TYPE` object created by
2949/// invoking a `bsl::optional` `in_place_t` constructor with the specified
2950/// `il` and `args` as the constructor arguments. If `t_TYPE` uses an
2951/// allocator, the default allocator will be used for the `optional` object.
2952template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
2954 std::initializer_list<t_INIT_LIST_TYPE> il,
2955 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2956
2957# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2958#endif
2959
2960} // close namespace bsl
2961
2962// ============================================================================
2963// INLINE DEFINITIONS
2964// ============================================================================
2965
2966
2967namespace bslstl {
2968
2969// ============================================================================
2970// Section: bslstl::Optional_* Definitions
2971// ============================================================================
2972
2973 // ======================
2974 // class Optional_DataImp
2975 // ======================
2976
2977// CREATORS
2978template <class t_TYPE>
2983
2984// MANIPULATORS
2985#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2986template <class t_TYPE>
2987template <class... t_ARGS>
2988inline
2990 bslma::Allocator *allocator,
2991 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
2992{
2993 reset();
2994 BloombergLP::bslma::ConstructionUtil::construct(
2995 d_buffer.address(),
2996 allocator,
2997 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
2998 d_hasValue = true;
2999 return d_buffer.object();
3000}
3001
3002# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3003template <class t_TYPE>
3004template <class t_INIT_LIST_TYPE, class... t_ARGS>
3006 bslma::Allocator *allocator,
3007 std::initializer_list<t_INIT_LIST_TYPE> il,
3008 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3009{
3010 reset();
3011 BloombergLP::bslma::ConstructionUtil::construct(
3012 d_buffer.address(),
3013 allocator,
3014 il,
3015 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3016 d_hasValue = true;
3017 return d_buffer.object();
3018}
3019# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3020#endif
3021
3022template <class t_TYPE>
3024{
3025 if (d_hasValue) {
3026 d_hasValue = false;
3027 bslma::DestructionUtil::destroy(d_buffer.address());
3028 }
3029}
3030
3031# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3032template <class t_TYPE>
3033inline
3035{
3036 // We do not assert on an empty object in this function as the assert level
3037 // is determined by the 'Optional_Base' method invoking 'value()'
3038
3039 return d_buffer.object();
3040}
3041
3042template <class t_TYPE>
3043inline
3045{
3046 // We do not assert on an empty object in this function as the assert level
3047 // is determined by the 'Optional_Base' method invoking 'value()'
3048
3049 return std::move(d_buffer.object());
3050}
3051# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3052template <class t_TYPE>
3053inline
3055{
3056 // We do not assert on an empty object in this function as the assert level
3057 // is determined by the 'Optional_Base' method invoking 'value()'
3058
3059 return d_buffer.object();
3060}
3061# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3062
3063// ACCESSORS
3064template <class t_TYPE>
3065inline
3067{
3068 return d_hasValue;
3069}
3070
3071# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3072template <class t_TYPE>
3073inline
3074const t_TYPE& Optional_DataImp<t_TYPE>::value() const&
3075{
3076 // We do not assert on an empty object in this function as the assert level
3077 // is determined by the 'Optional_Base' method invoking 'value()'
3078
3079 return d_buffer.object();
3080}
3081
3082template <class t_TYPE>
3083inline
3084const t_TYPE&& Optional_DataImp<t_TYPE>::value() const&&
3085{
3086 // We do not assert on an empty object in this function as the assert level
3087 // is determined by the 'Optional_Base' method invoking 'value()'
3088
3089 return std::move(d_buffer.object());
3090}
3091# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3092template <class t_TYPE>
3093inline
3095{
3096 // We do not assert on an empty object in this function as the assert level
3097 // is determined by the 'Optional_Base' method invoking 'value()'
3098
3099 return d_buffer.object();
3100}
3101# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3102
3103 // ===================
3104 // class Optional_Data
3105 // ===================
3106
3107// CREATORS
3108template <class t_TYPE, bool t_IS_TRIVIALLY_DESTRUCTIBLE>
3113
3114// ============================================================================
3115// Section: Allocator-Aware 'Optional_Base' Method Definitions
3116// ============================================================================
3117
3118 // ===================
3119 // class Optional_Base
3120 // ===================
3121
3122// PROTECTED CREATORS
3123template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3124inline
3128
3129template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3130inline
3134
3135template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3136inline
3138 const Optional_Base& original)
3139{
3140 if (original.has_value()) {
3141 emplace(*original);
3142 }
3143}
3144
3145template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3146inline
3148 BloombergLP::bslmf::MovableRef<Optional_Base> original)
3151: d_allocator(MoveUtil::access(original).get_allocator())
3152{
3153 Optional_Base& lvalue = original;
3154
3155 if (lvalue.has_value()) {
3156 emplace(MoveUtil::move(*lvalue));
3157 }
3158}
3159
3160template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3161template <class t_ANY_TYPE>
3162inline
3164 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3165 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
3166{
3167 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value));
3168}
3169
3170template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3171template <class t_ANY_TYPE>
3172inline
3174 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3175 const Optional_Base<t_ANY_TYPE>& original)
3176{
3177 if (original.has_value()) {
3178 emplace(original.value());
3179 }
3180}
3181
3182template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3183template <class t_ANY_TYPE>
3184inline
3186 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3189 t_ANY_TYPE))
3190{
3191 Optional_Base<t_ANY_TYPE>& lvalue = original;
3192 if (lvalue.has_value()) {
3193 emplace(MoveUtil::move(*lvalue));
3194 }
3195}
3196
3197template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3198template <class t_ANY_TYPE>
3199inline
3201 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3204 t_ANY_TYPE))
3205: d_allocator(MoveUtil::access(original).get_allocator())
3206{
3207 Optional_Base<t_ANY_TYPE>& lvalue = original;
3208 if (lvalue.has_value()) {
3209 emplace(MoveUtil::move(*lvalue));
3210 }
3211}
3212
3213# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3214template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3215template <class t_ANY_TYPE>
3216inline
3218 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3219 const std::optional<t_ANY_TYPE>& original)
3220{
3221 if (original.has_value()) {
3222 emplace(original.value());
3223 }
3224}
3225
3226template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3227template <class t_ANY_TYPE>
3228inline
3230 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
3231 std::optional<t_ANY_TYPE>&& original)
3232{
3233 if (original.has_value()) {
3234 emplace(std::move(original.value()));
3235 }
3236}
3237# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3238
3239#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3240template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3241template <class... t_ARGS>
3242inline
3249
3250# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3251template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3252template <class t_INIT_LIST_TYPE, class... t_ARGS>
3253inline
3256 std::initializer_list<t_INIT_LIST_TYPE> il,
3257 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3258{
3259 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3260}
3261# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3262#endif
3263
3264template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3265inline
3267 bsl::allocator_arg_t,
3268 allocator_type allocator)
3269: d_allocator(allocator)
3270{
3271}
3272
3273template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3274inline
3276 bsl::allocator_arg_t,
3277 allocator_type allocator,
3279: d_allocator(allocator)
3280{
3281}
3282
3283template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3284inline
3286 bsl::allocator_arg_t,
3287 allocator_type allocator,
3288 const Optional_Base& original)
3289: d_allocator(allocator)
3290{
3291 if (original.has_value()) {
3292 emplace(*original);
3293 }
3294}
3295
3296template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3297inline
3299 bsl::allocator_arg_t,
3300 allocator_type allocator,
3301 BloombergLP::bslmf::MovableRef<Optional_Base> original)
3302: d_allocator(allocator)
3303{
3304 Optional_Base& lvalue = original;
3305
3306 if (lvalue.has_value()) {
3307 emplace(MoveUtil::move(*lvalue));
3308 }
3309}
3310
3311template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3312template <class t_ANY_TYPE>
3313inline
3315 bsl::allocator_arg_t,
3316 allocator_type allocator,
3317 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3318 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
3319: d_allocator(allocator)
3320{
3322}
3323
3324template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3325template <class t_ANY_TYPE>
3326inline
3328 bsl::allocator_arg_t,
3329 allocator_type allocator,
3330 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3331 const Optional_Base<t_ANY_TYPE>& original)
3332: d_allocator(allocator)
3333{
3334 if (original.has_value()) {
3335 emplace(original.value());
3336 }
3337}
3338
3339template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3340template <class t_ANY_TYPE>
3341inline
3343 bsl::allocator_arg_t,
3344 allocator_type allocator,
3345 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3347: d_allocator(allocator)
3348{
3349 Optional_Base<t_ANY_TYPE>& lvalue = original;
3350 if (lvalue.has_value()) {
3351 emplace(MoveUtil::move(*lvalue));
3352 }
3353}
3354
3355# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3356template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3357template <class t_ANY_TYPE>
3358inline
3360 bsl::allocator_arg_t,
3361 allocator_type allocator,
3362 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3363 const std::optional<t_ANY_TYPE>& original)
3364: d_allocator(allocator)
3365{
3366 if (original.has_value()) {
3367 emplace(original.value());
3368 }
3369}
3370
3371template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3372template <class t_ANY_TYPE>
3373inline
3375 bsl::allocator_arg_t,
3376 allocator_type allocator,
3377 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
3378 std::optional<t_ANY_TYPE>&& original)
3379: d_allocator(allocator)
3380{
3381 if (original.has_value()) {
3382 emplace(std::move(original.value()));
3383 }
3384}
3385# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3386
3387#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3388template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3389template <class... t_ARGS>
3390inline
3392 bsl::allocator_arg_t,
3393 allocator_type alloc,
3395 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3396: d_allocator(alloc)
3397{
3398 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3399}
3400
3401# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3402template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3403template <class t_INIT_LIST_TYPE, class... t_ARGS>
3404inline
3406 bsl::allocator_arg_t,
3407 allocator_type alloc,
3409 std::initializer_list<t_INIT_LIST_TYPE> il,
3410 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3411: d_allocator(alloc)
3412{
3413 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3414}
3415# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3416#endif
3417
3418// PROTECTED MANIPULATORS
3419template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3420template <class t_ANY_TYPE>
3422 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
3423{
3424 if (has_value()) {
3425 d_value.value() = BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs);
3426 } else {
3427 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs));
3428 }
3429}
3430
3431# ifndef BDE_OMIT_INTERNAL_DEPRECATED
3432template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3434{
3435 // This method is provided for the purpose of allowing 'NullableValue' to
3436 // determine the assert level in its value() method. Do not assert here.
3437
3438 return d_value.value();
3439}
3440
3441// PROTECTED ACCESORS
3442template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3444{
3445 // This method is provided for the purpose of allowing 'NullableValue' to
3446 // determine the assert level in its value() method. Do not assert here.
3447
3448 return d_value.value();
3449}
3450# endif // BDE_OMIT_INTERNAL_DEPRECATED
3451
3452// MANIPULATORS
3453#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3454template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3455template <class... t_ARGS>
3456inline
3458 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3459{
3460 return d_value.emplace(d_allocator.mechanism(),
3461 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3462}
3463
3464# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3465template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3466template <class t_INIT_LIST_TYPE, class... t_ARGS>
3468 std::initializer_list<t_INIT_LIST_TYPE> il,
3469 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3470{
3471 return d_value.emplace(d_allocator.mechanism(),
3472 il,
3473 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3474}
3475# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3476#endif
3477
3478template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3479inline
3484
3485template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3489 bsl::is_nothrow_swappable<t_TYPE>::value)
3490{
3491 BSLS_ASSERT(d_allocator == other.d_allocator);
3492
3493 if (this->has_value() && other.has_value()) {
3494 BloombergLP::bslalg::SwapUtil::swap(
3495 BSLS_UTIL_ADDRESSOF(d_value.value()),
3496 BSLS_UTIL_ADDRESSOF(*other));
3497 }
3498 else if (this->has_value()) {
3499 other.emplace(MoveUtil::move(d_value.value()));
3500 this->reset();
3501 }
3502 else if (other.has_value()) {
3503 this->emplace(MoveUtil::move(*other));
3504 other.reset();
3505 }
3506}
3507
3508# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3509template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3510inline
3512{
3513 if (!has_value())
3514 BSLS_THROW(bsl::bad_optional_access());
3515
3516 return d_value.value();
3517}
3518
3519template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3520inline
3522{
3523 if (!has_value())
3524 BSLS_THROW(bsl::bad_optional_access());
3525
3526 return std::move(d_value.value());
3527}
3528
3529# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3530template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3531inline
3533{
3534 if (!has_value())
3535 BSLS_THROW(bsl::bad_optional_access());
3536
3537 return d_value.value();
3538}
3539
3540# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3541
3542# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3543template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3544template <class t_ANY_TYPE>
3545inline
3547 t_ANY_TYPE&& value) &&
3548{
3549 if (has_value()) {
3550 return t_TYPE(std::move(d_value.value())); // RETURN
3551 }
3552 else {
3553 return t_TYPE(std::forward<t_ANY_TYPE>(value)); // RETURN
3554 }
3555}
3556
3557# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3558template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3559template <class t_ANY_TYPE>
3560inline
3562 bsl::allocator_arg_t,
3563 allocator_type allocator,
3564 t_ANY_TYPE&& value) &&
3565{
3566 if (has_value()) {
3567 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3568 allocator,
3569 std::move(d_value.value())); // RETURN
3570 }
3571 else {
3572 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3573 allocator,
3574 std::forward<t_ANY_TYPE>(value)); // RETURN
3575 }
3576}
3577# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3578# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3579
3580template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3581inline
3582Optional_Base<t_TYPE, t_USES_BSLMA_ALLOC>&
3584{
3585 if (rhs.has_value()) {
3586 if (this->has_value()) {
3587 d_value.value() = *rhs;
3588 }
3589 else {
3590 emplace(*rhs);
3591 }
3592 }
3593 else {
3594 reset();
3595 }
3596 return *this;
3597}
3598
3599template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3600inline
3603 BloombergLP::bslmf::MovableRef<Optional_Base> rhs)
3604{
3605 Optional_Base& lvalue = rhs;
3606
3607 if (lvalue.has_value()) {
3608 if (this->has_value()) {
3609 d_value.value() = MoveUtil::move(*lvalue);
3610 }
3611 else {
3612 emplace(MoveUtil::move(*lvalue));
3613 }
3614 }
3615 else {
3616 reset();
3617 }
3618 return *this;
3619}
3620
3621template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3622inline
3624{
3625 BSLS_ASSERT(has_value());
3626
3627 return BSLS_UTIL_ADDRESSOF(d_value.value());
3628}
3629
3630# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3631template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3632inline
3634{
3635 BSLS_ASSERT(has_value());
3636
3637 return d_value.value();
3638}
3639
3640template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3641inline
3643{
3644 BSLS_ASSERT(has_value());
3645
3646 return std::move(d_value.value());
3647}
3648
3649# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3650template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3651inline
3653{
3654 BSLS_ASSERT(has_value());
3655
3656 return d_value.value();
3657}
3658
3659# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3660
3661// ACCESSORS
3662
3663template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3664inline
3671
3672template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3673inline
3674bool
3677{
3678 return d_value.hasValue();
3679}
3680
3681# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3682template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3683inline
3685{
3686 if (!has_value())
3687 BSLS_THROW(bsl::bad_optional_access());
3688
3689 return d_value.value();
3690}
3691
3692template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3693inline
3695{
3696 if (!has_value())
3697 BSLS_THROW(bsl::bad_optional_access());
3698
3699 return std::move(d_value.value());
3700}
3701
3702# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3703template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3704inline
3706{
3707 if (!has_value())
3708 BSLS_THROW(bsl::bad_optional_access());
3709
3710 return d_value.value();
3711}
3712
3713# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3714
3715# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3716template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3717template <class t_ANY_TYPE>
3718inline
3720 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&
3721{
3722 if (has_value()) {
3723 return t_TYPE(d_value.value()); // RETURN
3724 }
3725 else {
3726 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
3727 value)); // RETURN
3728 }
3729}
3730
3731# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3732template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3733template <class t_ANY_TYPE>
3734inline
3736 bsl::allocator_arg_t,
3737 allocator_type allocator,
3738 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&
3739{
3740 if (has_value()) {
3741 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3742 allocator, d_value.value()); // RETURN
3743 }
3744 else {
3745 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3746 allocator,
3747 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value)); // RETURN
3748 }
3749}
3750# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3751# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3752template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3753template <class t_ANY_TYPE>
3754inline
3756 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
3757{
3758 if (has_value()) {
3759 return t_TYPE(d_value.value()); // RETURN
3760 }
3761 else {
3762 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
3763 value)); // RETURN
3764 }
3765}
3766
3767# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3768template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3769template <class t_ANY_TYPE>
3770inline
3772 bsl::allocator_arg_t,
3773 allocator_type allocator,
3774 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
3775{
3776 if (has_value()) {
3777 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3778 allocator, d_value.value()); // RETURN
3779 }
3780 else {
3781 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
3782 allocator,
3783 BSLS_COMPILERFEATURES_FORWARD(ANY_TYPE, value)); // RETURN
3784 }
3785}
3786# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
3787# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3788
3789template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3790inline
3792{
3793 BSLS_ASSERT(has_value());
3794
3795 return BSLS_UTIL_ADDRESSOF(d_value.value());
3796}
3797
3798# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3799template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3800inline
3802{
3803 BSLS_ASSERT(has_value());
3804
3805 return d_value.value();
3806}
3807
3808template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3809inline
3811{
3812 BSLS_ASSERT(has_value());
3813
3814 return std::move(d_value.value());
3815}
3816
3817# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3818template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3819inline
3821{
3822 BSLS_ASSERT(has_value());
3823
3824 return d_value.value();
3825}
3826# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3827
3828#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
3829template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3832{
3833 return has_value();
3834}
3835#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
3836
3837// ============================================================================
3838// Section: C++17 Allocator-Unaware 'Optional_Base' Method Definitions
3839// ============================================================================
3840
3841 // ==================================
3842 // class Optional_Base<t_TYPE, false>
3843 // ==================================
3844
3845# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3846// PROTECTED CREATORS
3847template <class t_TYPE>
3848inline
3850{
3851}
3852
3853template <class t_TYPE>
3854inline
3856{
3857}
3858
3859template <class t_TYPE>
3860template <class t_ANY_TYPE>
3861inline
3863 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3864 t_ANY_TYPE&& value)
3865: StdOptionalBase(std::forward<t_ANY_TYPE>(value))
3866{
3867}
3868
3869template <class t_TYPE>
3870template <class t_ANY_TYPE>
3871inline
3873 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3874 const Optional_Base<t_ANY_TYPE>& original)
3875{
3876 if (original.has_value()) {
3877 this->emplace(original.value());
3878 }
3879}
3880
3881template <class t_TYPE>
3882template <class t_ANY_TYPE>
3883inline
3885 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3886 Optional_Base<t_ANY_TYPE>&& original)
3887{
3888 if (original.has_value()) {
3889 this->emplace(std::move(original.value()));
3890 }
3891}
3892
3893template <class t_TYPE>
3894template <class t_ANY_TYPE>
3895inline
3897 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3898 const std::optional<t_ANY_TYPE>& original)
3899: StdOptionalBase(original)
3900{
3901}
3902
3903template <class t_TYPE>
3904template <class t_ANY_TYPE>
3905inline
3907 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
3908 std::optional<t_ANY_TYPE>&& original)
3909: StdOptionalBase(std::move(original))
3910{
3911}
3912
3913template <class t_TYPE>
3914template <class... t_ARGS>
3915inline
3917: StdOptionalBase(bsl::in_place, std::forward<t_ARGS>(args)...)
3918{
3919}
3920
3921template <class t_TYPE>
3922template <class t_INIT_LIST_TYPE, class... t_ARGS>
3923inline
3926 std::initializer_list<t_INIT_LIST_TYPE> il,
3927 t_ARGS&&... args)
3928: StdOptionalBase(bsl::in_place, il, std::forward<t_ARGS>(args)...)
3929{
3930}
3931
3932template <class t_TYPE>
3933inline
3934Optional_Base<t_TYPE, false>::Optional_Base(bsl::allocator_arg_t, AllocType)
3935{
3936 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3937}
3938
3939template <class t_TYPE>
3940inline
3942 AllocType,
3944{
3945 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3946}
3947
3948template <class t_TYPE>
3949template <class t_ANY_TYPE>
3950inline
3952 bsl::allocator_arg_t,
3953 AllocType,
3954 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3955 t_ANY_TYPE&&)
3956{
3957 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3958}
3959
3960template <class t_TYPE>
3961template <class t_ANY_TYPE>
3962inline
3964 bsl::allocator_arg_t,
3965 AllocType,
3966 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3967 const Optional_Base<t_ANY_TYPE>&)
3968{
3969 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3970}
3971
3972template <class t_TYPE>
3973template <class t_ANY_TYPE>
3974inline
3976 bsl::allocator_arg_t,
3977 AllocType,
3978 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3979 Optional_Base<t_ANY_TYPE>&&)
3980{
3981 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3982}
3983
3984template <class t_TYPE>
3985template <class t_ANY_TYPE>
3986inline
3988 bsl::allocator_arg_t,
3989 AllocType,
3990 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3991 const std::optional<t_ANY_TYPE>&)
3992{
3993 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
3994}
3995
3996template <class t_TYPE>
3997template <class t_ANY_TYPE>
3998inline
4000 bsl::allocator_arg_t,
4001 AllocType,
4002 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
4003 std::optional<t_ANY_TYPE>&&)
4004{
4005 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4006}
4007
4008template <class t_TYPE>
4009template <class... t_ARGS>
4010inline
4012 AllocType,
4014 t_ARGS&&...)
4015{
4016 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4017}
4018
4019template <class t_TYPE>
4020template <class t_INIT_LIST_TYPE, class... t_ARGS>
4021inline
4023 bsl::allocator_arg_t,
4024 AllocType,
4026 std::initializer_list<t_INIT_LIST_TYPE>,
4028{
4029 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4030}
4031
4032// PROTECTED MANIPULATORS
4033template <class t_TYPE>
4034template <class t_ANY_TYPE>
4036{
4037 StdOptionalBase::operator=(std::forward<t_ANY_TYPE>(rhs));
4038}
4039
4040# ifndef BDE_OMIT_INTERNAL_DEPRECATED
4041template <class t_TYPE>
4043{
4044 // This method is provided for the purpose of allowing 'NullableValue' to
4045 // determine the assert level in its value() method. Do not assert here.
4046
4047 return this->operator*();
4048
4049}
4050
4051// PROTECTED ACCESORS
4052template <class t_TYPE>
4054{
4055 // This method is provided for the purpose of allowing 'NullableValue' to
4056 // determine the assert level in its value() method. Do not assert here.
4057
4058 return this->operator*();
4059
4060}
4061# endif // BDE_OMIT_INTERNAL_DEPRECATED
4062# else // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4063
4064// ============================================================================
4065// Section: Pre-C++17 Allocator-Unaware 'Optional_Base' Method Definitions
4066// ============================================================================
4067
4068// PROTECTED CREATORS
4069template <class t_TYPE>
4070inline
4074
4075template <class t_TYPE>
4076inline
4080
4081template <class t_TYPE>
4082inline
4084{
4085 if (original.has_value()) {
4086 emplace(original.value());
4087 }
4088}
4089
4090template <class t_TYPE>
4091inline
4093 BloombergLP::bslmf::MovableRef<Optional_Base> original)
4096{
4097 Optional_Base& lvalue = original;
4098
4099 if (lvalue.has_value()) {
4100 emplace(MoveUtil::move(*lvalue));
4101 }
4102}
4103
4104template <class t_TYPE>
4105template <class t_ANY_TYPE>
4106inline
4108 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4109 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
4110{
4111 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value));
4112}
4113
4114template <class t_TYPE>
4115template <class t_ANY_TYPE>
4116inline
4118 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4119 const Optional_Base<t_ANY_TYPE>& original)
4120{
4121 if (original.has_value()) {
4122 emplace(original.value());
4123 }
4124}
4125
4126template <class t_TYPE>
4127template <class t_ANY_TYPE>
4128inline
4130 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4132{
4133 Optional_Base<t_ANY_TYPE>& lvalue = original;
4134 if (lvalue.has_value()) {
4135 emplace(MoveUtil::move(*lvalue));
4136 }
4137}
4138
4139#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4140template <class t_TYPE>
4141template <class... t_ARGS>
4142inline
4149
4150# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4151template <class t_TYPE>
4152template <class t_INIT_LIST_TYPE, class... t_ARGS>
4153inline
4156 std::initializer_list<t_INIT_LIST_TYPE> il,
4157 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4158{
4159 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4160}
4161# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4162#endif
4163
4164template <class t_TYPE>
4165inline
4166Optional_Base<t_TYPE, false>::Optional_Base(bsl::allocator_arg_t, AllocType)
4167{
4168 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4169}
4170
4171template <class t_TYPE>
4172inline
4174 AllocType,
4176{
4177 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4178}
4179
4180template <class t_TYPE>
4181inline
4183 AllocType,
4184 const Optional_Base&)
4185{
4186 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4187}
4188
4189template <class t_TYPE>
4190inline
4192 bsl::allocator_arg_t,
4193 AllocType,
4194 BloombergLP::bslmf::MovableRef<Optional_Base>)
4195{
4196 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4197}
4198
4199template <class t_TYPE>
4200template <class t_ANY_TYPE>
4201inline
4203 bsl::allocator_arg_t,
4204 AllocType,
4205 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4207{
4208 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4209}
4210
4211template <class t_TYPE>
4212template <class t_ANY_TYPE>
4213inline
4215 bsl::allocator_arg_t,
4216 AllocType,
4217 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4219{
4220 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4221}
4222
4223template <class t_TYPE>
4224template <class t_ANY_TYPE>
4225inline
4227 bsl::allocator_arg_t,
4228 AllocType,
4229 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4231{
4232 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4233}
4234
4235#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4236template <class t_TYPE>
4237template <class... t_ARGS>
4238inline
4240 bsl::allocator_arg_t,
4241 AllocType,
4244{
4245 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4246}
4247
4248# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4249template <class t_TYPE>
4250template <class t_INIT_LIST_TYPE, class... t_ARGS>
4251inline
4253 bsl::allocator_arg_t,
4254 AllocType,
4256 std::initializer_list<t_INIT_LIST_TYPE>,
4258{
4259 BSLS_ASSERT_INVOKE_NORETURN("Unreachable");
4260}
4261# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4262#endif
4263
4264// PROTECTED MANIPULATORS
4265template <class t_TYPE>
4266template <class t_ANY_TYPE>
4268 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
4269{
4270 if (has_value()) {
4271 d_value.value() = BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs);
4272 } else {
4273 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs));
4274 }
4275}
4276
4277# ifndef BDE_OMIT_INTERNAL_DEPRECATED
4278template <class t_TYPE>
4280{
4281 // This method is provided for the purpose of allowing 'NullableValue' to
4282 // determine the assert level in its value() method. Do not assert here.
4283
4284 return d_value.value();
4285
4286}
4287
4288// PROTECTED ACCESORS
4289template <class t_TYPE>
4291{
4292 // This method is provided for the purpose of allowing 'NullableValue' to
4293 // determine the assert level in its value() method. Do not assert here.
4294
4295 return d_value.value();
4296
4297}
4298# endif // BDE_OMIT_INTERNAL_DEPRECATED
4299
4300// MANIPULATORS
4301#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4302template <class t_TYPE>
4303template <class... t_ARGS>
4304inline
4305t_TYPE&
4307 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4308{
4309 return d_value.emplace(NULL,
4310 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4311}
4312
4313# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4314template <class t_TYPE>
4315template <class t_INIT_LIST_TYPE, class... t_ARGS>
4317 std::initializer_list<t_INIT_LIST_TYPE> il,
4318 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4319{
4320 return d_value.emplace(
4321 NULL, il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4322}
4323# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4324#endif
4325
4326template <class t_TYPE>
4327inline
4329{
4330 d_value.reset();
4331}
4332
4333template <class t_TYPE>
4337 bsl::is_nothrow_swappable<t_TYPE>::value)
4338{
4339 if (this->has_value() && other.has_value()) {
4340 BloombergLP::bslalg::SwapUtil::swap(
4341 BSLS_UTIL_ADDRESSOF(d_value.value()),
4342 BSLS_UTIL_ADDRESSOF(*other));
4343 }
4344 else if (this->has_value()) {
4345 other.emplace(MoveUtil::move(d_value.value()));
4346 this->reset();
4347 }
4348 else if (other.has_value()) {
4349 this->emplace(MoveUtil::move(*other));
4350 other.reset();
4351 }
4352}
4353
4354# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4355template <class t_TYPE>
4356inline
4358{
4359 if (!has_value())
4360 BSLS_THROW(bsl::bad_optional_access());
4361
4362 return d_value.value();
4363}
4364template <class t_TYPE>
4365inline
4366t_TYPE&&
4368{
4369 if (!has_value())
4370 BSLS_THROW(bsl::bad_optional_access());
4371
4372 return std::move(d_value.value());
4373}
4374
4375# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4376template <class t_TYPE>
4377inline
4379{
4380 if (!has_value())
4381 BSLS_THROW(bsl::bad_optional_access());
4382
4383 return d_value.value();
4384}
4385
4386# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4387
4388# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4389template <class t_TYPE>
4390template <class t_ANY_TYPE>
4391inline
4392t_TYPE
4393Optional_Base<t_TYPE, false>::value_or(t_ANY_TYPE&& value) &&
4394{
4395 if (has_value()) {
4396 return t_TYPE(std::move(d_value.value())); // RETURN
4397 }
4398 else {
4399 return t_TYPE(std::forward<t_ANY_TYPE>(value)); // RETURN
4400 }
4401}
4402# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4403
4404template <class t_TYPE>
4405inline
4406Optional_Base<t_TYPE, false>&
4408{
4409 if (rhs.has_value()) {
4410 if (this->has_value()) {
4411 d_value.value() = *rhs;
4412 }
4413 else {
4414 emplace(*rhs);
4415 }
4416 }
4417 else {
4418 reset();
4419 }
4420 return *this;
4421}
4422
4423template <class t_TYPE>
4424inline
4427 BloombergLP::bslmf::MovableRef<Optional_Base> rhs)
4428{
4429 Optional_Base& lvalue = rhs;
4430 if (lvalue.has_value()) {
4431 if (this->has_value()) {
4432 d_value.value() = MoveUtil::move(*lvalue);
4433 }
4434 else {
4435 emplace(MoveUtil::move(*lvalue));
4436 }
4437 }
4438 else {
4439 reset();
4440 }
4441 return *this;
4442}
4443
4444# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4445template <class t_TYPE>
4446inline
4448{
4449 BSLS_ASSERT(has_value());
4450
4451 return d_value.value();
4452}
4453
4454template <class t_TYPE>
4455inline
4457{
4458 BSLS_ASSERT(has_value());
4459
4460 return std::move(d_value.value());
4461}
4462# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4463template <class t_TYPE>
4464inline
4466{
4467 BSLS_ASSERT(has_value());
4468
4469 return d_value.value();
4470}
4471# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4472
4473template <class t_TYPE>
4474inline
4476{
4477 BSLS_ASSERT(has_value());
4478
4479 return BSLS_UTIL_ADDRESSOF(d_value.value());
4480}
4481
4482// ACCESSORS
4483
4484template <class t_TYPE>
4485inline
4487{
4488 return d_value.hasValue();
4489}
4490
4491# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4492template <class t_TYPE>
4493inline
4494const t_TYPE&
4496{
4497 if (!has_value())
4498 BSLS_THROW(bsl::bad_optional_access());
4499
4500 return d_value.value();
4501}
4502
4503template <class t_TYPE>
4504inline
4505const t_TYPE&&
4507{
4508 if (!has_value())
4509 BSLS_THROW(bsl::bad_optional_access());
4510
4511 return std::move(d_value.value());
4512}
4513
4514# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4515template <class t_TYPE>
4516inline
4517const t_TYPE&
4519{
4520 if (!has_value())
4521 BSLS_THROW(bsl::bad_optional_access());
4522
4523 return d_value.value();
4524}
4525
4526# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4527
4528# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4529
4530template <class t_TYPE>
4531template <class t_ANY_TYPE>
4532inline
4533t_TYPE
4535 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
4536const &
4537{
4538 if (has_value()) {
4539 return t_TYPE(d_value.value()); // RETURN
4540 }
4541 else {
4542 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
4543 value)); // RETURN
4544 }
4545}
4546
4547# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4548template <class t_TYPE>
4549template <class t_ANY_TYPE>
4550inline
4551t_TYPE
4553 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
4554const
4555{
4556 if (has_value()) {
4557 return t_TYPE(d_value.value()); // RETURN
4558 }
4559 else {
4560 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
4561 value)); // RETURN
4562 }
4563}
4564
4565# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4566
4567template <class t_TYPE>
4568inline
4570{
4571 BSLS_ASSERT(has_value());
4572
4573 return BSLS_UTIL_ADDRESSOF(d_value.value());
4574}
4575
4576# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4577template <class t_TYPE>
4578inline
4579const t_TYPE& Optional_Base<t_TYPE, false>::operator*() const&
4580{
4581 BSLS_ASSERT(has_value());
4582
4583 return d_value.value();
4584}
4585
4586template <class t_TYPE>
4587inline
4588const t_TYPE&& Optional_Base<t_TYPE, false>::operator*() const&&
4589{
4590 BSLS_ASSERT(has_value());
4591
4592 return std::move(d_value.value());
4593}
4594
4595# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4596template <class t_TYPE>
4597inline
4599{
4600 BSLS_ASSERT(has_value());
4601
4602 return d_value.value();
4603}
4604# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4605
4606#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
4607template <class t_TYPE>
4609{
4610 return has_value();
4611}
4612#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
4613# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4614
4615} // close package namespace
4616
4617
4618// ============================================================================
4619// Section: 'optional' Method Definitions
4620// ============================================================================
4621
4622 // ==============
4623 // class optional
4624 // ==============
4625
4626namespace bsl {
4627
4628// CREATORS
4629template <class t_TYPE>
4634
4635template <class t_TYPE>
4640
4641#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
4642template <class t_TYPE>
4643template <class t_DERIVED>
4645 BloombergLP::bslmf::MovableRef<t_DERIVED> original,
4649: BaseType(MoveUtil::move(static_cast<BaseType&>(original)))
4650{
4651}
4652#endif
4653
4654template <class t_TYPE>
4655template <class t_ANY_TYPE>
4657 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
4660: BaseType(BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
4661 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
4662{
4663}
4664
4665template <class t_TYPE>
4666template <class t_ANY_TYPE>
4668 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
4671: BaseType(BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
4672 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
4673{
4674}
4675
4676template <class t_TYPE>
4677template <class t_ANY_TYPE>
4679 const optional<t_ANY_TYPE>& original,
4681 const t_ANY_TYPE&),
4683 const t_ANY_TYPE&))
4684: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
4685 original)
4686{
4687}
4688
4689template <class t_TYPE>
4690template <class t_ANY_TYPE>
4692 const optional<t_ANY_TYPE>& original,
4694 const t_ANY_TYPE&),
4695 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE&))
4696: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
4697 original)
4698{
4699}
4700
4701template <class t_TYPE>
4702template <class t_ANY_TYPE>
4707: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
4708 MoveUtil::move(
4709 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
4710 original)))
4711{
4712}
4713
4714template <class t_TYPE>
4715template <class t_ANY_TYPE>
4720: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
4721 MoveUtil::move(
4722 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
4723 original)))
4724{
4725}
4726
4727#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4728template <class t_TYPE>
4729template <class t_ANY_TYPE>
4731 const std::optional<t_ANY_TYPE>& original,
4733 const t_ANY_TYPE&),
4735: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
4736 original)
4737{
4738}
4739
4740template <class t_TYPE>
4741template <class t_ANY_TYPE>
4743 const std::optional<t_ANY_TYPE>& original,
4745 const t_ANY_TYPE&),
4747: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
4748 original)
4749{
4750}
4751
4752template <class t_TYPE>
4753template <class t_ANY_TYPE>
4755 std::optional<t_ANY_TYPE>&& original,
4758: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
4759 std::move(original))
4760{
4761}
4762
4763template <class t_TYPE>
4764template <class t_ANY_TYPE>
4766 std::optional<t_ANY_TYPE>&& original,
4769: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
4770 std::move(original))
4771{
4772}
4773# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4774
4775#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4776template <class t_TYPE>
4777template <class... t_ARGS>
4783#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4784template <class t_TYPE>
4785template <class t_INIT_LIST_TYPE, class... t_ARGS>
4787 std::initializer_list<t_INIT_LIST_TYPE> il,
4788 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4789: BaseType(bsl::in_place, il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
4790{
4791}
4792#endif
4793#endif
4794
4795template <class t_TYPE>
4796optional<t_TYPE>::optional(bsl::allocator_arg_t, AllocType allocator)
4797: BaseType(bsl::allocator_arg, allocator)
4798{
4799}
4800
4801template <class t_TYPE>
4802optional<t_TYPE>::optional(bsl::allocator_arg_t,
4803 AllocType allocator,
4805: BaseType(bsl::allocator_arg, allocator)
4806{
4807}
4808
4809template <class t_TYPE>
4810optional<t_TYPE>::optional(bsl::allocator_arg_t,
4811 AllocType allocator,
4812 const optional& original)
4813: BaseType(bsl::allocator_arg, allocator, original)
4814{
4815}
4816
4817template <class t_TYPE>
4818template <class t_DERIVED>
4819optional<t_TYPE>::optional(bsl::allocator_arg_t,
4820 AllocType allocator,
4821 BSLMF_MOVABLEREF_DEDUCE(t_DERIVED) original,
4823 typename bsl::remove_reference<t_DERIVED>::type))
4824: BaseType(bsl::allocator_arg_t(),
4825 allocator,
4826 MoveUtil::move(static_cast<BaseType&>(original)))
4827{
4828 // Implementation Note: The @ref remove_reference in the signature is needed
4829 // to work around a bug in GCC 10. (It has not been determined whether
4830 // other versions are affected.)
4831}
4832
4833template <class t_TYPE>
4834template <class t_ANY_TYPE>
4836 bsl::allocator_arg_t,
4837 AllocType allocator,
4838 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
4841: BaseType(bsl::allocator_arg_t(),
4842 allocator,
4843 BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
4844 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
4845{
4846}
4847
4848template <class t_TYPE>
4849template <class t_ANY_TYPE>
4851 bsl::allocator_arg_t,
4852 AllocType allocator,
4853 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
4856: BaseType(bsl::allocator_arg_t(),
4857 allocator,
4858 BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
4859 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
4860{
4861}
4862
4863template <class t_TYPE>
4864template <class t_ANY_TYPE>
4866 bsl::allocator_arg_t,
4867 AllocType allocator,
4868 const optional<t_ANY_TYPE>& original,
4870 const t_ANY_TYPE&),
4872 const t_ANY_TYPE&))
4873: BaseType(bsl::allocator_arg_t(),
4874 allocator,
4875 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
4876 original)
4877{
4878}
4879
4880template <class t_TYPE>
4881template <class t_ANY_TYPE>
4883 bsl::allocator_arg_t,
4884 AllocType allocator,
4885 const optional<t_ANY_TYPE>& original,
4887 const t_ANY_TYPE&),
4888 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE&))
4889: BaseType(bsl::allocator_arg_t(),
4890 allocator,
4891 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
4892 original)
4893{
4894}
4895
4896template <class t_TYPE>
4897template <class t_ANY_TYPE>
4899 bsl::allocator_arg_t,
4900 AllocType allocator,
4904: BaseType(bsl::allocator_arg_t(),
4905 allocator,
4906 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
4907 MoveUtil::move(
4908 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
4909 original)))
4910{
4911}
4912
4913template <class t_TYPE>
4914template <class t_ANY_TYPE>
4916 bsl::allocator_arg_t,
4917 AllocType allocator,
4921: BaseType(bsl::allocator_arg_t(),
4922 allocator,
4923 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
4924 MoveUtil::move(
4925 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
4926 original)))
4927{
4928}
4929
4930#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4931template <class t_TYPE>
4932template <class t_ANY_TYPE>
4934 bsl::allocator_arg_t,
4935 AllocType allocator,
4936 const std::optional<t_ANY_TYPE>& original,
4938 const t_ANY_TYPE&),
4940 const t_ANY_TYPE&))
4941: BaseType(bsl::allocator_arg_t(),
4942 allocator,
4943 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
4944 original)
4945{
4946}
4947
4948template <class t_TYPE>
4949template <class t_ANY_TYPE>
4951 bsl::allocator_arg_t,
4952 AllocType allocator,
4953 const std::optional<t_ANY_TYPE>& original,
4955 const t_ANY_TYPE&),
4956 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE))
4957: BaseType(bsl::allocator_arg_t(),
4958 allocator,
4959 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
4960 original)
4961{
4962}
4963
4964template <class t_TYPE>
4965template <class t_ANY_TYPE>
4967 bsl::allocator_arg_t,
4968 AllocType allocator,
4969 std::optional<t_ANY_TYPE>&& original,
4972: BaseType(bsl::allocator_arg_t(),
4973 allocator,
4974 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
4975 std::move(original))
4976{
4977}
4978
4979template <class t_TYPE>
4980template <class t_ANY_TYPE>
4982 bsl::allocator_arg_t,
4983 AllocType allocator,
4984 std::optional<t_ANY_TYPE>&& original,
4987: BaseType(bsl::allocator_arg_t(),
4988 allocator,
4989 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
4990 std::move(original))
4991{
4992}
4993# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4994
4995#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4996template <class t_TYPE>
4997template <class... t_ARGS>
4999 bsl::allocator_arg_t,
5000 AllocType allocator,
5002 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5003: BaseType(bsl::allocator_arg,
5004 allocator,
5005 bsl::in_place,
5006 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
5007{
5008}
5009#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5010template <class t_TYPE>
5011template <class t_INIT_LIST_TYPE, class... t_ARGS>
5013 bsl::allocator_arg_t,
5014 AllocType allocator,
5016 std::initializer_list<t_INIT_LIST_TYPE> il,
5017 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5018: BaseType(bsl::allocator_arg,
5019 allocator,
5020 bsl::in_place,
5021 il,
5022 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
5023{
5024}
5025#endif
5026#endif
5027
5028// MANIPULATORS
5029template <class t_TYPE>
5030optional<t_TYPE>&
5032{
5033 this->reset();
5034 return *this;
5035}
5036
5037#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5038template <class t_TYPE>
5039template <class t_DERIVED>
5041optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_DERIVED> rhs)
5042{
5043 BaseType& lvalue = rhs;
5044 BaseType::operator=(MoveUtil::move(lvalue));
5045 return *this;
5046}
5047#endif
5048
5049template <class t_TYPE>
5050template <class t_ANY_TYPE>
5053{
5054 if (rhs.has_value()) {
5055 this->assignOrEmplace(*rhs);
5056 } else {
5057 this->reset();
5058 }
5059 return *this;
5060}
5061
5062template <class t_TYPE>
5063template <class t_ANY_TYPE>
5066{
5067 BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>& lvalue = rhs;
5068 if (lvalue.has_value()) {
5069 this->assignOrEmplace(MoveUtil::move(*lvalue));
5070 } else {
5071 this->reset();
5072 }
5073 return *this;
5074}
5075
5076#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5077template <class t_TYPE>
5078template <class t_ANY_TYPE>
5080optional<t_TYPE>::operator=(t_ANY_TYPE&& rhs)
5081{
5082 this->assignOrEmplace(std::forward<t_ANY_TYPE>(rhs));
5083 return *this;
5084}
5085#else
5086template <class t_TYPE>
5088{
5089 this->assignOrEmplace(rhs);
5090 return *this;
5091}
5092
5093template <class t_TYPE>
5095optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_TYPE> rhs)
5096{
5097 this->assignOrEmplace(MoveUtil::move(rhs));
5098 return *this;
5099}
5100
5101template <class t_TYPE>
5102template <class t_ANY_TYPE>
5104optional<t_TYPE>::operator=(const t_ANY_TYPE& rhs)
5105{
5106 this->assignOrEmplace(rhs);
5107 return *this;
5108}
5109
5110template <class t_TYPE>
5111template <class t_ANY_TYPE>
5113optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_ANY_TYPE> rhs)
5114{
5115 this->assignOrEmplace(MoveUtil::move(rhs));
5116 return *this;
5117}
5118#endif // RVALUES else
5119
5120#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5121template <class t_TYPE>
5122template <class t_ANY_TYPE>
5123BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(t_TYPE, const t_ANY_TYPE&)&
5124optional<t_TYPE>::operator=(const std::optional<t_ANY_TYPE>& rhs)
5125{
5126 if (rhs.has_value()) {
5127 this->assignOrEmplace(*rhs);
5128 } else {
5129 this->reset();
5130 }
5131 return *this;
5132}
5133
5134template <class t_TYPE>
5135template <class t_ANY_TYPE>
5137optional<t_TYPE>::operator=(std::optional<t_ANY_TYPE>&& rhs)
5138{
5139 if (rhs.has_value()) {
5140 this->assignOrEmplace(std::move(*rhs));
5141 } else {
5142 this->reset();
5143 }
5144 return *this;
5145}
5146# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5147
5148// ============================================================================
5149// Section: Free Function Definitions
5150// ============================================================================
5151
5152template <class t_TYPE>
5153inline
5155 void>::type
5157{
5158 if (lhs.get_allocator() == rhs.get_allocator()) {
5159 lhs.swap(rhs);
5160
5161 return; // RETURN
5162 }
5163
5164 bsl::optional<t_TYPE> futureLhs(
5165 bsl::allocator_arg, lhs.get_allocator(), rhs);
5166 bsl::optional<t_TYPE> futureRhs(
5167 bsl::allocator_arg, rhs.get_allocator(), lhs);
5168
5169 futureLhs.swap(lhs);
5170 futureRhs.swap(rhs);
5171}
5172
5173template <class t_TYPE>
5174inline
5176 void>::type
5178{
5179 lhs.swap(rhs);
5180}
5181
5182// HASH SPECIALIZATIONS
5183template <class t_HASHALG, class t_TYPE>
5184void hashAppend(t_HASHALG& hashAlg, const bsl::optional<t_TYPE>& input)
5185{
5186 using ::BloombergLP::bslh::hashAppend;
5187
5188 if (input.has_value()) {
5189 hashAppend(hashAlg, true);
5190 hashAppend(hashAlg, *input);
5191 }
5192 else {
5193 hashAppend(hashAlg, false);
5194 }
5195}
5196
5197// FREE OPERATORS
5198
5199template <class t_LHS_TYPE, class t_RHS_TYPE>
5200bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
5201 const bsl::optional<t_RHS_TYPE>& rhs)
5202 BSLSTL_OPTIONAL_REQUIRES(requires {
5203 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5204 })
5205{
5206 if (lhs.has_value() && rhs.has_value()) {
5207 return *lhs == *rhs; // RETURN
5208 }
5209 return lhs.has_value() == rhs.has_value();
5210}
5211
5212template <class t_LHS_TYPE, class t_RHS_TYPE>
5214 const bsl::optional<t_RHS_TYPE>& rhs)
5215 BSLSTL_OPTIONAL_REQUIRES(requires {
5216 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5217 })
5218{
5219 if (lhs.has_value() && rhs.has_value()) {
5220 return *lhs != *rhs; // RETURN
5221 }
5222
5223 return lhs.has_value() != rhs.has_value();
5224}
5225
5226template <class t_LHS_TYPE, class t_RHS_TYPE>
5227bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
5228 const bsl::optional<t_RHS_TYPE>& rhs)
5229 BSLSTL_OPTIONAL_REQUIRES(requires {
5230 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5231 })
5232{
5233 if (!rhs.has_value()) {
5234 return false; // RETURN
5235 }
5236
5237 return !lhs.has_value() || *lhs < *rhs;
5238}
5239
5240template <class t_LHS_TYPE, class t_RHS_TYPE>
5241bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
5242 const bsl::optional<t_RHS_TYPE>& rhs)
5243 BSLSTL_OPTIONAL_REQUIRES(requires {
5244 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5245 })
5246{
5247 if (!lhs.has_value()) {
5248 return false; // RETURN
5249 }
5250
5251 return !rhs.has_value() || *lhs > *rhs;
5252}
5253
5254template <class t_LHS_TYPE, class t_RHS_TYPE>
5256 const bsl::optional<t_RHS_TYPE>& rhs)
5257 BSLSTL_OPTIONAL_REQUIRES(requires {
5258 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5259 })
5260{
5261 if (!lhs.has_value()) {
5262 return true; // RETURN
5263 }
5264
5265 return rhs.has_value() && *lhs <= *rhs;
5266}
5267
5268template <class t_LHS_TYPE, class t_RHS_TYPE>
5270 const bsl::optional<t_RHS_TYPE>& rhs)
5271 BSLSTL_OPTIONAL_REQUIRES(requires {
5272 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5273 })
5274{
5275 if (!rhs.has_value()) {
5276 return true; // RETURN
5277 }
5278 return lhs.has_value() && *lhs >= *rhs;
5279}
5280
5281// comparison with 'nullopt_t'
5282
5283template <class t_TYPE>
5284inline
5286 const bsl::optional<t_TYPE>& value,
5288{
5289 return !value.has_value();
5290}
5291
5292#if !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) && \
5293 defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
5294template <class t_TYPE>
5295inline
5297 const bsl::nullopt_t&,
5299{
5300 return !value.has_value();
5301}
5302
5303template <class t_TYPE>
5304inline
5306 const bsl::optional<t_TYPE>& value,
5308{
5309 return value.has_value();
5310}
5311
5312template <class t_TYPE>
5313inline
5315 const bsl::nullopt_t&,
5317{
5318 return value.has_value();
5319}
5320
5321template <class t_TYPE>
5322inline
5324 const bsl::optional<t_TYPE>&,
5326{
5327 return false;
5328}
5329
5330template <class t_TYPE>
5331inline
5333 const bsl::nullopt_t&,
5335{
5336 return value.has_value();
5337}
5338
5339template <class t_TYPE>
5340inline
5342 const bsl::optional<t_TYPE>& value,
5344{
5345 return value.has_value();
5346}
5347
5348template <class t_TYPE>
5349inline
5351 const bsl::nullopt_t&,
5353{
5354 return false;
5355}
5356
5357template <class t_TYPE>
5358inline
5360 const bsl::optional<t_TYPE>& value,
5362{
5363 return !value.has_value();
5364}
5365
5366template <class t_TYPE>
5367inline
5369 const bsl::nullopt_t&,
5371{
5372 return true;
5373}
5374
5375template <class t_TYPE>
5376inline
5378 const bsl::optional<t_TYPE>&,
5380{
5381 return true;
5382}
5383
5384template <class t_TYPE>
5385inline
5387 const bsl::nullopt_t&,
5389{
5390 return !value.has_value();
5391}
5392#endif // !(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS &&
5393 // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON)
5394
5395// comparison with 'value_type'
5396
5397template <class t_LHS_TYPE, class t_RHS_TYPE>
5398bool operator==(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5400 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5401 && requires {
5402 { *lhs == rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5403 })
5404{
5405 return lhs.has_value() && *lhs == rhs;
5406}
5407
5408template <class t_LHS_TYPE, class t_RHS_TYPE>
5409bool operator==(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5411 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5412 && requires {
5413 { lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5414 })
5415{
5416 return rhs.has_value() && lhs == *rhs;
5417}
5418
5419template <class t_LHS_TYPE, class t_RHS_TYPE>
5420bool operator!=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5422 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5423 && requires {
5424 { *lhs != rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5425 })
5426{
5427 return !lhs.has_value() || *lhs != rhs;
5428}
5429
5430template <class t_LHS_TYPE, class t_RHS_TYPE>
5431bool operator!=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5433 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5434 && requires {
5435 { lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5436 })
5437{
5438 return !rhs.has_value() || lhs != *rhs;
5439}
5440
5441template <class t_LHS_TYPE, class t_RHS_TYPE>
5442bool operator<(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5444 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5445 && requires {
5446 { *lhs < rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5447 })
5448{
5449 return !lhs.has_value() || *lhs < rhs;
5450}
5451
5452template <class t_LHS_TYPE, class t_RHS_TYPE>
5453bool operator<(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5455 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5456 && requires {
5457 { lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5458 })
5459{
5460 return rhs.has_value() && lhs < *rhs;
5461}
5462
5463template <class t_LHS_TYPE, class t_RHS_TYPE>
5464bool operator>(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5466 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5467 && requires {
5468 { *lhs > rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5469 })
5470{
5471 return lhs.has_value() && *lhs > rhs;
5472}
5473
5474template <class t_LHS_TYPE, class t_RHS_TYPE>
5475bool operator>(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5477 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5478 && requires {
5479 { lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5480 })
5481{
5482 return !rhs.has_value() || lhs > *rhs;
5483}
5484
5485template <class t_LHS_TYPE, class t_RHS_TYPE>
5486bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5488 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5489 && requires {
5490 { *lhs <= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5491 })
5492{
5493 return !lhs.has_value() || *lhs <= rhs;
5494}
5495
5496template <class t_LHS_TYPE, class t_RHS_TYPE>
5497bool operator<=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5499 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5500 && requires {
5501 { lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5502 })
5503{
5504 return rhs.has_value() && lhs <= *rhs;
5505}
5506
5507template <class t_LHS_TYPE, class t_RHS_TYPE>
5508bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
5510 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
5511 && requires {
5512 { *lhs >= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5513 })
5514{
5515 return lhs.has_value() && *lhs >= rhs;
5516}
5517
5518template <class t_LHS_TYPE, class t_RHS_TYPE>
5519bool operator>=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
5521 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
5522 && requires {
5523 { lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5524 })
5525{
5526 return !rhs.has_value() || lhs >= *rhs;
5527}
5528
5529#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
5530 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
5531template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
5532constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
5533 const bsl::optional<t_LHS>& lhs,
5534 const bsl::optional<t_RHS>& rhs)
5535{
5536 const bool lhs_has_value = lhs.has_value(),
5537 rhs_has_value = rhs.has_value();
5538 if (lhs_has_value && rhs_has_value) {
5539 return *lhs <=> *rhs;
5540 }
5541 return lhs_has_value <=> rhs_has_value;
5542}
5543
5544template <class t_LHS, class t_RHS>
5545requires (!BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS>) &&
5546 three_way_comparable_with<t_LHS, t_RHS>
5547constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
5548 const bsl::optional<t_LHS>& lhs,
5549 const t_RHS& rhs)
5550{
5551 if (lhs) {
5552 return *lhs <=> rhs;
5553 }
5554 return strong_ordering::less;
5555}
5556
5557template <class t_TYPE>
5558constexpr strong_ordering operator<=>(const bsl::optional<t_TYPE>& value,
5560{
5561 return value.has_value() <=> false;
5562}
5563
5564template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
5565constexpr compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
5566 const bsl::optional<t_LHS>& lhs,
5567 const std::optional<t_RHS>& rhs)
5568{
5569 const bool lhs_has_value = lhs.has_value(),
5570 rhs_has_value = rhs.has_value();
5571 if (lhs_has_value && rhs_has_value) {
5572 return *lhs <=> *rhs;
5573 }
5574 return lhs_has_value <=> rhs_has_value;
5575}
5576#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON &&
5577 // BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
5578
5579# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5580template <class t_TYPE>
5581inline
5583 void>::type
5584swap(bsl::optional<t_TYPE>& lhs, std::optional<t_TYPE>& rhs)
5585{
5586 lhs.swap(rhs);
5587}
5588
5589template <class t_TYPE>
5590inline
5592 void>::type
5593swap(std::optional<t_TYPE>& lhs, bsl::optional<t_TYPE>& rhs)
5594{
5595 lhs.swap(rhs);
5596}
5597
5598// comparison with 'std::optional'
5599
5600template <class t_LHS_TYPE, class t_RHS_TYPE>
5601inline
5603 const std::optional<t_RHS_TYPE>& rhs)
5604{
5605 if (lhs.has_value() && rhs.has_value()) {
5606 return *lhs == *rhs;
5607 }
5608 return lhs.has_value() == rhs.has_value();
5609}
5610
5611template <class t_LHS_TYPE, class t_RHS_TYPE>
5612inline
5613bool operator==(const std::optional<t_LHS_TYPE>& lhs,
5614 const bsl::optional<t_RHS_TYPE>& rhs)
5615{
5616 if (lhs.has_value() && rhs.has_value()) {
5617 return *lhs == *rhs;
5618 }
5619 return lhs.has_value() == rhs.has_value();
5620}
5621
5622template <class t_LHS_TYPE, class t_RHS_TYPE>
5623inline
5625 const std::optional<t_RHS_TYPE>& rhs)
5626{
5627 if (lhs.has_value() && rhs.has_value()) {
5628 return *lhs != *rhs;
5629 }
5630
5631 return lhs.has_value() != rhs.has_value();
5632}
5633
5634template <class t_LHS_TYPE, class t_RHS_TYPE>
5635inline
5636bool operator!=(const std::optional<t_LHS_TYPE>& lhs,
5637 const bsl::optional<t_RHS_TYPE>& rhs)
5638{
5639 if (lhs.has_value() && rhs.has_value()) {
5640 return *lhs != *rhs;
5641 }
5642
5643 return lhs.has_value() != rhs.has_value();
5644}
5645
5646template <class t_LHS_TYPE, class t_RHS_TYPE>
5647inline
5648bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
5649 const std::optional<t_RHS_TYPE>& rhs)
5650{
5651 if (!rhs.has_value()) {
5652 return false; // RETURN
5653 }
5654
5655 return !lhs.has_value() || *lhs < *rhs;
5656}
5657
5658template <class t_LHS_TYPE, class t_RHS_TYPE>
5659inline
5660bool operator<(const std::optional<t_LHS_TYPE>& lhs,
5661 const bsl::optional<t_RHS_TYPE>& rhs)
5662{
5663 if (!rhs.has_value()) {
5664 return false; // RETURN
5665 }
5666
5667 return !lhs.has_value() || *lhs < *rhs;
5668}
5669
5670template <class t_LHS_TYPE, class t_RHS_TYPE>
5671inline
5672bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
5673 const std::optional<t_RHS_TYPE>& rhs)
5674{
5675 if (!lhs.has_value()) {
5676 return false; // RETURN
5677 }
5678
5679 return !rhs.has_value() || *lhs > *rhs;
5680}
5681
5682template <class t_LHS_TYPE, class t_RHS_TYPE>
5683inline
5684bool operator>(const std::optional<t_LHS_TYPE>& lhs,
5685 const bsl::optional<t_RHS_TYPE>& rhs)
5686{
5687 if (!lhs.has_value()) {
5688 return false; // RETURN
5689 }
5690
5691 return !rhs.has_value() || *lhs > *rhs;
5692}
5693
5694template <class t_LHS_TYPE, class t_RHS_TYPE>
5695inline
5697 const std::optional<t_RHS_TYPE>& rhs)
5698{
5699 if (!lhs.has_value()) {
5700 return true; // RETURN
5701 }
5702
5703 return rhs.has_value() && *lhs <= *rhs;
5704}
5705
5706template <class t_LHS_TYPE, class t_RHS_TYPE>
5707inline
5708bool operator<=(const std::optional<t_LHS_TYPE>& lhs,
5709 const bsl::optional<t_RHS_TYPE>& rhs)
5710{
5711 if (!lhs.has_value()) {
5712 return true; // RETURN
5713 }
5714
5715 return rhs.has_value() && *lhs <= *rhs;
5716}
5717
5718template <class t_LHS_TYPE, class t_RHS_TYPE>
5719inline
5721 const std::optional<t_RHS_TYPE>& rhs)
5722{
5723 if (!rhs.has_value()) {
5724 return true; // RETURN
5725 }
5726 return lhs.has_value() && *lhs >= *rhs;
5727}
5728
5729template <class t_LHS_TYPE, class t_RHS_TYPE>
5730inline
5731bool operator>=(const std::optional<t_LHS_TYPE>& lhs,
5732 const bsl::optional<t_RHS_TYPE>& rhs)
5733{
5734 if (!rhs.has_value()) {
5735 return true; // RETURN
5736 }
5737 return lhs.has_value() && *lhs >= *rhs;
5738}
5739# endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5740
5741template <class t_TYPE>
5743make_optional(bsl::allocator_arg_t,
5744 const typename bsl::optional<
5745 typename bsl::decay<t_TYPE>::type>::allocator_type& alloc,
5747{
5749 bsl::allocator_arg,
5750 alloc,
5752 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, rhs));
5753}
5754
5755#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5756template <class t_TYPE, class... t_ARGS>
5758 bsl::allocator_arg_t,
5759 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
5760 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5761{
5762 return bsl::optional<t_TYPE>(
5763 bsl::allocator_arg,
5764 alloc,
5766 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
5767}
5768#endif
5769
5770#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5771# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) && \
5772 !(defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
5773template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
5775 bsl::allocator_arg_t,
5776 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
5777 std::initializer_list<t_INIT_LIST_TYPE> il,
5778 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5779{
5780 return bsl::optional<t_TYPE>(
5781 bsl::allocator_arg,
5782 alloc,
5784 il,
5785 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
5786}
5787# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5788#endif
5789
5790template <class t_TYPE>
5797
5798template <class t_TYPE>
5803
5804#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5805template <class t_TYPE, class t_ARG, class... t_ARGS>
5809{
5810 return bsl::optional<t_TYPE>(
5813 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
5814}
5815
5816# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS) && \
5817 !(defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
5818template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
5820 std::initializer_list<t_INIT_LIST_TYPE> il,
5821 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5822{
5823 return bsl::optional<t_TYPE>(
5825 il,
5826 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
5827}
5828# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5829#endif
5830} // close namespace bsl
5831
5832// There is a problem in the standard definition of the is-optional concept
5833// that results in types inheriting from std::optional not being identified
5834// correctly as optional types. The end result is endless recursion evaluating
5835// the requires clause for the spaceship operator when it is implemented
5836// according to the C++20 specification, which currently happens for GCC 11-13
5837// and MSVC-2022 prior to MSVC 19.36 when building with C++20. In MSVC 19.36
5838// Microsoft implemented the solution suggested in LWG-3746, so the workaround
5839// is not required for that and subsequent versions.
5840//
5841// The issue with the standard is tracked here:
5842// https://cplusplus.github.io/LWG/lwg-active.html#3746
5843//
5844// See DRQS 170388558 for more information
5845//
5846// BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED and
5847// BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED are deliberately
5848// exposed to allow their use in higher level optional types (i.e.,
5849// bdlb::NullableValue).
5850
5851// The following hacks prevent compiler crashes, and should only be applied on
5852// compiler versions where the problem is not fixed. The hacks required for
5853// gcc and for MSVC are different due to different standard library
5854// implementations, hence the two distinct macros and implementations.
5855
5856# if BSLS_COMPILERFEATURES_CPLUSPLUS==202002L && \
5857 defined(BSLS_LIBRARYFEATURES_STDCPP_GNU) && \
5858 (11 <= _GLIBCXX_RELEASE && _GLIBCXX_RELEASE < 14)
5859
5860#define BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
5861
5862namespace std {
5863template<typename _Tp>
5864inline constexpr bool __is_optional_v<bsl::optional<_Tp>> = true;
5865}
5866
5867# endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
5868
5869# if BSLS_COMPILERFEATURES_CPLUSPLUS == 202002L && \
5870 defined(BSLS_PLATFORM_CMP_MSVC) && \
5871 (BSLS_PLATFORM_CMP_VERSION >= 1930 && BSLS_PLATFORM_CMP_VERSION < 1936)
5872 // This workaround is not required from MSVC 19.36 onwards.
5873
5874#define BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
5875
5876namespace std {
5877template <typename _Tp>
5878inline constexpr bool _Is_specialization_v<bsl::optional<_Tp>, std::optional> =
5879 true;
5880}
5881
5882# endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
5883
5884#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL
5885#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL
5886#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL
5887#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL
5888#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR
5889#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR
5890#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR
5891#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR
5892#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM
5893#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM
5894#undef BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL
5895#undef BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT
5896#undef BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT
5897#undef BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT
5898#undef BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT
5899#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL
5900#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL
5901#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED
5902#undef BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG
5903#undef BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG
5904#undef BSLSTL_OPTIONAL_REQUIRES
5905
5906#endif // End C++11 code
5907
5908#endif // INCLUDED_BSLSTL_OPTIONAL
5909
5910// ----------------------------------------------------------------------------
5911// Copyright 2020 Bloomberg Finance L.P.
5912//
5913// Licensed under the Apache License, Version 2.0 (the "License");
5914// you may not use this file except in compliance with the License.
5915// You may obtain a copy of the License at
5916//
5917// http://www.apache.org/licenses/LICENSE-2.0
5918//
5919// Unless required by applicable law or agreed to in writing, software
5920// distributed under the License is distributed on an "AS IS" BASIS,
5921// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5922// See the License for the specific language governing permissions and
5923// limitations under the License.
5924// ----------------------------- END-OF-FILE ----------------------------------
5925
5926/** @} */
5927/** @} */
5928/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION_IF(t_TYPE, t_TRAIT, t_COND)
Definition bslmf_nestedtraitdeclaration.h:243
Definition bslma_bslallocator.h:580
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1126
decay_imp< U, k_ISARRAY, k_ISFUNC >::type type
Definition bslmf_decay.h:166
Definition bslstl_optional.h:1861
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslmf::UsesAllocatorArgT, BloombergLP::bslma::UsesBslmaAllocator< t_TYPE >::value)
optional() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:4630
BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(t_TYPE, t_ANY_TYPE) &operator
optional(bsl::allocator_arg_t, AllocType allocator)
Definition bslstl_optional.h:4796
BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED(t_TYPE, t_DERIVED) &operator
optional(bsl::allocator_arg_t, AllocType allocator, BSLMF_MOVABLEREF_DEDUCE(t_DERIVED) original, BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(typename bsl::remove_reference< t_DERIVED >::type))
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslmf::IsBitwiseCopyable, BloombergLP::bslmf::IsBitwiseCopyable< t_TYPE >::value)
BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE) &operator
optional(bsl::allocator_arg_t, AllocType allocator, BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional(BSLMF_MOVABLEREF_DEDUCE(optional< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional(bsl::allocator_arg_t, AllocType allocator, BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional & operator=(const t_TYPE &rhs)
Definition bslstl_optional.h:5087
optional(bsl::allocator_arg_t, AllocType allocator, const optional &original)
Definition bslstl_optional.h:4810
optional & operator=(bsl::nullopt_t) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:5031
optional(BSLMF_MOVABLEREF_DEDUCE(optional< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional(bsl::allocator_arg_t, AllocType allocator, bsl::nullopt_t)
Definition bslstl_optional.h:4802
optional & operator=(BloombergLP::bslmf::MovableRef< t_TYPE > rhs)
Definition bslstl_optional.h:5095
optional(bsl::allocator_arg_t, AllocType allocator, BSLMF_MOVABLEREF_DEDUCE(optional< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional(BloombergLP::bslmf::MovableRef< t_DERIVED > original, BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(t_DERIVED)) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl optional(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
optional(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslma::UsesBslmaAllocator, BloombergLP::bslma::UsesBslmaAllocator< t_TYPE >::value)
optional(bsl::allocator_arg_t, AllocType allocator, bsl::in_place_t, BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:4998
optional(bsl::allocator_arg_t, AllocType allocator, const optional< t_ANY_TYPE > &original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE &))
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslmf::IsBitwiseMoveable, BloombergLP::bslmf::IsBitwiseMoveable< t_TYPE >::value)
optional(bsl::in_place_t, BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:4778
optional(const optional< t_ANY_TYPE > &original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE &))
optional(bsl::allocator_arg_t, AllocType allocator, const optional< t_ANY_TYPE > &original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &), BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE &))
optional(const optional< t_ANY_TYPE > &original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE &))
optional(bsl::allocator_arg_t, AllocType allocator, BSLMF_MOVABLEREF_DEDUCE(optional< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE), BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &) &operator
Definition bslma_allocator.h:457
void swap(Optional_Base &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl t_TYPE & value()
Definition bslstl_optional.h:1730
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Base, BloombergLP::bslmf::IsBitwiseCopyable, BloombergLP::bslmf::IsBitwiseCopyable< t_TYPE >::value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Base, BloombergLP::bslmf::IsBitwiseMoveable, BloombergLP::bslmf::IsBitwiseMoveable< t_TYPE >::value)
Optional_Base(BloombergLP::bslmf::MovableRef< Optional_Base > original) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef, BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
t_TYPE value_type
Definition bslstl_optional.h:1665
Definition bslstl_optional.h:803
Optional_Base()
Definition bslstl_optional.h:3125
const t_TYPE & value() const
t_TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:3457
Optional_Base & operator=(const Optional_Base &rhs)
Definition bslstl_optional.h:3583
void assignOrEmplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
Definition bslstl_optional.h:3421
t_TYPE & dereferenceRaw()
Definition bslstl_optional.h:3433
allocator_type AllocType
Definition bslstl_optional.h:818
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return false if this object is disengaged, and true otherwise.
Definition bslstl_optional.h:3675
t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
Definition bslstl_optional.h:3755
void swap(Optional_Base &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl t_TYPE & value()
Definition bslstl_optional.h:1158
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return allocator used for construction of value_type.
Definition bslstl_optional.h:3666
BSLMF_NESTED_TRAIT_DECLARATION(Optional_Base, BloombergLP::bslmf::UsesAllocatorArgT)
t_TYPE & operator*()
Definition bslstl_optional.h:3652
void reset() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:3480
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Base, BloombergLP::bslmf::IsBitwiseCopyable, BloombergLP::bslmf::IsBitwiseCopyable< t_TYPE >::value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Base, BloombergLP::bslmf::IsBitwiseMoveable, BloombergLP::bslmf::IsBitwiseMoveable< t_TYPE >::value)
BSLMF_NESTED_TRAIT_DECLARATION(Optional_Base, BloombergLP::bslma::UsesBslmaAllocator)
Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional, BSLMF_MOVABLEREF_DEDUCE(Optional_Base< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR(t_TYPE, t_ANY_TYPE))
Optional_Base(BloombergLP::bslmf::MovableRef< Optional_Base > original) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef, BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
t_TYPE value_type
Definition bslstl_optional.h:812
bsl::allocator< char > allocator_type
Definition bslstl_optional.h:814
t_TYPE * operator->()
Definition bslstl_optional.h:3623
Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional, BSLMF_MOVABLEREF_DEDUCE(Optional_Base< t_ANY_TYPE >) original, BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(t_TYPE, t_ANY_TYPE))
#define BSLMF_MOVABLEREF_DEDUCE(...)
Definition bslmf_movableref.h:690
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:1895
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2012
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_THROW(X)
Definition bsls_exceptionutil.h:374
#define BSLS_NOTHROW_SPEC
Definition bsls_exceptionutil.h:386
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:609
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:381
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:295
#define BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED)
Definition bslstl_optional.h:351
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, ANY_TYPE)
Definition bslstl_optional.h:321
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:389
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( TYPE, ANY_TYPE)
Definition bslstl_optional.h:327
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE)
Definition bslstl_optional.h:340
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:287
#define BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:371
#define BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG(ARG)
Definition bslstl_optional.h:426
#define BSLSTL_OPTIONAL_REQUIRES(EXPR)
Definition bslstl_optional.h:442
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE)
Definition bslstl_optional.h:346
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:308
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(TYPE, ANY_TYPE)
Definition bslstl_optional.h:417
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, ANY_TYPE)
Definition bslstl_optional.h:314
#define BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(DERIVED)
Definition bslstl_optional.h:357
#define BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:366
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:301
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_FORWARD_REF(TYPE, ANY_TYPE)
Definition bslstl_optional.h:406
#define BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:376
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( TYPE, ANY_TYPE)
Definition bslstl_optional.h:334
#define BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:361
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED(TYPE, DERIVED)
Definition bslstl_optional.h:398
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void swap(OptionValue &a, OptionValue &b)
bool operator<(const MetricId &lhs, const MetricId &rhs)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
bool operator>=(const Guid &lhs, const Guid &rhs)
bool operator<=(const Guid &lhs, const Guid &rhs)
bool operator>(const Guid &lhs, const Guid &rhs)
Decimal32 operator*(Decimal32 lhs, Decimal32 rhs)
Definition bdlb_printmethods.h:283
const nullopt_t nullopt
bool operator==(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator==(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator!=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator!=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator<(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator<(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator>(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator>(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator<=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator<=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator>=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP bool operator>=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLS_KEYWORD_CONSTEXPR bsl::optional< typename bsl::decay< t_TYPE >::type > make_optional(bsl::allocator_arg_t, const typename bsl::optional< typename bsl::decay< t_TYPE >::type >::allocator_type &alloc, BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) rhs)
Definition bslstl_optional.h:2881
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:950
const in_place_t in_place
Definition balxml_encoderoptions.h:68
Definition bslstl_algorithm.h:82
Definition bdldfp_decimal.h:5188
Definition bslmf_enableif.h:525
Definition bslstl_inplace.h:99
Definition bslmf_integralconstant.h:244
Definition bslmf_isnothrowmoveconstructible.h:358
Definition bslmf_issame.h:146
Definition bslstl_optional.h:467
BSLS_KEYWORD_CONSTEXPR nullopt_t(t_TYPE, typename enable_if< is_same< t_TYPE, BloombergLP::bslstl::Optional_NulloptConstructToken >::value, int >::type=0) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:475
t_TYPE type
This typedef is an alias to the (template parameter) t_TYPE.
Definition bslmf_removeconst.h:161
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisecopyable.h:298
Definition bslstl_optional.h:615
Definition bslstl_optional.h:604
Definition bslstl_optional.h:616
Definition bslstl_optional.h:618
Definition bslstl_optional.h:635
t_TYPE & emplace(bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:2989
Optional_DataImp() BSLS_KEYWORD_NOEXCEPT
Create an empty Optional_DataImp object.
Definition bslstl_optional.h:2979
bool hasValue() const BSLS_KEYWORD_NOEXCEPT
Return true if this objects has a value, and false otherwise.
Definition bslstl_optional.h:3066
t_TYPE & value()
Definition bslstl_optional.h:3054
void reset() BSLS_KEYWORD_NOEXCEPT
Destroy the value_type object in d_buffer, if any.
Definition bslstl_optional.h:3023
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Data, bslmf::IsBitwiseCopyable, bslmf::IsBitwiseCopyable< t_TYPE >::value)
Definition bslstl_optional.h:724
~Optional_Data()
Destroy the managed value_type object, if it exists.
Definition bslstl_optional.h:3109
Definition bslstl_optional.h:521
Definition bslstl_optional.h:617
Definition bslstl_optional.h:619
Definition bslstl_optional.h:449
Definition bslstl_optional.h:551
BSLS_KEYWORD_CONSTEXPR Optional_OptNoSuchType(int) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:563
Definition bslstl_optional.h:585
Definition bsls_objectbuffer.h:276