BDE 4.39.x 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-canonical-header"> Canonical Header </a>
28/// * <a href="#bslstl_optional-description"> Description </a>
29/// * <a href="#bslstl_optional-sections"> Sections: </a>
30/// * <a href="#bslstl_optional-usage"> Usage </a>
31/// * <a href="#bslstl_optional-known-limitations"> Known limitations </a>
32///
33/// # Purpose {#bslstl_optional-purpose}
34/// Provide a standard-compliant allocator aware optional type.
35///
36/// # Classes {#bslstl_optional-classes}
37///
38/// - bsl::optional: template class for optional objects
39///
40/// # Canonical Header {#bslstl_optional-canonical-header}
41/// bsl_optional.h
42///
43/// # Description {#bslstl_optional-description}
44/// This component provides a template class,
45/// `bsl::optional<TYPE>`, that implements a notion of object that may or may
46/// not contain a `TYPE` value. This template class also provides an interface
47/// to check if the optional object contains a value or not, as well as a
48/// contextual conversion to `bool`. If an optional object is engaged, i.e.
49/// contains a value, it will evaluate to `true` when converted to `bool`;
50/// otherwise, it will evaluate to `false` when converted to `bool`.
51///
52/// An optional object is engaged if it has been initialized with, or assigned
53/// from an object of `TYPE` or another engaged optional object, or if the value
54/// was created using the `emplace` method. Other types of assignment and
55/// initialization (including default initialization), as well as calling
56/// `reset` method will result in the optional object being disengaged.
57///
58/// If the underlying `TYPE` has value-semantics, then so will the type
59/// `bsl::optional<TYPE>`. Two homogeneous optional objects have the same value
60/// if their underlying (non-null) `TYPE` values are the same, or both are null.
61///
62/// Note that the object of template parameter `TYPE` that is managed by a
63/// `bsl::optional<TYPE>` object is created *in*-*place*. Consequently, the
64/// template parameter `TYPE` must be a complete type when the class is
65/// instantiated.
66///
67/// In addition to the standard homogeneous, value-semantic, operations such as
68/// copy/move construction, copy/move assignment, equality comparison, and
69/// relational operators, `bsl::optional` also supports conversion between
70/// optional types for which the underlying types are convertible, i.e., for
71/// heterogeneous copy construction, copy assignment, and equality comparison
72/// (e.g., between `int` and `double`); attempts at conversion between
73/// incompatible types, such as `int` and `bsl::string`, will fail to compile.
74///
75/// For allocator-aware types, bsl::optional uses the same allocator for all
76/// `value_type` objects it manages during its lifetime.
77///
78/// ## Sections: {#bslstl_optional-sections}
79///
80///
81/// This file is very complex, a navigation map of this file can be obtained by:
82/// `$ grep -n Section: bslstl_optional.h`
83///
84/// ## Usage {#bslstl_optional-usage}
85///
86///
87/// The following snippets of code illustrate use of this component:
88///
89/// First, create a `optional` `int` object:
90/// @code
91/// bsl::optional<int> optionalInt;
92/// assert(!optionalInt.has_value());
93/// @endcode
94/// Next, give the `int` object the value 123 (making it non-null):
95/// @code
96/// optionalInt.emplace(123);
97/// assert( optionalInt.has_value());
98/// assert(123 == optionalInt.value());
99/// @endcode
100/// Finally, reset the object to its default constructed state (i.e., null):
101/// @code
102/// optionalInt.reset();
103/// assert(!optionalInt.has_value());
104/// @endcode
105///
106/// ## Known limitations {#bslstl_optional-known-limitations}
107///
108///
109/// * For assignment/construction constraints, we use `is_constructible` but
110/// the exact creation will be done using allocation construction that will
111/// invoke an allocator-extended constructor for allocator-aware types.
112/// If the `value_type` is constructible from the assignment/constructor
113/// argument, but doesn't have a corresponding allocator-extended
114/// constructor, the overload selection may not be be correct.
115/// * `optional<const TYPE>` is fully supported in C++11 and onwards. However,
116/// due to limitations of `MovableRef<const TYPE>`, C++03 support for const
117/// `value_type`s is limited and move semantics of such an `optional` in
118/// C++03 will not work.
119/// @}
120/** @} */
121/** @} */
122
123/** @addtogroup bsl
124 * @{
125 */
126/** @addtogroup bslstl
127 * @{
128 */
129/** @addtogroup bslstl_optional
130 * @{
131 */
132
133#include <bslscm_version.h>
134
136#include <bslstl_compare.h>
137#include <bslstl_hash.h>
138#include <bslstl_inplace.h>
139
140#include <bslalg_swaputil.h>
141
142#include <bslma_aatypeutil.h>
144#include <bslma_default.h>
146#include <bslma_bslallocator.h>
148
149#include <bslmf_allocatorargt.h>
150#include <bslmf_conjunction.h>
151#include <bslmf_decay.h>
156#include <bslmf_isconvertible.h>
159#include <bslmf_issame.h>
160#include <bslmf_movableref.h>
162#include <bslmf_removeconst.h>
163#include <bslmf_removecvref.h>
164#include <bslmf_util.h> // 'forward(V)'
165
166#include <bsls_assert.h>
168#include <bsls_exceptionutil.h>
169#include <bsls_keyword.h>
170#include <bsls_libraryfeatures.h>
171#include <bsls_objectbuffer.h>
172#include <bsls_platform.h>
173#include <bsls_unspecifiedbool.h>
174#include <bsls_util.h> // 'forward<T>(V)'
175
176#include <stddef.h>
177
178#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
179# include <bslmf_if.h>
180#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
181
182#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
183# include <type_traits>
184#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
185
186#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
187//In C++17, bsl::optional for non-aa types inherits from std::optional
188# include <optional>
189#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
190
191#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
192# include <initializer_list>
193#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
194
195#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
196# include <functional> // `std::invoke`
197#endif
198
199#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
200// clang-format off
201// Include version that can be compiled with C++03
202// Generated on Tue May 27 19:17:51 2025
203// Command line: sim_cpp11_features.pl bslstl_optional.h
204
205# define COMPILING_BSLSTL_OPTIONAL_H
206# include <bslstl_optional_cpp03.h>
207# undef COMPILING_BSLSTL_OPTIONAL_H
208
209// clang-format on
210#else
211
212// ============================================================================
213// Section: BSLSTL_OPTIONAL_* Macros
214// ============================================================================
215
216#if defined (BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) && \
217 !(defined(BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED) && \
218 (BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED < 17))
219
220/// The following macro `BSLSTL_OPTIONAL_USES_STD_ALIASES` controls whether
221/// platform standard library is used as a basis for `bsl` types in the
222/// following ways:
223/// - `bsl::nullopt` is an alias to `std::nullopt`
224///
225/// - `bsl::optional<T>` inherits from `std::optional<T>` when `T` is not
226/// allocator-aware.
227///
228/// This macro does *not* control whether there are conversions and comparisons
229/// between `std::optional` and `bsl::optional`, that is conditioned only on
230/// whether `std::optional` is available (i.e.,
231/// `BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY` is defined).
232# define BSLSTL_OPTIONAL_USES_STD_ALIASES
233
234/// `BSLSTL_OPTIONAL_CONSTEXPR17` controls whether constructors that are
235/// `constexpr` in C++17 `std::optional` are `constexpr` in `bsl::optional`
236/// for allocator-unaware types.
237# define BSLSTL_OPTIONAL_CONSTEXPR17 constexpr
238
239/// `BSLSTL_OPTIONAL_CONSTEXPR20` controls whether constructors that are
240/// `constexpr` in C++20 `std::optional` are `constexpr` in `bsl::optional`
241/// for allocator-unaware types.
242# ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
243# define BSLSTL_OPTIONAL_CONSTEXPR20 BSLS_KEYWORD_CONSTEXPR_CPP20
244# else
245# define BSLSTL_OPTIONAL_CONSTEXPR20
246# endif
247#else
248# define BSLSTL_OPTIONAL_CONSTEXPR17
249# define BSLSTL_OPTIONAL_CONSTEXPR20
250#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY & not disabled
251
252# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
253
254// This macro is defined as 'std::is_constructible<U, V>::value' in C++11 and
255// later, and as 'DEFAULT' in C++03 with the value of 'DEFAULT' typically
256// chosen to not affect the constraint this macro appears in. Note that
257// 'is_constructible', unlike 'is_convertible', is 'true' for both implicitly
258// and explicitly constructible conversions.
259#define BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(U, V, DEFAULT) \
260 std::is_constructible<U, V>::value
261
262// This macro is defined as 'std::is_assignable<U, V>::value' in C++11 and
263// later, and as 'DEFAULT' in C++03 with the value of 'DEFAULT' typically
264// chosen to not affect the constraint this macro appears in.
265#define BSLSTL_OPTIONAL_IS_ASSIGNABLE(U, V, DEFAULT) \
266 std::is_assignable<U, V>::value
267
268# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
269
270#define BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(U, V, DEFAULT) DEFAULT
271
272#define BSLSTL_OPTIONAL_IS_ASSIGNABLE(U, V, DEFAULT) DEFAULT
273
274# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
275
276// As in 'std' implementation, if the 'TYPE' converts from any value category
277// of an optional type 'OPT_TYPE', we consider it convertible from that
278// optional type.
279#define BSLSTL_OPTIONAL_CONVERTS_FROM(TYPE, OPT_TYPE) \
280 (bsl::is_convertible<const OPT_TYPE&, TYPE>::value || \
281 bsl::is_convertible<OPT_TYPE&, TYPE>::value || \
282 bsl::is_convertible<const OPT_TYPE, TYPE>::value || \
283 bsl::is_convertible<OPT_TYPE, TYPE>::value || \
284 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, const OPT_TYPE&, false) || \
285 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, OPT_TYPE&, false) || \
286 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, const OPT_TYPE, false) || \
287 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, OPT_TYPE, false))
288
289// As in 'std' implementation, if the 'TYPE' can be assigned to from any value
290// category of an optional type 'OPT_TYPE', we consider it convertible from
291// that optional type.
292# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
293#define BSLSTL_OPTIONAL_ASSIGNS_FROM(TYPE, OPT_TYPE) \
294 (std::is_assignable<TYPE&, const OPT_TYPE&>::value || \
295 std::is_assignable<TYPE&, OPT_TYPE&>::value || \
296 std::is_assignable<TYPE&, const OPT_TYPE>::value || \
297 std::is_assignable<TYPE&, OPT_TYPE>::value)
298
299# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
300// The value of this macro is chosen so it does not affect the disjunction-form
301// constraint this macro appears in.
302#define BSLSTL_OPTIONAL_ASSIGNS_FROM(TYPE, OPT_TYPE) false
303# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
304
305#define BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
306 BSLSTL_OPTIONAL_CONVERTS_FROM( \
307 TYPE, \
308 bsl::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
309
310#define BSLSTL_OPTIONAL_ASSIGNS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
311 BSLSTL_OPTIONAL_ASSIGNS_FROM( \
312 TYPE, \
313 bsl::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
314
315# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
316#define BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
317 BSLSTL_OPTIONAL_CONVERTS_FROM( \
318 TYPE, \
319 std::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
320
321#define BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
322 BSLSTL_OPTIONAL_ASSIGNS_FROM( \
323 TYPE, \
324 std::optional<typename bsl::remove_cvref<ANY_TYPE>::type>)
325# else // BSLSTL_OPTIONAL_USES_STD_ALIASES
326// The value of these macros is chosen to not affect the constraints these
327// macros appears in.
328#define BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) false
329#define BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) false
330
331# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES else
332
333// Macros to define common constraints that enable a constructor or assignment
334// operator.
335#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, \
336 ANY_TYPE) \
337 typename bsl::enable_if< \
338 !bsl::is_same<TYPE, ANY_TYPE>::value && \
339 !BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) && \
340 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true), \
341 BloombergLP::bslstl::Optional_OptNoSuchType>::type
342
343#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, \
344 ANY_TYPE) \
345 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL( \
346 TYPE, \
347 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
348
349#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, \
350 ANY_TYPE) \
351 typename bsl::enable_if< \
352 !BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) && \
353 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true), \
354 BloombergLP::bslstl::Optional_OptNoSuchType>::type
355
356#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, \
357 ANY_TYPE) \
358 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL( \
359 TYPE, \
360 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
361
362#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, \
363 ANY_TYPE) \
364 typename bsl::enable_if< \
365 BloombergLP::bslstl::Optional_PropagatesAllocator<TYPE, \
366 ANY_TYPE>::value, \
367 BloombergLP::bslstl::Optional_OptNoSuchType>::type
368
369#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, \
370 ANY_TYPE) \
371 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR( \
372 TYPE, \
373 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
374
375#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
376 TYPE, ANY_TYPE) \
377 typename bsl::enable_if< \
378 !BloombergLP::bslstl::Optional_PropagatesAllocator<TYPE, \
379 ANY_TYPE>::value, \
380 BloombergLP::bslstl::Optional_OptNoSuchType>::type
381
382#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
383 TYPE, ANY_TYPE) \
384 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( \
385 TYPE, \
386 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
387
388#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE) \
389 typename bsl::enable_if< \
390 BloombergLP::bslstl::Optional_ConstructsFromType<TYPE, \
391 ANY_TYPE>::value, \
392 BloombergLP::bslstl::Optional_OptNoSuchType>::type
393
394#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE) \
395 BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM( \
396 TYPE, \
397 ANY_TYPE) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
398
399#define BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED) \
400 typename bsl::enable_if< \
401 BloombergLP::bslmf::IsAccessibleBaseOf<optional, DERIVED>::value && \
402 !bsl::is_const<DERIVED>::value, \
403 BloombergLP::bslstl::Optional_OptNoSuchType>::type
404
405#define BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(DERIVED) \
406 BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED) = \
407 BloombergLP::bslstl::Optional_OptNoSuchType(0)
408
409#define BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(U, V) \
410 typename bsl::enable_if< \
411 !bsl::is_convertible<V, U>::value, \
412 BloombergLP::bslstl::Optional_OptNoSuchType>::type
413
414#define BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(U, V) \
415 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT( \
416 U, \
417 V) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
418
419#define BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT(U, V) \
420 typename bsl::enable_if< \
421 bsl::is_convertible<V, U>::value, \
422 BloombergLP::bslstl::Optional_OptNoSuchType>::type
423
424#define BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(U, V) \
425 BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT( \
426 U, \
427 V) = BloombergLP::bslstl::Optional_OptNoSuchType(0)
428
429#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) \
430 typename bsl::enable_if< \
431 !BSLSTL_OPTIONAL_CONVERTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE) && \
432 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true) && \
433 BSLSTL_OPTIONAL_IS_ASSIGNABLE(TYPE&, ANY_TYPE, true) && \
434 !BSLSTL_OPTIONAL_ASSIGNS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE), \
435 optional<TYPE> >::type
436
437#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) \
438 typename bsl::enable_if< \
439 !BSLSTL_OPTIONAL_CONVERTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE) && \
440 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(TYPE, ANY_TYPE, true) && \
441 BSLSTL_OPTIONAL_IS_ASSIGNABLE(TYPE&, ANY_TYPE, true) && \
442 !BSLSTL_OPTIONAL_ASSIGNS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE), \
443 optional<TYPE> >::type
444
445# if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
446# define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED(TYPE, DERIVED) \
447 typename bsl::enable_if< \
448 BloombergLP::bslmf::IsAccessibleBaseOf<bsl::optional<TYPE>, \
449 DERIVED>::value && \
450 !bsl::is_same<bsl::optional<TYPE>, DERIVED>::value, \
451 optional<TYPE> >::type
452# endif
453
454#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_FORWARD_REF(TYPE, ANY_TYPE) \
455 typename bsl::enable_if< \
456 !bsl::is_same<bsl::optional<TYPE>, \
457 typename bsl::remove_cvref<ANY_TYPE>::type>::value && \
458 !(bsl::is_same<TYPE, \
459 typename bsl::decay<ANY_TYPE>::type>::value && \
460 std::is_scalar<TYPE>::value) && \
461 std::is_constructible<TYPE, ANY_TYPE>::value && \
462 std::is_assignable<TYPE, ANY_TYPE>::value, \
463 optional<TYPE> >::type
464
465#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(TYPE, ANY_TYPE) \
466 typename bsl::enable_if< \
467 !::BloombergLP::bslmf::IsAccessibleBaseOf< \
468 bsl::optional<TYPE>, \
469 typename bsl::remove_cv< \
470 typename ::BloombergLP::bslmf::MovableRefUtil:: \
471 RemoveReference<ANY_TYPE>::type>::type>::value, \
472 optional<TYPE> >::type
473
474#define BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG(ARG) \
475 typename bsl::enable_if< \
476 !bsl::is_same< \
477 typename bsl::remove_cvref<ARG>::type, \
478 bsl::allocator_arg_t>::value, \
479 optional<t_TYPE> >::type
480
481#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS
482 #define BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(ARG) = ARG
483#else
484 #define BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(ARG)
485#endif
486
487#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
488 #define BSLSTL_OPTIONAL_REQUIRES(EXPR) requires(EXPR)
489#else
490 #define BSLSTL_OPTIONAL_REQUIRES(EXPR)
491#endif
492
493
494namespace bslstl {
495/// This trivial tag type is used to create `nullopt_t` objects prior to
496/// C++17.
497///
498/// See @ref bslstl_optional
501} // close package namespace
502
503
504namespace bsl {
505
506# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
507
508using nullopt_t = std::nullopt_t;
509using std::nullopt;
510
511# else // BSLSTL_OPTIONAL_USES_STD_ALIASES
512
513 // ================
514 // struct nullopt_t
515 // ================
516
517/// This trivial tag type is used to create `optional` objects in a disengaged
518/// state. It uses a constructor template to avoid being constructible from
519/// any braced list. See implementation notes for more information.
520///
521/// See @ref bslstl_optional
522struct nullopt_t {
523
524 // CREATORS
525
526 /// Create a `nullopt_t` object.
527 /// \note Note that the argument is not used.
528 template <class t_TYPE>
530 t_TYPE,
531 typename enable_if<is_same<t_TYPE,
532 BloombergLP::bslstl::
533 Optional_NulloptConstructToken>::value,
534 int>::type = 0) BSLS_KEYWORD_NOEXCEPT
535 {
536 }
537};
538
539/// Value of type `nullopt_t` used as an argument to functions that take a
540/// `nullopt_t` argument.
541# if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES)
542inline constexpr
543nullopt_t nullopt(BloombergLP::bslstl::Optional_NulloptConstructToken{});
544# else
545extern const nullopt_t nullopt;
546# endif
547
548# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
549
550template <class t_TYPE>
551class optional;
552
553} // close namespace bsl
554
555// ============================================================================
556// Section: bslstl::Optional_* Utility Classes
557// ============================================================================
558
559
560namespace bslstl {
561
562 // =============================
563 // struct Optional_IsBslOptional
564 // =============================
565
566template <class t_TYPE>
569
570template <class t_TYPE>
571struct Optional_IsBslOptional<bsl::optional<t_TYPE> > : bsl::true_type {
572};
573
574 // =======================================
575 // struct Optional_IsTriviallyDestructible
576 // =======================================
577
578# ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
579
580/// This metafunction is derived from
581/// `std::is_trivially_destructible<t_TYPE>` in C++11 and later. In C++03,
582/// the metafunction is derived from `bsl::is_trivially_copyable`, a trait
583/// that implies the type is also trivially destructible.
584template <class t_TYPE>
586: std::is_trivially_destructible<t_TYPE> {
587};
588
589# else // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
590
591/// C++03 does not provide a trivially destructible trait. Instead we use
592/// `bslmf::IsBitwiseCopyable` which implies the type is also trivially
593/// destructible.
594///
595///
596/// \note Note that we use `bslmf::IsBitwiseCopyable` here and not
597/// `bsl::is_trivially_copyable` because on some platforms, the native
598/// `std::is_trivially_copyable<Optional_Data<t_TYPE, true>>` is `false` even
599/// though it has no dtor and `TYPE` is trivally copyable.
600template <class t_TYPE>
603
604# endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY else
605
606 // ============================
607 // class Optional_OptNoSuchType
608 // ============================
609
610/// This component-private trivial tag type is used to distinguish between
611/// arguments passed by a user, and an `enable_if` argument. It is not default
612/// constructible so the following construction never invokes a constrained
613/// single parameter constructor:
614/// @code
615/// optional<SomeType> o(int, {});
616/// @endcode
617///
618/// See @ref bslstl_optional
620
621 // CREATORS
622
623 /// Create an `Optional_OptNoSuchType` object.
624 /// \note Note that the argument is
625 /// not used.
628};
629
630// CREATORS
631inline
636
637 // ==================================
638 // class Optional_PropagatesAllocator
639 // ==================================
640
641/// This metafunction is derived from `bsl::true_type` if `t_TYPE` is an
642/// allocator-aware const type, and if `t_ANY_TYPE` is the same as `t_TYPE`,
643/// minus the cv qualification. This trait is used to enable a constructor
644/// overload for a const qualified allocator-aware `ValueType` taking an rvalue
645/// of Optional_Base of the non-const qualified `ValueType`. Such an overload
646/// needs to propagate the allocator.
647template <class t_TYPE, class t_ANY_TYPE>
650 bool,
651 bslma::UsesBslmaAllocator<t_TYPE>::value &&
652 bsl::is_const<t_TYPE>::value &&
653 bsl::is_same<t_ANY_TYPE,
654 typename bsl::remove_cv<t_TYPE>::type>::value> {
655};
656
657/// This metafunction is derived from `bsl::true_type` if `t_ANY_TYPE` is not
658/// derived from `bsl::optional<t_TYPE>`, `t_ANY_TYPE` is not a tag type, and
659/// `t_TYPE` is constructible from `t_ANY_TYPE`.
660template <class t_TYPE, class t_ANY_TYPE>
663 bool,
664 !bslmf::IsAccessibleBaseOf<
665 bsl::optional<t_TYPE>,
666 typename bsl::remove_cvref<t_ANY_TYPE>::type>::value &&
667 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
668 bsl::nullopt_t>::value &&
669 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
670 bsl::in_place_t>::value &&
671 !bsl::is_same<typename bsl::remove_cvref<t_ANY_TYPE>::type,
672 bsl::allocator_arg_t>::value &&
673 BSLSTL_OPTIONAL_IS_CONSTRUCTIBLE(t_TYPE, t_ANY_TYPE, true)> {
674};
675
676#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
677 // ===============================
678 // struct Optional_ImmovableHelper
679 // ===============================
680
681/// This struct is used to implement direct initialization of the private data
682/// member of the `std::optional` class, which makes it possible to support
683/// immovable types returned from the `transform` member function.
684///
685/// See @ref bslstl_optional
686template <class t_TYPE, class t_INVOCABLE, class t_ARG>
687struct Optional_ImmovableHelper {
688 t_INVOCABLE&& invocable;
689 t_ARG&& arg;
690
691 operator t_TYPE()
692 {
693 return std::invoke(std::forward<t_INVOCABLE>(invocable),
694 std::forward<t_ARG>(arg));
695 }
696};
697#endif
698
699 // ===========================
700 // Component-Private Tag Types
701 // ===========================
702
703// The types defined in this section are used to select particular templated
704// constructors of 'class Optional_Base'. This avoids the need to duplicate
705// constraints between 'optional' and 'Optional_Base'.
706
712
713#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
714/// Constructor tag used to implement the `transform` function.
715///
716/// See @ref bslstl_optional
717struct Optional_InvokeConstructorTag {
718 explicit Optional_InvokeConstructorTag() = default;
719};
720#endif
721
722 // ======================
723 // class Optional_DataImp
724 // ======================
725
726/// This component-private `struct` manages a `value_type` object in an
727/// `Optional_Base` object. This class provides an abstraction for `const`
728/// value type. An `Optional_Base` object may contain an object of `const`
729/// type. An assignment to such an `Optional_Base` object should not succeed.
730/// However, unless the `Optional_Base` object itself is `const`, it should be
731/// possible to change the value of the `Optional_Base` object using `emplace`.
732/// In order to allow for that, this class manages a non-const object of
733/// `value_type`, but all the accessors return a `const` adjusted reference to
734/// the managed object.
735///
736/// See @ref bslstl_optional
737template <class t_TYPE>
739
740 private:
741 // PRIVATE TYPES
742 typedef typename bsl::remove_const<t_TYPE>::type StoredType;
743
744 // DATA
745
746 // in-place `TYPE` object
748
749 // `true` if object has a value, and `false` otherwise
750 bool d_hasValue;
751
752 public:
753 // CREATORS
754
755 /// Create an empty `Optional_DataImp` object.
757
758#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
759 /// Create an `Optional_DataImp` object, which contains the result of
760 /// invocation of the specified `invocable` with the specified `arg`.
761 template <class t_INVOCABLE, class t_ARG>
762 Optional_DataImp(Optional_InvokeConstructorTag ,
763 t_INVOCABLE&& invocable,
764 t_ARG&& arg);
765#endif
766
767 // MANIPULATORS
768#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
769 /// Create an object of `StoredType` in `d_buffer` using the specified
770 /// `allocator` and `args` and return a reference providing modifiable
771 /// access to the underlying `t_TYPE` object.
772 template <class... t_ARGS>
773 t_TYPE& emplace(bslma::Allocator *allocator,
774 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
775
776# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
777 /// Create an object of `StoredType` in `d_buffer` using the specified
778 /// `allocator`, @ref initializer_list , and `args`, and return a reference
779 /// providing modifiable access to the underlying `t_TYPE` object.
780 template <class t_INIT_LIST_TYPE, class... t_ARGS>
781 t_TYPE& emplace(
782 bslma::Allocator *allocator,
783 std::initializer_list<t_INIT_LIST_TYPE> initializer_list,
784 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
785# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
786#endif
787
788 /// Destroy the `value_type` object in `d_buffer`, if any.
790
791# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
792 /// Return the `value_type` object in `d_buffer` with const
793 /// qualification adjusted to match that of `t_TYPE`.
794 ///
795 /// \pre The behavior is undefined unless `this->hasValue() == true`.
796 t_TYPE& value() &;
797 t_TYPE&& value() &&;
798# else
799 /// Return the `value_type` object in `d_buffer` with const
800 /// qualification adjusted to match that of `t_TYPE`.
801 ///
802 /// \pre The behavior is undefined unless `this->hasValue() == true`.
803 t_TYPE& value();
804# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
805
806 // ACCESSORS
807
808 /// Return `true` if this objects has a value, and `false` otherwise.
809 bool hasValue() const BSLS_KEYWORD_NOEXCEPT;
810
811# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
812 /// Return the `value_type` object in `d_buffer` with const
813 /// qualification adjusted to match that of `t_TYPE`.
814 ///
815 /// \pre The behavior is undefined unless `this->hasValue() == true`.
816 const t_TYPE& value() const &;
817 const t_TYPE&& value() const &&;
818
819# else
820 /// Return the `value_type` object in `d_buffer` with const qualification adjusted to match that of `t_TYPE`.
821 ///
822 /// \pre The behavior is undefined unless
823 /// `this->hasValue() == true`.
824 const t_TYPE& value() const;
825# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
826};
827
828 // ===================
829 // class Optional_Data
830 // ===================
831
832/// This component-private `struct` manages a `value_type` object in
833/// `Optional_Base` by inheriting from `Optional_DataImp`. In addition,
834/// this primary template properly destroys the owned instance of `t_TYPE`
835/// in its destructor.
836///
837/// See @ref bslstl_optional
838template <
839 class t_TYPE,
840 bool t_IS_TRIVIALLY_DESTRUCTIBLE =
842struct Optional_Data : public Optional_DataImp<t_TYPE> {
843
844 public:
845 // CREATORS
846#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
848#endif
849
850 /// Destroy the managed `value_type` object, if it exists.
852};
853
854 // ===================
855 // class Optional_Data
856 // ===================
857
858/// This partial specialization manages a trivially destructible
859/// `value_type` in Optional_Base. It does not have a user-provided
860/// destructor, which makes it `is_trivially_destructible` itself.
861template <class t_TYPE>
862struct Optional_Data<t_TYPE, true> : public Optional_DataImp<t_TYPE> {
863
864 public:
868
869#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
870 // CREATORS
872#endif
873};
874
875 // ==========================
876 // Component-private concepts
877 // ==========================
878
879#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
880template <class t_TYPE>
881void optional_acceptsBslOptional(const bsl::optional<t_TYPE>&);
882
883template <class t_TYPE>
884void optional_acceptsStdOptional(const std::optional<t_TYPE>&);
885
886// This component-private concept models the Standard's exposition-only
887// `boolean-testable` concept.
888template <class t_TYPE>
889concept Optional_ConvertibleToBool =
890 bsl::is_convertible_v<t_TYPE, bool>;
891
892// This component-private concept is used in the subsequent implementation
893// of the component-private concept `Optional_DerivedFromOptional`.
894template <class t_TYPE>
895concept Optional_DerivedFromBslOptional =
896 requires (const t_TYPE& t) { optional_acceptsBslOptional(t); };
897
898// This component-private concept is used in the subsequent implementation
899// of the component-private concept `Optional_DerivedFromOptional`.
900template <class t_TYPE>
901concept Optional_DerivedFromStdOptional =
902 requires (const t_TYPE& t) { optional_acceptsStdOptional(t); };
903
904/// This component-private concept models whether a type is derived from one
905/// of `std::optional` or `bsl::optional`.
906template <class t_TYPE>
907concept Optional_DerivedFromOptional =
908 Optional_DerivedFromBslOptional<t_TYPE> ||
909 Optional_DerivedFromStdOptional<t_TYPE>;
910#endif
911
912// ============================================================================
913// Section: Definition of Allocator-Aware 'Optional_Base'
914// ============================================================================
915
916 // ===================
917 // class Optional_Base
918 // ===================
919
920/// This component-private class template implements the functionality of
921/// `bsl::optional`. The primary template is instantiated when `TYPE` is
922/// allocator-aware, and holds the allocator that is used to create the
923/// stored object.
924///
925/// See @ref bslstl_optional
926template <class t_TYPE,
927 bool t_USES_BSLMA_ALLOC =
928 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>
930
931 public:
932 // TYPES
933
934 /// `value_type` is an alias for the underlying `TYPE` upon which this
935 /// template class is instantiated, and represents the type of the
936 /// managed object. The name is chosen so it is compatible with the
937 /// `std::optional` implementation.
938 typedef t_TYPE value_type;
939
941
942 protected:
943 // PROTECTED TYPES
945
946 private:
947 // PRIVATE TYPES
948 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
949
950# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
951 // UNSPECIFIED BOOL
952
953 /// This type is needed only in C++03 mode, where `explicit` conversion
954 /// operators are not supported. An `optional` object is contextually
955 /// converted to `UnspecifiedBool` when used in `if` statements, but is not
956 /// implicitly convertible to `bool`.
957 typedef BloombergLP::bsls::UnspecifiedBool<Optional_Base>
958 UnspecifiedBoolUtil;
959 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
960# endif
961
962 // DATA
963
964 // in-place `TYPE` object
965 BloombergLP::bslstl::Optional_Data<t_TYPE> d_value;
966
967 // allocator to be used for all in-place `TYPE` objects
968 allocator_type d_allocator;
969
970 protected:
971 // PROTECTED CREATORS
972
973 /// Create a disengaged `Optional_Base` object. Use the currently
974 /// installed default allocator to supply memory.
976
977 /// Create a disengaged `Optional_Base` object. Use the currently
978 /// installed default allocator to supply memory.
979 Optional_Base(bsl::nullopt_t); // IMPLICIT
980
981 /// Create an `Optional_Base` object having the value of the specified
982 /// `original` object. Use the currently installed default allocator to
983 /// supply memory.
984 Optional_Base(const Optional_Base& original);
985
986 /// Create an `Optional_Base` object having the same value as the
987 /// specified `original` object by moving the contents of `original` to
988 /// the newly-created object. The allocator associated with `original`
989 /// is propagated for use in the newly-created object. `original` is
990 /// left in a valid, but unspecified state.
991 Optional_Base(BloombergLP::bslmf::MovableRef<Optional_Base> original)
994
995 /// Create an `Optional_Base` object whose contained value is
996 /// initialized by forwarding from the specified `value`. Use the
997 /// currently installed default allocator to supply memory.
998 template <class t_ANY_TYPE>
999 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1001
1002 /// Create a disengaged `Optional_Base` object if the specified
1003 /// `original` object is disengaged, and an `Optional_Base` object with
1004 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1005 /// Use the currently installed default allocator to supply memory.
1006 template <class t_ANY_TYPE>
1007 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1008 const Optional_Base<t_ANY_TYPE>& original);
1009
1010 /// Create a disengaged `Optional_Base` object if the specified
1011 /// `original` object is disengaged, and an `Optional_Base` object with
1012 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1013 /// Use the currently installed default allocator to supply memory.
1014 /// `original` is left in a valid but unspecified state.
1015 template <class t_ANY_TYPE>
1017 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1020 t_TYPE,
1021 t_ANY_TYPE));
1022
1023 /// Create a disengaged `Optional_Base` object if the specified
1024 /// `original` object is disengaged, and an `Optional_Base` object with
1025 /// the value of `original.value()` otherwise. This is a special case
1026 /// constructor where `t_ANY_TYPE` is a non-const version of `t_TYPE`
1027 /// and we use the allocator from `original` to supply memory.
1028 /// `original` is left in a valid but unspecified state.
1029 template <class t_ANY_TYPE>
1031 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1034 t_ANY_TYPE));
1035
1036# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
1037 /// Create a disengaged `Optional_Base` object if the specified
1038 /// `original` object is disengaged, and an `Optional_Base` object with
1039 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1040 /// Use the currently installed default allocator to supply memory.
1041 template <class t_ANY_TYPE>
1042 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1043 const std::optional<t_ANY_TYPE>& original);
1044
1045 /// Create a disengaged `Optional_Base` object if the specified
1046 /// `original` object is disengaged, and an `Optional_Base` object with
1047 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1048 /// Use the currently installed default allocator to supply memory.
1049 template <class t_ANY_TYPE>
1050 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1051 std::optional<t_ANY_TYPE>&& original);
1052# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
1053
1054#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1055 /// Create an `Optional_Base` object having the value of the (template
1056 /// parameter) `t_TYPE` created in place using the specified `args`.
1057 /// Use the currently installed default allocator to supply memory.
1058 template <class... t_ARGS>
1060 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1061# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1062 /// Create an `Optional_Base` object having the value of the (template
1063 /// parameter) `t_TYPE` created in place using the specified `il` and
1064 /// specified `args`. Use the currently installed default allocator to
1065 /// supply memory.
1066 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1068 std::initializer_list<t_INIT_LIST_TYPE> il,
1069 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1070# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1071#endif
1072
1073#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1074 /// Create an `Optional_Base` object, which contains the result of
1075 /// invocation of the specified `invocable` with the specified `arg`.
1076 template <class t_INVOCABLE, class t_ARG>
1077 Optional_Base(Optional_InvokeConstructorTag ,
1078 t_INVOCABLE&& invocable,
1079 t_ARG&& arg);
1080#endif
1081
1082 // allocator-extended constructors
1083
1084 /// Create a disengaged `Optional_Base` object. Use the specified
1085 /// `allocator` to supply memory.
1087
1088 /// Create a disengaged `Optional_Base` object. Use the specified
1089 /// `allocator` to supply memory.
1091 allocator_type allocator,
1093
1094 /// If the specified `original` contains a value, create an
1095 /// `Optional_Base` object whose contained value is initialized from
1096 /// `*original`. Otherwise, create a disengaged `Optional_Base` object.
1097 /// Use the specified `allocator` to supply memory.
1099 allocator_type allocator,
1100 const Optional_Base& original);
1101
1102 /// If the specified `original` contains a value, create an
1103 /// `Optional_Base` object whose contained value is initialized by
1104 /// moving `*original`. Otherwise, create a disengaged `Optional_Base`
1105 /// object. Use the specified `allocator` to supply memory. `original`
1106 /// is left in a valid but unspecified state.
1108 allocator_type allocator,
1109 BloombergLP::bslmf::MovableRef<Optional_Base> original);
1110
1111 /// Create an `Optional_Base` object whose contained value is
1112 /// initialized by forwarding from the specified `value`. Use the
1113 /// specified `allocator` to supply memory.
1114 template <class t_ANY_TYPE>
1116 allocator_type allocator,
1117 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1119
1120 /// If the specified `original` contains a value, create an
1121 /// `Optional_Base` object whose contained value is initialized from
1122 /// `*original`, converted to `t_TYPE`. Otherwise, create a disengaged
1123 /// `Optional_Base`. Use the specified `allocator` to supply memory.
1124 template <class t_ANY_TYPE>
1126 allocator_type allocator,
1127 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1128 const Optional_Base<t_ANY_TYPE>& original);
1129
1130 /// If the specified `original` contains a value, create an
1131 /// `Optional_Base` object whose contained value is initialized by
1132 /// moving from `*original` and converting to `t_TYPE`. Otherwise,
1133 /// create a disengaged `Optional_Base`. Use the specified `allocator`
1134 /// to supply memory. `original` is left in a valid but unspecified
1135 /// state.
1136 template <class t_ANY_TYPE>
1138 allocator_type allocator,
1139 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1141
1142# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
1143 /// If the specified `original` contains a value, create an
1144 /// `Optional_Base` object whose contained value is initialized from
1145 /// `*original`, converted to `t_TYPE`. Otherwise, create a disengaged
1146 /// `Optional_Base` object. Use the specified `allocator` to supply
1147 /// memory.
1148 template <class t_ANY_TYPE>
1150 allocator_type allocator,
1151 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1152 const std::optional<t_ANY_TYPE>& original);
1153
1154 /// If the specified `original` contains a value, create an
1155 /// `Optional_Base` object whose contained value is initialized from
1156 /// moving from `*original` and converting to `t_TYPE`. Otherwise,
1157 /// create a disengaged `Optional_Base`. Use the specified `allocator`
1158 /// to supply memory. `original` is left in a valid but unspecified
1159 /// state.
1160 template <class t_ANY_TYPE>
1162 allocator_type allocator,
1163 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1164 std::optional<t_ANY_TYPE>&& original);
1165# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
1166
1167#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1168 /// Create an `Optional_Base` object whose contained value is
1169 /// initialized from the specified `args`. Use the specified
1170 /// `allocator` to supply memory.
1171 template <class... t_ARGS>
1173 allocator_type allocator,
1175 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1176
1177# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1178 /// Create an `Optional_Base` object whose contained value is
1179 /// initialized from the specified `il` and `args`. Use the specified
1180 /// `allocator` to supply memory.
1181 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1183 allocator_type allocator,
1185 std::initializer_list<t_INIT_LIST_TYPE> il,
1186 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1187# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1188#endif
1189
1190 // PROTECTED MANIPULATORS
1191
1192 /// If `*this` holds an object, assign to that object the value of the
1193 /// specified `rhs`, converted to `t_TYPE`. Otherwise, construct a held
1194 /// object from `rhs`, converted to `t_TYPE`. The allocators of `*this`
1195 /// and `rhs` remain unchanged.
1196 template <class t_ANY_TYPE>
1198
1199# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1200 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1201 ///
1202 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1203 ///
1204 /// \note Note that this function is only intended to
1205 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use 'bsl::Optional_Base.
1206 ///
1207 /// \note Note that ref-qualified
1208 /// versions of `value()` are not provided because `NullableValue` does
1209 /// not require them.
1210 t_TYPE& dereferenceRaw();
1211
1212 // PROTECTED ACCESSORS
1213
1214 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
1215 ///
1216 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1217 ///
1218 /// \note Note that this function is only intended to
1219 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use 'bsl::Optional_Base.
1220 ///
1221 /// \note Note that ref-qualified
1222 /// versions of `value()` are not provided because `NullableValue` does
1223 /// not require them.
1224 const t_TYPE& dereferenceRaw() const;
1225# endif // BDE_OMIT_INTERNAL_DEPRECATED
1226
1227 public:
1228 // TRAITS
1230 BloombergLP::bslma::UsesBslmaAllocator);
1232 BloombergLP::bslmf::UsesAllocatorArgT);
1235 BloombergLP::bslmf::IsBitwiseMoveable,
1236 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1239 BloombergLP::bslmf::IsBitwiseCopyable,
1240 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1241
1242 // MANIPULATORS
1243
1244#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1245 /// Assign to this `Optional_Base` object the value of the (template
1246 /// parameter) `t_TYPE` created in place using the specified `args` and
1247 /// return a reference providing modifiable access to the underlying
1248 /// `t_TYPE` object. If this `Optional_Base` object already contains an
1249 /// object (`true == hasValue()`), that object is destroyed before the
1250 /// new object is created. The allocator specified at the construction
1251 /// of this `Optional_Base` object is used to supply memory to the value
1252 /// object. Attempts to explicitly specify via `args` another allocator
1253 /// to supply memory to the created (value) object are disallowed by the compiler.
1254 ///
1255 /// \note Note that if the constructor of `t_TYPE` throws an
1256 /// exception this object is left in a disengaged state.
1257 template <class... t_ARGS>
1258 t_TYPE& emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1259
1260# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1261 /// Assign to this `Optional_Base` object the value of the (template
1262 /// parameter) `t_TYPE` created in place using the specified `il` and
1263 /// specified `args` and return a reference providing modifiable access
1264 /// to the underlying `t_TYPE` object. If this `Optional_Base` object
1265 /// already contains an object (`true == hasValue()`), that object is
1266 /// destroyed before the new object is created. The allocator specified
1267 /// at the construction of this `Optional_Base` object is used to supply
1268 /// memory to the value object. Attempts to explicitly specify via
1269 /// `args` another allocator to supply memory to the created (value) object are disallowed by the compiler.
1270 ///
1271 /// \note Note that if the constructor
1272 /// of `t_TYPE` throws an exception this object is left in a disengaged
1273 /// state.
1274 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1275 t_TYPE& emplace(std::initializer_list<t_INIT_LIST_TYPE> il,
1276 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1277
1278# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1279#endif
1280 /// Reset this object to the default constructed state (i.e., to a
1281 /// disengaged state).
1283
1284 /// Efficiently exchange the value of this object with the value of the
1285 /// specified `other` object. This method provides the no-throw
1286 /// exception-safety guarantee if the template parameter `t_TYPE` provides
1287 /// that guarantee and the result of the `hasValue` method for the two objects being swapped is the same.
1288 ///
1289 /// \pre The behavior is undefined unless
1290 /// this object was created with the same allocator as `other`.
1292 bsl::is_nothrow_move_constructible<t_TYPE>::value &&
1293 bsl::is_nothrow_swappable<t_TYPE>::value);
1294
1295# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1296 /// Return a reference providing modifiable access to the underlying
1297 /// `t_TYPE` object if `true == has_value()` and throw
1298 /// `bsl::bad_optional_access` otherwise.
1299 t_TYPE& value() &;
1300 t_TYPE&& value() &&;
1301# else
1302 /// Return a reference providing modifiable access to the underlying
1303 /// `t_TYPE` object. Throws a `bsl::bad_optional_access` if the
1304 /// `Optional_Base` object is disengaged.
1305 t_TYPE& value();
1306# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1307
1308# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1309 /// Return a copy of the underlying object of a (template parameter)
1310 /// `t_TYPE` if this object is non-null, and the specified `value` converted to `t_TYPE` otherwise.
1311 ///
1312 /// \note Note that this method returns *by*
1313 /// *value*, so may be inefficient in some contexts.
1314 template <class t_ANY_TYPE>
1315 t_TYPE value_or(t_ANY_TYPE&& value) &&;
1316# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1317 /// If this object is non-null, return a copy of the underlying object
1318 /// of a (template parameter) `t_TYPE` created using the provided
1319 /// allocator, and the specified `value` converted to `t_TYPE` using the specified `allocator` otherwise.
1320 ///
1321 /// \note Note that this method returns *by*
1322 /// *value*, so may be inefficient in some contexts.
1323 template <class t_ANY_TYPE>
1326 t_ANY_TYPE&& value) &&;
1327# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1328# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1329
1330 /// Assign to this object the value of the specified `rhs` object, and
1331 /// return a non-`const` reference to this object.
1333
1334 /// Assign to this object the value of the specified `rhs` object, and
1335 /// return a non-`const` reference to this object. The allocators of this
1336 /// object and `rhs` both remain unchanged. The contents of `rhs` are
1337 /// either move-constructed into or move-assigned to this object. `rhs` is
1338 /// left in a valid but unspecified state.
1340 BloombergLP::bslmf::MovableRef<Optional_Base> rhs);
1341
1342 /// Return a pointer providing modifiable access to the underlying `t_TYPE` object.
1343 ///
1344 /// \pre The behavior is undefined if the `Optional_Base` object is
1345 /// disengaged.
1346 t_TYPE *operator->();
1347
1348# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1349 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1350 ///
1351 /// \pre The behavior is undefined if the `Optional_Base`
1352 /// object is disengaged.
1353 t_TYPE& operator*() &;
1354 t_TYPE&& operator*() &&;
1355# else
1356 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1357 ///
1358 /// \pre The behavior is undefined if the `Optional_Base`
1359 /// object is disengaged.
1360 t_TYPE& operator*();
1361# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1362
1363 // ACCESSORS
1364
1365 /// Return allocator used for construction of `value_type`.
1367
1368 /// Return `false` if this object is disengaged, and `true` otherwise.
1369 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
1370
1371# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1372 /// Return a reference providing non-modifiable access to the underlying
1373 /// `t_TYPE` object if `true == has_value()` and throw
1374 /// `bsl::bad_optional_access` otherwise.
1375 const t_TYPE& value() const &;
1376 const t_TYPE&& value() const &&;
1377# else
1378 /// Return a reference providing non-modifiable access to the underlying
1379 /// `t_TYPE` object. Throws a `bsl::bad_optional_access` if the
1380 /// `Optional_Base` object is disengaged.
1381 const t_TYPE& value() const;
1382# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1383
1384 /// Return a pointer providing non-modifiable access to the underlying `t_TYPE` object.
1385 ///
1386 /// \pre The behavior is undefined if the `Optional_Base`
1387 /// object is disengaged.
1388 const t_TYPE *operator->() const;
1389
1390# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1391 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
1392 ///
1393 /// \pre The behavior is undefined if the `Optional_Base`
1394 /// object is disengaged.
1395 const t_TYPE& operator*() const &;
1396 const t_TYPE&& operator*() const &&;
1397# else
1398 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
1399 ///
1400 /// \pre The behavior is undefined if the `Optional_Base`
1401 /// object is disengaged.
1402 const t_TYPE& operator*() const;
1403# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1404
1405# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1406 /// Return a copy of the underlying object of a (template parameter)
1407 /// `t_TYPE` if this object is non-null, and the specified `value` converted to `t_TYPE` otherwise.
1408 ///
1409 /// \note Note that this method returns *by*
1410 /// *value*, so may be inefficient in some contexts.
1411 template <class t_ANY_TYPE>
1412 t_TYPE value_or(
1413 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1414# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1415 /// If this object is non-null, return a copy of the underlying object
1416 /// of a (template parameter) `t_TYPE` created using the provided
1417 /// allocator, and the specified `value` converted to `t_TYPE` using the specified `allocator` otherwise.
1418 ///
1419 /// \note Note that this method returns *by*
1420 /// *value*, so may be inefficient in some contexts.
1421 template <class t_ANY_TYPE>
1422 t_TYPE value_or(
1425 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1426# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1427# else
1428 /// Return a copy of the underlying object of a (template parameter)
1429 /// `t_TYPE` if this object is non-null, and the specified `value` converted to `t_TYPE` otherwise.
1430 ///
1431 /// \note Note that this method returns **by
1432 /// value**, so may be inefficient in some contexts.
1433 template <class t_ANY_TYPE>
1434 t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1435# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1436 /// If this object is non-null, return a copy of the underlying object of a
1437 /// (template parameter) `t_TYPE` created using the provided allocator, and
1438 /// the specified `value` converted to `t_TYPE` using the specified `allocator` otherwise.
1439 ///
1440 /// \note Note that this method returns **by value**, so
1441 /// may be inefficient in some contexts.
1442 template <class t_ANY_TYPE>
1445 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1446# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
1447# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1448
1449#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1450 /// Return `false` if this object is disengaged, and `true` otherwise.
1451 explicit operator bool() const BSLS_KEYWORD_NOEXCEPT;
1452#else
1453 /// Simulation of explicit conversion to bool. Inlined to work around xlC
1454 /// bug when out-of-line.
1455 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
1456 {
1457 return UnspecifiedBoolUtil::makeValue(has_value());
1458 }
1459#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
1460};
1461
1462// ============================================================================
1463// Section: Definition of C++17 Allocator-Unaware 'Optional_Base'
1464// ============================================================================
1465
1466 // ==================================
1467 // class Optional_Base<t_TYPE, false>
1468 // ==================================
1469
1470# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
1471/// Specialization of `Optional_Base` for `value_type` that is not
1472/// allocator-aware when `std::optional` is available.
1473template <class t_TYPE>
1474class Optional_Base<t_TYPE, false> : public std::optional<t_TYPE> {
1475
1476 private:
1477 // PRIVATE TYPES
1478 typedef std::optional<t_TYPE> StdOptionalBase;
1479
1480 protected:
1481 // PROTECTED TYPES
1482 struct AllocType {
1483 private:
1484 // NOT IMPLEMENTED
1485
1486 /// This constructor prevents `AllocType` from being an aggregate.
1487 explicit AllocType(int) = delete;
1488 };
1489
1490 // PROTECTED CREATORS
1491
1492 /// Create a disengaged `Optional_Base` object.
1493 constexpr Optional_Base();
1494
1495 /// Create a disengaged `Optional_Base` object.
1496 constexpr Optional_Base(bsl::nullopt_t); // IMPLICIT
1497
1498 /// Create an `Optional_Base` object whose contained value is initialized
1499 /// by forwarding from the specified `value`.
1500 template <class t_ANY_TYPE>
1501 constexpr
1502 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1503 t_ANY_TYPE&& value);
1504
1505 /// Create a disengaged `Optional_Base` object if the specified `original`
1506 /// object is disengaged, and an `Optional_Base` object with the value of
1507 /// `original.value()` (of `t_ANY_TYPE`) converted to `t_TYPE` otherwise.
1508 template <class t_ANY_TYPE>
1510 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1511 const Optional_Base<t_ANY_TYPE>& original);
1512
1513 /// Create a disengaged `Optional_Base` object if the specified `original`
1514 /// object is disengaged, and an `Optional_Base` object with the value of
1515 /// `original.value()` (of `t_ANY_TYPE`) converted to `t_TYPE` otherwise.
1516 /// `original` is left in a valid but unspecified state.
1517 template <class t_ANY_TYPE>
1519 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1520 Optional_Base<t_ANY_TYPE>&& original);
1521
1522 template <class t_ANY_TYPE>
1524 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1525 const std::optional<t_ANY_TYPE>& original);
1526
1527 template <class t_ANY_TYPE>
1529 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1530 std::optional<t_ANY_TYPE>&& original);
1531
1532 /// Create an `Optional_Base` object whose contained value is initialized
1533 /// from the specified `args`.
1534 template <class... t_ARGS>
1535 explicit constexpr Optional_Base(bsl::in_place_t, t_ARGS&&... args);
1536
1537 /// Create an `Optional_Base` object whose contained value is initialized
1538 /// from the specified `il` and `args`.
1539 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1540 constexpr
1542 std::initializer_list<t_INIT_LIST_TYPE> il,
1543 t_ARGS&&... args);
1544
1545#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1546 /// Create an `Optional_Base` object, which contains the result of
1547 /// invocation of the specified `invocable` with the specified `arg`.
1548 template <class t_INVOCABLE, class t_ARG>
1549 Optional_Base(Optional_InvokeConstructorTag ,
1550 t_INVOCABLE&& invocable,
1551 t_ARG&& arg);
1552#endif
1553
1554 /// These allocator-extended constructors cannot be called, and are
1555 /// provided only to prevent compilation errors when 'optional' is
1556 /// explicitly instantiated.
1558
1560
1561 template <class t_ANY_TYPE>
1563 AllocType,
1564 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1565 t_ANY_TYPE&&);
1566
1567 template <class t_ANY_TYPE>
1569 AllocType,
1570 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1571 const Optional_Base<t_ANY_TYPE>&);
1572
1573 template <class t_ANY_TYPE>
1575 AllocType,
1576 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1577 Optional_Base<t_ANY_TYPE>&&);
1578
1579 template <class t_ANY_TYPE>
1581 AllocType,
1582 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
1583 const std::optional<t_ANY_TYPE>&);
1584
1585 template <class t_ANY_TYPE>
1587 AllocType,
1588 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
1589 std::optional<t_ANY_TYPE>&&);
1590
1591 template <class... t_ARGS>
1593 AllocType,
1595 t_ARGS&&...);
1596
1597 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1599 AllocType,
1601 std::initializer_list<t_INIT_LIST_TYPE>,
1602 t_ARGS&&...);
1603
1604 // PROTECTED MANIPULATORS
1605
1606 /// If `*this` holds an object, assign to that object the value of the
1607 /// specified `rhs`, converted to `t_TYPE`. Otherwise, construct a held
1608 /// object from `rhs`, converted to `t_TYPE`.
1609 template <class t_ANY_TYPE>
1610 BSLSTL_OPTIONAL_CONSTEXPR20 void assignOrEmplace(t_ANY_TYPE&& rhs);
1611
1612# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1613 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1614 ///
1615 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1616 ///
1617 /// \note Note that this function is only intended to
1618 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use 'bsl::Optional_Base.
1619 ///
1620 /// \note Note that ref-qualified
1621 /// versions of `value()` are not provided because `NullableValue` does
1622 /// not require them.
1623 t_TYPE& dereferenceRaw();
1624
1625 // PROTECTED ACCESSORS
1626
1627 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
1628 ///
1629 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1630 ///
1631 /// \note Note that this function is only intended to
1632 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use 'bsl::Optional_Base.
1633 ///
1634 /// \note Note that ref-qualified
1635 /// versions of `value()` are not provided because `NullableValue` does
1636 /// not require them.
1637 const t_TYPE& dereferenceRaw() const;
1638# endif // BDE_OMIT_INTERNAL_DEPRECATED
1639
1640 public:
1641 // TRAITS
1644 BloombergLP::bslmf::IsBitwiseMoveable,
1645 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1648 BloombergLP::bslmf::IsBitwiseCopyable,
1649 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1650};
1651# else // BSLSTL_OPTIONAL_USES_STD_ALIASES
1652
1653// ============================================================================
1654// Section: Definition of Pre-C++17 Allocator-Unaware 'Optional_Base'
1655// ============================================================================
1656
1657 // ==================================
1658 // class Optional_Base<t_TYPE, false>
1659 // ==================================
1660
1661/// Specialization of `Optional_Base` for `value_type` that is not
1662/// allocator-aware.
1663template <class t_TYPE>
1664class Optional_Base<t_TYPE, false> {
1665
1666 private:
1667 // PRIVATE TYPES
1668 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1669
1670# ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1671 // UNSPECIFIED BOOL
1672
1673 /// This type is needed only in C++03 mode, where 'explicit' conversion
1674 /// operators are not supported. An 'optional' object is contextually
1675 /// converted to 'UnspecifiedBool' when used in 'if' statements, but is not
1676 /// implicitly convertible to 'bool'.
1677 typedef BloombergLP::bsls::UnspecifiedBool<Optional_Base>
1678 UnspecifiedBoolUtil;
1679 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
1680# endif
1681
1682 // DATA
1683
1684 /// in-place `TYPE` object
1685 BloombergLP::bslstl::Optional_Data<t_TYPE> d_value;
1686
1687 protected:
1688 // PROTECTED TYPES
1689 struct AllocType {
1690 private:
1691 // NOT IMPLEMENTED
1692
1693 /// This constructor prevents `AllocType` from being an aggregate.
1694 explicit AllocType(int) BSLS_KEYWORD_DELETED;
1695 };
1696
1697 // PROTECTED CREATORS
1698
1699 /// Create a disengaged `Optional_Base` object.
1700 Optional_Base();
1701
1702 /// Create a disengaged `Optional_Base` object.
1703 Optional_Base(bsl::nullopt_t); // IMPLICIT
1704
1705 /// Create an `Optional_Base` object having the value of the specified
1706 /// `original` object.
1707 Optional_Base(const Optional_Base& original);
1708
1709 /// Create an `Optional_Base` object having the same value as the
1710 /// specified `original` object by moving the contents of `original` to
1711 /// the newly-created object. `original` is left in a valid, but
1712 /// unspecified state.
1713 Optional_Base(BloombergLP::bslmf::MovableRef<Optional_Base> original)
1716
1717 /// Create an `Optional_Base` object whose contained value is initialized
1718 /// by forwarding from the specified `value`.
1719 template <class t_ANY_TYPE>
1720 Optional_Base(BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1722
1723 /// Create a disengaged `Optional_Base` object if the specified
1724 /// `original` object is disengaged, and an `Optional_Base` object with
1725 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1726 template <class t_ANY_TYPE>
1727 Optional_Base(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1728 const Optional_Base<t_ANY_TYPE>& original);
1729
1730 /// Create a disengaged `Optional_Base` object if the specified
1731 /// `original` object is disengaged, and an `Optional_Base` object with
1732 /// the value of `original.value()` converted to `t_TYPE` otherwise.
1733 /// `original` is left in a valid but unspecified state.
1734 template <class t_ANY_TYPE>
1735 Optional_Base(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1737
1738#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1739 /// Create an `Optional_Base` object holding an object of type
1740 /// Create an `Optional_Base` object having the value of the (template
1741 /// parameter) `t_TYPE` created in place using the specified `args`.
1742 template <class... t_ARGS>
1744 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1745
1746# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1747 /// Create an `Optional_Base` object having the value of the (template
1748 /// parameter) `t_TYPE` created in place using the specified `il` and
1749 /// specified `args`.
1750 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1752 std::initializer_list<t_INIT_LIST_TYPE> il,
1753 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1754# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1755#endif
1756
1757 /// These allocator-extended constructors cannot be called, and are provided
1758 /// only to prevent compilation errors when `optional` is explicitly
1759 /// instantiated.
1761
1763
1765
1767 AllocType,
1768 BloombergLP::bslmf::MovableRef<Optional_Base>);
1769
1770 template <class t_ANY_TYPE>
1772 AllocType,
1773 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
1775
1776 template <class t_ANY_TYPE>
1778 AllocType,
1779 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
1781
1782 template <class t_ANY_TYPE>
1784 AllocType,
1785 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
1787
1788#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1789 template <class... t_ARGS>
1791 AllocType,
1794
1795# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1796 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1798 AllocType,
1800 std::initializer_list<t_INIT_LIST_TYPE>,
1802# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1803#endif
1804
1805 // PROTECTED MANIPULATORS
1806
1807 /// If `*this` holds an object, assign to that object the value of
1808 /// `rhs`, converted to `t_TYPE`. Otherwise, construct a held object
1809 /// from `rhs`, converted to `t_TYPE`.
1810 template <class t_ANY_TYPE>
1812
1813# ifndef BDE_OMIT_INTERNAL_DEPRECATED
1814 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1815 ///
1816 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1817 ///
1818 /// \note Note that this function is only intended to
1819 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use `bsl::Optional_Base`.
1820 ///
1821 /// \note Note that ref-qualified
1822 /// versions of `value()` are not provided because `NullableValue` does
1823 /// not require them.
1824 t_TYPE& dereferenceRaw();
1825
1826 // PROTECTED ACCESSORS
1827
1828 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
1829 ///
1830 /// \pre The behavior is undefined if the `Optional_Base` object is disengaged.
1831 ///
1832 /// \note Note that this function is only intended to
1833 /// be called by `bdlb::NullableValue::value` during transition of its implementation to use `bsl::Optional_Base`.
1834 ///
1835 /// \note Note that ref-qualified
1836 /// versions of `value()` are not provided because `NullableValue` does
1837 /// not require them.
1838 const t_TYPE& dereferenceRaw() const;
1839# endif // !BDE_OMIT_INTERNAL_DEPRECATED
1840
1841 public:
1842 // TYPES
1843
1844 /// `value_type` is an alias for the underlying `t_TYPE` upon which this
1845 /// template class is instantiated, and represents the type of the
1846 /// managed object. The name is chosen so it is compatible with the
1847 /// `std::optional` implementation.
1848 typedef t_TYPE value_type;
1849
1850 // TRAITS
1853 BloombergLP::bslmf::IsBitwiseMoveable,
1854 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
1857 BloombergLP::bslmf::IsBitwiseCopyable,
1858 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
1859
1860 // MANIPULATORS
1861#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1862 /// Assign to this `Optional_Base` object the value of the (template
1863 /// parameter) `t_TYPE` created in place using the specified `args` and
1864 /// return a reference providing modifiable access to the underlying
1865 /// `t_TYPE` object. If this `Optional_Base` object already contains an
1866 /// object (`true == hasValue()`), that object is destroyed before the new object is created.
1867 ///
1868 /// \note Note that if the constructor of `t_TYPE`
1869 /// throws an exception this object is left in a disengaged state.
1870 template <class... t_ARGS>
1871 t_TYPE& emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1872
1873# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1874 /// Assign to this `Optional_Base` object the value of the (template
1875 /// parameter) `t_TYPE` created in place using the specified `il` and
1876 /// specified `args` and return a reference providing modifiable access
1877 /// to the underlying `t_TYPE` object. If this `Optional_Base` object
1878 /// already contains an object (`true == hasValue()`), that object is destroyed before the new object is created.
1879 ///
1880 /// \note Note that if the
1881 /// constructor of `t_TYPE` throws an exception this object is left in a
1882 /// disengaged state.
1883 template <class t_INIT_LIST_TYPE, class... t_ARGS>
1884 t_TYPE& emplace(std::initializer_list<t_INIT_LIST_TYPE> il,
1885 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
1886# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
1887#endif
1888
1889 /// Reset this object to the default constructed state (i.e., to be in a
1890 /// disengaged state).
1892
1893 /// Efficiently exchange the value of this object with the value of the
1894 /// specified `other` object. This method provides the no-throw
1895 /// exception-safety guarantee if the template parameter `t_TYPE`
1896 /// provides that guarantee and the result of the `hasValue` method for
1897 /// the two objects being swapped is the same.
1899 bsl::is_nothrow_move_constructible<t_TYPE>::value &&
1900 bsl::is_nothrow_swappable<t_TYPE>::value);
1901
1902# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1903 /// Return a reference providing modifiable access to the underlying
1904 /// `t_TYPE` object if `true == has_value()` and throw
1905 /// `bsl::bad_optional_access` otherwise.
1906 t_TYPE& value() &;
1907 t_TYPE&& value() &&;
1908# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1909 /// Return a reference providing modifiable access to the underlying
1910 /// `t_TYPE` object. Throws a `bsl::bad_optional_access` if the
1911 /// `Optional_Base` object is disengaged.
1912 t_TYPE& value();
1913# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1914
1915# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1916 /// Return a copy of the underlying object of a (template parameter)
1917 /// 't_TYPE' if this object is non-null, and the specified 'value' converted to 't_TYPE' otherwise.
1918 ///
1919 /// \note Note that this method returns **by
1920 /// value**, so may be inefficient in some contexts.
1921 template <class t_ANY_TYPE>
1922 t_TYPE value_or(t_ANY_TYPE&& value) &&;
1923# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1924
1925 /// Assign to this object the value of the specified `rhs` object, and
1926 /// return a non-`const` reference to this object.
1928
1929 /// Assign to this object the value of the specified `rhs` object, and
1930 /// return a non-`const` reference to this object. The allocators of this
1931 /// object and `rhs` both remain unchanged. The contents of `rhs` are
1932 /// either move-constructed into or move-assigned to this object. `rhs` is
1933 /// left in a valid but unspecified state.
1935 BloombergLP::bslmf::MovableRef<Optional_Base> rhs);
1936
1937 /// Return a pointer providing modifiable access to the underlying `t_TYPE` object.
1938 ///
1939 /// \pre The behavior is undefined if this object is disengaged.
1940 t_TYPE *operator->();
1941
1942# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1943 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1944 ///
1945 /// \pre The behavior is undefined if this object is
1946 /// disengaged.
1947 t_TYPE& operator*() &;
1948 t_TYPE&& operator*() &&;
1949# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1950 /// Return a reference providing modifiable access to the underlying `t_TYPE` object.
1951 ///
1952 /// \pre The behavior is undefined if this object is
1953 /// disengaged.
1954 t_TYPE& operator*();
1955# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1956
1957 // ACCESSORS
1958
1959 /// Return `false` if this object is disengaged, and `true` otherwise.
1960 bool has_value() const BSLS_KEYWORD_NOEXCEPT;
1961
1962# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1963 /// Return a reference providing non-modifiable access to the underlying
1964 /// `t_TYPE` object if `true == has_value()` and throw
1965 /// `bsl::bad_optional_access` otherwise.
1966 const t_TYPE& value() const &;
1967 const t_TYPE&& value() const &&;
1968# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1969 /// Return a reference providing non-modifiable access to the underlying
1970 /// 't_TYPE' object. Throws a 'bsl::bad_optional_access' if the
1971 /// 'Optional_Base' object is disengaged.
1972 const t_TYPE& value() const;
1973# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1974
1975# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1976 /// Return a copy of the underlying object of a (template parameter)
1977 /// `t_TYPE` if this object is non-null, and the specified `value` converted to `t_TYPE` otherwise.
1978 ///
1979 /// \note Note that this method returns **by
1980 /// value**, so may be inefficient in some contexts.
1981 template <class t_ANY_TYPE>
1982 t_TYPE value_or(
1983 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&;
1984# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
1985 /// Return a copy of the underlying object of a (template parameter)
1986 /// `t_TYPE` if this object is non-null, and the specified `value` converted to `t_TYPE` otherwise.
1987 ///
1988 /// \note Note that this method returns **by
1989 /// value**, so may be inefficient in some contexts.
1990 template <class t_ANY_TYPE>
1991 t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const;
1992# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
1993
1994 /// Return a pointer providing non-modifiable access to the underlying `t_TYPE` object.
1995 ///
1996 /// \pre The behavior is undefined if this object is
1997 /// disengaged.
1998 const t_TYPE *operator->() const;
1999
2000# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
2001 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
2002 ///
2003 /// \pre The behavior is undefined if this object is
2004 /// disengaged.
2005 const t_TYPE& operator*() const&;
2006 const t_TYPE&& operator*() const&&;
2007# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
2008 /// Return a reference providing non-modifiable access to the underlying `t_TYPE` object.
2009 ///
2010 /// \pre The behavior is undefined if this object is
2011 /// disengaged.
2012 const t_TYPE& operator*() const;
2013# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
2014
2015#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
2016 /// Return `false` if this object is disengaged, and `true` otherwise.
2017 explicit operator bool() const BSLS_KEYWORD_NOEXCEPT;
2018#else
2019 /// Simulation of explicit conversion to bool. Inlined to work around xlC
2020 /// bug when out-of-line.
2021 operator UnspecifiedBool() const BSLS_NOTHROW_SPEC
2022 {
2023 return UnspecifiedBoolUtil::makeValue(has_value());
2024 }
2025#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT else
2026};
2027# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES else
2028
2029} // close package namespace
2030
2031
2032namespace bsl {
2033
2034// ============================================================================
2035// Section: Definition of Class Template 'optional'
2036// ============================================================================
2037
2038 // ==============
2039 // class optional
2040 // ==============
2041
2042template <class t_TYPE>
2043class optional : public BloombergLP::bslstl::Optional_Base<t_TYPE> {
2044 private:
2045 // PRIVATE TYPES
2046 typedef BloombergLP::bslstl::Optional_Base<t_TYPE> BaseType;
2047
2048 typedef typename BaseType::AllocType AllocType;
2049
2050 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2051
2052#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2053 // FRIENDS
2054 template <class t_ANY_TYPE> friend class optional;
2055
2056 // PRIVATE CREATORS
2057
2058 /// Create an `optional` object, which contains the result of invocation of
2059 /// the specified `invocable` with the specified `arg`.
2060 template <class t_INVOCABLE, class t_ARG>
2061 optional(BloombergLP::bslstl::Optional_InvokeConstructorTag ,
2062 t_INVOCABLE&& invocable,
2063 t_ARG&& arg);
2064#endif
2065
2066 public:
2067 // TRAITS
2069 optional,
2070 BloombergLP::bslma::UsesBslmaAllocator,
2071 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value);
2073 optional,
2074 BloombergLP::bslmf::UsesAllocatorArgT,
2075 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value);
2077 optional,
2078 BloombergLP::bslmf::IsBitwiseMoveable,
2079 BloombergLP::bslmf::IsBitwiseMoveable<t_TYPE>::value);
2081 optional,
2082 BloombergLP::bslmf::IsBitwiseCopyable,
2083 BloombergLP::bslmf::IsBitwiseCopyable<t_TYPE>::value);
2084
2085 // CREATORS
2086
2087 /// Create a disengaged `optional` object. Use the currently installed
2088 /// default allocator to supply memory. This constructor can be called in
2089 /// constant expressions only when `t_TYPE` is not allocator-aware.
2091
2092 /// Create a disengaged `optional` object. Use the currently installed
2093 /// default allocator to supply memory. This constructor can be called in
2094 /// constant expressions only when `t_TYPE` is not allocator-aware.
2097
2098#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2099 /// If the `optional` base class of the specified `original` holds a
2100 /// value, create an `optional` object whose contained value is
2101 /// initialized by moving from that value; otherwise, create a
2102 /// disengaged `optional` object. The allocator associated with the
2103 /// `optional` base class of `original` is propagated for use in the
2104 /// newly-created object. `original` is left in a valid, but unspecified state.
2105 ///
2106 /// \note Note that this constructor does not participate
2107 /// in overload resolution unless `optional` is an accessible base class
2108 /// of `t_DERIVED` or `t_DERIVED` is `optional` itself (in which case
2109 /// the instantiation provides the move constructor in C++03; a move
2110 /// constructor is implicitly declared in C++11).
2111 template <class t_DERIVED>
2112 optional(BloombergLP::bslmf::MovableRef<t_DERIVED> original,
2116#endif
2117
2118 /// Create an `optional` object whose contained value is initialized by
2119 /// forwarding from the specified `value`. Use the currently installed default allocator to supply memory.
2120 ///
2121 /// \note Note that this constructor
2122 /// participates in overload resolution only when `t_TYPE` is
2123 /// constructible from `t_ANY_TYPE` and is implicit only when
2124 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`. This constructor
2125 /// can be called in constant expressions only when `t_TYPE` is not
2126 /// allocator-aware.
2127 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2132 t_ANY_TYPE));
2133 // IMPLICIT
2134 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2136 explicit optional(
2137 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
2140
2141 /// Create a disengaged `optional` object if the specified `original`
2142 /// object is disengaged, and an `optional` object with the value of
2143 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2144 /// currently installed default allocator to supply memory.
2145 ///
2146 /// \note Note that this constructor participates in overload resolution only when
2147 /// `t_TYPE` is constructible from an lvalue of `const t_ANY_TYPE`, and
2148 /// is implicit only when an lvalue of `const t_ANY_TYPE` is implicitly
2149 /// convertible to `t_TYPE`. This constructor can be called in constant
2150 /// expressions only when neither `t_TYPE` nor `t_ANY_TYPE` is
2151 /// allocator-aware.
2152 template <class t_ANY_TYPE>
2154 const optional<t_ANY_TYPE>& original,
2156 t_TYPE,
2157 const t_ANY_TYPE&),
2159 const t_ANY_TYPE&));
2160 // IMPLICIT
2161 template <class t_ANY_TYPE>
2163 const optional<t_ANY_TYPE>& original,
2165 t_TYPE,
2166 const t_ANY_TYPE&),
2168 const t_ANY_TYPE&));
2169
2170 /// Create a disengaged `optional` object if the specified `original`
2171 /// object is disengaged, and an `optional` object with the value of
2172 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
2173 /// the allocator from `original` to supply memory if `t_ANY_TYPE` is a
2174 /// non-const version of `t_TYPE`; otherwise, use the currently
2175 /// installed default allocator. `original` is left in a valid but unspecified state.
2176 ///
2177 /// \note Note that this constructor participates in
2178 /// overload resolution only when `t_TYPE` is constructible from an
2179 /// xvalue of `t_ANY_TYPE`, and is implicit only when an xvalue of
2180 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`. This constructor
2181 /// can be called in constant expressions only when neither `t_TYPE` nor
2182 /// `t_ANY_TYPE` is allocator-aware.
2183 template <class t_ANY_TYPE>
2187 t_ANY_TYPE),
2189 // IMPLICIT
2190 template <class t_ANY_TYPE>
2194 t_ANY_TYPE),
2196
2197# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
2198 /// Create a disengaged `optional` object if the specified `original`
2199 /// object is disengaged, and an `optional` object with the value of
2200 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2201 /// currently installed default allocator to supply memory.
2202 ///
2203 /// \note Note that this constructor participates in overload resolution only when
2204 /// `t_TYPE` is constructible from an lvalue of `const t_ANY_TYPE`, and
2205 /// is implicit only when an lvalue of `const t_ANY_TYPE` is implicitly
2206 /// convertible to `t_TYPE`. This constructor can be called in constant
2207 /// expressions only when `t_TYPE` is not allocator-aware.
2208 template <class t_ANY_TYPE>
2210 const std::optional<t_ANY_TYPE>& original,
2212 t_TYPE,
2213 const t_ANY_TYPE&),
2215 t_ANY_TYPE));
2216 // IMPLICIT
2217 template <class t_ANY_TYPE>
2219 const std::optional<t_ANY_TYPE>& original,
2221 t_TYPE,
2222 const t_ANY_TYPE&),
2224
2225 /// Create a disengaged `optional` object if the specified `original`
2226 /// object is disengaged, and an `optional` object with the value of
2227 /// `original.value()` converted to `t_TYPE` otherwise. Use the
2228 /// currently installed default allocator to supply memory.
2229 ///
2230 /// \note Note that this constructor participates in overload resolution only when
2231 /// `t_TYPE` is constructible from an xvalue of `t_ANY_TYPE`, and is
2232 /// implicit only when an xvalue of `t_ANY_TYPE` is implicitly
2233 /// convertible to `t_TYPE`. This constructor can be called in constant
2234 /// expressions only when `t_TYPE` is not allocator-aware.
2235 template <class t_ANY_TYPE>
2237 std::optional<t_ANY_TYPE>&& original,
2239 t_ANY_TYPE),
2241 // IMPLICIT
2242 template <class t_ANY_TYPE>
2244 std::optional<t_ANY_TYPE>&& original,
2246 t_ANY_TYPE),
2248# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
2249
2250#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2251 /// Create an `optional` object having the value of the (template
2252 /// parameter) `t_TYPE` created in place using the specified `args`.
2253 /// Use the currently installed default allocator to supply memory. This
2254 /// constructor can be called in constant expressions only when `t_TYPE` is
2255 /// not allocator-aware.
2256 template <class... t_ARGS>
2259 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2260
2261# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2262 /// Create an `optional` object having the value of the (template
2263 /// parameter) `t_TYPE` created in place using the specified `il` and
2264 /// specified `args`. Use the currently installed default allocator to
2265 /// supply memory. This constructor can be called in constant expressions
2266 /// only when `t_TYPE` is not allocator-aware.
2267 template <class t_INIT_LIST_TYPE, class... t_ARGS>
2270 std::initializer_list<t_INIT_LIST_TYPE> il,
2271 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2272#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
2273#endif
2274
2275 // These allocator-extended constructors can be called only when 't_TYPE'
2276 // is allocator-aware.
2277
2278 /// Create a disengaged `optional` object. Use the specified
2279 /// `allocator` to supply memory.
2281
2282 /// Create a disengaged `optional` object. Use the specified
2283 /// `allocator` to supply memory.
2285
2286 /// If the specified `original` contains a value, create an `optional`
2287 /// object whose contained value is initialized from `*original`;
2288 /// otherwise, create a disengaged `optional` object. Use the specified
2289 /// `allocator` to supply memory.
2291 AllocType allocator,
2292 const optional& original);
2293
2294 /// If the `optional` base class of the specified `original` holds a
2295 /// value, create an `optional` object whose contained value is
2296 /// initialized by moving from that value; otherwise, create a
2297 /// disengaged `optional` object. Use the specified `allocator` to
2298 /// supply memory. `original` is left in a valid, but unspecified state.
2299 ///
2300 /// \note Note that this constructor does not participate in overload
2301 /// resolution unless `optional` is an accessible base class of
2302 /// `t_DERIVED` or `t_DERIVED` is `optional` itself (in which case the
2303 /// instantiation provides the allocator-extended move constructor).
2304 template <class t_DERIVED>
2306 AllocType allocator,
2307 BSLMF_MOVABLEREF_DEDUCE(t_DERIVED) original,
2310
2311 /// Create an `optional` object whose contained value is initialized by
2312 /// forwarding from the specified `value`. Use the specified `allocator` to supply memory.
2313 ///
2314 /// \note Note that this constructor
2315 /// participates in overload resolution only when `t_TYPE` is
2316 /// constructible from `t_ANY_TYPE`, and is implicit only when
2317 /// `t_ANY_TYPE` is implicitly convertible to `t_TYPE`.
2318 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2320 AllocType allocator,
2321 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
2324 t_ANY_TYPE));
2325 template <class t_ANY_TYPE BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG(t_TYPE)>
2326 explicit optional(
2328 AllocType allocator,
2329 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
2332
2333 /// Create a disengaged `optional` object if the specified `original`
2334 /// object is disengaged, and an `optional` object with the value of
2335 /// `original.value()` converted to `t_TYPE` otherwise. Use the specified `allocator` to supply memory.
2336 ///
2337 /// \note Note that this constructor
2338 /// participates in overload resolution only when `t_TYPE` is
2339 /// constructible from an lvalue of `const t_ANY_TYPE`, and is implicit
2340 /// only when an lvalue of `const t_ANY_TYPE` is implicitly convertible
2341 /// to `t_TYPE`.
2342 template <class t_ANY_TYPE>
2345 AllocType allocator,
2346 const optional<t_ANY_TYPE>& original,
2348 t_TYPE,
2349 const t_ANY_TYPE&),
2351 const t_ANY_TYPE&));
2352 template <class t_ANY_TYPE>
2353 explicit optional(
2355 AllocType allocator,
2356 const optional<t_ANY_TYPE>& original,
2358 t_TYPE,
2359 const t_ANY_TYPE&),
2361 const t_ANY_TYPE&));
2362
2363 /// Create a disengaged `optional` object if the specified `original`
2364 /// object is disengaged, and an `optional` object with the value of
2365 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
2366 /// the specified `allocator` to supply memory. `original` is left in a valid but unspecified state.
2367 ///
2368 /// \note Note that this constructor
2369 /// participates in overload resolution only when `t_TYPE` is
2370 /// constructible from an xvalue of `t_ANY_TYPE`, and is implicit only
2371 /// when an xvalue of `t_ANY_TYPE` is implicitly convertible to
2372 /// `t_TYPE`.
2373 template <class t_ANY_TYPE>
2376 AllocType allocator,
2379 t_ANY_TYPE),
2381 template <class t_ANY_TYPE>
2382 explicit optional(
2384 AllocType allocator,
2387 t_ANY_TYPE),
2389
2390# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
2391 /// Create a disengaged `optional` object if the specified `original`
2392 /// object is disengaged, and an `optional` object with the value of
2393 /// `original.value()` converted to `t_TYPE` otherwise. Use the specified `allocator` to supply memory.
2394 ///
2395 /// \note Note that this constructor
2396 /// participates in overload resolution only when `t_TYPE` is
2397 /// constructible from an lvalue of `const t_ANY_TYPE`, and is implicit
2398 /// only when an lvalue of `const t_ANY_TYPE` is implicitly convertible
2399 /// to `t_TYPE`.
2400 template <class t_ANY_TYPE>
2401 optional(
2403 AllocType allocator,
2404 const std::optional<t_ANY_TYPE>& original,
2406 t_TYPE,
2407 const t_ANY_TYPE&),
2409 const t_ANY_TYPE&));
2410 template <class t_ANY_TYPE>
2411 explicit optional(
2413 AllocType allocator,
2414 const std::optional<t_ANY_TYPE>& original,
2416 t_TYPE,
2417 const t_ANY_TYPE&),
2419 const t_ANY_TYPE));
2420
2421 /// Create a disengaged `optional` object if the specified `original`
2422 /// object is disengaged, and an `optional` object with the value of
2423 /// `original.value()` moved and converted to `t_TYPE` otherwise. Use
2424 /// the specified `allocator` to supply memory. `original` is left in a valid but unspecified state.
2425 ///
2426 /// \note Note that this constructor
2427 /// participates in overload resolution only when `t_TYPE` is
2428 /// constructible from an xvalue of `t_ANY_TYPE`, and is implicit only
2429 /// when an xvalue of `t_ANY_TYPE` is implicitly convertible to
2430 /// `t_TYPE`.
2431 template <class t_ANY_TYPE>
2432 optional(
2434 AllocType allocator,
2435 std::optional<t_ANY_TYPE>&& original,
2437 t_ANY_TYPE),
2439 template <class t_ANY_TYPE>
2440 explicit optional(
2442 AllocType allocator,
2443 std::optional<t_ANY_TYPE>&& original,
2445 t_ANY_TYPE),
2447# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
2448
2449#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2450 /// Create an `optional` object having the value of the (template
2451 /// parameter) `t_TYPE` created in place using the specified `args`.
2452 /// Use the specified `allocator` to supply memory.
2453 template <class... t_ARGS>
2455 AllocType allocator,
2457 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2458
2459# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2460 /// Create an `optional` object having the value of the (template
2461 /// parameter) `t_TYPE` created in place using the specified `il` and
2462 /// `args`. Use the specified `allocator` to supply memory.
2463 template <class t_INIT_LIST_TYPE, class... t_ARGS>
2465 AllocType allocator,
2467 std::initializer_list<t_INIT_LIST_TYPE> il,
2468 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
2469# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
2470#endif
2471
2472 // MANIPULATORS
2473
2474 // We implement 'operator=' in the most derived class to avoid having to
2475 // repeat constraints in each of the three implementations of
2476 // 'Optional_Base'.
2477
2478 /// Reset this object to be disengaged and return a reference providing
2479 /// modifiable access to this object. This assignment operator can be
2480 /// called in constant expressions only when `t_TYPE` is not
2481 /// allocator-aware.
2484
2485#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2486 /// If the `optional` base class of the specified `rhs` holds a value,
2487 /// move-construct or move-assign the contained value of `*this` from
2488 /// that value. Otherwise, set `*this` to be disengaged. Return a
2489 /// reference providing modifiable access to this object. `rhs` is left
2490 /// in a valid but unspecified state. This method does not participate
2491 /// in overload resolution unless `optional` is an accessible base class
2492 /// of `t_DERIVED` or `t_DERIVED` is `optional` itself (in which case
2493 /// the instantiation provides the move assignment operator in C++03; a
2494 /// move assignment operator is implicitly declared in C++11).
2495 template <class t_DERIVED>
2497 operator=(BloombergLP::bslmf::MovableRef<t_DERIVED> rhs);
2498#endif
2499
2500 /// Disengage this object if the specified `rhs` object is disengaged,
2501 /// and assign to this object the value of `rhs.value()` (of
2502 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference providing modifiable access to this object.
2503 ///
2504 /// \note Note that this method
2505 /// does not participate in overload resolution unless `t_TYPE` and
2506 /// `t_ANY_TYPE` are compatible. This assignment operator can be called in
2507 /// constant expressions only when neither `t_TYPE` nor `t_ANY_TYPE` is
2508 /// allocator-aware.
2509 template <class t_ANY_TYPE>
2513
2514 /// Disengage this object if the specified `rhs` object is disengaged,
2515 /// and move assign to this object the value of `rhs.value()` (of
2516 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference providing modifiable access to this object.
2517 ///
2518 /// \note Note that this method
2519 /// does not participate in overload resolution unless `t_TYPE` and
2520 /// `t_ANY_TYPE` are compatible. This assignment operator can be called in
2521 /// constant expressions only when neither `t_TYPE` nor `t_ANY_TYPE` is
2522 /// allocator-aware.
2523 template <class t_ANY_TYPE>
2527
2528#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2529 /// Assign to this object the value of the specified `rhs` object
2530 /// converted to `t_TYPE`, and return a reference providing modifiable access to this object.
2531 ///
2532 /// \note Note that this method may invoke assignment
2533 /// from `rhs`, or construction from `rhs`, depending on whether this
2534 /// object is engaged. This assignment operator does not participate in
2535 /// overload resolution if `t_ANY_TYPE` is possibly cv-qualified
2536 /// `bsl::optional<t_TYPE>`. Also note that an assignment of the form
2537 /// `o = {};`, where `o` is of type `optional`, will always assign to
2538 /// `o` the empty state, and never call this overload (see
2539 /// implementation notes). This assignment operator can be called in
2540 /// constant expressions only when `t_TYPE` is not allocator-aware.
2541 template <class t_ANY_TYPE = t_TYPE>
2544 operator=(t_ANY_TYPE&& rhs);
2545#else
2546 // The existence of MovableRef in C++11 affects the above functions, and
2547 // they need to be defined in terms of rvalue references and perfect
2548 // forwarding. For C++03, the MovableRef overloads are provided below.
2549
2550 /// Assign to this object the value of the specified `rhs`, and return a
2551 /// reference providing modifiable access to this object.
2552 optional& operator=(const t_TYPE& rhs);
2553
2554 /// Assign to this object the value of the specified `rhs`, and return a
2555 /// reference providing modifiable access to this object. The contents
2556 /// of `rhs` are either move-constructed into or move-assigned to this
2557 /// object. `rhs` is left in a valid but unspecified state.
2558 optional& operator=(BloombergLP::bslmf::MovableRef<t_TYPE> rhs);
2559
2560 /// Assign to this object the value of the specified `rhs` object (of
2561 /// `ANY_TYPE`) converted to `TYPE`, and return a reference providing modifiable access to this object.
2562 ///
2563 /// \note Note that this method may invoke
2564 /// assignment from `rhs`, or construction from `rhs`, depending on
2565 /// whether this `optional` object is engaged.
2566 template <class t_ANY_TYPE>
2568 operator=(const t_ANY_TYPE& rhs);
2569
2570 template <class t_ANY_TYPE>
2572 operator=(BloombergLP::bslmf::MovableRef<t_ANY_TYPE> rhs);
2573#endif // RVALUES else
2574
2575#ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
2576 /// Disengage this object if the specified `rhs` object is disengaged,
2577 /// and assign to this object the value of `rhs.value()` (of
2578 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference providing modifiable access to this object.
2579 ///
2580 /// \note Note that this method
2581 /// does not participate in overload resolution unless `t_TYPE` and
2582 /// `t_ANY_TYPE` are compatible. This assignment operator can be called in
2583 /// constant expressions only when `t_TYPE` is not allocator-aware.
2584 template <class t_ANY_TYPE = t_TYPE>
2586 BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(t_TYPE, const t_ANY_TYPE&)&
2587 operator=(const std::optional<t_ANY_TYPE>& rhs);
2588
2589 /// Disengage this object if the specified `rhs` object is disengaged,
2590 /// and move assign to this object the value of `rhs.value()` (of
2591 /// `t_ANY_TYPE`) converted to `t_TYPE` otherwise. Return a reference providing modifiable access to this object.
2592 ///
2593 /// \note Note that this method
2594 /// does not participate in overload resolution unless `t_TYPE` and
2595 /// `t_ANY_TYPE` are compatible. This assignment operator can be called in
2596 /// constant expressions only when `t_TYPE` is not allocator-aware.
2597 template <class t_ANY_TYPE = t_TYPE>
2600 operator=(std::optional<t_ANY_TYPE>&& rhs);
2601# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
2602
2603#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
2604
2605 // This macro indicates that `bsl::optional` provides @ref and_then ,
2606 // `or_else`, and `transform` methods.
2607 #define BSLSTL_OPTIONAL_PROVIDES_MONADICS
2608
2609 /// If this object contains a value, invoke the specified `func` with the
2610 /// contained value as an argument and return `optional<U>` that contains
2611 /// the result of that invocation, where `U` is the cv-unqualified `func`
2612 /// return type, which can be different from `t_TYPE`; otherwise, return an empty `optional<U>`.
2613 ///
2614 /// \note Note that `func` must return an object type other
2615 /// than array, `bsl::in_place_t` or `bsl::nullopt`. Also note that there
2616 /// is no requirement that `U` is movable. Finally note that the returned
2617 /// optional uses the allocator of the object returned by `func`, or the
2618 /// default allocator if `func` is not invoked.
2619 template <class t_FUNC> constexpr auto transform(t_FUNC&& func) &;
2620 template <class t_FUNC> constexpr auto transform(t_FUNC&& func) &&;
2621 template <class t_FUNC> constexpr auto transform(t_FUNC&& func) const &;
2622 template <class t_FUNC> constexpr auto transform(t_FUNC&& func) const &&;
2623
2624 /// If this object contains a value, invoke the specified `func` with the
2625 /// contained value as an argument and return the result of that invocation; otherwise, return an empty optional.
2626 ///
2627 /// \note Note that `func` must
2628 /// return a specialization of `bsl::optional`. Also note that the return
2629 /// type of `func` does not have to be this object type. Also note that
2630 /// the optional object returned by `func` is returned as-is, without
2631 /// copying or moving. Finally note that the default allocator is used for
2632 /// constructing the empty optional when `func` is not invoked.
2633 template <class t_FUNC> constexpr auto and_then(t_FUNC&& func) &;
2634 template <class t_FUNC> constexpr auto and_then(t_FUNC&& func) &&;
2635 template <class t_FUNC> constexpr auto and_then(t_FUNC&& func) const &;
2636 template <class t_FUNC> constexpr auto and_then(t_FUNC&& func) const &&;
2637
2638 /// If this object does not contain a value, invoke the specified `func`
2639 /// and return the result of that invocation. Otherwise return a copy-constructed value from this object.
2640 ///
2641 /// \note Note that `func` must return
2642 /// `bsl::optional`. Also note that the optional object returned by `func`
2643 /// is returned as-is, without copying or moving.
2644 template <class t_FUNC>
2645 constexpr
2646 enable_if_t<conjunction_v<std::is_invocable<t_FUNC>,
2647 std::is_copy_constructible<t_TYPE>>,
2648 optional> or_else(t_FUNC&& func) const &;
2649
2650 /// If this object does not contain a value, invoke the specified `func`
2651 /// and return the result of that invocation; otherwise, return a
2652 /// move-constructed value from this object, leaving this object in an unspecified but valid state.
2653 ///
2654 /// \note Note that `func` must return
2655 /// `bsl::optional`. Also note that the optional object returned by `func`
2656 /// is returned as-is, without copying or moving.
2657 template <class t_FUNC>
2658 constexpr
2659 enable_if_t<conjunction_v<std::is_invocable<t_FUNC>,
2660 std::is_move_constructible<t_TYPE>>,
2661 optional> or_else(t_FUNC&& func) &&;
2662#endif
2663};
2664
2665} // close namespace bsl
2666
2667// ============================================================================
2668// Section: Type Traits on Allocator-Unaware 'Optional_Base'
2669// ============================================================================
2670
2671
2672namespace bslma {
2673
2674template <class t_TYPE>
2675struct UsesBslmaAllocator<bslstl::Optional_Base<t_TYPE, false> >
2677};
2678
2679template <class t_TYPE>
2680struct UsesBslmaAllocator<bsl::optional<t_TYPE> >
2681: UsesBslmaAllocator<t_TYPE> {
2682};
2683
2684} // close namespace bslma
2685
2686
2687namespace bsl {
2688
2689// ============================================================================
2690// Section: CTAD Constructors
2691// ============================================================================
2692
2693# ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2694// CLASS TEMPLATE DEDUCTION GUIDES
2695
2696/// Deduce the specified type `t_TYPE` from the corresponding type supplied
2697/// to the constructor of `optional`.
2698template <class t_TYPE>
2699optional(t_TYPE) -> optional<t_TYPE>;
2700
2701/// Deduce the specified type `t_TYPE` from the corresponding type supplied
2702/// to the constructor of `optional`. This guide does not participate in
2703/// deduction unless the deduced type `t_TYPE` supports the bslma allocator
2704/// model, and the specified `t_ALLOC` can be implicitly converted to
2705/// `bsl::allocator<char>`.
2706template <class t_TYPE,
2707 class t_ALLOC,
2708 class = typename bsl::enable_if_t<
2709 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>,
2710 class = typename bsl::enable_if_t<
2711 bsl::is_convertible_v<t_ALLOC, bsl::allocator<char>>>
2712 >
2713optional(bsl::allocator_arg_t, t_ALLOC, t_TYPE)
2714-> optional<t_TYPE>;
2715
2716/// Deduce the specified type `t_TYPE` from the corresponding template
2717/// parameter type supplied to the constructor of `optional`. This guide
2718/// does not participate in deduction unless the deduced type `t_TYPE`
2719/// supports the bslma allocator model, and the specified `t_ALLOC` can be
2720/// implicitly converted to `bsl::allocator<char>`.
2721template <class t_TYPE,
2722 class t_ALLOC,
2723 class = typename bsl::enable_if_t<
2724 BloombergLP::bslma::UsesBslmaAllocator<t_TYPE>::value>,
2725 class = typename bsl::enable_if_t<
2726 bsl::is_convertible_v<t_ALLOC, bsl::allocator<char>>>
2727 >
2728optional(bsl::allocator_arg_t, t_ALLOC, optional<t_TYPE>)
2729-> optional<t_TYPE>;
2730# endif // BSLS_COMPILERFEATURES_SUPPORT_CTAD
2731
2732// ============================================================================
2733// Section: Free Function Declarations
2734// ============================================================================
2735
2736// FREE FUNCTIONS
2737
2738/// Efficiently exchange the values of the specified `lhs` and `rhs`
2739/// objects. This method provides the no-throw exception-safety guarantee
2740/// if the template parameter `t_TYPE` provides that guarantee, `lhs` and
2741/// `rhs` have equal allocators, and `lhs.hasValue() == rhs.hasValue()`.
2742template <class t_TYPE>
2744 void>::type
2746
2747/// Efficiently exchange the values of the specified `lhs` and `rhs`
2748/// objects. This method provides the no-throw exception-safety guarantee
2749/// if the template parameter `t_TYPE` provides that guarantee and the
2750/// result of the `hasValue` method for `lhs` and `rhs` is the same.
2751template <class t_TYPE>
2754 void>::type
2756
2757// HASH SPECIALIZATIONS
2758
2759/// Pass the specified `input` to the specified `hashAlg`, where `hashAlg`
2760/// is a hashing algorithm.
2761template <class t_HASHALG, class t_TYPE>
2762void hashAppend(t_HASHALG& hashAlg, const optional<t_TYPE>& input);
2763
2764// FREE OPERATORS
2765
2766/// Return `true` if the specified `lhs` and `rhs` `optional` objects have the
2767/// same value, and `false` otherwise. Two `optional` objects have the same
2768/// value if both are disengaged, or if both are engaged and the values of
2769/// their underlying objects compare equal. This function can be called in
2770/// constant expressions only if neither `t_LHS_TYPE` nor `t_RHS_TYPE` is
2771/// allocator-aware.
2772template <class t_LHS_TYPE, class t_RHS_TYPE>
2774bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
2776 BSLSTL_OPTIONAL_REQUIRES(requires {
2777 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2778 });
2779
2780/// Return `true` if the specified `lhs` and `rhs` `optional` objects do not
2781/// have the same value, and `false` otherwise. Two `optional` objects do
2782/// not have the same value if one is disengaged and the other is engaged,
2783/// or if both are engaged and the values of their underlying objects do not
2784/// compare equal. This function can be called in constant expressions only if
2785/// neither `t_LHS_TYPE` nor `t_RHS_TYPE` is allocator-aware.
2786template <class t_LHS_TYPE, class t_RHS_TYPE>
2788bool operator!=(const bsl::optional<t_LHS_TYPE>& lhs,
2790 BSLSTL_OPTIONAL_REQUIRES(requires {
2791 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2792 });
2793
2794/// Return `true` if the specified `lhs` `optional` object is ordered before
2795/// the specified `rhs` `optional` object, and `false` otherwise. `lhs` is
2796/// ordered before `rhs` if `lhs` is disengaged and `rhs` is engaged or if
2797/// both are engaged and `lhs.value()` is ordered before `rhs.value()`. This
2798/// function can be called in constant expressions only if neither `t_LHS_TYPE`
2799/// nor `t_RHS_TYPE` is allocator-aware.
2800template <class t_LHS_TYPE, class t_RHS_TYPE>
2802bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
2804 BSLSTL_OPTIONAL_REQUIRES(requires {
2805 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2806 });
2807
2808/// Return `true` if the specified `lhs` `optional` object is ordered after
2809/// the specified `rhs` `optional` object, and `false` otherwise. `lhs` is
2810/// ordered after `rhs` if `lhs` is engaged and `rhs` is disengaged or if
2811/// both are engaged and `lhs.value()` is ordered after `rhs.value()`. This
2812/// function can be called in constant expressions only if neither `t_LHS_TYPE`
2813/// nor `t_RHS_TYPE` is allocator-aware.
2814template <class t_LHS_TYPE, class t_RHS_TYPE>
2816bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
2818 BSLSTL_OPTIONAL_REQUIRES(requires {
2819 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2820 });
2821
2822/// Return `true` if the specified `lhs` `optional` object is ordered before
2823/// the specified `rhs` `optional` object or if `lhs` and `rhs` have the
2824/// same value, and `false` otherwise. (See `operator<` and `operator==`.)
2825/// This function can be called in constant expressions only if neither
2826/// `t_LHS_TYPE` nor `t_RHS_TYPE` is allocator-aware.
2827template <class t_LHS_TYPE, class t_RHS_TYPE>
2829bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs,
2831 BSLSTL_OPTIONAL_REQUIRES(requires {
2832 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2833 });
2834
2835/// Return `true` if the specified `lhs` `optional` object is ordered after
2836/// the specified `rhs` `optional` object or if `lhs` and `rhs` have the
2837/// same value, and `false` otherwise. (See `operator>` and `operator==`.)
2838/// This function can be called in constant expressions only if neither
2839/// `t_LHS_TYPE` nor `t_RHS_TYPE` is allocator-aware.
2840template <class t_LHS_TYPE, class t_RHS_TYPE>
2842bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs,
2844 BSLSTL_OPTIONAL_REQUIRES(requires {
2845 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2846 });
2847
2848// comparison with 'nullopt_t'
2849
2850/// Return `true` if the specified `value` is disengaged, and `false`
2851/// otherwise. This function can be called in constant expressions only if
2852/// `t_TYPE` is not allocator-aware.
2853template <class t_TYPE>
2855bool operator==(const bsl::optional<t_TYPE>& value,
2857#if !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) && \
2858 defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
2859template <class t_TYPE>
2861bool operator==(const bsl::nullopt_t&,
2863
2864/// Return `true` if the specified `value` is engaged, and `false` otherwise.
2865/// These functions can be called in constant expressions only if `t_TYPE` is
2866/// not allocator-aware.
2867template <class t_TYPE>
2869bool operator!=(const bsl::optional<t_TYPE>& value,
2871template <class t_TYPE>
2873bool operator!=(const bsl::nullopt_t&,
2875
2876/// Return `false`.
2877/// \note Note that `bsl::nullopt_t` never orders after a
2878/// `bsl::optional`. This function can be called in constant expressions only
2879/// if `t_TYPE` is not allocator-aware.
2880template <class t_TYPE>
2882bool operator<(const bsl::optional<t_TYPE>&,
2884
2885/// Return `true` if the specified `value` is engaged, and `false` otherwise.
2886///
2887/// \note Note that `bsl::nullopt_t` is ordered before any `bsl::optional` that is
2888/// engaged. This function can be called in constant expressions only if
2889/// `t_TYPE` is not allocator-aware.
2890template <class t_TYPE>
2892bool operator<(const bsl::nullopt_t&,
2894
2895/// Return `true` if the specified `value` is engaged, and `false` otherwise.
2896/// This function can be called in constant expressions only if `t_TYPE` is not
2897/// allocator-aware.
2898template <class t_TYPE>
2900bool operator>(const bsl::optional<t_TYPE>& value,
2902
2903/// Return `false`.
2904/// \note Note that `bsl::nullopt_t` never orders after a
2905/// `bsl::optional`. This function can be called in constant expressions only
2906/// if `t_TYPE` is not allocator-aware.
2907template <class t_TYPE>
2909bool operator>(const bsl::nullopt_t&,
2911
2912/// Return `true` if the specified `value` is disengaged, and `false`
2913/// otherwise. This function can be called in constant expressions only if
2914/// `t_TYPE` is not allocator-aware.
2915template <class t_TYPE>
2917bool operator<=(const bsl::optional<t_TYPE>& value,
2919
2920/// Return `true`.
2921/// \note Note that `bsl::nullopt_t` is ordered before any
2922/// `bsl::optional` that is engaged. This function can be called in constant
2923/// expressions only if `t_TYPE` is not allocator-aware.
2924template <class t_TYPE>
2926bool operator<=(const bsl::nullopt_t&,
2928
2929/// Return `true`.
2930/// \note Note that `bsl::nullopt_t` is ordered before any
2931/// `bsl::optional` that is engaged. This function can be called in constant
2932/// expressions only if `t_TYPE` is not allocator-aware.
2933template <class t_TYPE>
2935bool operator>=(const bsl::optional<t_TYPE>&,
2937
2938/// Return `true` if the specified `value` is disengaged, and `false`
2939/// otherwise. This function can be called in constant expressions only if
2940/// `t_TYPE` is not allocator-aware.
2941template <class t_TYPE>
2943bool operator>=(const bsl::nullopt_t&,
2945#endif // !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) &&
2946 // defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
2947
2948// comparison with 'value_type'
2949
2950/// Return `true` if the specified `lhs` and `rhs` objects have the same
2951/// value, and `false` otherwise. An `optional` object and a value of some
2952/// type have the same value if the optional object is engaged and its
2953/// underlying value compares equal to the other value. These functions can be
2954/// called in constant expressions only if the `optional`'s value type is not
2955/// allocator-aware.
2956template <class t_LHS_TYPE, class t_RHS_TYPE>
2958bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
2959 const t_RHS_TYPE& rhs)
2961 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2962 && requires {
2963 { *lhs == rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2964 });
2965template <class t_LHS_TYPE, class t_RHS_TYPE>
2967bool operator==(const t_LHS_TYPE& lhs,
2970 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2971 && requires {
2972 { lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2973 });
2974
2975/// Return `true` if the specified `lhs` and `rhs` objects do not have the same
2976/// value, and `false` otherwise. An `optional` object and a value of some
2977/// type do not have the same value if either the optional object is
2978/// disengaged, or its underlying value does not compare equal to the other
2979/// value. These function can be called in constant expressions only if the
2980/// `optional`'s value type is not allocator-aware.
2981template <class t_LHS_TYPE, class t_RHS_TYPE>
2984 const t_RHS_TYPE& rhs)
2986 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
2987 && requires {
2988 { *lhs != rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2989 });
2990template <class t_LHS_TYPE, class t_RHS_TYPE>
2992bool operator!=(const t_LHS_TYPE& lhs,
2995 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
2996 && requires {
2997 { lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
2998 });
2999
3000/// Return `true` if the specified `lhs` `optional` object is ordered before
3001/// the specified `rhs`, and `false` otherwise. `lhs` is ordered before
3002/// `rhs` if `lhs` is disengaged or `lhs.value()` is ordered before `rhs`.
3003/// This function can be called in constant expressions only if `t_LHS_TYPE`
3004/// is not allocator-aware.
3005template <class t_LHS_TYPE, class t_RHS_TYPE>
3007bool operator<(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
3009 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
3010 && requires {
3011 { *lhs < rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3012 });
3013
3014/// Return `true` if the specified `lhs` is ordered before the specified `rhs`
3015/// `optional` object, and `false` otherwise. `lhs` is ordered before `rhs` if
3016/// `rhs` is engaged and `lhs` is ordered before `rhs.value()`. This function
3017/// can be called in constant expressions only if `t_RHS_TYPE` is not
3018/// allocator-aware.
3019template <class t_LHS_TYPE, class t_RHS_TYPE>
3021bool operator<(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
3023 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
3024 && requires {
3025 { lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3026 });
3027
3028/// Return `true` if the specified `lhs` `optional` object is ordered after the
3029/// specified `rhs`, and `false` otherwise. `lhs` is ordered after `rhs` if
3030/// `lhs` is engaged and `lhs.value()` is ordered after `rhs`. This function
3031/// can be called in constant expressions only if `t_LHS_TYPE` is not
3032/// allocator-aware.
3033template <class t_LHS_TYPE, class t_RHS_TYPE>
3035bool operator>(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
3037 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
3038 && requires {
3039 { *lhs > rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3040 });
3041
3042/// Return `true` if the specified `lhs` is ordered after the specified `rhs`
3043/// `optional` object, and `false` otherwise. `lhs` is ordered after `rhs` if
3044/// `rhs` is disengaged or `lhs` is ordered after `rhs.value()`. This
3045/// function can be called in constant expressions only if `t_RHS_TYPE` is not
3046/// allocator-aware.
3047template <class t_LHS_TYPE, class t_RHS_TYPE>
3049bool operator>(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
3051 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
3052 && requires {
3053 { lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3054 });
3055
3056/// Return `true` if the specified `lhs` `optional` object is ordered before
3057/// the specified `rhs` or `lhs` and `rhs` have the same value, and `false`
3058/// otherwise. (See `operator<` and `operator==`.) This function can be
3059/// called in constant expressions only if `t_LHS_TYPE` is not allocator-aware.
3060template <class t_LHS_TYPE, class t_RHS_TYPE>
3062bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
3064 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
3065 && requires {
3066 { *lhs <= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3067 });
3068
3069/// Return `true` if the specified `lhs` is ordered before the specified `rhs`
3070/// `optional` object or `lhs` and `rhs` have the same value, and `false`
3071/// otherwise. (See `operator<` and `operator==`.) This function can be
3072/// called in constant expressions only if `t_RHS_TYPE` is not allocator-aware.
3073template <class t_LHS_TYPE, class t_RHS_TYPE>
3075bool operator<=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
3077 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
3078 && requires {
3079 { lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3080 });
3081
3082/// Return `true` if the specified `lhs` `optional` object is ordered after the
3083/// specified `rhs` or if `lhs` and `rhs` have the same value, and `false`
3084/// otherwise. (See `operator>` and `operator==`.) This function can be
3085/// called in constant expressions only if `t_LHS_TYPE` is not allocator-aware.
3086template <class t_LHS_TYPE, class t_RHS_TYPE>
3088bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
3090 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
3091 && requires {
3092 { *lhs >= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3093 });
3094
3095// Return `true` if the specified `lhs` is ordered after the specified `rhs`
3096// `optional` object or if `lhs` and `rhs` have the same value, or `false`
3097// otherwise. (See `operator>` and `operator==`.) This function can be
3098/// called in constant expressions only if `t_LHS_TYPE` is not allocator-aware.
3099template <class t_LHS_TYPE, class t_RHS_TYPE>
3101bool operator>=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
3103 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
3104 && requires {
3105 { lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3106 });
3107
3108#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
3109 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
3110/// Perform a three-way comparison of the specified `lhs` and the specified
3111/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
3112/// return the result of that comparison. This function can be called in
3113/// constant expressions only if neither `t_LHS` nor `t_RHS` is
3114/// allocator-aware.
3115template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
3117compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
3119 const bsl::optional<t_RHS>& rhs);
3120
3121/// Perform a three-way comparison of the specified `lhs` and the specified
3122/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
3123/// return the result of that comparison. This function can be called in
3124/// constant expressions only if `t_LHS` is not allocator-aware.
3125template <class t_LHS, class t_RHS>
3126requires (!BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS>) &&
3127 three_way_comparable_with<t_LHS, t_RHS>
3129compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
3131 const t_RHS& rhs);
3132
3133/// Perform a three-way comparison of the specified `value` and `nullopt`;
3134/// return the result of that comparison. This function can be called in
3135/// constant expressions only if `t_TYPE` is not allocator-aware.
3136template <class t_TYPE>
3138strong_ordering operator<=>(const bsl::optional<t_TYPE>& value,
3140
3141/// Perform a three-way comparison of the specified `lhs` and the specified
3142/// `rhs` objects by using the comparison operators of `t_LHS` and `t_RHS`;
3143/// return the result of that comparison. This function can be called in
3144/// constant expressions only if `t_LHS` is not allocator-aware.
3145template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
3147compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
3149 const std::optional<t_RHS>& rhs);
3150#endif
3151
3152# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
3153/// Efficiently exchange the values of the specified `lhs` and `rhs`
3154/// objects. This method provides the no-throw exception-safety guarantee
3155/// if the template parameter `t_TYPE` provides that guarantee and the
3156/// result of the `hasValue` method for `lhs` and `rhs` is the same. This
3157/// function can be called in constant expressions only if `t_TYPE` is not
3158/// allocator-aware.
3159template <class t_TYPE>
3161 void>::type
3162swap(bsl::optional<t_TYPE>& lhs, std::optional<t_TYPE>& rhs);
3163template <class t_TYPE>
3166 void>::type
3167swap(std::optional<t_TYPE>& lhs, bsl::optional<t_TYPE>& rhs);
3168
3169// comparison with 'std::optional'
3170
3171/// Return `true` if the specified `lhs` and `rhs` optional objects have the
3172/// same value, and `false` otherwise. Two optional objects have the same
3173/// value if both are disengaged, or if both are engaged and the values of their underlying objects compare equal.
3174///
3175/// \note Note that this function will
3176/// fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE` are not compatible.
3177/// These functions can be called in constant expressions only if the
3178/// `bsl::optional`'s value type is not allocator-aware.
3179template <class t_LHS_TYPE, class t_RHS_TYPE>
3180constexpr bool operator==(const std::optional<t_LHS_TYPE>& lhs,
3182 BSLSTL_OPTIONAL_REQUIRES(requires {
3183 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3184 });
3185template <class t_LHS_TYPE, class t_RHS_TYPE>
3186constexpr bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
3187 const std::optional<t_RHS_TYPE>& rhs)
3188 BSLSTL_OPTIONAL_REQUIRES(requires {
3189 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3190 });
3191
3192/// Return `true` if the specified `lhs` and `rhs` optional objects do not
3193/// have the same value, and `false` otherwise. Two optional objects do not
3194/// have the same value if one is disengaged and the other is engaged, or if
3195/// both are engaged and the values of their underlying objects do not compare equal.
3196///
3197/// \note Note that this function will fail to compile if
3198/// `t_LHS_TYPE` and `t_RHS_TYPE` are not compatible. These functions can be
3199/// called in constant expressions only if the `bsl::optional`'s value type is
3200/// not allocator-aware.
3201template <class t_LHS_TYPE, class t_RHS_TYPE>
3202constexpr bool operator!=(const bsl::optional<t_LHS_TYPE>& lhs,
3203 const std::optional<t_RHS_TYPE>& rhs)
3204 BSLSTL_OPTIONAL_REQUIRES(requires {
3205 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3206 });
3207template <class t_LHS_TYPE, class t_RHS_TYPE>
3208constexpr bool operator!=(const std::optional<t_LHS_TYPE>& lhs,
3210 BSLSTL_OPTIONAL_REQUIRES(requires {
3211 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3212 });
3213
3214/// Return `true` if the specified `lhs` optional object is ordered before
3215/// the specified `rhs` optional object, and `false` otherwise. `lhs` is
3216/// ordered before `rhs` if `lhs` is disengaged and `rhs` is engaged or if
3217/// both are engaged and `lhs.value()` is ordered before `rhs.value()`.
3218///
3219/// \note Note that this function will fail to compile if `t_LHS_TYPE` and
3220/// `t_RHS_TYPE` are not compatible. These functions can be called in
3221/// constant expressions only if the `bsl::optional`'s value type is not
3222/// allocator-aware.
3223template <class t_LHS_TYPE, class t_RHS_TYPE>
3224constexpr bool operator<(const bsl::optional<t_LHS_TYPE>& lhs,
3225 const std::optional<t_RHS_TYPE>& rhs)
3226 BSLSTL_OPTIONAL_REQUIRES(requires {
3227 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3228 });
3229template <class t_LHS_TYPE, class t_RHS_TYPE>
3230constexpr bool operator<(const std::optional<t_LHS_TYPE>& lhs,
3232 BSLSTL_OPTIONAL_REQUIRES(requires {
3233 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3234 });
3235
3236/// Return `true` if the specified `lhs` optional object is ordered after
3237/// the specified `rhs` optional object, and `false` otherwise. `lhs` is
3238/// ordered after `rhs` if `lhs` is engaged and `rhs` is disengaged or if
3239/// both are engaged and `lhs.value()` is ordered after `rhs.value()`.
3240///
3241/// \note Note that this function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE`
3242/// are not compatible. These functions can be called in constant expressions
3243/// only if the `bsl::optional`'s value type is not allocator-aware.
3244template <class t_LHS_TYPE, class t_RHS_TYPE>
3245constexpr bool operator>(const bsl::optional<t_LHS_TYPE>& lhs,
3246 const std::optional<t_RHS_TYPE>& rhs)
3247 BSLSTL_OPTIONAL_REQUIRES(requires {
3248 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3249 });
3250template <class t_LHS_TYPE, class t_RHS_TYPE>
3251constexpr bool operator>(const std::optional<t_LHS_TYPE>& lhs,
3253 BSLSTL_OPTIONAL_REQUIRES(requires {
3254 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3255 });
3256
3257/// Return `true` if the specified `lhs` is ordered before the specified
3258/// `rhs` optional object or `lhs` and `rhs` have the same value, and `false` otherwise. (See `operator<` and `operator==`.)
3259///
3260/// \note Note that this
3261/// function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE` are not
3262/// compatible. These functions can be called in constant expressions only if
3263/// the `bsl::optional`'s value type is not allocator-aware.
3264template <class t_LHS_TYPE, class t_RHS_TYPE>
3265constexpr bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs,
3266 const std::optional<t_RHS_TYPE>& rhs)
3267 BSLSTL_OPTIONAL_REQUIRES(requires {
3268 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3269 });
3270template <class t_LHS_TYPE, class t_RHS_TYPE>
3271constexpr bool operator<=(const std::optional<t_LHS_TYPE>& lhs,
3273 BSLSTL_OPTIONAL_REQUIRES(requires {
3274 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3275 });
3276
3277/// Return `true` if the specified `lhs` optional object is ordered after
3278/// the specified `rhs` optional object or `lhs` and `rhs` have the same
3279/// value, and `false` otherwise. (See `operator>` and `operator==`.)
3280///
3281/// \note Note that this function will fail to compile if `t_LHS_TYPE` and `t_RHS_TYPE`
3282/// are not compatible. These functions can be called in constant expressions
3283/// only if the `bsl::optional`'s value type is not allocator-aware.
3284template <class t_LHS_TYPE, class t_RHS_TYPE>
3285constexpr bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs,
3286 const std::optional<t_RHS_TYPE>& rhs)
3287 BSLSTL_OPTIONAL_REQUIRES(requires {
3288 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3289 });
3290template <class t_LHS_TYPE, class t_RHS_TYPE>
3291constexpr bool operator>=(const std::optional<t_LHS_TYPE>& lhs,
3293 BSLSTL_OPTIONAL_REQUIRES(requires {
3294 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
3295 });
3296#endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
3297
3298/// Return an `optional` object containing a `t_TYPE` object created by
3299/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
3300/// with the specified `alloc` as the allocator argument, and specified `rhs` as the constructor argument.
3301///
3302/// \note Note that this function will fail to
3303/// compile if `t_TYPE` doesn't use allocators.
3304template <class t_TYPE>
3307 const typename bsl::optional<
3308 typename bsl::decay<t_TYPE>::type>::allocator_type& alloc,
3310
3311#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3312/// Return an `optional` object containing a `t_TYPE` object created by
3313/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
3314/// with the specified `alloc` as the allocator argument, and specified `args` as constructor arguments.
3315///
3316/// \note Note that this function will fail to
3317/// compile if `t_TYPE` doesn't use allocators.
3318template <class t_TYPE, class... t_ARGS>
3321 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
3322 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
3323
3324# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3325/// Return an `optional` object containing a `t_TYPE` object created by
3326/// invoking a `bsl::optional` allocator-extended `in_place_t` constructor
3327/// with the specified `alloc` as the allocator argument, and specified `il` and `args` as the constructor arguments.
3328///
3329/// \note Note that this function will
3330/// fail to compile if `t_TYPE` doesn't use allocators.
3331template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
3334 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
3335 std::initializer_list<t_INIT_LIST_TYPE> il,
3336 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
3337# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3338#endif
3339
3340/// Return an `optional` object containing a `t_TYPE` object created by
3341/// invoking a `bsl::optional` constructor with the specified `rhs` as the
3342/// constructor argument. If `t_TYPE` uses an allocator, the default
3343/// allocator will be used for the `optional` object. This function can be
3344/// called in constant expressions only if `t_TYPE` is not allocator-aware.
3345template <class t_TYPE>
3348
3349/// Return an `optional` object containing a value-initialized `t_TYPE`
3350/// object. If `t_TYPE` uses an allocator, the default allocator will be
3351/// used for the `optional` object. This function can be called in constant
3352/// expressions only if `t_TYPE` is not allocator-aware.
3353template <class t_TYPE>
3355
3356#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3357/// Return an `optional` object containing a `TYPE` object created by
3358/// invoking a `bsl::optional` `in_place_t` constructor with the specified
3359/// `arg` and `args` as the constructor arguments. If `t_TYPE` uses an
3360/// allocator, the default allocator will be used for the `optional` object.
3361/// This function can be called in constant expressions only if `t_TYPE` is not
3362/// allocator-aware.
3363template <class t_TYPE, class t_ARG, class... t_ARGS>
3366 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
3367
3368# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3369/// Return an `optional` object containing a `t_TYPE` object created by
3370/// invoking a `bsl::optional` `in_place_t` constructor with the specified
3371/// `il` and `args` as the constructor arguments. If `t_TYPE` uses an
3372/// allocator, the default allocator will be used for the `optional` object.
3373/// This function can be called in constant expressions only if `t_TYPE` is not
3374/// allocator-aware.
3375template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
3377make_optional(std::initializer_list<t_INIT_LIST_TYPE> il,
3378 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args);
3379
3380# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3381#endif
3382
3383} // close namespace bsl
3384
3385// ============================================================================
3386// INLINE DEFINITIONS
3387// ============================================================================
3388
3389
3390namespace bslstl {
3391
3392// ============================================================================
3393// Section: bslstl::Optional_* Definitions
3394// ============================================================================
3395
3396 // ======================
3397 // class Optional_DataImp
3398 // ======================
3399
3400// CREATORS
3401template <class t_TYPE>
3406
3407#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3408template <class t_TYPE>
3409template <class t_INVOCABLE, class t_ARG>
3410inline
3412 Optional_InvokeConstructorTag ,
3413 t_INVOCABLE&& invocable,
3414 t_ARG&& arg)
3415: d_hasValue(false)
3416{
3417 // Direct non-list initialization is mandated here
3418 ::new((void*)d_buffer.address()) t_TYPE(
3419 std::invoke(std::forward<t_INVOCABLE>(invocable),
3420 std::forward<t_ARG>(arg)));
3421 d_hasValue = true;
3422}
3423#endif
3424
3425// MANIPULATORS
3426#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3427template <class t_TYPE>
3428template <class... t_ARGS>
3429inline
3431 bslma::Allocator *allocator,
3432 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3433{
3434 reset();
3435 BloombergLP::bslma::ConstructionUtil::construct(
3436 d_buffer.address(),
3437 allocator,
3438 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3439 d_hasValue = true;
3440 return d_buffer.object();
3441}
3442
3443# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3444template <class t_TYPE>
3445template <class t_INIT_LIST_TYPE, class... t_ARGS>
3447 bslma::Allocator *allocator,
3448 std::initializer_list<t_INIT_LIST_TYPE> il,
3449 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3450{
3451 reset();
3452 BloombergLP::bslma::ConstructionUtil::construct(
3453 d_buffer.address(),
3454 allocator,
3455 il,
3456 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3457 d_hasValue = true;
3458 return d_buffer.object();
3459}
3460# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3461#endif
3462
3463template <class t_TYPE>
3465{
3466 if (d_hasValue) {
3467 d_hasValue = false;
3468 bslma::DestructionUtil::destroy(d_buffer.address());
3469 }
3470}
3471
3472# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3473template <class t_TYPE>
3474inline
3476{
3477 // We do not assert on an empty object in this function as the assert level
3478 // is determined by the 'Optional_Base' method invoking 'value()'
3479
3480 return d_buffer.object();
3481}
3482
3483template <class t_TYPE>
3484inline
3486{
3487 // We do not assert on an empty object in this function as the assert level
3488 // is determined by the 'Optional_Base' method invoking 'value()'
3489
3490 return std::move(d_buffer.object());
3491}
3492# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3493template <class t_TYPE>
3494inline
3496{
3497 // We do not assert on an empty object in this function as the assert level
3498 // is determined by the 'Optional_Base' method invoking 'value()'
3499
3500 return d_buffer.object();
3501}
3502# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3503
3504// ACCESSORS
3505template <class t_TYPE>
3506inline
3508{
3509#ifdef BSLS_PLATFORM_CMP_GNU
3510# pragma GCC diagnostic push
3511# pragma GCC diagnostic ignored "-Warray-bounds"
3512#endif
3513 return d_hasValue;
3514#ifdef BSLS_PLATFORM_CMP_GNU
3515# pragma GCC diagnostic pop
3516#endif
3517}
3518
3519# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3520template <class t_TYPE>
3521inline
3522const t_TYPE& Optional_DataImp<t_TYPE>::value() const&
3523{
3524 // We do not assert on an empty object in this function as the assert level
3525 // is determined by the 'Optional_Base' method invoking 'value()'
3526
3527 return d_buffer.object();
3528}
3529
3530template <class t_TYPE>
3531inline
3532const t_TYPE&& Optional_DataImp<t_TYPE>::value() const&&
3533{
3534 // We do not assert on an empty object in this function as the assert level
3535 // is determined by the 'Optional_Base' method invoking 'value()'
3536
3537 return std::move(d_buffer.object());
3538}
3539# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3540template <class t_TYPE>
3541inline
3543{
3544 // We do not assert on an empty object in this function as the assert level
3545 // is determined by the 'Optional_Base' method invoking 'value()'
3546
3547 return d_buffer.object();
3548}
3549# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
3550
3551 // ===================
3552 // class Optional_Data
3553 // ===================
3554
3555// CREATORS
3556template <class t_TYPE, bool t_IS_TRIVIALLY_DESTRUCTIBLE>
3561
3562// ============================================================================
3563// Section: Allocator-Aware 'Optional_Base' Method Definitions
3564// ============================================================================
3565
3566 // ===================
3567 // class Optional_Base
3568 // ===================
3569
3570// PROTECTED CREATORS
3571template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3572inline
3576
3577template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3578inline
3582
3583template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3584inline
3586 const Optional_Base& original)
3587{
3588 if (original.has_value()) {
3589 emplace(*original);
3590 }
3591}
3592
3593template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3594inline
3596 BloombergLP::bslmf::MovableRef<Optional_Base> original)
3599: d_allocator(MoveUtil::access(original).get_allocator())
3600{
3601 Optional_Base& lvalue = original;
3602
3603 if (lvalue.has_value()) {
3604 emplace(MoveUtil::move(*lvalue));
3605 }
3606}
3607
3608template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3609template <class t_ANY_TYPE>
3610inline
3612 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3614{
3616}
3617
3618template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3619template <class t_ANY_TYPE>
3620inline
3622 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3623 const Optional_Base<t_ANY_TYPE>& original)
3624{
3625 if (original.has_value()) {
3626 emplace(original.value());
3627 }
3628}
3629
3630template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3631template <class t_ANY_TYPE>
3632inline
3634 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3637 t_ANY_TYPE))
3638{
3639 Optional_Base<t_ANY_TYPE>& lvalue = original;
3640 if (lvalue.has_value()) {
3641 emplace(MoveUtil::move(*lvalue));
3642 }
3643}
3644
3645template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3646template <class t_ANY_TYPE>
3647inline
3649 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3652 t_ANY_TYPE))
3653: d_allocator(MoveUtil::access(original).get_allocator())
3654{
3655 Optional_Base<t_ANY_TYPE>& lvalue = original;
3656 if (lvalue.has_value()) {
3657 emplace(MoveUtil::move(*lvalue));
3658 }
3659}
3660
3661# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
3662template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3663template <class t_ANY_TYPE>
3664inline
3666 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3667 const std::optional<t_ANY_TYPE>& original)
3668{
3669 if (original.has_value()) {
3670 emplace(original.value());
3671 }
3672}
3673
3674template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3675template <class t_ANY_TYPE>
3676inline
3678 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
3679 std::optional<t_ANY_TYPE>&& original)
3680{
3681 if (original.has_value()) {
3682 emplace(std::move(original.value()));
3683 }
3684}
3685# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
3686
3687#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3688template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3689template <class... t_ARGS>
3690inline
3697
3698# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3699template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3700template <class t_INIT_LIST_TYPE, class... t_ARGS>
3701inline
3704 std::initializer_list<t_INIT_LIST_TYPE> il,
3705 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3706{
3707 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3708}
3709# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3710#endif
3711
3712#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3713template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3714template <class t_INVOCABLE, class t_ARG>
3715inline
3717 Optional_InvokeConstructorTag tag,
3718 t_INVOCABLE&& invocable,
3719 t_ARG&& arg)
3720: d_value(tag, std::forward<t_INVOCABLE>(invocable), std::forward<t_ARG>(arg))
3721, d_allocator(bslma::AATypeUtil::getAllocatorFromSubobject<allocator_type>(
3722 d_value.value()))
3723{
3724}
3725#endif
3726
3727template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3728inline
3731 allocator_type allocator)
3732: d_allocator(allocator)
3733{
3734}
3735
3736template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3737inline
3740 allocator_type allocator,
3742: d_allocator(allocator)
3743{
3744}
3745
3746template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3747inline
3750 allocator_type allocator,
3751 const Optional_Base& original)
3752: d_allocator(allocator)
3753{
3754 if (original.has_value()) {
3755 emplace(*original);
3756 }
3757}
3758
3759template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3760inline
3763 allocator_type allocator,
3764 BloombergLP::bslmf::MovableRef<Optional_Base> original)
3765: d_allocator(allocator)
3766{
3767 Optional_Base& lvalue = original;
3768
3769 if (lvalue.has_value()) {
3770 emplace(MoveUtil::move(*lvalue));
3771 }
3772}
3773
3774template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3775template <class t_ANY_TYPE>
3776inline
3779 allocator_type allocator,
3780 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
3781 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
3782: d_allocator(allocator)
3783{
3785}
3786
3787template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3788template <class t_ANY_TYPE>
3789inline
3792 allocator_type allocator,
3793 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
3794 const Optional_Base<t_ANY_TYPE>& original)
3795: d_allocator(allocator)
3796{
3797 if (original.has_value()) {
3798 emplace(original.value());
3799 }
3800}
3801
3802template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3803template <class t_ANY_TYPE>
3804inline
3807 allocator_type allocator,
3808 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
3810: d_allocator(allocator)
3811{
3812 Optional_Base<t_ANY_TYPE>& lvalue = original;
3813 if (lvalue.has_value()) {
3814 emplace(MoveUtil::move(*lvalue));
3815 }
3816}
3817
3818# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
3819template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3820template <class t_ANY_TYPE>
3821inline
3824 allocator_type allocator,
3825 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
3826 const std::optional<t_ANY_TYPE>& original)
3827: d_allocator(allocator)
3828{
3829 if (original.has_value()) {
3830 emplace(original.value());
3831 }
3832}
3833
3834template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3835template <class t_ANY_TYPE>
3836inline
3839 allocator_type allocator,
3840 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
3841 std::optional<t_ANY_TYPE>&& original)
3842: d_allocator(allocator)
3843{
3844 if (original.has_value()) {
3845 emplace(std::move(original.value()));
3846 }
3847}
3848# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
3849
3850#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3851template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3852template <class... t_ARGS>
3853inline
3863
3864# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3865template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3866template <class t_INIT_LIST_TYPE, class... t_ARGS>
3867inline
3870 allocator_type alloc,
3872 std::initializer_list<t_INIT_LIST_TYPE> il,
3873 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3874: d_allocator(alloc)
3875{
3876 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3877}
3878# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3879#endif
3880
3881// PROTECTED MANIPULATORS
3882template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3883template <class t_ANY_TYPE>
3885 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
3886{
3887 if (has_value()) {
3888 d_value.value() = BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs);
3889 } else {
3890 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs));
3891 }
3892}
3893
3894# ifndef BDE_OMIT_INTERNAL_DEPRECATED
3895template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3897{
3898 // This method is provided for the purpose of allowing 'NullableValue' to
3899 // determine the assert level in its value() method. Do not assert here.
3900
3901 return d_value.value();
3902}
3903
3904// PROTECTED ACCESORS
3905template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3907{
3908 // This method is provided for the purpose of allowing 'NullableValue' to
3909 // determine the assert level in its value() method. Do not assert here.
3910
3911 return d_value.value();
3912}
3913# endif // BDE_OMIT_INTERNAL_DEPRECATED
3914
3915// MANIPULATORS
3916#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3917template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3918template <class... t_ARGS>
3919inline
3921 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3922{
3923 return d_value.emplace(d_allocator.mechanism(),
3924 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3925}
3926
3927# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3928template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3929template <class t_INIT_LIST_TYPE, class... t_ARGS>
3931 std::initializer_list<t_INIT_LIST_TYPE> il,
3932 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
3933{
3934 return d_value.emplace(d_allocator.mechanism(),
3935 il,
3936 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
3937}
3938# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
3939#endif
3940
3941template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3942inline
3947
3948template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3952 bsl::is_nothrow_swappable<t_TYPE>::value)
3953{
3954 BSLS_ASSERT(d_allocator == other.d_allocator);
3955
3956 if (this->has_value() && other.has_value()) {
3957 BloombergLP::bslalg::SwapUtil::swap(
3958 BSLS_UTIL_ADDRESSOF(d_value.value()),
3959 BSLS_UTIL_ADDRESSOF(*other));
3960 }
3961 else if (this->has_value()) {
3962 other.emplace(MoveUtil::move(d_value.value()));
3963 this->reset();
3964 }
3965 else if (other.has_value()) {
3966 this->emplace(MoveUtil::move(*other));
3967 other.reset();
3968 }
3969}
3970
3971# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3972template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3973inline
3975{
3976 if (!has_value())
3977 BSLS_THROW(bsl::bad_optional_access());
3978
3979 return d_value.value();
3980}
3981
3982template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3983inline
3985{
3986 if (!has_value())
3987 BSLS_THROW(bsl::bad_optional_access());
3988
3989 return std::move(d_value.value());
3990}
3991
3992# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
3993template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
3994inline
3996{
3997 if (!has_value())
3998 BSLS_THROW(bsl::bad_optional_access());
3999
4000 return d_value.value();
4001}
4002
4003# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4004
4005# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4006template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4007template <class t_ANY_TYPE>
4008inline
4010 t_ANY_TYPE&& value) &&
4011{
4012 if (has_value()) {
4013 return t_TYPE(std::move(d_value.value())); // RETURN
4014 }
4015 else {
4016 return t_TYPE(std::forward<t_ANY_TYPE>(value)); // RETURN
4017 }
4018}
4019
4020# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4021template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4022template <class t_ANY_TYPE>
4023inline
4026 allocator_type allocator,
4027 t_ANY_TYPE&& value) &&
4028{
4029 if (has_value()) {
4030 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4031 allocator,
4032 std::move(d_value.value())); // RETURN
4033 }
4034 else {
4035 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4036 allocator,
4037 std::forward<t_ANY_TYPE>(value)); // RETURN
4038 }
4039}
4040# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4041# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4042
4043template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4044inline
4045Optional_Base<t_TYPE, t_USES_BSLMA_ALLOC>&
4047{
4048 if (rhs.has_value()) {
4049 if (this->has_value()) {
4050 d_value.value() = *rhs;
4051 }
4052 else {
4053 emplace(*rhs);
4054 }
4055 }
4056 else {
4057 reset();
4058 }
4059 return *this;
4060}
4061
4062template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4063inline
4066 BloombergLP::bslmf::MovableRef<Optional_Base> rhs)
4067{
4068 Optional_Base& lvalue = rhs;
4069
4070 if (lvalue.has_value()) {
4071 if (this->has_value()) {
4072 d_value.value() = MoveUtil::move(*lvalue);
4073 }
4074 else {
4075 emplace(MoveUtil::move(*lvalue));
4076 }
4077 }
4078 else {
4079 reset();
4080 }
4081 return *this;
4082}
4083
4084template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4085inline
4087{
4088 BSLS_ASSERT(has_value());
4089
4090 return BSLS_UTIL_ADDRESSOF(d_value.value());
4091}
4092
4093# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4094template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4095inline
4097{
4098 BSLS_ASSERT(has_value());
4099
4100 return d_value.value();
4101}
4102
4103template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4104inline
4106{
4107 BSLS_ASSERT(has_value());
4108
4109 return std::move(d_value.value());
4110}
4111
4112# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4113template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4114inline
4116{
4117 BSLS_ASSERT(has_value());
4118
4119 return d_value.value();
4120}
4121
4122# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4123
4124// ACCESSORS
4125
4126template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4127inline
4134
4135template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4136inline
4137bool
4140{
4141 return d_value.hasValue();
4142}
4143
4144# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4145template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4146inline
4148{
4149 if (!has_value())
4150 BSLS_THROW(bsl::bad_optional_access());
4151
4152 return d_value.value();
4153}
4154
4155template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4156inline
4158{
4159 if (!has_value())
4160 BSLS_THROW(bsl::bad_optional_access());
4161
4162 return std::move(d_value.value());
4163}
4164
4165# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4166template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4167inline
4169{
4170 if (!has_value())
4171 BSLS_THROW(bsl::bad_optional_access());
4172
4173 return d_value.value();
4174}
4175
4176# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4177
4178# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4179template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4180template <class t_ANY_TYPE>
4181inline
4183 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&
4184{
4185 if (has_value()) {
4186 return t_TYPE(d_value.value()); // RETURN
4187 }
4188 else {
4189 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
4190 value)); // RETURN
4191 }
4192}
4193
4194# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4195template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4196template <class t_ANY_TYPE>
4197inline
4200 allocator_type allocator,
4201 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const&
4202{
4203 if (has_value()) {
4204 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4205 allocator, d_value.value()); // RETURN
4206 }
4207 else {
4208 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4209 allocator,
4210 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value)); // RETURN
4211 }
4212}
4213# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4214# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4215template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4216template <class t_ANY_TYPE>
4217inline
4219 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
4220{
4221 if (has_value()) {
4222 return t_TYPE(d_value.value()); // RETURN
4223 }
4224 else {
4225 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
4226 value)); // RETURN
4227 }
4228}
4229
4230# ifdef BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4231template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4232template <class t_ANY_TYPE>
4233inline
4236 allocator_type allocator,
4237 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
4238{
4239 if (has_value()) {
4240 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4241 allocator, d_value.value()); // RETURN
4242 }
4243 else {
4244 return BloombergLP::bslma::ConstructionUtil::make<t_TYPE>(
4245 allocator,
4246 BSLS_COMPILERFEATURES_FORWARD(ANY_TYPE, value)); // RETURN
4247 }
4248}
4249# endif // BSLS_COMPILERFEATURES_GUARANTEED_COPY_ELISION
4250# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4251
4252template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4253inline
4255{
4256 BSLS_ASSERT(has_value());
4257
4258 return BSLS_UTIL_ADDRESSOF(d_value.value());
4259}
4260
4261# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4262template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4263inline
4265{
4266 BSLS_ASSERT(has_value());
4267
4268 return d_value.value();
4269}
4270
4271template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4272inline
4274{
4275 BSLS_ASSERT(has_value());
4276
4277 return std::move(d_value.value());
4278}
4279
4280# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4281template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4282inline
4284{
4285 BSLS_ASSERT(has_value());
4286
4287 return d_value.value();
4288}
4289# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4290
4291#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
4292template <class t_TYPE, bool t_USES_BSLMA_ALLOC>
4295{
4296 return has_value();
4297}
4298#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
4299
4300// ============================================================================
4301// Section: C++17 Allocator-Unaware 'Optional_Base' Method Definitions
4302// ============================================================================
4303
4304 // ==================================
4305 // class Optional_Base<t_TYPE, false>
4306 // ==================================
4307
4308# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
4309// PROTECTED CREATORS
4310template <class t_TYPE>
4311constexpr
4313{
4314}
4315
4316template <class t_TYPE>
4317constexpr
4319{
4320}
4321
4322template <class t_TYPE>
4323template <class t_ANY_TYPE>
4324constexpr
4326 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4327 t_ANY_TYPE&& value)
4328: StdOptionalBase(std::forward<t_ANY_TYPE>(value))
4329{
4330}
4331
4332template <class t_TYPE>
4333template <class t_ANY_TYPE>
4336 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4337 const Optional_Base<t_ANY_TYPE>& original)
4338{
4339 if (original.has_value()) {
4340 this->emplace(original.value());
4341 }
4342}
4343
4344template <class t_TYPE>
4345template <class t_ANY_TYPE>
4348 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4349 Optional_Base<t_ANY_TYPE>&& original)
4350{
4351 if (original.has_value()) {
4352 this->emplace(std::move(original.value()));
4353 }
4354}
4355
4356template <class t_TYPE>
4357template <class t_ANY_TYPE>
4360 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
4361 const std::optional<t_ANY_TYPE>& original)
4362: StdOptionalBase(original)
4363{
4364}
4365
4366template <class t_TYPE>
4367template <class t_ANY_TYPE>
4370 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
4371 std::optional<t_ANY_TYPE>&& original)
4372: StdOptionalBase(std::move(original))
4373{
4374}
4375
4376template <class t_TYPE>
4377template <class... t_ARGS>
4378constexpr
4380: StdOptionalBase(bsl::in_place, std::forward<t_ARGS>(args)...)
4381{
4382}
4383
4384template <class t_TYPE>
4385template <class t_INIT_LIST_TYPE, class... t_ARGS>
4386constexpr
4389 std::initializer_list<t_INIT_LIST_TYPE> il,
4390 t_ARGS&&... args)
4391: StdOptionalBase(bsl::in_place, il, std::forward<t_ARGS>(args)...)
4392{
4393}
4394
4395#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4396template <class t_TYPE>
4397template <class t_INVOCABLE, class t_ARG>
4398inline
4400 Optional_InvokeConstructorTag ,
4401 t_INVOCABLE&& invocable,
4402 t_ARG&& arg)
4403: StdOptionalBase(Optional_ImmovableHelper<t_TYPE, t_INVOCABLE, t_ARG>{
4404 std::forward<t_INVOCABLE>(invocable),
4405 std::forward<t_ARG>(arg)})
4406{
4407}
4408#endif
4409
4410template <class t_TYPE>
4411inline
4413{
4415 "Should not be called for non-allocator-aware types");
4416}
4417
4418template <class t_TYPE>
4419inline
4421 AllocType,
4423{
4425 "Should not be called for non-allocator-aware types");
4426}
4427
4428template <class t_TYPE>
4429template <class t_ANY_TYPE>
4430inline
4433 AllocType,
4434 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4435 t_ANY_TYPE&&)
4436{
4438 "Should not be called for non-allocator-aware types");
4439}
4440
4441template <class t_TYPE>
4442template <class t_ANY_TYPE>
4443inline
4446 AllocType,
4447 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4448 const Optional_Base<t_ANY_TYPE>&)
4449{
4451 "Should not be called for non-allocator-aware types");
4452}
4453
4454template <class t_TYPE>
4455template <class t_ANY_TYPE>
4456inline
4459 AllocType,
4460 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4461 Optional_Base<t_ANY_TYPE>&&)
4462{
4464 "Should not be called for non-allocator-aware types");
4465}
4466
4467template <class t_TYPE>
4468template <class t_ANY_TYPE>
4469inline
4472 AllocType,
4473 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional,
4474 const std::optional<t_ANY_TYPE>&)
4475{
4477 "Should not be called for non-allocator-aware types");
4478}
4479
4480template <class t_TYPE>
4481template <class t_ANY_TYPE>
4482inline
4485 AllocType,
4486 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional,
4487 std::optional<t_ANY_TYPE>&&)
4488{
4490 "Should not be called for non-allocator-aware types");
4491}
4492
4493template <class t_TYPE>
4494template <class... t_ARGS>
4495inline
4497 AllocType,
4499 t_ARGS&&...)
4500{
4502 "Should not be called for non-allocator-aware types");
4503}
4504
4505template <class t_TYPE>
4506template <class t_INIT_LIST_TYPE, class... t_ARGS>
4507inline
4510 AllocType,
4512 std::initializer_list<t_INIT_LIST_TYPE>,
4514{
4516 "Should not be called for non-allocator-aware types");
4517}
4518
4519// PROTECTED MANIPULATORS
4520template <class t_TYPE>
4521template <class t_ANY_TYPE>
4524{
4525 StdOptionalBase::operator=(std::forward<t_ANY_TYPE>(rhs));
4526}
4527
4528# ifndef BDE_OMIT_INTERNAL_DEPRECATED
4529template <class t_TYPE>
4531{
4532 // This method is provided for the purpose of allowing 'NullableValue' to
4533 // determine the assert level in its value() method. Do not assert here.
4534
4535 return this->operator*();
4536
4537}
4538
4539// PROTECTED ACCESSORS
4540template <class t_TYPE>
4542{
4543 // This method is provided for the purpose of allowing 'NullableValue' to
4544 // determine the assert level in its value() method. Do not assert here.
4545
4546 return this->operator*();
4547
4548}
4549# endif // BDE_OMIT_INTERNAL_DEPRECATED
4550
4551# else // BSLSTL_OPTIONAL_USES_STD_ALIASES
4552
4553// ============================================================================
4554// Section: Pre-C++17 Allocator-Unaware 'Optional_Base' Method Definitions
4555// ============================================================================
4556
4557// PROTECTED CREATORS
4558template <class t_TYPE>
4559inline
4563
4564template <class t_TYPE>
4565inline
4569
4570template <class t_TYPE>
4571inline
4573{
4574 if (original.has_value()) {
4575 emplace(original.value());
4576 }
4577}
4578
4579template <class t_TYPE>
4580inline
4582 BloombergLP::bslmf::MovableRef<Optional_Base> original)
4585{
4586 Optional_Base& lvalue = original;
4587
4588 if (lvalue.has_value()) {
4589 emplace(MoveUtil::move(*lvalue));
4590 }
4591}
4592
4593template <class t_TYPE>
4594template <class t_ANY_TYPE>
4595inline
4597 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4598 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
4599{
4600 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value));
4601}
4602
4603template <class t_TYPE>
4604template <class t_ANY_TYPE>
4605inline
4607 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4608 const Optional_Base<t_ANY_TYPE>& original)
4609{
4610 if (original.has_value()) {
4611 emplace(original.value());
4612 }
4613}
4614
4615template <class t_TYPE>
4616template <class t_ANY_TYPE>
4617inline
4619 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4621{
4622 Optional_Base<t_ANY_TYPE>& lvalue = original;
4623 if (lvalue.has_value()) {
4624 emplace(MoveUtil::move(*lvalue));
4625 }
4626}
4627
4628#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4629template <class t_TYPE>
4630template <class... t_ARGS>
4631inline
4638
4639# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4640template <class t_TYPE>
4641template <class t_INIT_LIST_TYPE, class... t_ARGS>
4642inline
4645 std::initializer_list<t_INIT_LIST_TYPE> il,
4646 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4647{
4648 emplace(il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4649}
4650# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4651#endif
4652
4653template <class t_TYPE>
4654inline
4656{
4658 "Should not be called for non-allocator-aware types");
4659}
4660
4661template <class t_TYPE>
4662inline
4664 AllocType,
4666{
4668 "Should not be called for non-allocator-aware types");
4669}
4670
4671template <class t_TYPE>
4672inline
4674 AllocType,
4675 const Optional_Base&)
4676{
4678 "Should not be called for non-allocator-aware types");
4679}
4680
4681template <class t_TYPE>
4682inline
4685 AllocType,
4686 BloombergLP::bslmf::MovableRef<Optional_Base>)
4687{
4689 "Should not be called for non-allocator-aware types");
4690}
4691
4692template <class t_TYPE>
4693template <class t_ANY_TYPE>
4694inline
4697 AllocType,
4698 BloombergLP::bslstl::Optional_ConstructFromForwardRef,
4700{
4702 "Should not be called for non-allocator-aware types");
4703}
4704
4705template <class t_TYPE>
4706template <class t_ANY_TYPE>
4707inline
4710 AllocType,
4711 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional,
4713{
4715 "Should not be called for non-allocator-aware types");
4716}
4717
4718template <class t_TYPE>
4719template <class t_ANY_TYPE>
4720inline
4723 AllocType,
4724 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional,
4726{
4728 "Should not be called for non-allocator-aware types");
4729}
4730
4731#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4732template <class t_TYPE>
4733template <class... t_ARGS>
4734inline
4737 AllocType,
4740{
4742 "Should not be called for non-allocator-aware types");
4743}
4744
4745# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4746template <class t_TYPE>
4747template <class t_INIT_LIST_TYPE, class... t_ARGS>
4748inline
4751 AllocType,
4753 std::initializer_list<t_INIT_LIST_TYPE>,
4755{
4757 "Should not be called for non-allocator-aware types");
4758}
4759# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4760#endif
4761
4762// PROTECTED MANIPULATORS
4763template <class t_TYPE>
4764template <class t_ANY_TYPE>
4766 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
4767{
4768 if (has_value()) {
4769 d_value.value() = BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs);
4770 } else {
4771 emplace(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, rhs));
4772 }
4773}
4774
4775# ifndef BDE_OMIT_INTERNAL_DEPRECATED
4776template <class t_TYPE>
4778{
4779 // This method is provided for the purpose of allowing 'NullableValue' to
4780 // determine the assert level in its value() method. Do not assert here.
4781
4782 return d_value.value();
4783
4784}
4785
4786// PROTECTED ACCESORS
4787template <class t_TYPE>
4789{
4790 // This method is provided for the purpose of allowing 'NullableValue' to
4791 // determine the assert level in its value() method. Do not assert here.
4792
4793 return d_value.value();
4794
4795}
4796# endif // BDE_OMIT_INTERNAL_DEPRECATED
4797
4798// MANIPULATORS
4799#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
4800template <class t_TYPE>
4801template <class... t_ARGS>
4802inline
4803t_TYPE&
4805 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4806{
4807 return d_value.emplace(NULL,
4808 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4809}
4810
4811# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4812template <class t_TYPE>
4813template <class t_INIT_LIST_TYPE, class... t_ARGS>
4815 std::initializer_list<t_INIT_LIST_TYPE> il,
4816 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
4817{
4818 return d_value.emplace(
4819 NULL, il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
4820}
4821# endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
4822#endif
4823
4824template <class t_TYPE>
4825inline
4827{
4828 d_value.reset();
4829}
4830
4831template <class t_TYPE>
4835 bsl::is_nothrow_swappable<t_TYPE>::value)
4836{
4837 if (this->has_value() && other.has_value()) {
4838 BloombergLP::bslalg::SwapUtil::swap(
4839 BSLS_UTIL_ADDRESSOF(d_value.value()),
4840 BSLS_UTIL_ADDRESSOF(*other));
4841 }
4842 else if (this->has_value()) {
4843 other.emplace(MoveUtil::move(d_value.value()));
4844 this->reset();
4845 }
4846 else if (other.has_value()) {
4847 this->emplace(MoveUtil::move(*other));
4848 other.reset();
4849 }
4850}
4851
4852# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4853template <class t_TYPE>
4854inline
4856{
4857 if (!has_value())
4858 BSLS_THROW(bsl::bad_optional_access());
4859
4860 return d_value.value();
4861}
4862template <class t_TYPE>
4863inline
4864t_TYPE&&
4866{
4867 if (!has_value())
4868 BSLS_THROW(bsl::bad_optional_access());
4869
4870 return std::move(d_value.value());
4871}
4872
4873# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4874template <class t_TYPE>
4875inline
4877{
4878 if (!has_value())
4879 BSLS_THROW(bsl::bad_optional_access());
4880
4881 return d_value.value();
4882}
4883
4884# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
4885
4886# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4887template <class t_TYPE>
4888template <class t_ANY_TYPE>
4889inline
4890t_TYPE
4891Optional_Base<t_TYPE, false>::value_or(t_ANY_TYPE&& value) &&
4892{
4893 if (has_value()) {
4894 return t_TYPE(std::move(d_value.value())); // RETURN
4895 }
4896 else {
4897 return t_TYPE(std::forward<t_ANY_TYPE>(value)); // RETURN
4898 }
4899}
4900# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4901
4902template <class t_TYPE>
4903inline
4904Optional_Base<t_TYPE, false>&
4906{
4907 if (rhs.has_value()) {
4908 if (this->has_value()) {
4909 d_value.value() = *rhs;
4910 }
4911 else {
4912 emplace(*rhs);
4913 }
4914 }
4915 else {
4916 reset();
4917 }
4918 return *this;
4919}
4920
4921template <class t_TYPE>
4922inline
4925 BloombergLP::bslmf::MovableRef<Optional_Base> rhs)
4926{
4927 Optional_Base& lvalue = rhs;
4928 if (lvalue.has_value()) {
4929 if (this->has_value()) {
4930 d_value.value() = MoveUtil::move(*lvalue);
4931 }
4932 else {
4933 emplace(MoveUtil::move(*lvalue));
4934 }
4935 }
4936 else {
4937 reset();
4938 }
4939 return *this;
4940}
4941
4942# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4943template <class t_TYPE>
4944inline
4946{
4947 BSLS_ASSERT(has_value());
4948
4949 return d_value.value();
4950}
4951
4952template <class t_TYPE>
4953inline
4955{
4956 BSLS_ASSERT(has_value());
4957
4958 return std::move(d_value.value());
4959}
4960# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4961template <class t_TYPE>
4962inline
4964{
4965 BSLS_ASSERT(has_value());
4966
4967 return d_value.value();
4968}
4969# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4970
4971template <class t_TYPE>
4972inline
4974{
4975 BSLS_ASSERT(has_value());
4976
4977 return BSLS_UTIL_ADDRESSOF(d_value.value());
4978}
4979
4980// ACCESSORS
4981
4982template <class t_TYPE>
4983inline
4985{
4986 return d_value.hasValue();
4987}
4988
4989# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
4990template <class t_TYPE>
4991inline
4992const t_TYPE&
4994{
4995 if (!has_value())
4996 BSLS_THROW(bsl::bad_optional_access());
4997
4998 return d_value.value();
4999}
5000
5001template <class t_TYPE>
5002inline
5003const t_TYPE&&
5005{
5006 if (!has_value())
5007 BSLS_THROW(bsl::bad_optional_access());
5008
5009 return std::move(d_value.value());
5010}
5011
5012# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
5013template <class t_TYPE>
5014inline
5015const t_TYPE&
5017{
5018 if (!has_value())
5019 BSLS_THROW(bsl::bad_optional_access());
5020
5021 return d_value.value();
5022}
5023
5024# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
5025
5026# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
5027
5028template <class t_TYPE>
5029template <class t_ANY_TYPE>
5030inline
5031t_TYPE
5033 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
5034const &
5035{
5036 if (has_value()) {
5037 return t_TYPE(d_value.value()); // RETURN
5038 }
5039 else {
5040 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
5041 value)); // RETURN
5042 }
5043}
5044
5045# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
5046template <class t_TYPE>
5047template <class t_ANY_TYPE>
5048inline
5049t_TYPE
5051 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value)
5052const
5053{
5054 if (has_value()) {
5055 return t_TYPE(d_value.value()); // RETURN
5056 }
5057 else {
5058 return t_TYPE(BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE,
5059 value)); // RETURN
5060 }
5061}
5062
5063# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
5064
5065template <class t_TYPE>
5066inline
5068{
5069 BSLS_ASSERT(has_value());
5070
5071 return BSLS_UTIL_ADDRESSOF(d_value.value());
5072}
5073
5074# ifdef BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
5075template <class t_TYPE>
5076inline
5077const t_TYPE& Optional_Base<t_TYPE, false>::operator*() const&
5078{
5079 BSLS_ASSERT(has_value());
5080
5081 return d_value.value();
5082}
5083
5084template <class t_TYPE>
5085inline
5086const t_TYPE&& Optional_Base<t_TYPE, false>::operator*() const&&
5087{
5088 BSLS_ASSERT(has_value());
5089
5090 return std::move(d_value.value());
5091}
5092
5093# else // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS
5094template <class t_TYPE>
5095inline
5097{
5098 BSLS_ASSERT(has_value());
5099
5100 return d_value.value();
5101}
5102# endif // BSLS_COMPILERFEATURES_SUPPORT_REF_QUALIFIERS else
5103
5104#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
5105template <class t_TYPE>
5107{
5108 return has_value();
5109}
5110#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
5111# endif // else BSLSTL_OPTIONAL_USES_STD_ALIASES
5112
5113} // close package namespace
5114
5115
5116// ============================================================================
5117// Section: 'optional' Method Definitions
5118// ============================================================================
5119
5120 // ==============
5121 // class optional
5122 // ==============
5123
5124namespace bsl {
5125
5126#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5127// PRIVATE CREATORS
5128template <class t_TYPE>
5129template <class t_INVOCABLE, class t_ARG>
5130inline
5132 BloombergLP::bslstl::Optional_InvokeConstructorTag tag,
5133 t_INVOCABLE&& invocable,
5134 t_ARG&& arg)
5135: BaseType(tag, std::forward<t_INVOCABLE>(invocable), std::forward<t_ARG>(arg))
5136{
5137}
5138#endif
5139
5140// CREATORS
5141template <class t_TYPE>
5146
5147template <class t_TYPE>
5153
5154#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5155template <class t_TYPE>
5156template <class t_DERIVED>
5158 BloombergLP::bslmf::MovableRef<t_DERIVED> original,
5162: BaseType(MoveUtil::move(static_cast<BaseType&>(original)))
5163{
5164}
5165#endif
5166
5167template <class t_TYPE>
5168template <class t_ANY_TYPE>
5170 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
5173: BaseType(BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
5174 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
5175{
5176}
5177
5178template <class t_TYPE>
5179template <class t_ANY_TYPE>
5181 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
5184: BaseType(BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
5185 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
5186{
5187}
5188
5189template <class t_TYPE>
5190template <class t_ANY_TYPE>
5192 const optional<t_ANY_TYPE>& original,
5194 const t_ANY_TYPE&),
5196 const t_ANY_TYPE&))
5197: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
5198 original)
5199{
5200}
5201
5202template <class t_TYPE>
5203template <class t_ANY_TYPE>
5205 const optional<t_ANY_TYPE>& original,
5207 const t_ANY_TYPE&),
5208 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE&))
5209: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
5210 original)
5211{
5212}
5213
5214template <class t_TYPE>
5215template <class t_ANY_TYPE>
5220: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
5221 MoveUtil::move(
5222 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
5223 original)))
5224{
5225}
5226
5227template <class t_TYPE>
5228template <class t_ANY_TYPE>
5233: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
5234 MoveUtil::move(
5235 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
5236 original)))
5237{
5238}
5239
5240#ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
5241template <class t_TYPE>
5242template <class t_ANY_TYPE>
5244 const std::optional<t_ANY_TYPE>& original,
5246 const t_ANY_TYPE&),
5248: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
5249 original)
5250{
5251}
5252
5253template <class t_TYPE>
5254template <class t_ANY_TYPE>
5256 const std::optional<t_ANY_TYPE>& original,
5258 const t_ANY_TYPE&),
5260: BaseType(BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
5261 original)
5262{
5263}
5264
5265template <class t_TYPE>
5266template <class t_ANY_TYPE>
5268 std::optional<t_ANY_TYPE>&& original,
5271: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
5272 std::move(original))
5273{
5274}
5275
5276template <class t_TYPE>
5277template <class t_ANY_TYPE>
5279 std::optional<t_ANY_TYPE>&& original,
5282: BaseType(BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
5283 std::move(original))
5284{
5285}
5286# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
5287
5288#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5289template <class t_TYPE>
5290template <class... t_ARGS>
5297#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5298template <class t_TYPE>
5299template <class t_INIT_LIST_TYPE, class... t_ARGS>
5302 std::initializer_list<t_INIT_LIST_TYPE> il,
5303 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5304: BaseType(bsl::in_place, il, BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
5305{
5306}
5307#endif
5308#endif
5309
5310template <class t_TYPE>
5312: BaseType(bsl::allocator_arg, allocator)
5313{
5314}
5315
5316template <class t_TYPE>
5318 AllocType allocator,
5320: BaseType(bsl::allocator_arg, allocator)
5321{
5322}
5323
5324template <class t_TYPE>
5326 AllocType allocator,
5327 const optional& original)
5328: BaseType(bsl::allocator_arg, allocator, original)
5329{
5330}
5331
5332template <class t_TYPE>
5333template <class t_DERIVED>
5335 AllocType allocator,
5336 BSLMF_MOVABLEREF_DEDUCE(t_DERIVED) original,
5339: BaseType(bsl::allocator_arg_t(),
5340 allocator,
5341 MoveUtil::move(static_cast<BaseType&>(original)))
5342{
5343 // Implementation Note: The @ref remove_reference in the signature is needed
5344 // to work around a bug in GCC 10. (It has not been determined whether
5345 // other versions are affected.)
5346}
5347
5348template <class t_TYPE>
5349template <class t_ANY_TYPE>
5352 AllocType allocator,
5353 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
5356: BaseType(bsl::allocator_arg_t(),
5357 allocator,
5358 BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
5359 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
5360{
5361}
5362
5363template <class t_TYPE>
5364template <class t_ANY_TYPE>
5367 AllocType allocator,
5368 BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value,
5371: BaseType(bsl::allocator_arg_t(),
5372 allocator,
5373 BloombergLP::bslstl::Optional_ConstructFromForwardRef(),
5374 BSLS_COMPILERFEATURES_FORWARD(t_ANY_TYPE, value))
5375{
5376}
5377
5378template <class t_TYPE>
5379template <class t_ANY_TYPE>
5382 AllocType allocator,
5383 const optional<t_ANY_TYPE>& original,
5385 const t_ANY_TYPE&),
5387 const t_ANY_TYPE&))
5388: BaseType(bsl::allocator_arg_t(),
5389 allocator,
5390 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
5391 original)
5392{
5393}
5394
5395template <class t_TYPE>
5396template <class t_ANY_TYPE>
5399 AllocType allocator,
5400 const optional<t_ANY_TYPE>& original,
5402 const t_ANY_TYPE&),
5403 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE&))
5404: BaseType(bsl::allocator_arg_t(),
5405 allocator,
5406 BloombergLP::bslstl::Optional_CopyConstructFromOtherOptional(),
5407 original)
5408{
5409}
5410
5411template <class t_TYPE>
5412template <class t_ANY_TYPE>
5415 AllocType allocator,
5419: BaseType(bsl::allocator_arg_t(),
5420 allocator,
5421 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
5422 MoveUtil::move(
5423 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
5424 original)))
5425{
5426}
5427
5428template <class t_TYPE>
5429template <class t_ANY_TYPE>
5432 AllocType allocator,
5436: BaseType(bsl::allocator_arg_t(),
5437 allocator,
5438 BloombergLP::bslstl::Optional_MoveConstructFromOtherOptional(),
5439 MoveUtil::move(
5440 static_cast<BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>&>(
5441 original)))
5442{
5443}
5444
5445#ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
5446template <class t_TYPE>
5447template <class t_ANY_TYPE>
5450 AllocType allocator,
5451 const std::optional<t_ANY_TYPE>& original,
5453 const t_ANY_TYPE&),
5455 const t_ANY_TYPE&))
5456: BaseType(bsl::allocator_arg_t(),
5457 allocator,
5458 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
5459 original)
5460{
5461}
5462
5463template <class t_TYPE>
5464template <class t_ANY_TYPE>
5467 AllocType allocator,
5468 const std::optional<t_ANY_TYPE>& original,
5470 const t_ANY_TYPE&),
5471 BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(t_TYPE, const t_ANY_TYPE))
5472: BaseType(bsl::allocator_arg_t(),
5473 allocator,
5474 BloombergLP::bslstl::Optional_CopyConstructFromStdOptional(),
5475 original)
5476{
5477}
5478
5479template <class t_TYPE>
5480template <class t_ANY_TYPE>
5483 AllocType allocator,
5484 std::optional<t_ANY_TYPE>&& original,
5487: BaseType(bsl::allocator_arg_t(),
5488 allocator,
5489 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
5490 std::move(original))
5491{
5492}
5493
5494template <class t_TYPE>
5495template <class t_ANY_TYPE>
5498 AllocType allocator,
5499 std::optional<t_ANY_TYPE>&& original,
5502: BaseType(bsl::allocator_arg_t(),
5503 allocator,
5504 BloombergLP::bslstl::Optional_MoveConstructFromStdOptional(),
5505 std::move(original))
5506{
5507}
5508# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
5509
5510#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
5511template <class t_TYPE>
5512template <class... t_ARGS>
5515 AllocType allocator,
5517 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5518: BaseType(bsl::allocator_arg,
5519 allocator,
5520 bsl::in_place,
5521 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
5522{
5523}
5524#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
5525template <class t_TYPE>
5526template <class t_INIT_LIST_TYPE, class... t_ARGS>
5529 AllocType allocator,
5531 std::initializer_list<t_INIT_LIST_TYPE> il,
5532 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
5533: BaseType(bsl::allocator_arg,
5534 allocator,
5535 bsl::in_place,
5536 il,
5537 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...)
5538{
5539}
5540#endif
5541#endif
5542
5543// MANIPULATORS
5544template <class t_TYPE>
5545BSLSTL_OPTIONAL_CONSTEXPR20 optional<t_TYPE>&
5547{
5548 this->reset();
5549 return *this;
5550}
5551
5552#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5553template <class t_TYPE>
5554template <class t_DERIVED>
5556optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_DERIVED> rhs)
5557{
5558 BaseType& lvalue = rhs;
5559 BaseType::operator=(MoveUtil::move(lvalue));
5560 return *this;
5561}
5562#endif
5563
5564template <class t_TYPE>
5565template <class t_ANY_TYPE>
5569{
5570 if (rhs.has_value()) {
5571 this->assignOrEmplace(*rhs);
5572 } else {
5573 this->reset();
5574 }
5575 return *this;
5576}
5577
5578template <class t_TYPE>
5579template <class t_ANY_TYPE>
5583{
5584 BloombergLP::bslstl::Optional_Base<t_ANY_TYPE>& lvalue = rhs;
5585 if (lvalue.has_value()) {
5586 this->assignOrEmplace(MoveUtil::move(*lvalue));
5587 } else {
5588 this->reset();
5589 }
5590 return *this;
5591}
5592
5593#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
5594template <class t_TYPE>
5595template <class t_ANY_TYPE>
5598optional<t_TYPE>::operator=(t_ANY_TYPE&& rhs)
5599{
5600 this->assignOrEmplace(std::forward<t_ANY_TYPE>(rhs));
5601 return *this;
5602}
5603#else
5604template <class t_TYPE>
5606{
5607 this->assignOrEmplace(rhs);
5608 return *this;
5609}
5610
5611template <class t_TYPE>
5613optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_TYPE> rhs)
5614{
5615 this->assignOrEmplace(MoveUtil::move(rhs));
5616 return *this;
5617}
5618
5619template <class t_TYPE>
5620template <class t_ANY_TYPE>
5622optional<t_TYPE>::operator=(const t_ANY_TYPE& rhs)
5623{
5624 this->assignOrEmplace(rhs);
5625 return *this;
5626}
5627
5628template <class t_TYPE>
5629template <class t_ANY_TYPE>
5631optional<t_TYPE>::operator=(BloombergLP::bslmf::MovableRef<t_ANY_TYPE> rhs)
5632{
5633 this->assignOrEmplace(MoveUtil::move(rhs));
5634 return *this;
5635}
5636#endif // RVALUES else
5637
5638#ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
5639template <class t_TYPE>
5640template <class t_ANY_TYPE>
5642BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(t_TYPE, const t_ANY_TYPE&)&
5643optional<t_TYPE>::operator=(const std::optional<t_ANY_TYPE>& rhs)
5644{
5645 if (rhs.has_value()) {
5646 this->assignOrEmplace(*rhs);
5647 } else {
5648 this->reset();
5649 }
5650 return *this;
5651}
5652
5653template <class t_TYPE>
5654template <class t_ANY_TYPE>
5657optional<t_TYPE>::operator=(std::optional<t_ANY_TYPE>&& rhs)
5658{
5659 if (rhs.has_value()) {
5660 this->assignOrEmplace(std::move(*rhs));
5661 } else {
5662 this->reset();
5663 }
5664 return *this;
5665}
5666# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
5667
5668#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5669template <class t_TYPE>
5670template <class t_FUNC>
5671constexpr auto optional<t_TYPE>::transform(t_FUNC&& func) &
5672{
5673 using ResultType = std::remove_cv_t<std::invoke_result_t<t_FUNC, t_TYPE&>>;
5674 static_assert(!std::is_array_v<ResultType>,
5675 "The callable must return an array");
5676 static_assert(!std::is_same_v<ResultType, nullopt_t>,
5677 "The callable must not return nullopt_t");
5678 static_assert(!std::is_same_v<ResultType, in_place_t>,
5679 "The callable must not return in_place_t");
5680 static_assert(std::is_object_v<ResultType>,
5681 "The callable must return an object type");
5682
5683 if (this->has_value()) {
5684 using BloombergLP::bslstl::Optional_InvokeConstructorTag;
5685 return optional<ResultType>{Optional_InvokeConstructorTag{},
5686 std::forward<t_FUNC>(func),
5687 **this};
5688 }
5689 return optional<ResultType>{};
5690}
5691
5692template <class t_TYPE>
5693template <class t_FUNC>
5694constexpr auto optional<t_TYPE>::transform(t_FUNC&& func) const &
5695{
5696 using ResultType =
5697 std::remove_cv_t<std::invoke_result_t<t_FUNC, const t_TYPE&>>;
5698 static_assert(!std::is_array_v<ResultType>,
5699 "The callable must return an array");
5700 static_assert(!std::is_same_v<ResultType, nullopt_t>,
5701 "The callable must not return nullopt_t");
5702 static_assert(!std::is_same_v<ResultType, in_place_t>,
5703 "The callable must not return in_place_t");
5704 static_assert(std::is_object_v<ResultType>,
5705 "The callable must return an object type");
5706
5707 if (this->has_value()) {
5708 using BloombergLP::bslstl::Optional_InvokeConstructorTag;
5709 return optional<ResultType>{Optional_InvokeConstructorTag{},
5710 std::forward<t_FUNC>(func),
5711 **this};
5712 }
5713 return optional<ResultType>{};
5714}
5715
5716template <class t_TYPE>
5717template <class t_FUNC>
5718constexpr auto optional<t_TYPE>::transform(t_FUNC&& func) &&
5719{
5720 using ResultType =
5721 std::remove_cv_t<std::invoke_result_t<t_FUNC, t_TYPE&&>>;
5722 static_assert(!std::is_array_v<ResultType>,
5723 "The callable must return an array");
5724 static_assert(!std::is_same_v<ResultType, nullopt_t>,
5725 "The callable must not return nullopt_t");
5726 static_assert(!std::is_same_v<ResultType, in_place_t>,
5727 "The callable must not return in_place_t");
5728 static_assert(std::is_object_v<ResultType>,
5729 "The callable must return an object type");
5730
5731 if (this->has_value()) {
5732 using BloombergLP::bslstl::Optional_InvokeConstructorTag;
5733 return optional<ResultType>{Optional_InvokeConstructorTag{},
5734 std::forward<t_FUNC>(func),
5735 std::move(**this)};
5736 }
5737 return optional<ResultType>{};
5738}
5739
5740template <class t_TYPE>
5741template <class t_FUNC>
5742constexpr auto optional<t_TYPE>::transform(t_FUNC&& func) const &&
5743{
5744 using ResultType =
5745 std::remove_cv_t<std::invoke_result_t<t_FUNC, const t_TYPE&&>>;
5746 static_assert(!std::is_array_v<ResultType>,
5747 "The callable must return an array");
5748 static_assert(!std::is_same_v<ResultType, nullopt_t>,
5749 "The callable must not return nullopt_t");
5750 static_assert(!std::is_same_v<ResultType, in_place_t>,
5751 "The callable must not return in_place_t");
5752 static_assert(std::is_object_v<ResultType>,
5753 "The callable must return an object type");
5754
5755 if (this->has_value()) {
5756 using BloombergLP::bslstl::Optional_InvokeConstructorTag;
5757 return optional<ResultType>{Optional_InvokeConstructorTag{},
5758 std::forward<t_FUNC>(func),
5759 std::move(**this)};
5760 }
5761 return optional<ResultType>{};
5762}
5763
5764template <class t_TYPE>
5765template <class t_FUNC>
5766constexpr auto optional<t_TYPE>::and_then(t_FUNC&& func) &
5767{
5768 using ResultType = std::remove_cv_t<std::remove_reference_t<
5769 std::invoke_result_t<t_FUNC, t_TYPE&>>>;
5770 using ::BloombergLP::bslstl::Optional_IsBslOptional;
5771 static_assert(Optional_IsBslOptional<ResultType>::value,
5772 "The callable must return bsl::optional");
5773
5774 if (this->has_value()) {
5775 return std::invoke(std::forward<t_FUNC>(func), **this);
5776 }
5777 return ResultType{};
5778}
5779
5780template <class t_TYPE>
5781template <class t_FUNC>
5782constexpr auto optional<t_TYPE>::and_then(t_FUNC&& func) const &
5783{
5784 using ResultType = std::remove_cv_t<std::remove_reference_t<
5785 std::invoke_result_t<t_FUNC, const t_TYPE&>>>;
5786 using ::BloombergLP::bslstl::Optional_IsBslOptional;
5787 static_assert(Optional_IsBslOptional<ResultType>::value,
5788 "The callable must return bsl::optional");
5789
5790 if (this->has_value()) {
5791 return std::invoke(std::forward<t_FUNC>(func), **this);
5792 }
5793 return ResultType{};
5794}
5795
5796template <class t_TYPE>
5797template <class t_FUNC>
5798constexpr auto optional<t_TYPE>::and_then(t_FUNC&& func) &&
5799{
5800 using ResultType = std::remove_cv_t<std::remove_reference_t<
5801 std::invoke_result_t<t_FUNC, t_TYPE&&>>>;
5802 using ::BloombergLP::bslstl::Optional_IsBslOptional;
5803 static_assert(Optional_IsBslOptional<ResultType>::value,
5804 "The callable must return bsl::optional");
5805
5806 if (this->has_value()) {
5807 return std::invoke(std::forward<t_FUNC>(func), std::move(**this));
5808 }
5809 return ResultType{};
5810}
5811
5812template <class t_TYPE>
5813template <class t_FUNC>
5814constexpr auto optional<t_TYPE>::and_then(t_FUNC&& func) const &&
5815{
5816 using ResultType = std::remove_cv_t<std::remove_reference_t<
5817 std::invoke_result_t<t_FUNC, const t_TYPE&&>>>;
5818 using ::BloombergLP::bslstl::Optional_IsBslOptional;
5819 static_assert(Optional_IsBslOptional<ResultType>::value,
5820 "The callable must return bsl::optional");
5821
5822 if (this->has_value()) {
5823 return std::invoke(std::forward<t_FUNC>(func), std::move(**this));
5824 }
5825 return ResultType{};
5826}
5827
5828template <class t_TYPE>
5829template <class t_FUNC>
5830constexpr
5831enable_if_t<conjunction_v<std::is_invocable<t_FUNC>,
5832 std::is_copy_constructible<t_TYPE>>,
5833 optional<t_TYPE>> optional<t_TYPE>::or_else(t_FUNC&& func) const &
5834{
5835 static_assert(std::is_same_v<remove_cvref_t<std::invoke_result_t<t_FUNC>>,
5836 optional<t_TYPE>>,
5837 "The callable must return bsl::optional<T>");
5838
5839 if (this->has_value()) {
5840 return *this;
5841 }
5842 return std::forward<t_FUNC>(func)();
5843}
5844
5845template <class t_TYPE>
5846template <class t_FUNC>
5847constexpr
5848enable_if_t<conjunction_v<std::is_invocable<t_FUNC>,
5849 std::is_move_constructible<t_TYPE>>,
5850 optional<t_TYPE>> optional<t_TYPE>::or_else(t_FUNC&& func) &&
5851{
5852 static_assert(std::is_same_v<remove_cvref_t<std::invoke_result_t<t_FUNC>>,
5853 optional<t_TYPE>>,
5854 "The callable must return bsl::optional<T>");
5855
5856 if (this->has_value()) {
5857 return std::move(*this);
5858 }
5859 return std::forward<t_FUNC>(func)();
5860}
5861#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5862
5863// ============================================================================
5864// Section: Free Function Definitions
5865// ============================================================================
5866
5867template <class t_TYPE>
5868inline
5870 void>::type
5872{
5873 if (lhs.get_allocator() == rhs.get_allocator()) {
5874 lhs.swap(rhs);
5875
5876 return; // RETURN
5877 }
5878
5879 bsl::optional<t_TYPE> futureLhs(
5880 bsl::allocator_arg, lhs.get_allocator(), rhs);
5881 bsl::optional<t_TYPE> futureRhs(
5882 bsl::allocator_arg, rhs.get_allocator(), lhs);
5883
5884 futureLhs.swap(lhs);
5885 futureRhs.swap(rhs);
5886}
5887
5888template <class t_TYPE>
5891 void>::type
5896
5897// HASH SPECIALIZATIONS
5898template <class t_HASHALG, class t_TYPE>
5899void hashAppend(t_HASHALG& hashAlg, const bsl::optional<t_TYPE>& input)
5900{
5901 using ::BloombergLP::bslh::hashAppend;
5902
5903 if (input.has_value()) {
5904 hashAppend(hashAlg, true);
5905 hashAppend(hashAlg, *input);
5906 }
5907 else {
5908 hashAppend(hashAlg, false);
5909 }
5910}
5911
5912// FREE OPERATORS
5913
5914template <class t_LHS_TYPE, class t_RHS_TYPE>
5916bool operator==(const bsl::optional<t_LHS_TYPE>& lhs,
5918 BSLSTL_OPTIONAL_REQUIRES(requires {
5919 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5920 })
5921{
5922 if (lhs.has_value() && rhs.has_value()) {
5923 return *lhs == *rhs; // RETURN
5924 }
5925 return lhs.has_value() == rhs.has_value();
5926}
5927
5928template <class t_LHS_TYPE, class t_RHS_TYPE>
5932 BSLSTL_OPTIONAL_REQUIRES(requires {
5933 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5934 })
5935{
5936 if (lhs.has_value() && rhs.has_value()) {
5937 return *lhs != *rhs; // RETURN
5938 }
5939
5940 return lhs.has_value() != rhs.has_value();
5941}
5942
5943template <class t_LHS_TYPE, class t_RHS_TYPE>
5947 BSLSTL_OPTIONAL_REQUIRES(requires {
5948 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5949 })
5950{
5951 if (!rhs.has_value()) {
5952 return false; // RETURN
5953 }
5954
5955 return !lhs.has_value() || *lhs < *rhs;
5956}
5957
5958template <class t_LHS_TYPE, class t_RHS_TYPE>
5962 BSLSTL_OPTIONAL_REQUIRES(requires {
5963 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5964 })
5965{
5966 if (!lhs.has_value()) {
5967 return false; // RETURN
5968 }
5969
5970 return !rhs.has_value() || *lhs > *rhs;
5971}
5972
5973template <class t_LHS_TYPE, class t_RHS_TYPE>
5977 BSLSTL_OPTIONAL_REQUIRES(requires {
5978 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5979 })
5980{
5981 if (!lhs.has_value()) {
5982 return true; // RETURN
5983 }
5984
5985 return rhs.has_value() && *lhs <= *rhs;
5986}
5987
5988template <class t_LHS_TYPE, class t_RHS_TYPE>
5992 BSLSTL_OPTIONAL_REQUIRES(requires {
5993 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
5994 })
5995{
5996 if (!rhs.has_value()) {
5997 return true; // RETURN
5998 }
5999 return lhs.has_value() && *lhs >= *rhs;
6000}
6001
6002// comparison with 'nullopt_t'
6003
6004template <class t_TYPE>
6005inline
6007 const bsl::optional<t_TYPE>& value,
6009{
6010 return !value.has_value();
6011}
6012
6013#if !(defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) && \
6014 defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS))
6015template <class t_TYPE>
6016inline
6018 const bsl::nullopt_t&,
6020{
6021 return !value.has_value();
6022}
6023
6024template <class t_TYPE>
6025inline
6027 const bsl::optional<t_TYPE>& value,
6029{
6030 return value.has_value();
6031}
6032
6033template <class t_TYPE>
6034inline
6036 const bsl::nullopt_t&,
6038{
6039 return value.has_value();
6040}
6041
6042template <class t_TYPE>
6043inline
6045 const bsl::optional<t_TYPE>&,
6047{
6048 return false;
6049}
6050
6051template <class t_TYPE>
6052inline
6054 const bsl::nullopt_t&,
6056{
6057 return value.has_value();
6058}
6059
6060template <class t_TYPE>
6061inline
6063 const bsl::optional<t_TYPE>& value,
6065{
6066 return value.has_value();
6067}
6068
6069template <class t_TYPE>
6070inline
6072 const bsl::nullopt_t&,
6074{
6075 return false;
6076}
6077
6078template <class t_TYPE>
6079inline
6081 const bsl::optional<t_TYPE>& value,
6083{
6084 return !value.has_value();
6085}
6086
6087template <class t_TYPE>
6088inline
6090 const bsl::nullopt_t&,
6092{
6093 return true;
6094}
6095
6096template <class t_TYPE>
6097inline
6099 const bsl::optional<t_TYPE>&,
6101{
6102 return true;
6103}
6104
6105template <class t_TYPE>
6106inline
6108 const bsl::nullopt_t&,
6110{
6111 return !value.has_value();
6112}
6113#endif // !(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS &&
6114 // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON)
6115
6116// comparison with 'value_type'
6117
6118template <class t_LHS_TYPE, class t_RHS_TYPE>
6120bool operator==(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6122 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6123 && requires {
6124 { *lhs == rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6125 })
6126{
6127 return lhs.has_value() && *lhs == rhs;
6128}
6129
6130template <class t_LHS_TYPE, class t_RHS_TYPE>
6132bool operator==(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6134 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6135 && requires {
6136 { lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6137 })
6138{
6139 return rhs.has_value() && lhs == *rhs;
6140}
6141
6142template <class t_LHS_TYPE, class t_RHS_TYPE>
6144bool operator!=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6146 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6147 && requires {
6148 { *lhs != rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6149 })
6150{
6151 return !lhs.has_value() || *lhs != rhs;
6152}
6153
6154template <class t_LHS_TYPE, class t_RHS_TYPE>
6156bool operator!=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6158 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6159 && requires {
6160 { lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6161 })
6162{
6163 return !rhs.has_value() || lhs != *rhs;
6164}
6165
6166template <class t_LHS_TYPE, class t_RHS_TYPE>
6168bool operator<(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6170 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6171 && requires {
6172 { *lhs < rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6173 })
6174{
6175 return !lhs.has_value() || *lhs < rhs;
6176}
6177
6178template <class t_LHS_TYPE, class t_RHS_TYPE>
6180bool operator<(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6182 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6183 && requires {
6184 { lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6185 })
6186{
6187 return rhs.has_value() && lhs < *rhs;
6188}
6189
6190template <class t_LHS_TYPE, class t_RHS_TYPE>
6192bool operator>(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6194 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6195 && requires {
6196 { *lhs > rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6197 })
6198{
6199 return lhs.has_value() && *lhs > rhs;
6200}
6201
6202template <class t_LHS_TYPE, class t_RHS_TYPE>
6204bool operator>(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6206 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6207 && requires {
6208 { lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6209 })
6210{
6211 return !rhs.has_value() || lhs > *rhs;
6212}
6213
6214template <class t_LHS_TYPE, class t_RHS_TYPE>
6216bool operator<=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6218 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6219 && requires {
6220 { *lhs <= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6221 })
6222{
6223 return !lhs.has_value() || *lhs <= rhs;
6224}
6225
6226template <class t_LHS_TYPE, class t_RHS_TYPE>
6228bool operator<=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6230 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6231 && requires {
6232 { lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6233 })
6234{
6235 return rhs.has_value() && lhs <= *rhs;
6236}
6237
6238template <class t_LHS_TYPE, class t_RHS_TYPE>
6240bool operator>=(const bsl::optional<t_LHS_TYPE>& lhs, const t_RHS_TYPE& rhs)
6242 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS_TYPE>
6243 && requires {
6244 { *lhs >= rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6245 })
6246{
6247 return lhs.has_value() && *lhs >= rhs;
6248}
6249
6250template <class t_LHS_TYPE, class t_RHS_TYPE>
6252bool operator>=(const t_LHS_TYPE& lhs, const bsl::optional<t_RHS_TYPE>& rhs)
6254 !BloombergLP::bslstl::Optional_DerivedFromOptional<t_LHS_TYPE>
6255 && requires {
6256 { lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6257 })
6258{
6259 return !rhs.has_value() || lhs >= *rhs;
6260}
6261
6262#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
6263 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
6264template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
6266compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
6269{
6270 const bool lhs_has_value = lhs.has_value(),
6271 rhs_has_value = rhs.has_value();
6272 if (lhs_has_value && rhs_has_value) {
6273 return *lhs <=> *rhs;
6274 }
6275 return lhs_has_value <=> rhs_has_value;
6276}
6277
6278template <class t_LHS, class t_RHS>
6279requires (!BloombergLP::bslstl::Optional_DerivedFromOptional<t_RHS>) &&
6280 three_way_comparable_with<t_LHS, t_RHS>
6282compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
6284 const t_RHS& rhs)
6285{
6286 if (lhs) {
6287 return *lhs <=> rhs;
6288 }
6289 return strong_ordering::less;
6290}
6291
6292template <class t_TYPE>
6294strong_ordering operator<=>(const bsl::optional<t_TYPE>& value,
6296{
6297 return value.has_value() <=> false;
6298}
6299
6300template <class t_LHS, three_way_comparable_with<t_LHS> t_RHS>
6302compare_three_way_result_t<t_LHS, t_RHS> operator<=>(
6304 const std::optional<t_RHS>& rhs)
6305{
6306 const bool lhs_has_value = lhs.has_value(),
6307 rhs_has_value = rhs.has_value();
6308 if (lhs_has_value && rhs_has_value) {
6309 return *lhs <=> *rhs;
6310 }
6311 return lhs_has_value <=> rhs_has_value;
6312}
6313#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON &&
6314 // BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
6315
6316# ifdef BSLSTL_OPTIONAL_USES_STD_ALIASES
6317template <class t_TYPE>
6318inline
6320 void>::type
6321swap(bsl::optional<t_TYPE>& lhs, std::optional<t_TYPE>& rhs)
6322{
6323 lhs.swap(rhs);
6324}
6325
6326template <class t_TYPE>
6329 void>::type
6330swap(std::optional<t_TYPE>& lhs, bsl::optional<t_TYPE>& rhs)
6331{
6332 lhs.swap(rhs);
6333}
6334
6335// comparison with 'std::optional'
6336
6337template <class t_LHS_TYPE, class t_RHS_TYPE>
6338constexpr
6340 const std::optional<t_RHS_TYPE>& rhs)
6341 BSLSTL_OPTIONAL_REQUIRES(requires {
6342 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6343 })
6344{
6345 if (lhs.has_value() && rhs.has_value()) {
6346 return *lhs == *rhs;
6347 }
6348 return lhs.has_value() == rhs.has_value();
6349}
6350
6351template <class t_LHS_TYPE, class t_RHS_TYPE>
6352constexpr
6353bool operator==(const std::optional<t_LHS_TYPE>& lhs,
6355 BSLSTL_OPTIONAL_REQUIRES(requires {
6356 { *lhs == *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6357 })
6358{
6359 if (lhs.has_value() && rhs.has_value()) {
6360 return *lhs == *rhs;
6361 }
6362 return lhs.has_value() == rhs.has_value();
6363}
6364
6365template <class t_LHS_TYPE, class t_RHS_TYPE>
6366constexpr
6368 const std::optional<t_RHS_TYPE>& rhs)
6369 BSLSTL_OPTIONAL_REQUIRES(requires {
6370 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6371 })
6372{
6373 if (lhs.has_value() && rhs.has_value()) {
6374 return *lhs != *rhs;
6375 }
6376
6377 return lhs.has_value() != rhs.has_value();
6378}
6379
6380template <class t_LHS_TYPE, class t_RHS_TYPE>
6381constexpr
6382bool operator!=(const std::optional<t_LHS_TYPE>& lhs,
6384 BSLSTL_OPTIONAL_REQUIRES(requires {
6385 { *lhs != *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6386 })
6387{
6388 if (lhs.has_value() && rhs.has_value()) {
6389 return *lhs != *rhs;
6390 }
6391
6392 return lhs.has_value() != rhs.has_value();
6393}
6394
6395template <class t_LHS_TYPE, class t_RHS_TYPE>
6396constexpr
6398 const std::optional<t_RHS_TYPE>& rhs)
6399 BSLSTL_OPTIONAL_REQUIRES(requires {
6400 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6401 })
6402{
6403 if (!rhs.has_value()) {
6404 return false; // RETURN
6405 }
6406
6407 return !lhs.has_value() || *lhs < *rhs;
6408}
6409
6410template <class t_LHS_TYPE, class t_RHS_TYPE>
6411constexpr
6412bool operator<(const std::optional<t_LHS_TYPE>& lhs,
6414 BSLSTL_OPTIONAL_REQUIRES(requires {
6415 { *lhs < *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6416 })
6417{
6418 if (!rhs.has_value()) {
6419 return false; // RETURN
6420 }
6421
6422 return !lhs.has_value() || *lhs < *rhs;
6423}
6424
6425template <class t_LHS_TYPE, class t_RHS_TYPE>
6426constexpr
6428 const std::optional<t_RHS_TYPE>& rhs)
6429 BSLSTL_OPTIONAL_REQUIRES(requires {
6430 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6431 })
6432{
6433 if (!lhs.has_value()) {
6434 return false; // RETURN
6435 }
6436
6437 return !rhs.has_value() || *lhs > *rhs;
6438}
6439
6440template <class t_LHS_TYPE, class t_RHS_TYPE>
6441constexpr
6442bool operator>(const std::optional<t_LHS_TYPE>& lhs,
6444 BSLSTL_OPTIONAL_REQUIRES(requires {
6445 { *lhs > *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6446 })
6447{
6448 if (!lhs.has_value()) {
6449 return false; // RETURN
6450 }
6451
6452 return !rhs.has_value() || *lhs > *rhs;
6453}
6454
6455template <class t_LHS_TYPE, class t_RHS_TYPE>
6456constexpr
6458 const std::optional<t_RHS_TYPE>& rhs)
6459 BSLSTL_OPTIONAL_REQUIRES(requires {
6460 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6461 })
6462{
6463 if (!lhs.has_value()) {
6464 return true; // RETURN
6465 }
6466
6467 return rhs.has_value() && *lhs <= *rhs;
6468}
6469
6470template <class t_LHS_TYPE, class t_RHS_TYPE>
6471constexpr
6472bool operator<=(const std::optional<t_LHS_TYPE>& lhs,
6474 BSLSTL_OPTIONAL_REQUIRES(requires {
6475 { *lhs <= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6476 })
6477{
6478 if (!lhs.has_value()) {
6479 return true; // RETURN
6480 }
6481
6482 return rhs.has_value() && *lhs <= *rhs;
6483}
6484
6485template <class t_LHS_TYPE, class t_RHS_TYPE>
6486constexpr
6488 const std::optional<t_RHS_TYPE>& rhs)
6489 BSLSTL_OPTIONAL_REQUIRES(requires {
6490 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6491 })
6492{
6493 if (!rhs.has_value()) {
6494 return true; // RETURN
6495 }
6496 return lhs.has_value() && *lhs >= *rhs;
6497}
6498
6499template <class t_LHS_TYPE, class t_RHS_TYPE>
6500constexpr
6501bool operator>=(const std::optional<t_LHS_TYPE>& lhs,
6503 BSLSTL_OPTIONAL_REQUIRES(requires {
6504 { *lhs >= *rhs } -> BloombergLP::bslstl::Optional_ConvertibleToBool;
6505 })
6506{
6507 if (!rhs.has_value()) {
6508 return true; // RETURN
6509 }
6510 return lhs.has_value() && *lhs >= *rhs;
6511}
6512# endif // BSLSTL_OPTIONAL_USES_STD_ALIASES
6513
6514template <class t_TYPE>
6517 const typename bsl::optional<
6518 typename bsl::decay<t_TYPE>::type>::allocator_type& alloc,
6520{
6522 bsl::allocator_arg,
6523 alloc,
6526}
6527
6528#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6529template <class t_TYPE, class... t_ARGS>
6532 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
6533 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
6534{
6535 return bsl::optional<t_TYPE>(
6536 bsl::allocator_arg,
6537 alloc,
6539 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
6540}
6541#endif
6542
6543#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6544# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
6545template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
6548 typename bsl::optional<t_TYPE>::allocator_type const& alloc,
6549 std::initializer_list<t_INIT_LIST_TYPE> il,
6550 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
6551{
6552 return bsl::optional<t_TYPE>(
6553 bsl::allocator_arg,
6554 alloc,
6556 il,
6557 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
6558}
6559# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
6560#endif
6561
6562template <class t_TYPE>
6569
6570template <class t_TYPE>
6575
6576#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6577template <class t_TYPE, class t_ARG, class... t_ARGS>
6581{
6582 return bsl::optional<t_TYPE>(
6585 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
6586}
6587
6588# if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
6589template <class t_TYPE, class t_INIT_LIST_TYPE, class... t_ARGS>
6591make_optional(std::initializer_list<t_INIT_LIST_TYPE> il,
6592 BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
6593{
6594 return bsl::optional<t_TYPE>(
6596 il,
6597 BSLS_COMPILERFEATURES_FORWARD(t_ARGS, args)...);
6598}
6599# endif // defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
6600#endif
6601} // close namespace bsl
6602
6603// There is a problem in the standard definition of the is-optional concept
6604// that results in types inheriting from std::optional not being identified
6605// correctly as optional types. The end result is endless recursion evaluating
6606// the requires clause for the spaceship operator when it is implemented
6607// according to the C++20 specification, which happens for GCC 11-14 and
6608// MSVC-2022 prior to MSVC 19.36 when building with C++20 and later. In MSVC
6609// 19.36 Microsoft implemented the solution suggested in LWG-3746, so the
6610// workaround is not required for that and subsequent versions; similarly, the
6611// issue will be resolved in GCC 15 (to be released).
6612//
6613// The issue with the standard is tracked here:
6614// https://cplusplus.github.io/LWG/issue3746
6615//
6616// See DRQS 170388558 for more information
6617//
6618// BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED and
6619// BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED are deliberately
6620// exposed to allow their use in higher level optional types (i.e.,
6621// bdlb::NullableValue).
6622
6623// The following hacks prevent compiler crashes, and should only be applied on
6624// compiler versions where the problem is not fixed. The hacks required for
6625// gcc and for MSVC are different due to different standard library
6626// implementations, hence the two distinct macros and implementations.
6627
6628# if BSLS_COMPILERFEATURES_CPLUSPLUS >= 202002L && \
6629 defined(BSLS_LIBRARYFEATURES_STDCPP_GNU) && \
6630 (11 <= _GLIBCXX_RELEASE && _GLIBCXX_RELEASE <= 14)
6631
6632#define BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
6633
6634namespace std {
6635template<typename _Tp>
6636inline constexpr bool __is_optional_v<bsl::optional<_Tp>> = true;
6637}
6638
6639# endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_GNU_WORKAROUND_NEEDED
6640
6641# if BSLS_COMPILERFEATURES_CPLUSPLUS == 202002L && \
6642 defined(BSLS_PLATFORM_CMP_MSVC) && \
6643 (BSLS_PLATFORM_CMP_VERSION >= 1930 && BSLS_PLATFORM_CMP_VERSION < 1936)
6644 // This workaround is not required from MSVC 19.36 onwards.
6645
6646#define BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
6647
6648namespace std {
6649template <typename _Tp>
6650inline constexpr bool _Is_specialization_v<bsl::optional<_Tp>, std::optional> =
6651 true;
6652}
6653
6654# endif // BSLSTL_OPTIONAL_CPP20_IS_OPTIONAL_MSVC_WORKAROUND_NEEDED
6655
6656#undef BSLSTL_OPTIONAL_CONSTEXPR17
6657#undef BSLSTL_OPTIONAL_CONSTEXPR20
6658#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL
6659#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL
6660#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL
6661#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL
6662#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR
6663#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR
6664#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR
6665#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR
6666#undef BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM
6667#undef BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM
6668#undef BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL
6669#undef BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT
6670#undef BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT
6671#undef BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT
6672#undef BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT
6673#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL
6674#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL
6675#undef BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED
6676#undef BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG
6677#undef BSLSTL_OPTIONAL_DEFAULT_TEMPLATE_ARG
6678#undef BSLSTL_OPTIONAL_REQUIRES
6679
6680#endif // End C++11 code
6681
6682#endif // End C++11 code
6683
6684// ----------------------------------------------------------------------------
6685// Copyright 2020 Bloomberg Finance L.P.
6686//
6687// Licensed under the Apache License, Version 2.0 (the "License");
6688// you may not use this file except in compliance with the License.
6689// You may obtain a copy of the License at
6690//
6691// http://www.apache.org/licenses/LICENSE-2.0
6692//
6693// Unless required by applicable law or agreed to in writing, software
6694// distributed under the License is distributed on an "AS IS" BASIS,
6695// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6696// See the License for the specific language governing permissions and
6697// limitations under the License.
6698// ----------------------------- END-OF-FILE ----------------------------------
6699
6700/** @} */
6701/** @} */
6702/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION_IF(t_TYPE, t_TRAIT, t_COND)
Definition bslmf_nestedtraitdeclaration.h:243
Definition bslma_bslallocator.h:588
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1146
decay_imp< U, k_ISARRAY, k_ISFUNC >::type type
Definition bslmf_decay.h:167
Definition bslstl_optional.h:2043
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslmf::UsesAllocatorArgT, BloombergLP::bslma::UsesBslmaAllocator< t_TYPE >::value)
BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(t_TYPE, t_ANY_TYPE) &operator
optional(BloombergLP::bslmf::MovableRef< t_DERIVED > original, BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(t_DERIVED)) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl BSLSTL_OPTIONAL_CONSTEXPR17 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))
BSLSTL_OPTIONAL_CONSTEXPR20 BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(t_TYPE, t_ANY_TYPE) &operator
optional(bsl::allocator_arg_t, AllocType allocator)
Definition bslstl_optional.h:5311
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_CONSTEXPR20 BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(t_TYPE, const t_ANY_TYPE &) &operator
BSLSTL_OPTIONAL_CONSTEXPR20 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_EXPLICIT_CONSTRUCT(t_TYPE, t_ANY_TYPE))
BSLSTL_OPTIONAL_CONSTEXPR17 optional(bsl::in_place_t, BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:5292
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:5605
optional(bsl::allocator_arg_t, AllocType allocator, const optional &original)
Definition bslstl_optional.h:5325
optional(bsl::allocator_arg_t, AllocType allocator, bsl::nullopt_t)
Definition bslstl_optional.h:5317
BSLSTL_OPTIONAL_CONSTEXPR20 optional & operator=(bsl::nullopt_t) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:5546
BSLSTL_OPTIONAL_CONSTEXPR17 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))
optional & operator=(BloombergLP::bslmf::MovableRef< t_TYPE > rhs)
Definition bslstl_optional.h:5613
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))
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:5513
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 &))
BSLSTL_OPTIONAL_CONSTEXPR20 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))
BSLMF_NESTED_TRAIT_DECLARATION_IF(optional, BloombergLP::bslmf::IsBitwiseMoveable, BloombergLP::bslmf::IsBitwiseMoveable< t_TYPE >::value)
BSLSTL_OPTIONAL_CONSTEXPR20 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 &))
BSLSTL_OPTIONAL_CONSTEXPR20 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 &))
BSLSTL_OPTIONAL_CONSTEXPR17 optional() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:5142
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))
Definition bslma_allocator.h:545
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:1848
Definition bslstl_optional.h:929
Optional_Base()
Definition bslstl_optional.h:3573
const t_TYPE & value() const
t_TYPE & emplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:3920
Optional_Base & operator=(const Optional_Base &rhs)
Definition bslstl_optional.h:4046
void assignOrEmplace(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) rhs)
Definition bslstl_optional.h:3884
t_TYPE & dereferenceRaw()
Definition bslstl_optional.h:3896
allocator_type AllocType
Definition bslstl_optional.h:944
bool has_value() const BSLS_KEYWORD_NOEXCEPT
Return false if this object is disengaged, and true otherwise.
Definition bslstl_optional.h:4138
t_TYPE value_or(BSLS_COMPILERFEATURES_FORWARD_REF(t_ANY_TYPE) value) const
Definition bslstl_optional.h:4218
void swap(Optional_Base &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl t_TYPE & value()
Definition bslstl_optional.h:1305
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return allocator used for construction of value_type.
Definition bslstl_optional.h:4129
BSLMF_NESTED_TRAIT_DECLARATION(Optional_Base, BloombergLP::bslmf::UsesAllocatorArgT)
t_TYPE & operator*()
Definition bslstl_optional.h:4115
void reset() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:3943
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:938
bsl::allocator< char > allocator_type
Definition bslstl_optional.h:940
t_TYPE * operator->()
Definition bslstl_optional.h:4086
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:691
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:2101
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_THROW(X)
Definition bsls_exceptionutil.h:374
#define BSLS_NOTHROW_SPEC
Definition bsls_exceptionutil.h:386
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:651
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:296
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:429
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:343
#define BSLSTL_OPTIONAL_DEFINE_IF_DERIVED_FROM_OPTIONAL(DERIVED)
Definition bslstl_optional.h:399
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, ANY_TYPE)
Definition bslstl_optional.h:369
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:437
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( TYPE, ANY_TYPE)
Definition bslstl_optional.h:375
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE)
Definition bslstl_optional.h:388
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_BSL_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:335
#define BSLSTL_OPTIONAL_DEFINE_IF_NOT_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:419
#define BSLSTL_OPTIONAL_ENABLE_IF_NOT_ALLOCATOR_TAG(ARG)
Definition bslstl_optional.h:474
#define BSLSTL_OPTIONAL_CONSTEXPR20
Definition bslstl_optional.h:249
#define BSLSTL_OPTIONAL_REQUIRES(EXPR)
Definition bslstl_optional.h:490
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM(TYPE, ANY_TYPE)
Definition bslstl_optional.h:394
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:356
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_ANY_TYPE(TYPE, ANY_TYPE)
Definition bslstl_optional.h:465
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCT_PROPAGATES_ALLOCATOR(TYPE, ANY_TYPE)
Definition bslstl_optional.h:362
#define BSLSTL_OPTIONAL_DECLARE_IF_DERIVED_FROM_OPTIONAL(DERIVED)
Definition bslstl_optional.h:405
#define BSLSTL_OPTIONAL_CONSTEXPR17
Definition bslstl_optional.h:248
#define BSLSTL_OPTIONAL_DECLARE_IF_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:414
#define BSLSTL_OPTIONAL_DEFINE_IF_CONSTRUCTS_FROM_STD_OPTIONAL(TYPE, ANY_TYPE)
Definition bslstl_optional.h:349
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_FORWARD_REF(TYPE, ANY_TYPE)
Definition bslstl_optional.h:454
#define BSLSTL_OPTIONAL_DECLARE_IF_NOT_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:424
#define BSLSTL_OPTIONAL_DECLARE_IF_CONSTRUCT_DOES_NOT_PROPAGATE_ALLOCATOR( TYPE, ANY_TYPE)
Definition bslstl_optional.h:382
#define BSLSTL_OPTIONAL_DEFINE_IF_EXPLICIT_CONSTRUCT(U, V)
Definition bslstl_optional.h:409
#define BSLSTL_OPTIONAL_ENABLE_ASSIGN_FROM_DERIVED(TYPE, DERIVED)
Definition bslstl_optional.h:446
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 bdlat_valuetypefunctions.h:939
const nullopt_t nullopt
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:959
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
const in_place_t in_place
ALLOCATOR & lhs
Definition bslstl_string.h:3917
BSLSTL_OPTIONAL_CONSTEXPR17 bool operator==(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator==(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator!=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator!=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator<(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator<(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator>(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator>(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator<=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator<=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator>=(const bsl::optional< t_LHS_TYPE > &lhs, const t_RHS_TYPE &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP BSLSTL_OPTIONAL_CONSTEXPR17 bool operator>=(const t_LHS_TYPE &lhs, const bsl::optional< t_RHS_TYPE > &rhs) BSLSTL_OPTIONAL_REQUIRES(!BloombergLP 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)
called in constant expressions only if t_LHS_TYPE is not allocator-aware.
Definition bslstl_optional.h:3306
Definition baljsn_encoder_testtypes.h:76
Definition bslstl_algorithm.h:84
Definition bdldfp_decimal.h:5549
Definition bslmf_allocatorargt.h:433
Definition bslmf_enableif.h:530
Definition bslstl_inplace.h:103
Definition bslmf_integralconstant.h:261
Definition bslmf_isnothrowmoveconstructible.h:361
Definition bslmf_issame.h:146
Definition bslstl_optional.h:522
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:529
t_TYPE type
This typedef is an alias to the (template parameter) t_TYPE.
Definition bslmf_removeconst.h:164
t_TYPE type
This typedef is an alias to the (template parameter) t_TYPE.
Definition bslmf_removereference.h:156
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwisecopyable.h:298
Definition bslstl_optional.h:707
Definition bslstl_optional.h:673
Definition bslstl_optional.h:708
Definition bslstl_optional.h:710
Definition bslstl_optional.h:738
t_TYPE & emplace(bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(t_ARGS)... args)
Definition bslstl_optional.h:3430
Optional_DataImp() BSLS_KEYWORD_NOEXCEPT
Create an empty Optional_DataImp object.
Definition bslstl_optional.h:3402
bool hasValue() const BSLS_KEYWORD_NOEXCEPT
Return true if this objects has a value, and false otherwise.
Definition bslstl_optional.h:3507
t_TYPE & value()
Definition bslstl_optional.h:3495
void reset() BSLS_KEYWORD_NOEXCEPT
Destroy the value_type object in d_buffer, if any.
Definition bslstl_optional.h:3464
BSLMF_NESTED_TRAIT_DECLARATION_IF(Optional_Data, bslmf::IsBitwiseCopyable, bslmf::IsBitwiseCopyable< t_TYPE >::value)
Definition bslstl_optional.h:842
~Optional_Data()
Destroy the managed value_type object, if it exists.
Definition bslstl_optional.h:3557
Definition bslstl_optional.h:567
Definition bslstl_optional.h:601
Definition bslstl_optional.h:709
Definition bslstl_optional.h:711
Definition bslstl_optional.h:499
Definition bslstl_optional.h:619
BSLS_KEYWORD_CONSTEXPR Optional_OptNoSuchType(int) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_optional.h:632
Definition bslstl_optional.h:654
Definition bsls_objectbuffer.h:277
TYPE * address()
Definition bsls_objectbuffer.h:335
TYPE & object()
Definition bsls_objectbuffer.h:352