BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_variant.h
Go to the documentation of this file.
1/// @file bslstl_variant.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_variant.h -*-C++-*-
8
9#ifndef INCLUDED_BSLSTL_VARIANT
10#define INCLUDED_BSLSTL_VARIANT
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslstl_variant bslstl_variant
16/// @brief Provide a standard-compliant allocator aware variant type.
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslstl
20/// @{
21/// @addtogroup bslstl_variant
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslstl_variant-purpose"> Purpose</a>
26/// * <a href="#bslstl_variant-classes"> Classes </a>
27/// * <a href="#bslstl_variant-description"> Description </a>
28/// * <a href="#bslstl_variant-usage"> Usage </a>
29/// * <a href="#bslstl_variant-example-1-basic-variant-use"> Example 1: Basic Variant Use </a>
30/// * <a href="#bslstl_variant-example-2-variant-default-construction"> Example 2: Variant Default Construction </a>
31/// * <a href="#bslstl_variant-known-limitations"> Known limitations </a>
32///
33/// # Purpose {#bslstl_variant-purpose}
34/// Provide a standard-compliant allocator aware variant type.
35///
36/// # Classes {#bslstl_variant-classes}
37///
38/// - bsl::variant: allocator-aware implementation of `std::variant`
39/// - bsl::variant_alternative: metafunction to return a variant alternative
40/// - bsl::variant_alternative_t: alias to return type of @ref variant_alternative
41/// - bsl::variant_size: metafunction to return number of variant alternatives
42/// - bsl::variant_size_v: the result value of the @ref variant_size metafunction
43///
44/// **Canonical header:** bsl_variant.h
45///
46/// # Description {#bslstl_variant-description}
47/// This component provides a class template,
48/// `bsl::variant<TYPES...>`, that is a not-yet-standardised allocator-aware
49/// version of `std::variant`. For functionality common to `std::variant`,
50/// C++23 was used as the reference specification, modulo limitations listed
51/// below. `bsl::variant` may hold and manage the lifetime of an object, known
52/// as the *contained value*, which is stored within the footprint of the
53/// `bsl::variant` object, and must be one of the template arguments `TYPES`.
54/// These template arguments are called *alternatives*, and the alternative
55/// corresponding to the contained value is said to be *active*. A
56/// `bsl::variant` object may also hold no value under exceptional
57/// circumstances.
58///
59/// A program that instantiates the definition of `variant` with no template
60/// arguments is ill-formed.
61///
62/// A reference or pointer to the contained value of a `bsl::variant` can be
63/// obtained using the free functions `get` or `get_if`, respectively. Such a
64/// reference or pointer that does not have top-level `const` may be used to
65/// modify the contained value directly, if desired.
66///
67/// `bsl::variant` is copy/move constructible when all alternatives are
68/// copy/move constructible; the resulting object holds the alternative that the
69/// source object held. `bsl::variant` can also be constructed from a value of
70/// one of the alternatives, or from an expression for which there is an
71/// unambiguous best match conversion to one of the alternatives. In addition,
72/// `bsl::variant` supports construction of an explicitly specified alternative
73/// from a variadic number of arguments.
74///
75/// If at least one alternative is allocator-aware, `bsl::variant` is
76/// allocator-aware. For an allocator-aware `bsl::variant`, each constructor
77/// has a matching allocator-extended version that specifies the allocator that
78/// will be used during the lifetime of the `bsl::variant` object to construct
79/// any allocator-aware alternative that the `bsl::variant` object holds. Note
80/// that the `bsl::variant` object itself does not allocate any memory; its
81/// footprint is large enough to hold any of its alternatives.
82///
83/// `bsl::variant` is copy/move assignable when all alternatives are copy/move
84/// assignable and copy/move constructible; if the LHS has a different active
85/// alternative than the RHS, the contained value of the LHS will be destroyed
86/// before the contained value of the new alternative is created.
87/// `bsl::variant` may also be assigned to from an expression for which there is
88/// an unambiguous best match conversion to one of the alternatives.
89///
90/// The `bsl::variant::emplace` methods, which take an explicitly specified
91/// alternative, can also be used to construct a contained value after a
92/// `bsl::variant` object has already been constructed. If the `bsl::variant`
93/// object already holds a contained value, that object will be destroyed before
94/// the specified alternative is created.
95///
96/// If an exception is thrown during an operation that changes the active
97/// alternative in a `bsl::variant` object, the `bsl::variant` object might be
98/// left in a state that holds no value, referred to as the *valueless by
99/// exception* state, indicated by the `valueless_by_exception()` method
100/// returning `true` and the `index()` method returning `bsl::variant_npos`.
101///
102/// Two `bsl::variant`s of the same type compare equal if they hold the same
103/// alternative and their contained values compare equal, or they both hold no
104/// value.
105///
106/// The `index()` method returns the zero-based index of the current
107/// alternative. Additionally, the free function @ref holds_alternative can be
108/// used to check whether an explicitly specified type is the currently active
109/// alternative.
110///
111/// Free function `bsl::visit` is provided that implements the visitor design
112/// pattern as specified by the C++ standard, modulo limitations listed below.
113///
114/// ## Usage {#bslstl_variant-usage}
115///
116///
117/// This section illustrates intended use of this component.
118///
119/// ### Example 1: Basic Variant Use {#bslstl_variant-example-1-basic-variant-use}
120///
121///
122/// First, we create a `variant` object that can hold an integer, a char, or
123/// a string. The default constructor of `bsl::variant<TYPES...>` creates the
124/// first alternative in `TYPES...`; to create a different alternative, we can
125/// provide the index or the type of the alternative to create:
126/// @code
127/// bsl::variant<int, char> v1;
128/// bsl::variant<int, char> v2(bsl::in_place_type_t<char>(), 'c');
129///
130/// assert(bsl::holds_alternative<int>(v1));
131/// assert(bsl::holds_alternative<char>(v2));
132/// @endcode
133/// Next, we create a visitor that can be called with a value of any of the
134/// alternatives:
135/// @code
136/// class MyVisitor {
137/// public:
138/// template <class t_TYPE>
139/// void operator()(const t_TYPE& value) const
140/// {
141/// bsl::cout << value << bsl::endl;
142/// }
143/// };
144/// @endcode
145/// We can now use `bsl::visit` to apply the visitor to our variant objects:
146/// @code
147/// MyVisitor visitor;
148/// bsl::visit(visitor, v1); // prints integer 0
149/// bsl::visit(visitor, v2); // prints char 'c'
150/// @endcode
151/// To retrieve a contained value, we can use the `get` free functions. If the
152/// requested alternative is not the currently active alternative, an exception
153/// of type `bsl::bad_variant_access` will be thrown.
154/// @code
155/// assert(0 == bsl::get<int>(v1));
156/// assert('c' == bsl::get<1>(v2));
157/// try {
158/// bsl::get<int>(v2);
159/// } catch (const bsl::bad_variant_access& ex) {
160/// bsl::cout << "non-active alternative requested" << bsl::endl;
161/// }
162/// @endcode
163///
164/// ### Example 2: Variant Default Construction {#bslstl_variant-example-2-variant-default-construction}
165///
166///
167/// Suppose we want to default construct a `bsl::variant` which can hold an
168/// alternative of type `S`. Type `S` is not default constructible so we use
169/// `bsl::monostate`as the first alternative to allow for default construction
170/// of the variant object.
171/// @code
172/// struct S {
173/// S(int i) : d_i(i) {}
174/// int d_i;
175/// };
176///
177/// bsl::variant<bsl::monostate, S> v3;
178/// @endcode
179/// To create an alternative of type `S`. we can use the emplace method.
180/// @code
181/// v3.emplace<S>(3);
182/// assert(bsl::holds_alternative<S>(v3));
183/// @endcode
184///
185/// ## Known limitations {#bslstl_variant-known-limitations}
186///
187///
188/// * The variadic constructors and emplace methods in C++03 are limited to one
189/// parameter.
190/// * In C++03, constructors and assignment operators that determine the
191/// best-matching alternative (instead of taking an explicitly specified
192/// alternative) require the argument type to exactly match one of the
193/// alternatives, modulo cv-qualification.
194/// * In C++03, the majority of functions do not have constraints due to
195/// language limitations. The documentation for each specific function lists
196/// any constraints that are implemented.
197/// * Visitation functionality is limited to one variant. Before C++17,
198/// visitation only supports the `VISITOR(ALTERNATIVE)` form of invocation;
199/// cases where the visitor is a pointer to member are not supported.
200/// * Constexpr, triviality, and exception specifications are not implemented.
201/// * In `operator=(const variant& rhs)` and `operator=(T&& t)`, only direct
202/// copy construction from the relevant alternative is tried. This behavior
203/// differs from the standard, which requires the construction of a temporary
204/// alternative object if construction of the relevant alternative is not
205/// `noexcept` (see [variant.assign] for details). The standard behavior
206/// causes unnecessary performance degradation in cases where the alternative
207/// constructor does not throw, yet is not marked `noexcept`; this behavior
208/// is therefore not implemented in `bsl::variant`.
209/// * Due to the C++03 limitations of the `bsl::invoke_result` facility, it is
210/// not possible to explicitly specify a return type for `bsl::visit` without
211/// triggering a hard error during substitution into the overload of
212/// `bsl::visit` having a deduced return type on some C++03 compilers (Sun
213/// for example). For this reason, the overload of `bsl::visit` that takes
214/// the return type as the first, non-deduced template argument is not
215/// provided in C++03. The non-standard free function `bsl::visitR` may be
216/// used instead. `bsl::visitR` is also provided in C++11 and later for
217/// backward compatibility with the C++03 interface.
218/// @}
219/** @} */
220/** @} */
221
222/** @addtogroup bsl
223 * @{
224 */
225/** @addtogroup bslstl
226 * @{
227 */
228/** @addtogroup bslstl_variant
229 * @{
230 */
231
232#include <bslscm_version.h>
233
235#include <bslstl_hash.h>
236#include <bslstl_inplace.h>
237
238#include <bslalg_swaputil.h>
239
242#include <bslma_stdallocator.h>
244
245#include <bslmf_allocatorargt.h>
246#include <bslmf_assert.h>
247#include <bslmf_conjunction.h>
250#include <bslmf_invokeresult.h>
252#include <bslmf_isconvertible.h>
254#include <bslmf_isreference.h>
255#include <bslmf_issame.h>
257#include <bslmf_movableref.h>
259#include <bslmf_removeconst.h>
260#include <bslmf_removecvref.h>
261#include <bslmf_util.h>
262#include <bslmf_voidtype.h>
263
264#include <bsls_assert.h>
266#include <bsls_exceptionutil.h>
267#include <bsls_keyword.h>
268#include <bsls_libraryfeatures.h>
269#include <bsls_objectbuffer.h>
270#include <bsls_util.h> // 'forward<T>(V)'
271
272#include <stddef.h>
273
274// We provide one of two feature sets for 'bsl::variant', depending on the
275// capabilities of the compiler. These are the necessary compiler features for
276// the full feature set of 'bsl::variant'.
277#ifdef BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
278#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
279#ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
280#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
281// Note that 'BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE' does not require
282// a C++14 compiler.
283#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE
284#define BSL_VARIANT_FULL_IMPLEMENTATION
285#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
286#endif // BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE
287#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
288#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
289#endif // BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE
290
291#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
292#include <type_traits>
293#include <functional> // std::invoke
294#endif // BSL_VARIANT_FULL_IMPLEMENTATION
295
296#ifdef BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
297#include <initializer_list>
298#endif // BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS
299
300#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
301#include <variant>
302#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
303
304#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
305// Include version that can be compiled with C++03
306// Generated on Fri Dec 22 18:51:14 2023
307// Command line: sim_cpp11_features.pl bslstl_variant.h
308# define COMPILING_BSLSTL_VARIANT_H
309# include <bslstl_variant_cpp03.h>
310# undef COMPILING_BSLSTL_VARIANT_H
311#else
312
313// When generating the expansion of a variadic template, the
314// sim_cpp11_features.pl script currently expands the primary template by the
315// required number of template arguments. If there is a partial specialization
316// that adds a non variadic template parameter, the generated primary template
317// will no longer match the expansion of such specialization. In the case of
318// 'variant' metafunction helpers, such additional template argument is always
319// a type parameter. To work around this issue, a dummy template type
320// parameter is added to the primary template and defaulted to
321// 'BSLSTL_VARIANT_NOT_A_TYPE'.
323
324namespace bsl {
325
326#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=18
327template <class t_HEAD, class... t_TAIL>
328class variant;
329#endif
330
331// TRAITS
332
333 // ===================
334 // struct variant_size
335 // ===================
336
337/// This metafunction calculates the number of alternatives in the (possibly
338/// cv-qualified) `bsl::variant` type of (template parameter)
339/// `t_BSL_VARIANT`. The primary template is not defined.
340template <class t_BSL_VARIANT>
342
343template <class t_BSL_VARIANT>
344struct variant_size<const t_BSL_VARIANT> : variant_size<t_BSL_VARIANT> {
345};
346
347template <class t_BSL_VARIANT>
348struct variant_size<volatile t_BSL_VARIANT> : variant_size<t_BSL_VARIANT> {
349};
350
351template <class t_BSL_VARIANT>
352struct variant_size<const volatile t_BSL_VARIANT>
353: variant_size<t_BSL_VARIANT> {
354};
355
356#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
357template <class t_HEAD, class... t_TAIL>
358struct variant_size<variant<t_HEAD, t_TAIL...> >
359: bsl::integral_constant<size_t, 1 + sizeof...(t_TAIL)> {
360};
361#endif
362
363#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
364/// This variable template represents the result value of the
365/// `bsl::variant_size` metafunction.
366template <class t_BSL_VARIANT>
367BSLS_KEYWORD_INLINE_VARIABLE constexpr size_t variant_size_v =
369#endif // BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
370
371/// This value is returned by `bsl::variant::index()` if
372/// `valueless_by_exception()` is `true`.
374
375 // ==========================
376 // struct variant_alternative
377 // ==========================
378
379/// This metafunction calculates the type of the alternative whose index is
380/// (template parameter) `t_INDEX` in the possibly cv-qualified
381/// `bsl::variant` type of (template parameter) `t_TYPE`. If `t_TYPE` is
382/// cv-qualified, its cv-qualifiers are applied to the alternative.
383template <size_t t_INDEX, class t_TYPE>
385
386template <size_t t_INDEX, class t_TYPE>
387struct variant_alternative<t_INDEX, const t_TYPE> {
389};
390
391template <size_t t_INDEX, class t_TYPE>
392struct variant_alternative<t_INDEX, volatile t_TYPE> {
394};
395
396template <size_t t_INDEX, class t_TYPE>
397struct variant_alternative<t_INDEX, const volatile t_TYPE> {
398 typedef
400};
401
402#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
403// 'Variant_VariantAlternativeImpl' defined to avoid 'variant<>' from the
404// sim_cpp11_features.pl script
405
406/// This component-private metafunction provides the implementation of
407/// `bsl::variant_alternative`.
408template <size_t t_INDEX,
409 class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE,
410 class... t_TAIL>
412: Variant_VariantAlternativeImpl<t_INDEX - 1, t_TAIL...> {
413};
414
415template <size_t t_INDEX>
418
419template <>
422
423template <class t_HEAD, class... t_TAIL>
424struct Variant_VariantAlternativeImpl<0, t_HEAD, t_TAIL...> {
425 typedef t_HEAD type;
426};
427
428template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
429struct variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >
430: Variant_VariantAlternativeImpl<t_INDEX, t_HEAD, t_TAIL...> {
431 BSLMF_ASSERT((t_INDEX <
433};
434
435#ifdef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
436template <size_t t_INDEX, class t_TYPE>
437using variant_alternative_t =
439// 'variant_alternative_t' is an alias to the return type of the
440// @ref variant_alternative metafunction.
441#endif // BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
442
443// FREE FUNCTIONS
444
445/// Efficiently exchange the values of the specified `lhs` and `rhs`
446/// objects. This method provides the no-throw guarantee if the two variant
447/// objects being swapped have the same active alternative and that
448/// alternative provides that guarantee; otherwise, this method provides the
449/// basic guarantee. If `lhs` and `rhs` do not contain the same alternative
450/// or they have unequal allocators, and an exception is thrown during the
451/// swap, either or both variant objects may be left in a valueless state or
452/// with an alternative in a moved-from state. All alternatives shall be
453/// move constructible and swappable. For simplicity of implementation,
454/// this function differs from the standard in the following :
455/// * constraints are not implemented
456/// * constexpr is not implemented
457template <class t_HEAD, class... t_TAIL>
460
461// HASH SPECIALIZATIONS
462
463/// Pass the specified `input` to the specified `hashAlg`, where `hashAlg`
464/// is a hashing algorithm.
465template <class t_HASHALG, class t_HEAD, class... t_TAIL>
466void hashAppend(t_HASHALG& hashAlg, const variant<t_HEAD, t_TAIL...>& input);
467
468// 20.7.5, value access
469
470/// Return `true` if the specified `obj` currently holds the (template
471/// parameter) `t_TYPE` alternative, and `false` otherwise. `t_TYPE` shall
472/// appear exactly once in the variant's list of alternatives.
473template <class t_TYPE, class t_HEAD, class... t_TAIL>
476#endif
477#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
478/// Return a reference to the alternative object at index (template
479/// parameter) `t_INDEX` in the specified `obj`. If `t_INDEX` is not the
480/// index of the currently active alternative, throw an exception of type
481/// `bad_variant_access`. `t_INDEX` shall be a valid index for the variant
482/// type of `obj`.
483template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
484typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type& get(
486template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
487const typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
489template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
490typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&& get(
492template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
493const typename variant_alternative<t_INDEX,
494 variant<t_HEAD, t_TAIL...> >::type&&
496
497/// Return a reference to the alternative object with type (template
498/// parameter) `t_TYPE` in the specified `obj`. If `t_TYPE` is not the type
499/// of the currently active alternative, throw an exception of type
500/// `bad_variant_access`. `t_TYPE` shall appear exactly once in the
501/// variant's list of alternatives.
502template <class t_TYPE, class t_HEAD, class... t_TAIL>
503t_TYPE& get(variant<t_HEAD, t_TAIL...>& obj);
504template <class t_TYPE, class t_HEAD, class... t_TAIL>
505const t_TYPE& get(const variant<t_HEAD, t_TAIL...>& obj);
506template <class t_TYPE, class t_HEAD, class... t_TAIL>
507t_TYPE&& get(variant<t_HEAD, t_TAIL...>&& obj);
508template <class t_TYPE, class t_HEAD, class... t_TAIL>
509const t_TYPE&& get(const variant<t_HEAD, t_TAIL...>&& obj);
510
511template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
512typename add_pointer<
513 typename variant_alternative<t_INDEX,
514 variant<t_HEAD, t_TAIL...> >::type>::type
516
517/// Return a pointer to the alternative object with index (template
518/// parameter) `t_INDEX` in the specified `obj`, or a null pointer if `obj`
519/// itself is a null pointer or if `t_INDEX` is not the index of the
520/// currently active alternative. `t_INDEX` shall be a valid alternative
521/// index.
522template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
523typename add_pointer<const typename variant_alternative<
524 t_INDEX,
525 variant<t_HEAD, t_TAIL...> >::type>::type
527
528template <class t_TYPE, class t_HEAD, class... t_TAIL>
531
532/// Return a pointer to the alternative object with type (template
533/// parameter) `t_TYPE` in the specified `obj`, or a null pointer if `obj`
534/// itself is a null pointer or if `t_TYPE` is not the type of the currently
535/// active alternative. `t_TYPE` shall appear exactly once in the variant's
536/// list of alternatives.
537template <class t_TYPE, class t_HEAD, class... t_TAIL>
540#else // BSL_VARIANT_FULL_IMPLEMENTATION
541
542// See 'bslstl_variant.cpp' for implementation notes regarding 'bsl::get'.
543template <bool t_VALID, size_t t_INDEX, class t_ARG, class t_VARIANT>
545 // This component-private metafunction computes the return types for
546 // 'bsl::get<t_INDEX>' and 'bsl::get_if<t_INDEX>' with an argument of type
547 // 't_ARG' or 't_ARG*', respectively, where 't_VARIANT' is 't_ARG' with
548 // cvref-qualifiers stripped, and shall be a specialization of
549 // 'bsl::variant'. 't_VALID' shall be 'true' if and only if 't_INDEX' is a
550 // valid index for 't_VARIANT'. If 't_VALID' is 'false', no member
551 // typedefs are provided.
552};
553
554template <size_t t_INDEX, class t_VARIANT>
555struct Variant_GetIndexReturnTypeImpl<true, t_INDEX, t_VARIANT, t_VARIANT> {
557
558 typedef
560};
561
562template <size_t t_INDEX, class t_VARIANT>
564 t_INDEX,
565 const t_VARIANT,
566 t_VARIANT> {
569
572};
573
574template <size_t t_INDEX, class t_VARIANT>
576 true,
577 t_INDEX,
578 BloombergLP::bslmf::MovableRef<t_VARIANT>,
579 t_VARIANT> {
580 typedef BloombergLP::bslmf::MovableRef<
583};
584
585template <size_t t_INDEX,
586 class t_ARG,
587 class t_VARIANT = typename BloombergLP::bslmf::MovableRefUtil::
588 Decay<t_ARG>::type>
590 // This component-private metafunction computes the return types for
591 // 'bsl::get<t_INDEX>' and 'bsl::get_if<t_INDEX>' with an argument of type
592 // 't_ARG' or 't_ARG*' respectively. If 't_ARG' is not a (possibly
593 // cvref-qualified) 'bsl::variant', no definition is provided. If
594 // 't_INDEX' is not a valid index for 't_ARG', the member typedefs 'type'
595 // and 'pointer' are not provided.
596
597#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
598template <size_t t_INDEX, class t_ARG, class t_HEAD, class... t_TAIL>
600 t_ARG,
601 bsl::variant<t_HEAD, t_TAIL...> >
602: Variant_GetIndexReturnTypeImpl<(t_INDEX <= sizeof...(t_TAIL)),
603 t_INDEX,
604 t_ARG,
605 bsl::variant<t_HEAD, t_TAIL...> > {
606};
607
608template <class t_TYPE, class t_HEAD, class... t_TAIL>
609struct Variant_GetTypeReturnType;
610 // This component-private metafunction is defined only when 't_HEAD' is a
611 // specialization of 'bsl::variant' and 't_TAIL' is empty, in which case it
612 // provides member typedefs corresponding to 't_TYPE'. Naming these member
613 // typedefs results in a substitution failure when this metafunction is not
614 // defined.
615
616template <class t_TYPE, class t_HEAD, class... t_TAIL>
617struct Variant_GetTypeReturnType<t_TYPE, bsl::variant<t_HEAD, t_TAIL...> > {
618 // This partial specialization provides member typedefs that are used to
619 // declare the 'get' and 'get_if' function templates in C++03 as
620 // non-variadic function templates that are constrained to accept only
621 // references or pointers to 'bsl::variant'.
622 typedef t_TYPE type;
623 typedef typename add_pointer<t_TYPE>::type pointer;
624};
625#endif
626
627template <size_t t_INDEX, class t_VARIANT>
628typename Variant_GetIndexReturnType<t_INDEX, t_VARIANT>::type
629get(t_VARIANT& obj);
630template <size_t t_INDEX, class t_VARIANT>
631typename Variant_GetIndexReturnType<
632 t_INDEX,
633 BloombergLP::bslmf::MovableRef<t_VARIANT> >::type
634get(BloombergLP::bslmf::MovableRef<t_VARIANT> obj);
635 // Return a reference to the alternative object at index (template
636 // parameter) 't_INDEX' in the specified 'obj'. If 't_INDEX' is not the
637 // index of the currently active alternative, throw an exception of type
638 // 'bad_variant_access'. 't_INDEX' shall be a valid index for the variant
639 // type of 'obj'. Note that 't_VARIANT' may be const-qualified.
640
641template <class t_TYPE, class t_VARIANT>
642typename Variant_GetTypeReturnType<t_TYPE&, t_VARIANT>::type get(
643 t_VARIANT& obj);
644template <class t_TYPE, class t_VARIANT>
645typename Variant_GetTypeReturnType<const t_TYPE&, t_VARIANT>::type get(
646 const t_VARIANT& obj);
647template <class t_TYPE, class t_VARIANT>
648typename Variant_GetTypeReturnType<BloombergLP::bslmf::MovableRef<t_TYPE>,
649 t_VARIANT>::type get(
650 BloombergLP::bslmf::MovableRef<t_VARIANT> obj);
651 // Return a reference to the alternative object with type (template
652 // parameter) 't_TYPE' in the specified 'obj'. If 't_TYPE' is not the type
653 // of the currently active alternative, throw an exception of type
654 // 'bad_variant_access'. 't_TYPE' shall appear exactly once in the
655 // variant's list of alternatives.
656
657template <size_t t_INDEX, class t_VARIANT>
658typename Variant_GetIndexReturnType<t_INDEX, t_VARIANT>::pointer
659get_if(t_VARIANT *obj) BSLS_KEYWORD_NOEXCEPT;
660 // Return a pointer to the alternative object with index (template
661 // parameter) 't_INDEX' in the specified 'obj', or a null pointer if 'obj'
662 // itself is a null pointer or if 't_INDEX' is not the index of the
663 // currently active alternative. 't_INDEX' shall be a valid alternative
664 // index. Note that 't_VARIANT' may be const-qualified.
665
666template <class t_TYPE, class t_VARIANT>
667typename Variant_GetTypeReturnType<t_TYPE, t_VARIANT>::pointer get_if(
668 t_VARIANT *obj) BSLS_KEYWORD_NOEXCEPT;
669template <class t_TYPE, class t_VARIANT>
670typename Variant_GetTypeReturnType<const t_TYPE, t_VARIANT>::pointer get_if(
671 const t_VARIANT *obj) BSLS_KEYWORD_NOEXCEPT;
672 // Return a pointer to the alternative object with type (template
673 // parameter) 't_TYPE' in the specified 'obj', or a null pointer if 'obj'
674 // itself is a null pointer or if 't_TYPE' is not the type of the currently
675 // active alternative. 't_TYPE' shall appear exactly once in the variant's
676 // list of alternatives.
677#endif // BSL_VARIANT_FULL_IMPLEMENTATION
678// FREE OPERATORS
679
680// 20.7.6, relational operators
681#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
682/// Return `true` if the specified `lhs` and `rhs` are both valueless by
683/// exception or if they have the same active alternative and their
684/// contained values compare equal; otherwise, return `false`. All
685/// alternatives shall support `operator==`.
686template <class t_HEAD, class... t_TAIL>
687bool operator==(const variant<t_HEAD, t_TAIL...>& lhs,
688 const variant<t_HEAD, t_TAIL...>& rhs);
689
690/// Return `true` if the specified `lhs` and `rhs` have different active
691/// alternatives or only one holds an alternative, or if they have the same
692/// active alternative and the contained values compare unequal; otherwise,
693/// return `false`. All alternatives shall support `operator!=`.
694template <class t_HEAD, class... t_TAIL>
695bool operator!=(const variant<t_HEAD, t_TAIL...>& lhs,
696 const variant<t_HEAD, t_TAIL...>& rhs);
697
698/// Return `true` if the index of the active alternative in the specified
699/// `lhs` is less than that of the specified `rhs`, or if both have the same
700/// active alternative and the contained value of `lhs` compares less than
701/// that of `rhs`, or if `lhs` is valueless by exception and `rhs` is not;
702/// otherwise, return `false`. All alternatives shall support `operator<`.
703template <class t_HEAD, class... t_TAIL>
704bool operator<(const variant<t_HEAD, t_TAIL...>& lhs,
705 const variant<t_HEAD, t_TAIL...>& rhs);
706
707/// Return `true` if the index of the active alternative in the specified
708/// `lhs` is greater than that of the specified `rhs`, or if both have the
709/// same active alternative and the contained value of `lhs` compares
710/// greater than that of `rhs`, or if `rhs` is valueless by exception and
711/// `lhs` is not; otherwise, return `false`. All alternatives shall support
712/// `operator>`.
713template <class t_HEAD, class... t_TAIL>
714bool operator>(const variant<t_HEAD, t_TAIL...>& lhs,
715 const variant<t_HEAD, t_TAIL...>& rhs);
716
717/// Return `true` if the index of the active alternative in the specified
718/// `lhs` is less than that of the specified `rhs`, or if both have the same
719/// active alternative and the contained value of `lhs` compares less than
720/// or equal to that of `rhs`, or if `lhs` is valueless by exception;
721/// otherwise, return `false`. All alternatives shall support `operator<=`.
722template <class t_HEAD, class... t_TAIL>
723bool operator<=(const variant<t_HEAD, t_TAIL...>& lhs,
724 const variant<t_HEAD, t_TAIL...>& rhs);
725
726/// Return `true` if the index of the active alternative in the specified
727/// `lhs` is greater than that of the specified `rhs`, or if both have the
728/// same active alternative and the contained value of `lhs` compares
729/// greater than or equal to that of `rhs`, or if `rhs` is valueless by
730/// exception; otherwise, return `false`. All alternatives shall support
731/// `operator>=`.
732template <class t_HEAD, class... t_TAIL>
733bool operator>=(const variant<t_HEAD, t_TAIL...>& lhs,
734 const variant<t_HEAD, t_TAIL...>& rhs);
735
736#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON && \
737 defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
738
739/// If `lhs` and `rhs` are not valueless by exception and hold the same
740/// alternative `i`, return `get<i>(lhs) <=> get<i>(rhs)` . If `lhs` and
741/// `rhs` are not valueless by exception and hold the aalternatives `i` and
742/// `j` respectively, return `i<=>j`. Return `strong_ordering::equal` if
743/// both variants are valueless by exception. Return
744/// `strong_ordering::less` if `lhs` is valueless by exception. Return
745/// `strong_ordering::greater` if `rhs` is valueless by exception.
746template <class... t_ALTS>
747 requires(std::three_way_comparable<t_ALTS> && ...)
748constexpr std::common_comparison_category_t<
749 std::compare_three_way_result_t<t_ALTS>...>
750operator<=>(const variant<t_ALTS...>& lhs, const variant<t_ALTS...>& rhs);
751#endif
752#endif
753
754} // close namespace bsl
755
756
757namespace bslstl {
758// COMPONENT-PRIVATE TAG TYPES
759
760/// This component-private tag type is used as a parameter type for
761/// constructors of `Variant_Base` that accept a `std::variant`.
762struct Variant_ConstructFromStdTag {};
763
764#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
765/// This component-private metafunction is derived from `bsl::true_type` if
766/// at least one template argument uses an allocator, and from
767/// `bsl::false_type` otherwise.
768template <class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE, class... t_TAIL>
769struct Variant_UsesBslmaAllocatorAny;
770
771template <>
772struct Variant_UsesBslmaAllocatorAny<BSLSTL_VARIANT_NOT_A_TYPE>
773: bsl::false_type {
774};
775
776template <class t_HEAD, class... t_TAIL>
777struct Variant_UsesBslmaAllocatorAny
778: bsl::integral_constant<
779 bool,
780 BloombergLP::bslma::UsesBslmaAllocator<t_HEAD>::value ||
781 BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny<
782 t_TAIL...>::value> {
783};
784
785/// This component-private metafunction is derived from `bsl::true_type` if
786/// all template arguments are bitwise moveable, and from `bsl::false_type`
787/// otherwise.
788template <class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE, class... t_TAIL>
789struct Variant_IsBitwiseMoveableAll;
790
791template <>
792struct Variant_IsBitwiseMoveableAll<BSLSTL_VARIANT_NOT_A_TYPE>
793: bsl::true_type {
794};
795
796template <class t_HEAD, class... t_TAIL>
797struct Variant_IsBitwiseMoveableAll
798: bsl::integral_constant<
799 bool,
800 BloombergLP::bslmf::IsBitwiseMoveable<t_HEAD>::value &&
801 Variant_IsBitwiseMoveableAll<t_TAIL...>::value> {
802};
803
804/// This component-private metafunction is derived from `bsl::true_type` if
805/// (template parameter) `t_TYPE` is not a tag type. This metafunction
806/// requires any cv and ref qualifications to be removed from the queried
807/// type.
808template <class t_TYPE>
809struct Variant_IsTag : bsl::false_type {
810};
811
812template <>
813struct Variant_IsTag<bsl::allocator_arg_t> : bsl::true_type {
814};
815
816template <class t_TYPE>
817struct Variant_IsTag<bsl::in_place_type_t<t_TYPE> > : bsl::true_type {
818};
819
820template <size_t t_INDEX>
821struct Variant_IsTag<bsl::in_place_index_t<t_INDEX> > : bsl::true_type {
822};
823
824#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
825/// This component-private metafunction derives from
826/// `std::is_constructible<t_TO, t_FROM>` in C++11 and later, and
827/// `bsl::true_type` in C++03.
828template <class t_TO, class t_FROM>
829struct Variant_IsConstructible : std::is_constructible<t_TO, t_FROM> {
830};
831
832/// This component-private metafunction derives from
833/// `std::is_assignable<t_LHS, t_RHS>` in C++11 and later, and
834/// `bsl::true_type` in C++03.
835template <class t_LHS, class t_RHS>
836struct Variant_IsAssignable : std::is_assignable<t_LHS, t_RHS> {
837};
838#else
839template <class t_TO, class t_FROM>
840struct Variant_IsConstructible : bsl::true_type {
841 // This component-private metafunction derives from
842 // 'std::is_constructible<t_TO, t_FROM>' in C++11 and later, and
843 // 'bsl::true_type' in C++03.
844};
845
846template <class t_LHS, class t_RHS>
847struct Variant_IsAssignable : bsl::true_type {
848 // This component-private metafunction derives from
849 // 'std::is_assignable<t_LHS, t_RHS>' in C++11 and later, and
850 // 'bsl::true_type' in C++03.
851};
852#endif // BSL_VARIANT_FULL_IMPLEMENTATION
853
854/// This component-private macro is used as a constraint in function
855/// definitions which require the specified `VARIANT` to be constructible
856/// from the specified `TYPE`.
857#define BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM(VARIANT, TYPE) \
858 typename bsl::enable_if< \
859 BloombergLP::bslstl::Variant_ConstructsFromType<VARIANT, \
860 TYPE>::value, \
861 BloombergLP::bslstl::Variant_NoSuchType>::type
862
863/// This component-private macro is used as a constraint in function
864/// declarations which require the specified `VARIANT` to be constructible
865/// from the specified `TYPE`.
866#define BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM(VARIANT, TYPE) \
867 BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM( \
868 VARIANT, \
869 TYPE) = BloombergLP::bslstl::Variant_NoSuchType(0)
870
871/// This component-private macro is used as a constraint when defining
872/// constructors of `variant` from the corresponding `std::variant`.
873#define BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM_STD(STD_VARIANT) \
874 bsl::enable_if_t< \
875 BloombergLP::bslstl::variant_constructsFromStd<variant, STD_VARIANT>, \
876 BloombergLP::bslstl::Variant_NoSuchType>
877
878/// This component-private macro is used as a constraintwhen declaring
879/// constructors of `variant` from the corresponding `std::variant`.
880#define BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM_STD(STD_VARIANT) \
881 BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM_STD(STD_VARIANT) \
882 = BloombergLP::bslstl::Variant_NoSuchType(0)
883
884/// This component-private macro is used as a constraint in function
885/// definitions which require the specified `TYPE` to be a unique
886/// alternative in `variant<t_HEAD, t_TAIL...>`.
887/// Implementation note: This macro can't use
888/// `BSLSTL_VARIANT_HAS_UNIQUE_TYPE` because this macro is used at points
889/// where `variant<t_HEAD, t_TAIL...>` expands to an invalid construct.
890#define BSLSTL_VARIANT_DEFINE_IF_HAS_UNIQUE_TYPE(TYPE) \
891 typename bsl::enable_if< \
892 BloombergLP::bslstl::Variant_HasUniqueType<TYPE, variant>::value, \
893 BloombergLP::bslstl::Variant_NoSuchType>::type
894
895/// This component-private macro is used as a constraint in function
896/// declarations which require the specified `TYPE` to be a unique
897/// alternative in `variant<t_HEAD, t_TAIL...>`.
898#define BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(TYPE) \
899 BSLSTL_VARIANT_DEFINE_IF_HAS_UNIQUE_TYPE( \
900 TYPE) = BloombergLP::bslstl::Variant_NoSuchType(0)
901
902/// This component-private macro expands to the check for whether the
903/// specified `TYPE` is a unique alternative in
904/// `variant<t_HEAD, t_TAIL...>`. See definition `Variant_HasUniqueType`
905/// for more details.
906#define BSLSTL_VARIANT_HAS_UNIQUE_TYPE(TYPE) \
907 BloombergLP::bslstl:: \
908 Variant_HasUniqueType<TYPE, variant<t_HEAD, t_TAIL...> >::value
909
910/// This component-private macro expands to the type of alternative at
911/// specified `INDEX` for a variant of type
912/// `bsl::variant<t_HEAD, t_TAIL...>`.
913#define BSLSTL_VARIANT_TYPE_AT_INDEX(INDEX) \
914 typename bsl::variant_alternative<INDEX, \
915 bsl::variant<t_HEAD, t_TAIL...> >::type
916
917/// This component-private macro expands to the index of the first
918/// alternative in the specified `VARIANT` that is identical to the
919/// specified `TYPE`, or `bsl::variant_npos` if no such alternative exists.
920#define BSLSTL_VARIANT_INDEX_OF(TYPE, VARIANT) \
921 BloombergLP::bslstl::Variant_TypeToIndex<TYPE, VARIANT>::value
922
923/// This component-private macro expands to the index of the first
924/// alternative in the specified `VARIANT` that is a "unique" best match for
925/// conversion from `std::declval<TYPE>()`. See the documentation for
926/// `Variant_ConvertIndex` for more details.
927#define BSLSTL_VARIANT_CONVERT_INDEX_OF(TYPE, VARIANT) \
928 BloombergLP::bslstl::Variant_ConvertIndex<TYPE, VARIANT>::value
929
930/// This component-private macro expands to the type of the alternative
931/// in the specified `VARIANT` that is a "unique" best match for conversion
932/// from `std::declval<TYPE>()`. See the documentation for
933/// `Variant_ConvertIndex` for more details.
934#define BSLSTL_VARIANT_CONVERT_TYPE_OF(TYPE, VARIANT) \
935 typename bsl::variant_alternative<BSLSTL_VARIANT_CONVERT_INDEX_OF( \
936 TYPE, VARIANT), \
937 VARIANT>::type
938
939/// This component-private macro expands to the invocation of
940/// `Variant_ImpUtil::visitId` with specified `RET` as return type, and
941/// specified `VISITOR` and specified `VAROBJ` as arguments. See the
942/// documentation of `Variant_ImpUtil::visitId` for more details.
943#define BSLSTL_VARIANT_VISITID(RET, VISITOR, VAROBJ) \
944 BloombergLP::bslstl::Variant_ImpUtil::visitId<RET>(VISITOR, VAROBJ);
945
946/// This component-private metafunction provides implementation for
947/// `Variant_TypeToIndex`. It evaluates to `t_INDEX + i` where `i` is the
948/// zero-based index of (template parameter) `t_TYPE` in (template parameters)
949/// `t_HEAD, t_TAIL...`, or `bsl::variant_npos` if `t_TYPE` is not found.
950template <size_t t_INDEX,
951 class t_TYPE,
952 class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE,
953 class... t_TAIL>
954struct Variant_TypeToIndexImpl
955: bsl::conditional<
956 bsl::is_same<t_TYPE, t_HEAD>::value,
957 bsl::integral_constant<size_t, t_INDEX>,
958 Variant_TypeToIndexImpl<t_INDEX + 1, t_TYPE, t_TAIL...> >::type {
959};
960
961/// This partial specialization is used when the list of alternatives
962/// `t_HEAD, t_TAIL...` is empty, i.e., `t_TYPE` wasn't found in the
963/// originally supplied list of alternatives.
964template <size_t t_INDEX, class t_TYPE>
965struct Variant_TypeToIndexImpl<t_INDEX, t_TYPE, BSLSTL_VARIANT_NOT_A_TYPE>
966: bsl::integral_constant<size_t, bsl::variant_npos> {
967};
968
969/// This component-private metafunction calculates the zero-based index of
970/// (template parameter) `t_TYPE` in the list of alternatives in (template
971/// parameter) `t_VARIANT`, or `bsl::variant_npos` if there is no such
972/// alternative. The primary template (used when `t_VARIANT` is not a
973/// `bsl::variant`) is not defined.
974template <class t_TYPE, class t_VARIANT>
975struct Variant_TypeToIndex; // primary template not defined
976
977template <class t_TYPE, class t_HEAD, class... t_TAIL>
978struct Variant_TypeToIndex<t_TYPE, bsl::variant<t_HEAD, t_TAIL...> >
979: Variant_TypeToIndexImpl<0, t_TYPE, t_HEAD, t_TAIL...> {
980};
981
982/// This component-private metafunction calculates the number of times
983/// (template parameter) `t_TYPE` occurs in (template parameters)
984/// `t_HEAD, t_TAIL...`. An alternative must have the same cv-qualification
985/// as `t_TYPE` in order to be counted.
986template <class t_TYPE,
987 class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE,
988 class... t_TAIL>
989struct Variant_CountType
990: bsl::integral_constant<size_t,
991 bsl::is_same<t_TYPE, t_HEAD>::value +
992 Variant_CountType<t_TYPE, t_TAIL...>::value> {
993};
994
995/// Specialization for purposes of the sim_cpp11_features.pl script.
996template <class t_TYPE>
997struct Variant_CountType<t_TYPE, BSLSTL_VARIANT_NOT_A_TYPE>
998: bsl::integral_constant<size_t, 0> {
999};
1000
1001/// This component-private metafunction derives from `bsl::true_type` if
1002/// (template parameter) `t_TYPE` occurs exactly once as an alternative of
1003/// (template parameter) `t_VARIANT`, and `bsl::false_type` otherwise. An
1004/// alternative must have the same cv-qualification as `t_TYPE` in order to
1005/// be counted. The primary template (used when `t_VARIANT` is not a
1006/// `bsl::variant`) is not defined.
1007template <class t_TYPE, class t_VARIANT>
1008struct Variant_HasUniqueType;
1009
1010template <class t_TYPE, class t_HEAD, class... t_TAIL>
1011struct Variant_HasUniqueType<t_TYPE, bsl::variant<t_HEAD, t_TAIL...> >
1012: bsl::integral_constant<bool,
1013 Variant_CountType<t_TYPE, t_HEAD, t_TAIL...>::value ==
1014 1> {
1015};
1016
1017/// This component-private metafunction calculates the number of times
1018/// (template parameter) `t_TYPE` occurs in (template parameters)
1019/// `t_HEAD, t_TAIL...`, where two types that differ only in top-level
1020/// cv-qualification are considered to be the same.
1021template <class t_TYPE,
1022 class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE,
1023 class... t_TAIL>
1024struct Variant_CountCVType
1025: bsl::integral_constant<
1026 size_t,
1027 bsl::is_same<typename bsl::remove_cv<t_TYPE>::type,
1028 typename bsl::remove_cv<t_HEAD>::type>::value +
1029 Variant_CountCVType<t_TYPE, t_TAIL...>::value> {
1030};
1031
1032/// Specialization for purposes of the sim_cpp11_features.pl script.
1033template <class t_TYPE>
1034struct Variant_CountCVType<t_TYPE, BSLSTL_VARIANT_NOT_A_TYPE>
1035: bsl::integral_constant<size_t, 0> {
1036};
1037
1038/// This component-private metafunction derives from `bsl::true_type` if
1039/// (template parameter) `t_TYPE` occurs exactly once as an alternative of
1040/// (template parameter) `t_VARIANT`, and `bsl::false_type` otherwise, where
1041/// two types that differ only in top-level cv-qualification are considered
1042/// to be the same. The primary template (used when `t_VARIANT` is not a
1043/// `bsl::variant`) is not defined.
1044template <class t_TYPE, class t_VARIANT>
1045struct Variant_HasUniqueCVType;
1046
1047template <class t_TYPE, class t_HEAD, class... t_TAIL>
1048struct Variant_HasUniqueCVType<t_TYPE, bsl::variant<t_HEAD, t_TAIL...> >
1049: bsl::integral_constant<
1050 bool,
1051 Variant_CountCVType<t_TYPE, t_HEAD, t_TAIL...>::value == 1> {
1052};
1053#endif
1054
1055/// This component-private metafunction calculates the alternative type at
1056/// index (template parameter) `t_INDEX` in (template parameter)
1057/// `t_VARIANT`, where the cv- and ref-qualifiers of `t_VARIANT` are added
1058/// to the alternative type. This metafunction is used to calculate the
1059/// return type of `bsl::visit`.
1060template <class t_VARIANT, size_t t_INDEX>
1061struct Variant_CVQualAlt {
1062
1063 /// Alternative at `t_INDEX` with combined cv-qualifiers
1064 typedef typename bsl::variant_alternative<
1065 t_INDEX,
1066 typename bslmf::MovableRefUtil::RemoveReference<t_VARIANT>::type>::type
1067 CVAlt;
1068
1069 typedef typename bsl::conditional<
1070 bslmf::MovableRefUtil::IsReference<t_VARIANT>::value,
1071 typename bsl::conditional<
1072 bslmf::MovableRefUtil::IsMovableReference<t_VARIANT>::value,
1073 typename bslmf::MovableRefUtil::AddMovableReference<CVAlt>::type,
1074 typename bslmf::MovableRefUtil::AddLvalueReference<CVAlt>::type>::
1075 type,
1076 CVAlt>::type type;
1077};
1078
1079/// This component-private metafunction derives from `bsl::true_type` if,
1080/// for each alternative `ALTi` in (template parameter) `t_VARIANT` with
1081/// index less than or equal to (template parameter) `t_INDEX`,
1082/// `decltype(std::declval<t_VISITOR>(std::declval<ALTi>()))` is `t_RET`;
1083/// otherwise, this metafunction derives from `bsl::false_type`. Note that
1084/// `ALTi` has the cv- and ref-qualifiers from `t_VARIANT` added to it.
1085/// This metafunction is used to determine whether invoking the visitor
1086/// results in the same type and value category for all alternatives.
1087template <class t_RET,
1088 class t_VISITOR,
1089 class t_VARIANT,
1090 size_t t_INDEX =
1091 bsl::variant_size<typename bslmf::MovableRefUtil::
1092 RemoveReference<t_VARIANT>::type>::value -
1093 1>
1094struct Variant_IsSameReturnType
1095: public bsl::integral_constant<
1096 bool,
1097 bsl::is_same<t_RET,
1098 typename bsl::invoke_result<
1099 t_VISITOR,
1100 typename Variant_CVQualAlt<t_VARIANT, t_INDEX>::type>::
1101 type>::value &&
1102 Variant_IsSameReturnType<t_RET, t_VISITOR, t_VARIANT, t_INDEX - 1>::
1103 value> {
1104};
1105template <class t_RET, class t_VISITOR, class t_VARIANT>
1106struct Variant_IsSameReturnType<t_RET, t_VISITOR, t_VARIANT, 0>
1107: bsl::is_same<t_RET,
1108 typename bsl::invoke_result<
1109 t_VISITOR,
1110 typename Variant_CVQualAlt<t_VARIANT, 0>::type>::type> {
1111};
1112
1113 // ======================
1114 // struct Variant_ImpUtil
1115 // ======================
1116
1117/// This `struct` provides a namespace for utility functions used implement
1118/// various operations on `bsl::variant`.
1119struct Variant_ImpUtil {
1120
1121 /// Return a reference to the alternative with index (template
1122 /// parameter) `t_INDEX` in the specified `variant`. If `t_INDEX` is
1123 /// not the index of the currently active alternative, throw an
1124 /// exception of type `bad_variant_access`. Note that the return type
1125 /// must be explicitly specified.
1126 template <class t_RET, size_t t_INDEX, class t_VARIANT>
1127 static t_RET& get(t_VARIANT& variant);
1128 template <class t_RET, size_t t_INDEX, class t_VARIANT>
1129 static t_RET& get(const t_VARIANT& variant);
1130
1131#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
1132 /// Invoke the specified `visitor` on the active alternative of the
1133 /// specified `variant`, implicitly converting the return type to the
1134 /// explicitly specified (template parameter) `t_RET`. The behavior is
1135 /// undefined unless `variant` holds a value. Note that the return type
1136 /// must be explicitly specified. This function does not require friend
1137 /// access to `Variant` and has been added to `Variant_ImpUtil` for the
1138 /// purposes of avoiding free functions.
1139 template <class t_RET, class t_VISITOR, class t_VARIANT>
1140 static t_RET visit(t_VISITOR&& visitor, t_VARIANT&& variant);
1141
1142 /// Invoke the specified `visitor` on the active alternative of the
1143 /// specified `variant`, implicitly converting the return type to the
1144 /// explicitly specified (template parameter) `t_RET`, and pass a tag
1145 /// representing the index of the selected alternative when invoking the
1146 /// visitor. It is used internally for visitors that participate in the
1147 /// `variant` implementation. The behavior is undefined unless
1148 /// `variant` holds a value. This function does not require friend
1149 /// access to `Variant` and has been added to `Variant_ImpUtil` for the
1150 /// purposes of avoiding free functions.
1151 template <class t_RET, class t_VISITOR, class t_VARIANT>
1152 static t_RET visitId(t_VISITOR&& visitor, t_VARIANT&& variant);
1153#else
1154 // Lack of perfect forwarding in C++03 means overload set must be
1155 // different.
1156 template <class t_RET, class t_VISITOR, class t_VARIANT>
1157 static t_RET visit(t_VISITOR& visitor, t_VARIANT& variant);
1158 template <class t_RET, class t_VISITOR, class t_VARIANT>
1159 static t_RET visit(t_VISITOR& visitor, const t_VARIANT& variant);
1160 // Invoke the specified 'visitor' on the active alternative of the
1161 // specified 'variant', implicitly converting the return type to the
1162 // explicitly specified (template parameter) 't_RET'. The behavior is
1163 // undefined if 'variant' does not hold a value. This function does
1164 // not require friend access to 'Variant' and has been added to
1165 // 'Variant_ImpUtil' for the purposes of avoiding free functions.
1166
1167 template <class t_RET, class t_VISITOR, class t_VARIANT>
1168 static t_RET moveVisit(t_VISITOR& visitor, t_VARIANT& variant);
1169 // Invoke the specified 'visitor' on a 'bslmf::MovableRef' referring to
1170 // the active alternative of the specified 'variant', implicitly
1171 // converting the return type to the explicitly specified (template
1172 // parameter) 't_RET'. The behavior is undefined if 'variant' does not
1173 // hold a value. This function does not require friend access to
1174 // 'Variant' and has been added to 'Variant_ImpUtil' for the purposes
1175 // of avoiding free functions.
1176
1177 template <class t_RET, class t_VISITOR, class t_VARIANT>
1178 static t_RET visitId(t_VISITOR& visitor, t_VARIANT& variant);
1179 template <class t_RET, class t_VISITOR, class t_VARIANT>
1180 static t_RET visitId(t_VISITOR& visitor, const t_VARIANT& variant);
1181 // Invoke the specified 'visitor' with a
1182 // 'bsl::in_place_index_t<t_INDEX>' tag (where 't_INDEX' is the index
1183 // of the first alternative that has the same type as the active
1184 // alternative of the specified 'variant') and the active alternative
1185 // of 'variant', implicitly converting the return type to the
1186 // explicitly specified (template parameter) 't_RET'. The behavior is
1187 // undefined if 'variant' does not hold a value. This function does
1188 // not require friend access to 'Variant' and has been added to
1189 // 'Variant_ImpUtil' for the purposes of avoiding free functions.
1190
1191#endif // BSL_VARIANT_FULL_IMPLEMENTATION
1192
1193#ifndef BSL_VARIANT_FULL_IMPLEMENTATION
1194 // In C++03, the internal visitation dispatch must call a type-based (not
1195 // index-based) getter. This internal type-based getter will always be
1196 // passed the type of the currently active alternative, so there is no need
1197 // to check whether the requested alternative matches the currently active
1198 // alternative. Moreover, in cases where there are alternatives of
1199 // identical type, 'bsl::get' cannot be passed such a type. To solve the
1200 // problem, we implement an unsafe type-based getter that is used only for
1201 // internal visitation.
1202
1203 template <class t_RET, size_t t_INDEX, class t_VARIANT>
1204 static t_RET& unsafeGet(t_VARIANT& variant);
1205 template <class t_RET, size_t t_INDEX, class t_VARIANT>
1206 static t_RET& unsafeGet(const t_VARIANT& variant);
1207 // Return a reference to type (template parameter) 't_RET' to the
1208 // alternative at (template parameter) 't_INDEX' in the specified
1209 // 'variant', regardless of whether that is the active alternative.
1210 // The behavior is undefined unless the active alternative of 'variant'
1211 // has the same type as the alternative with index 't_INDEX'. Note
1212 // that the return type must be explicitly specified.
1213
1214 template <class t_TYPE, class t_VARIANT>
1215 static t_TYPE& unsafeGet(t_VARIANT& obj);
1216 template <class t_TYPE, class t_VARIANT>
1217 static const t_TYPE& unsafeGet(const t_VARIANT& obj);
1218 // Return a reference to const-qualified (template parameter) 't_TYPE'
1219 // to the first alternative of the specified 'obj' that has type
1220 // 't_TYPE', regardless of whether that is the active alternative. The
1221 // behavior is undefined unless the active alternative of 'variant' is
1222 // of type 't_TYPE'. This function does not require friend access to
1223 // 'Variant' and has been added to 'Variant_ImpUtil' for the purposes
1224 // of avoiding free functions.
1225
1226#endif // BSL_VARIANT_FULL_IMPLEMENTATION
1227
1228 /// Return a reference to the object managed by the first member of the
1229 /// specified `variantUnion`. It is the base case for the overload of
1230 /// `getAlternative` below. This function does not require friend
1231 /// access to `Variant` and has been added to `Variant_ImpUtil` for the
1232 /// purposes of avoiding free functions.
1233 template <class t_RET, class t_VARIANT_UNION>
1234 static t_RET& getAlternative(
1235 bsl::in_place_index_t<0>,
1236 t_VARIANT_UNION& variantUnion) BSLS_KEYWORD_NOEXCEPT;
1237
1238 /// Return a reference to the alternative with index (template
1239 /// parameter) `t_INDEX` in the specified `variantUnion` by recursively
1240 /// unravelling `variantUnion` until the desired alternative is at the
1241 /// head. `t_INDEX` shall be a valid alternative index. The behavior
1242 /// is undefined unless the alternative with index `t_INDEX` has the
1243 /// same type as the active alternative of `variantUnion`. This
1244 /// function does not require friend access to `Variant` and has been
1245 /// added to `Variant_ImpUtil` for the purposes of avoiding free
1246 /// functions.
1247 template <class t_RET, size_t t_INDEX, class t_VARIANT_UNION>
1248 static t_RET& getAlternative(
1249 bsl::in_place_index_t<t_INDEX>,
1250 t_VARIANT_UNION& variantUnion) BSLS_KEYWORD_NOEXCEPT;
1251
1252 template <class t_VARIANT>
1253 static bool Equal(const t_VARIANT& lhs, const t_VARIANT& rhs);
1254 template <class t_VARIANT>
1255 static bool NotEqual(const t_VARIANT& lhs, const t_VARIANT& rhs);
1256 template <class t_VARIANT>
1257 static bool LessThan(const t_VARIANT& lhs, const t_VARIANT& rhs);
1258 template <class t_VARIANT>
1259 static bool GreaterThan(const t_VARIANT& lhs, const t_VARIANT& rhs);
1260 template <class t_VARIANT>
1261 static bool LessOrEqual(const t_VARIANT& lhs, const t_VARIANT& rhs);
1262
1263 /// Return the result of comparing the specified `lhs` with the
1264 /// specified `rhs`. The behavior is undefined unless both `lhs` and
1265 /// `rhs` hold the same alternative. Note that the capitalization of
1266 /// the names of these methods has been chosen so that their definitions
1267 /// can be generated using a macro.
1268 template <class t_VARIANT>
1269 static bool GreaterOrEqual(const t_VARIANT& lhs, const t_VARIANT& rhs);
1270
1271#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1272 /// This visitor is used to implement the explicit constructor for
1273 /// `bsl::variant` from `std::variant`.
1274 template <class t_VARIANT, class t_STD_VARIANT>
1275 class ConstructFromStdVisitor;
1276#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1277};
1278
1279#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1280
1281 // ==============================================
1282 // class Variant_ImpUtil::ConstructFromStdVisitor
1283 // ==============================================
1284
1285template <class t_VARIANT, class t_STD_VARIANT>
1286class Variant_ImpUtil::ConstructFromStdVisitor {
1287 private:
1288 // DATA
1289 t_VARIANT& d_target;
1290 t_STD_VARIANT& d_original;
1291
1292 public:
1293 // CREATORS
1294
1295 /// Create a `ConstructFromStdVisitor` object that, when invoked, will
1296 /// construct the alternative of the specified `target` corresponding to
1297 /// the active alternative of the specified `original`. `target` shall
1298 /// have the same sequence of alternative types as `original`.
1299 explicit ConstructFromStdVisitor(t_VARIANT& target,
1300 t_STD_VARIANT& original);
1301
1302 // ACCESSORS
1303
1304 /// Construct the alternative at index (template parameter) `t_INDEX`
1305 /// in `d_target` from the contained value of `d_original`. If
1306 /// `t_STD_VARIANT` is an lvalue reference type, the alternative will be
1307 /// created by copy construction, otherwise it will be created by move
1308 /// construction. The behavior is undefined unless `d_original` holds a
1309 /// value and `d_target.index() == d_original.index()`. Note that the
1310 /// unused parameter of type `t_TYPE&` refers to the alternative that
1311 /// will be constructed, but we do not construct directly into that
1312 /// object because we need to make sure that the allocator of `d_target`
1313 /// (if any) is used.
1314 template <size_t t_INDEX, class t_TYPE>
1315 void operator()(bsl::in_place_index_t<t_INDEX>, t_TYPE&) const;
1316};
1317#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1318
1319#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
1320/// This component-private struct is used to check whether an alternative
1321/// given by (template parameter) `t_TYPE` is a potential match for an
1322/// argument of a `bsl::variant` constructor or assignment operator that
1323/// does not take an explicitly specified alternative type. The standard
1324/// allows such conversion only when the declaration `t_TYPE d_x[] = {expr};`
1325/// is valid, where `expr` is the (forwarded) argument expression.
1326template <class t_TYPE>
1327struct Variant_ArrayHelper {
1328 t_TYPE d_x[1];
1329};
1330
1331/// This component-private metafunction checks whether a conversion from a
1332/// pointer type to (template parameter) `t_TYPE` is narrowing. It is
1333/// instantiated only for `bool`, and its behavior depends on whether the
1334/// compiler has implemented P1957R2.
1335template <class t_TYPE, class = void>
1336struct Variant_CheckForP1957R2 : bsl::true_type {
1337};
1338
1339template <class t_TYPE>
1340struct Variant_CheckForP1957R2<
1341 t_TYPE,
1342 bsl::void_t<decltype(Variant_ArrayHelper<t_TYPE>{{"bc"}})> >
1343: bsl::false_type {
1344};
1345
1346template <class t_DEST, class t_SOURCE, class = void>
1347struct Variant_ConvertsWithoutNarrowing : bsl::false_type {
1348};
1349
1350/// This component-private metafunction is derived from `bsl::true_type` if
1351/// (template parameter) `t_SOURCE` can be converted to (template parameter)
1352/// `t_DEST` without narrowing, and `bsl::false_type` otherwise. A
1353/// conversion from pointer or pointer-to-member type to cv `bool` is
1354/// considered narrowing even if the compiler does not implement P1957R2
1355/// (which was adopted as a DR); however, on compilers that do not implement
1356/// P1957R2, we do not have the ability to check whether a user-defined
1357/// conversion sequence to cv `bool` would use a narrowing standard
1358/// conversion, so on those compilers, we permit conversion to a `t_DEST`
1359/// that is cv `bool` only if `t_SOURCE` is also cv `bool`, and not when
1360/// `t_SOURCE` is a class type. This behavior is not expected to pose a
1361/// problem for users migrating from `bdlb::Variant`, because that class
1362/// does not support implicit conversions from an argument type to an
1363/// alternative type.
1364template <class t_DEST, class t_SOURCE>
1365struct Variant_ConvertsWithoutNarrowing<
1366 t_DEST,
1367 t_SOURCE,
1368 bsl::void_t<decltype(
1369 Variant_ArrayHelper<t_DEST>{{std::declval<t_SOURCE>()}})> >
1370: bsl::integral_constant<
1371 bool,
1372 !(!Variant_CheckForP1957R2<bool>::value &&
1373 bsl::is_same<bool, typename bsl::remove_cvref<t_DEST>::type>::value &&
1374 !bsl::is_same<bool,
1375 typename bsl::remove_cvref<t_SOURCE>::type>::value)> {
1376};
1377
1378 // =============================
1379 // struct Variant_OverloadSetImp
1380 // =============================
1381
1382/// This component-private metafunction computes an overload set consisting
1383/// of one function, named `candidate`, for each type in (template
1384/// parameters) `t_HEAD, t_TAIL...`, having one parameter of that type.
1385/// Each such function participates in overload resolution only when
1386/// `std::declval<t_SRC>()` is convertible to the alternative without
1387/// narrowing, and returns `bsl::integral_constant<t_INDEX + i>`, where `i`
1388/// is the zero-based index of the corresponding alternative. Note that a
1389/// type that occurs multiple times in `t_HEAD, t_TAIL...` (possibly with
1390/// varying cv-qualifications) will only result in the generation of a
1391/// single candidate. This implementation relies on expression SFINAE,
1392/// `decltype`, `std::declval`, and P1957R2; since these features are not
1393/// available in C++03, the C++03 version requires an exact match modulo
1394/// cv-qualification.
1395template <class t_SRC, size_t t_INDEX, class t_HEAD, class... t_TAIL>
1396struct Variant_OverloadSetImp
1397: Variant_OverloadSetImp<t_SRC, t_INDEX + 1, t_TAIL...> {
1398
1399 using Variant_OverloadSetImp<t_SRC, t_INDEX + 1, t_TAIL...>::candidate;
1400
1401 template <class t_DEST = t_HEAD>
1402 static typename bsl::enable_if<
1403 Variant_ConvertsWithoutNarrowing<t_DEST, t_SRC>::value,
1404 bsl::integral_constant<size_t, t_INDEX> >::type candidate(t_HEAD);
1405};
1406template <class t_SRC, size_t t_INDEX, class t_HEAD>
1407struct Variant_OverloadSetImp<t_SRC, t_INDEX, t_HEAD> {
1408 template <class t_DEST = t_HEAD>
1409 static typename bsl::enable_if<
1410 Variant_ConvertsWithoutNarrowing<t_DEST, t_SRC>::value,
1411 bsl::integral_constant<size_t, t_INDEX> >::type candidate(t_HEAD);
1412};
1413
1414/// This component-private metafunction provides a member typedef `Index`
1415/// representing the value that should be computed by
1416/// `Variant_ConvertIndex`. The primary template is instantiated when the
1417/// partial specialization below is not viable because no viable alternative
1418/// exists for the conversion or because the best match is not "unique" (see
1419/// the documentation of `Variant_ConvertIndex` for an explanation).
1420template <class t_SRC, class t_VARIANT, class = void>
1421struct Variant_OverloadHelper {
1422
1423 typedef bsl::integral_constant<size_t, bsl::variant_npos> Index;
1424};
1425
1426/// This partial specialization is used when a "unique" best match is found
1427/// for converting `std::declval<t_SRC>()` to one of (template parameters)
1428/// `t_HEAD, t_TAIL...`.
1429template <class t_SRC, class t_HEAD, class... t_TAIL>
1430struct Variant_OverloadHelper<
1431 t_SRC,
1432 bsl::variant<t_HEAD, t_TAIL...>,
1433 bsl::void_t<decltype(Variant_OverloadSetImp<t_SRC, 0, t_HEAD, t_TAIL...>::
1434 candidate(std::declval<t_SRC>()))> > {
1435 typedef decltype(
1436 Variant_OverloadSetImp<t_SRC, 0, t_HEAD, t_TAIL...>::candidate(
1437 std::declval<t_SRC>())) Index;
1438};
1439
1440/// This component-private metafunction computes the index of the
1441/// alternative in (template parameter) `t_VARIANT` that is the "unique"
1442/// best match for conversion from `std::declval<t_TYPE>()`, or
1443/// `bsl::variant_npos` if there is no such alternative. An alternative
1444/// that occurs multiple times in `t_VARIANT` (possibly with varying
1445/// cv-qualifications) is considered to occur only once; thus, if all
1446/// alternatives that are tied for the best match are the same type
1447/// (possibly with varying cv-qualifications), the result is the lowest
1448/// index at which that type (with any cv-qualification) occurs.
1449template <class t_TYPE, class t_VARIANT>
1450struct Variant_ConvertIndex
1451: Variant_OverloadHelper<t_TYPE, t_VARIANT>::Index {
1452};
1453
1454#else // BSL_VARIANT_FULL_IMPLEMENTATION
1455
1456#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1457template <size_t t_INDEX,
1458 class t_TYPE,
1459 class t_HEAD = BSLSTL_VARIANT_NOT_A_TYPE,
1460 class... t_TAIL>
1461struct Variant_ConvertToIndexImpl;
1462 // This component-private metafunction computes 't_INDEX + i', where 'i' is
1463 // the zero-based index of the first occurrence of (template parameter)
1464 // 't_TYPE' in (template parameters) 't_HEAD, t_TAIL...', or
1465 // 'bsl::variant_npos' if not found. An alternative is considered to match
1466 // 't_TYPE' if the two types are the same modulo cv-qualification. This
1467 // metafunction is used to implement 'Variant_ConvertIndex'.
1468
1469template <size_t t_INDEX, class t_TYPE>
1470struct Variant_ConvertToIndexImpl<t_INDEX, t_TYPE, BSLSTL_VARIANT_NOT_A_TYPE>
1471: bsl::integral_constant<size_t, bsl::variant_npos> {
1472 // Specialization for the case when t_ARGS is empty, i.e. the type wasn't
1473 // found in the given list of template type arguments.
1474};
1475template <size_t t_INDEX, class t_TYPE, class t_HEAD, class... t_TAIL>
1476struct Variant_ConvertToIndexImpl<t_INDEX, t_TYPE, t_HEAD, t_TAIL...>
1477: bsl::conditional<
1478 bsl::is_same<typename bsl::remove_cv<t_TYPE>::type,
1479 typename bsl::remove_cv<t_HEAD>::type>::value,
1480 bsl::integral_constant<size_t, t_INDEX>,
1481 Variant_ConvertToIndexImpl<t_INDEX + 1, t_TYPE, t_TAIL...> >::type {
1482};
1483
1484template <class t_TYPE, class t_VARIANT>
1485struct Variant_ConvertIndex;
1486 // This component-private metafunction computes the zero-based index of the
1487 // first occurrence of (template parameter) 't_TYPE' in the list of
1488 // alternatives of (template parameter) 't_VARIANT', or 'bsl::variant_npos'
1489 // if not found. An alternative is considered to match 't_TYPE' if the two
1490 // types are the same modulo cv-qualification. The primary template (used
1491 // when 't_VARIANT' is not a 'bsl::variant') is not defined. This
1492 // metafunction is used to determine the alternative to be constructed or
1493 // assigned to from a given argument type when the alternative type is not
1494 // explicitly specified. Note that in C++11 and later,
1495 // 'Variant_ConvertIndex' allows implicit conversions, but this behavior
1496 // cannot be implemented in C++03.
1497
1498template <class t_TYPE, class t_HEAD, class... t_TAIL>
1499struct Variant_ConvertIndex<t_TYPE, bsl::variant<t_HEAD, t_TAIL...> >
1500: Variant_ConvertToIndexImpl<
1501 0,
1502 typename bslmf::MovableRefUtil::RemoveReference<t_TYPE>::type,
1503 t_HEAD,
1504 t_TAIL...> {
1505};
1506
1507#endif
1508#endif // BSL_VARIANT_FULL_IMPLEMENTATION
1509
1510/// This component-private metafunction is derived from `bsl::true_type` if
1511/// there is a unique best match alternative in (template parameter)
1512/// `t_VARIANT` for 'std::declval<t_TYPE>() and that alternative is
1513/// constructible from `std::declval<t_TYPE>(), and `bsl::false_type'
1514/// otherwise.
1515template <class t_VARIANT,
1516 class t_TYPE,
1517 size_t t_INDEX = BSLSTL_VARIANT_CONVERT_INDEX_OF(t_TYPE, t_VARIANT)>
1518struct Variant_IsAlternativeConstructibleFrom
1519: bsl::integral_constant<
1520 bool,
1521 Variant_IsConstructible<
1522 typename bsl::variant_alternative<t_INDEX, t_VARIANT>::type,
1523 t_TYPE>::value &&
1524 Variant_HasUniqueCVType<BSLSTL_VARIANT_CONVERT_TYPE_OF(t_TYPE,
1525 t_VARIANT),
1526 t_VARIANT>::value> {
1527};
1528
1529template <class t_VARIANT, class t_TYPE>
1530struct Variant_IsAlternativeConstructibleFrom<t_VARIANT,
1531 t_TYPE,
1532 bsl::variant_npos>
1533: bsl::false_type {
1534};
1535
1536/// This component-private metafunction is derived from `bsl::true_type` if
1537/// there is a unique best match alternative in (template parameter)
1538/// `t_VARIANT` for `std::declval<t_TYPE>()` and that alternative is both
1539/// constructible and assignable from `std::declval<t_TYPE>()`, and
1540/// `bsl::false_type` otherwise.
1541template <class t_VARIANT,
1542 class t_TYPE,
1543 size_t t_INDEX = BSLSTL_VARIANT_CONVERT_INDEX_OF(t_TYPE, t_VARIANT)>
1544struct Variant_isAlternativeAssignableFrom
1545: bsl::integral_constant<
1546 bool,
1547 Variant_IsAssignable<
1548 typename bsl::variant_alternative<t_INDEX, t_VARIANT>::type&,
1549 t_TYPE>::value &&
1550 Variant_HasUniqueCVType<BSLSTL_VARIANT_CONVERT_TYPE_OF(t_TYPE,
1551 t_VARIANT),
1552 t_VARIANT>::value> {
1553};
1554
1555template <class t_VARIANT, class t_TYPE>
1556struct Variant_isAlternativeAssignableFrom<t_VARIANT,
1557 t_TYPE,
1558 bsl::variant_npos>
1559: bsl::false_type {
1560};
1561
1562/// This component-private metafunction declares a member `type` that is an
1563/// alias to the `std::variant` type corresponding to `t_TYPE` if one
1564/// exists, and `void` otherwise.
1565template <class t_TYPE>
1566struct Variant_CorrespondingStdVariant {
1567 typedef void type;
1568};
1569
1570#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1571template <class t_HEAD, class... t_TAIL>
1572struct Variant_CorrespondingStdVariant<bsl::variant<t_HEAD, t_TAIL...>> {
1573 typedef std::variant<t_HEAD, t_TAIL...> type;
1574};
1575#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1576
1577/// This component-private metafunction is derived from `bsl::true_type` if
1578/// (template parameter) `t_TYPE` is neither a tag type, nor the type
1579/// (template parameter) `t_VARIANT` (modulo cv-qualification), nor the
1580/// corresponding (possibly cv-qualified) `std::variant` type, there is a
1581/// unique best match alternative in `t_VARIANT` for
1582/// `std::declval<t_TYPE>()`, and that alternative is constructible from
1583/// `std::declval<t_TYPE>()`; otherwise, this metafunction is derived from
1584/// `bsl::false_type`.
1585template <class t_VARIANT, class t_TYPE>
1586struct Variant_ConstructsFromType
1587: bsl::integral_constant<
1588 bool,
1589 !bsl::is_same<typename bsl::remove_cvref<t_TYPE>::type,
1590 t_VARIANT>::value &&
1591 !Variant_IsTag<typename bsl::remove_cvref<t_TYPE>::type>::value &&
1592 !bsl::is_same<
1593 typename Variant_CorrespondingStdVariant<t_VARIANT>::type,
1594 typename bsl::remove_cvref<t_TYPE>::type>::value &&
1595 Variant_IsAlternativeConstructibleFrom<t_VARIANT, t_TYPE>::value> {
1596};
1597
1598/// This component-private metafunction is derived from `bsl::true_type` if
1599/// (template parameter) `t_TYPE` is neither a tag type nor the type
1600/// (template parameter) `t_VARIANT` (modulo cv-qualification), there is a
1601/// unique best match alternative in `t_VARIANT` for
1602/// `std::declval<t_TYPE>()`, and that alternative is constructible and
1603/// assignable from `std::declval<t_TYPE>()`; otherwise, this metafunction
1604/// is derived from `bsl::false_type`.
1605template <class t_VARIANT, class t_TYPE>
1606struct Variant_AssignsFromType
1607: bsl::integral_constant<
1608 bool,
1609 !bsl::is_same<typename bsl::remove_cvref<t_TYPE>::type,
1610 t_VARIANT>::value &&
1611 Variant_IsAlternativeConstructibleFrom<t_VARIANT, t_TYPE>::value &&
1612 Variant_isAlternativeAssignableFrom<t_VARIANT, t_TYPE>::value> {
1613};
1614
1615#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1616template <class t_VARIANT, class t_STD_VARIANT>
1617constexpr bool variant_constructsFromStd =
1618 // This component-private constexpr variable template is 'true' if
1619 // 't_VARIANT' is a specialization of 'bsl::variant', and 't_STD_VARIANT'
1620 // is the 'std::variant' type (possibly with added cvref-qualification)
1621 // that has the same sequence of alternatives, and each alternative of
1622 // 't_VARIANT' is constructible from the corresponding alternative of
1623 // 't_STD_VARIANT' (with cv-qualification and value category matching that
1624 // of 't_STD_VARIANT'). Note that we use 'bsl::conjunction_v' for its
1625 // short-circuiting properties: if 't_STD_VARIANT' isn't a 'std::variant'
1626 // (for example, if it's a 'bsl::variant') we avoid recursing into the
1627 // constraints of 'bsl::variant'.
1628 bsl::conjunction_v<
1629 bsl::is_same<typename Variant_CorrespondingStdVariant<t_VARIANT>::type,
1630 bsl::remove_cvref_t<t_STD_VARIANT>>,
1631 std::is_constructible<bsl::remove_cvref_t<t_STD_VARIANT>,
1632 t_STD_VARIANT>>;
1633#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1634
1635#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
1636// The following component-private machinery allows for conditionally deleting
1637// special member functions.
1638
1639/// This component-private class has deleted copy constructor if (template
1640/// parameter) `t_ISCOPYCONSTRUCTIBLE` is `false`. All other special member
1641/// functions are defaulted.
1642template <bool t_ISCOPYCONSTRUCTIBLE>
1643struct Variant_CopyConstructorBase {
1644};
1645template <>
1646struct Variant_CopyConstructorBase<false> {
1647 Variant_CopyConstructorBase() = default;
1648 Variant_CopyConstructorBase(const Variant_CopyConstructorBase&) = delete;
1649 Variant_CopyConstructorBase(Variant_CopyConstructorBase&&) = default;
1650 Variant_CopyConstructorBase&
1651 operator=(const Variant_CopyConstructorBase&) = default;
1652 Variant_CopyConstructorBase&
1653 operator=(Variant_CopyConstructorBase&&) = default;
1654};
1655
1656/// This component-private class has deleted move constructor if (template
1657/// parameter) `t_ISMOVECONSTRUCTIBLE` is `false`. All other special member
1658/// functions are defaulted.
1659template <bool t_ISCOPYCONSTRUCTIBLE, bool t_ISMOVECONSTRUCTIBLE>
1660struct Variant_MoveConstructorBase
1661: Variant_CopyConstructorBase<t_ISCOPYCONSTRUCTIBLE> {
1662};
1663template <bool t_ISCOPYCONSTRUCTIBLE>
1664struct Variant_MoveConstructorBase<t_ISCOPYCONSTRUCTIBLE, false>
1665: Variant_CopyConstructorBase<t_ISCOPYCONSTRUCTIBLE> {
1666 Variant_MoveConstructorBase() = default;
1667 Variant_MoveConstructorBase(const Variant_MoveConstructorBase&) = default;
1668 Variant_MoveConstructorBase(Variant_MoveConstructorBase&&) = delete;
1669 Variant_MoveConstructorBase&
1670 operator=(const Variant_MoveConstructorBase&) = default;
1671 Variant_MoveConstructorBase&
1672 operator=(Variant_MoveConstructorBase&&) = default;
1673};
1674
1675/// This component-private class has deleted copy assignment operator if
1676/// (template parameter) `t_ISCOPYASSIGNABLE` is `false`. All other special
1677/// member functions are defaulted.
1678template <bool t_ISCOPYCONSTRUCTIBLE,
1679 bool t_ISMOVECONSTRUCTIBLE,
1680 bool t_ISCOPYASSIGNABLE>
1681struct Variant_CopyAssignBase
1682: Variant_MoveConstructorBase<t_ISCOPYCONSTRUCTIBLE, t_ISMOVECONSTRUCTIBLE> {
1683};
1684template <bool t_ISCOPYCONSTRUCTIBLE, bool t_ISMOVECONSTRUCTIBLE>
1685struct Variant_CopyAssignBase<t_ISCOPYCONSTRUCTIBLE,
1686 t_ISMOVECONSTRUCTIBLE,
1687 false>
1688: Variant_MoveConstructorBase<t_ISCOPYCONSTRUCTIBLE, t_ISMOVECONSTRUCTIBLE> {
1689 Variant_CopyAssignBase() = default;
1690 Variant_CopyAssignBase(const Variant_CopyAssignBase&) = default;
1691 Variant_CopyAssignBase(Variant_CopyAssignBase&&) = default;
1692 Variant_CopyAssignBase& operator=(const Variant_CopyAssignBase&) = delete;
1693 Variant_CopyAssignBase& operator=(Variant_CopyAssignBase&&) = default;
1694};
1695
1696/// This component-private class has deleted move assignment operator if
1697/// (template parameter) `t_ISMOVEASSIGNABLE` is `false`. All other special
1698/// member functions are defaulted.
1699template <bool t_ISCOPYCONSTRUCTIBLE,
1700 bool t_ISMOVECONSTRUCTIBLE,
1701 bool t_ISCOPYASSIGNABLE,
1702 bool t_ISMOVEASSIGNABLE>
1703struct Variant_MoveAssignBase : Variant_CopyAssignBase<t_ISCOPYCONSTRUCTIBLE,
1704 t_ISMOVECONSTRUCTIBLE,
1705 t_ISCOPYASSIGNABLE> {
1706};
1707template <bool t_ISCOPYCONSTRUCTIBLE,
1708 bool t_ISMOVECONSTRUCTIBLE,
1709 bool t_ISCOPYASSIGNABLE>
1710struct Variant_MoveAssignBase<t_ISCOPYCONSTRUCTIBLE,
1711 t_ISMOVECONSTRUCTIBLE,
1712 t_ISCOPYASSIGNABLE,
1713 false>
1714: Variant_CopyAssignBase<t_ISCOPYCONSTRUCTIBLE,
1715 t_ISMOVECONSTRUCTIBLE,
1716 t_ISCOPYASSIGNABLE> {
1717 Variant_MoveAssignBase() = default;
1718 Variant_MoveAssignBase(const Variant_MoveAssignBase&) = default;
1719 Variant_MoveAssignBase(Variant_MoveAssignBase&&) = default;
1720 Variant_MoveAssignBase& operator=(const Variant_MoveAssignBase&) = default;
1721 Variant_MoveAssignBase& operator=(Variant_MoveAssignBase&&) = delete;
1722};
1723
1724/// This component-private class has special member functions that are
1725/// either deleted or defaulted according to the specified template
1726/// parameters.
1727template <bool t_ISCOPYCONSTRUCTIBLE,
1728 bool t_ISMOVECONSTRUCTIBLE,
1729 bool t_ISCOPYASSIGNABLE,
1730 bool t_ISMOVEASSIGNABLE>
1731struct Variant_SMFBase : Variant_MoveAssignBase<t_ISCOPYCONSTRUCTIBLE,
1732 t_ISMOVECONSTRUCTIBLE,
1733 t_ISCOPYASSIGNABLE,
1734 t_ISMOVEASSIGNABLE> {
1735};
1736
1737/// This component-private metafunction is derived from `bsl::true_type` if
1738/// all template parameters are copy constructible, and `bsl::false_type`
1739/// otherwise.
1740template <class t_HEAD, class... t_TAIL>
1741struct Variant_IsCopyConstructibleAll
1742: bsl::integral_constant<
1743 bool,
1744 std::is_copy_constructible<t_HEAD>::value &&
1745 Variant_IsCopyConstructibleAll<t_TAIL...>::value> {
1746};
1747
1748template <class t_HEAD>
1749struct Variant_IsCopyConstructibleAll<t_HEAD>
1750: std::is_copy_constructible<t_HEAD> {
1751};
1752
1753/// This component-private metafunction is derived from `bsl::true_type` if
1754/// all template parameters are move constructible, and `bsl::false_type`
1755/// otherwise.
1756template <class t_HEAD, class... t_TAIL>
1757struct Variant_IsMoveConstructibleAll
1758: bsl::integral_constant<
1759 bool,
1760 std::is_move_constructible<t_HEAD>::value &&
1761 Variant_IsMoveConstructibleAll<t_TAIL...>::value> {
1762};
1763
1764template <class t_HEAD>
1765struct Variant_IsMoveConstructibleAll<t_HEAD>
1766: std::is_move_constructible<t_HEAD> {
1767};
1768
1769/// This component-private metafunction is derived from `bsl::true_type` if
1770/// all template parameters are copy assignable, and `bsl::false_type`
1771/// otherwise.
1772template <class t_HEAD, class... t_TAIL>
1773struct Variant_IsCopyAssignableAll
1774: bsl::integral_constant<bool,
1775 std::is_copy_assignable<t_HEAD>::value &&
1776 Variant_IsCopyAssignableAll<t_TAIL...>::value> {
1777};
1778
1779template <class t_HEAD>
1780struct Variant_IsCopyAssignableAll<t_HEAD> : std::is_copy_assignable<t_HEAD> {
1781};
1782
1783/// This component-private metafunction is derived from `bsl::true_type` if
1784/// all template parameters are move assignable, and `bsl::false_type`
1785/// otherwise.
1786template <class t_HEAD, class... t_TAIL>
1787struct Variant_IsMoveAssignableAll
1788: bsl::integral_constant<bool,
1789 std::is_move_assignable<t_HEAD>::value &&
1790 Variant_IsMoveAssignableAll<t_TAIL...>::value> {
1791};
1792
1793template <class t_HEAD>
1794struct Variant_IsMoveAssignableAll<t_HEAD> : std::is_move_assignable<t_HEAD> {
1795};
1796#endif // BSL_VARIANT_FULL_IMPLEMENTATION
1797
1798#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
1799template <class t_RET, class t_VISITOR, class t_VARIANT, size_t t_INDEX>
1800struct Variant_Function {
1801 /// This component-private function invokes the specified `visitor` with
1802 /// the active alternative object of the specified `variant` and
1803 /// implicitly converts the return type to (template parameter) `t_RET`.
1804 /// The pre-C++17 implementation is limited to invocations of the form
1805 /// `visitor(variant)`. The behavior is undefined unless (template
1806 /// parameter) `t_INDEX` is the index of the active alternative.
1807 static t_RET functionImpl(t_VISITOR&& visitor, t_VARIANT&& variant)
1808 {
1809#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1810 return std::invoke(
1811 std::forward<t_VISITOR>(visitor),
1812 bsl::get<t_INDEX>(std::forward<t_VARIANT>(variant)));
1813#else
1814 return std::forward<t_VISITOR>(visitor)(
1815 bsl::get<t_INDEX>(std::forward<t_VARIANT>(variant)));
1816#endif
1817 }
1818};
1819
1820/// This partial specialization is used when `t_RET` is `void`. The visitor
1821/// is invoked and its return value, if any, is ignored. This partial
1822/// specialization is necessary because a `void`-returning function cannot
1823/// contain a `return` statement with a non-`void` operand.
1824template <class t_VISITOR, class t_VARIANT, size_t t_INDEX>
1825struct Variant_Function<void, t_VISITOR, t_VARIANT, t_INDEX> {
1826
1827 static void functionImpl(t_VISITOR&& visitor, t_VARIANT&& variant)
1828 {
1829#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1830 std::invoke(std::forward<t_VISITOR>(visitor),
1831 bsl::get<t_INDEX>(std::forward<t_VARIANT>(variant)));
1832#else
1833 std::forward<t_VISITOR>(visitor)(
1834 bsl::get<t_INDEX>(std::forward<t_VARIANT>(variant)));
1835#endif
1836 }
1837};
1838
1839template <class t_RET, class t_VISITOR, class t_VARIANT, size_t t_INDEX>
1840struct Variant_FunctionId {
1841 /// This component-private function invokes the specified `visitor` with
1842 /// a `bsl::in_place_index_t` tag representing the value of (template
1843 /// parameter) `t_INDEX` and the active alternative object of the
1844 /// specified `variant`, implicitly converting the return type to
1845 /// (template parameter) `t_RET`. The behavior is undefined unless
1846 /// `t_INDEX` is the index of the active alternative.
1847 static t_RET functionImpl(t_VISITOR&& visitor, t_VARIANT&& variant)
1848 {
1849 return visitor(bsl::in_place_index_t<t_INDEX>(),
1850 bsl::get<t_INDEX>(std::forward<t_VARIANT>(variant)));
1851 }
1852};
1853
1854/// This component-private struct computes an array in which element `i` is
1855/// a pointer to
1856/// `Variant_Function<t_RET, t_VISITOR, t_VARIANT, i>::functionImpl`,
1857/// defined above as a function that invokes a `t_VISITOR` with alternative
1858/// `i` of `t_VARIANT` and implicitly converts the return type to `t_RET`.
1859template <class t_RET, class t_VISITOR, class t_VARIANT, class t_DUMMY>
1860struct Variant_VTable;
1861
1862/// In order to allow for perfect forwarding, both t_VISITOR and t_VARIANT
1863/// must be of reference type. If they are not, something went wrong.
1864template <class t_RET, class t_VISITOR, class t_VARIANT, size_t... t_INDICES>
1865struct Variant_VTable<t_RET,
1866 t_VISITOR,
1867 t_VARIANT,
1868 bslmf::IntegerSequence<std::size_t, t_INDICES...> > {
1869 BSLMF_ASSERT(bsl::is_reference<t_VISITOR>::value);
1870 BSLMF_ASSERT(bsl::is_reference<t_VARIANT>::value);
1871
1872 typedef t_RET (*FuncPtr)(t_VISITOR, t_VARIANT);
1873
1874 static BSLS_KEYWORD_CONSTEXPR FuncPtr s_map[sizeof...(t_INDICES)] = {
1875 &(Variant_Function<t_RET, t_VISITOR, t_VARIANT, t_INDICES>::
1876 functionImpl)...};
1877};
1878
1879/// This component-private struct computes an array in which element `i` is
1880/// a pointer to
1881/// `Variant_FunctionId<t_RET, t_VISITOR, t_VARIANT, i>::functionImpl`,
1882/// defined above as a function that invokes a `t_VISITOR` with a tag
1883/// representing `i` and alternative `i` of `t_VARIANT`, implicitly
1884/// converting the return type to `t_RET`. Implementation note: The
1885/// constexpr static maps of pointers defined by `Variant_VTable` and this
1886/// class have deliberately been defined in two different classes as having
1887/// them in the same class caused issues with Clang and Microsoft Visual
1888/// C++.
1889template <class t_RET, class t_VISITOR, class t_VARIANT, class t_DUMMY>
1890struct Variant_VTableId;
1891
1892/// In order to allow for perfect forwarding, both t_VISITOR and t_VARIANT
1893/// must be of reference type. If they are not, something went wrong.
1894template <class t_RET, class t_VISITOR, class t_VARIANT, size_t... t_INDICES>
1895struct Variant_VTableId<t_RET,
1896 t_VISITOR,
1897 t_VARIANT,
1898 bslmf::IntegerSequence<std::size_t, t_INDICES...> > {
1899 BSLMF_ASSERT(bsl::is_reference<t_VISITOR>::value);
1900 BSLMF_ASSERT(bsl::is_reference<t_VARIANT>::value);
1901
1902 typedef t_RET (*FuncPtr)(t_VISITOR, t_VARIANT);
1903
1904 static BSLS_KEYWORD_CONSTEXPR FuncPtr s_mapId[sizeof...(t_INDICES)] = {
1905 &(Variant_FunctionId<t_RET, t_VISITOR, t_VARIANT, t_INDICES>::
1906 functionImpl)...};
1907};
1908
1909// inline definitions of component-private function pointer maps
1910template <class t_RET, class t_VISITOR, class t_VARIANT, size_t... t_INDICES>
1911BSLS_KEYWORD_CONSTEXPR typename Variant_VTable<
1912 t_RET,
1913 t_VISITOR,
1914 t_VARIANT,
1915 bslmf::IntegerSequence<std::size_t, t_INDICES...> >::FuncPtr
1916 Variant_VTable<t_RET,
1917 t_VISITOR,
1918 t_VARIANT,
1919 bslmf::IntegerSequence<std::size_t, t_INDICES...> >::s_map
1920 [sizeof...(t_INDICES)];
1921
1922template <class t_RET, class t_VISITOR, class t_VARIANT, size_t... t_INDICES>
1923BSLS_KEYWORD_CONSTEXPR typename Variant_VTableId<
1924 t_RET,
1925 t_VISITOR,
1926 t_VARIANT,
1927 bslmf::IntegerSequence<std::size_t, t_INDICES...> >::FuncPtr
1928 Variant_VTableId<t_RET,
1929 t_VISITOR,
1930 t_VARIANT,
1931 bslmf::IntegerSequence<std::size_t, t_INDICES...> >::
1932 s_mapId[sizeof...(t_INDICES)];
1933
1934#else // BSL_VARIANT_FULL_IMPLEMENTATION
1935#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1936
1937template <class t_RET, class t_VISITOR, class t_VARIANT, class t_ALT_TYPE>
1938struct Variant_Function {
1939 static t_RET functionImpl(t_VISITOR& visitor, t_VARIANT& variant)
1940 // This component-private function invokes the specified 'visitor' on
1941 // the contained value of the specified 'variant', implicitly
1942 // converting the return type to (template parameter) 't_RET'. The
1943 // behavior is undefined if (template parameter) 't_ALT_TYPE' is not
1944 // the type of the active alternative.
1945 {
1946 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
1947 return visitor(ImpUtil::unsafeGet<t_ALT_TYPE>(variant));
1948 }
1949};
1950
1951template <class t_VISITOR, class t_VARIANT, class t_ALT_TYPE>
1952struct Variant_Function<void, t_VISITOR, t_VARIANT, t_ALT_TYPE> {
1953 // This partial specialization is used when 't_RET' is 'void'. The visitor
1954 // is invoked and its return value, if any, is ignored. This partial
1955 // specialization is necessary because a 'void'-returning function cannot
1956 // contain a 'return' statement with a non-'void' operand.
1957
1958 static void functionImpl(t_VISITOR& visitor, t_VARIANT& variant)
1959 {
1960 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
1961 visitor(ImpUtil::unsafeGet<t_ALT_TYPE>(variant));
1962 }
1963};
1964
1965template <class t_RET, class t_VISITOR, class t_VARIANT, class t_ALT_TYPE>
1966struct Variant_MoveFunction {
1967 static t_RET functionImpl(t_VISITOR& visitor, t_VARIANT& variant)
1968 // This component-private function invokes the specified 'visitor' with
1969 // a 'bslmf::MovableRef' referring to the active alternative object of
1970 // the specified 'variant', implicitly converting the return type to
1971 // (template parameter) 't_RET'. The behavior is undefined unless
1972 // 'variant' has an active alternative of type (template parameter)
1973 // 't_ALT_TYPE'.
1974 {
1975 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1976 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
1977
1978 return visitor(
1979 MoveUtil::move(ImpUtil::unsafeGet<t_ALT_TYPE>(variant)));
1980 }
1981};
1982
1983template <class t_VISITOR, class t_VARIANT, class t_ALT_TYPE>
1984struct Variant_MoveFunction<void, t_VISITOR, t_VARIANT, t_ALT_TYPE> {
1985 // This partial specialization is used when 't_RET' is 'void'. The visitor
1986 // is invoked and its return value, if any, is ignored. This partial
1987 // specialization is necessary because a 'void'-returning function cannot
1988 // contain a 'return' statement with a non-'void' operand.
1989
1990 static void functionImpl(t_VISITOR& visitor, t_VARIANT& variant)
1991 {
1992 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
1993 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
1994
1995 visitor(MoveUtil::move(ImpUtil::unsafeGet<t_ALT_TYPE>(variant)));
1996 }
1997};
1998
1999template <class t_RET, class t_VISITOR, class t_VARIANT, class t_ALT_TYPE>
2000struct Variant_FunctionId {
2001 static t_RET functionImpl(t_VISITOR& visitor, t_VARIANT& variant)
2002 // This component-private function invokes the specified 'visitor' with
2003 // a 'bsl::in_place_index_t' tag representing the index of the first
2004 // occurrence of (template parameter) 't_ALT_TYPE' in the specified
2005 // 'variant' and the active alternative object of 'variant', implicitly
2006 // converting the return type to (template parameter) 't_RET'. The
2007 // behavior is undefined unless 'variant' has an active alternative of
2008 // type 't_ALT_TYPE'. Note that the index passed to the visitor might
2009 // not be the index of the active alternative, if that alternative
2010 // occurs multiple times in 't_VARIANT'.
2011 {
2012 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2013 static const size_t t_INDEX = BSLSTL_VARIANT_INDEX_OF(
2014 t_ALT_TYPE, typename bsl::remove_cv<t_VARIANT>::type);
2015
2016 return visitor(bsl::in_place_index_t<t_INDEX>(),
2017 ImpUtil::unsafeGet<t_ALT_TYPE>(variant));
2018 }
2019};
2020
2021template <class t_RET, class t_VISITOR, class t_VARIANT, class... t_UNUSED>
2022struct Variant_VTable;
2023 // This component-private struct computes arrays in which element 'i' is a
2024 // pointer to one of the 'functionImpl' functions defined above, invoking
2025 // an lvalue of type (template parameter) 't_VISITOR' with alternative 'i'
2026 // of (template parameter) 't_VARIANT' and implicitly converting the return
2027 // type to 't_RET'. The primary template (used when 't_VARIANT' is not a
2028 // 'bsl::variant') is not defined. Note that the 't_UNUSED' template
2029 // parameter is required due to limitations of 'sim_cpp11_features.pl'.
2030
2031template <class t_RET, class t_VISITOR, class t_HEAD, class... t_TAIL>
2032struct Variant_VTable<t_RET, t_VISITOR, bsl::variant<t_HEAD, t_TAIL...> > {
2033 // This partial specialization is used when the 'bsl::variant' is not
2034 // 'const'.
2035
2036 typedef t_RET (*FuncPtr)(t_VISITOR&, bsl::variant<t_HEAD, t_TAIL...>&);
2037
2038 typedef bsl::variant<t_HEAD, t_TAIL...> Variant;
2039
2040 static const FuncPtr *map()
2041 // Return a pointer to the first element of an array of function
2042 // pointers that invoke the visitor with an lvalue referring to the
2043 // corresponding alternative.
2044 {
2045 static const FuncPtr s_mapArray[] = {
2046 &(Variant_Function<t_RET, t_VISITOR, Variant, t_HEAD>::
2047 functionImpl),
2048 &(Variant_Function<t_RET, t_VISITOR, Variant, t_TAIL>::
2049 functionImpl)...};
2050 return s_mapArray;
2051 }
2052
2053 static const FuncPtr *moveMap()
2054 // Return a pointer to the first element of an array of function
2055 // pointers that invoke the visitor with a 'bslmf::MovableRef'
2056 // referring to the corresponding alternative.
2057 {
2058 static const FuncPtr s_mapArray[] = {
2059 &(Variant_MoveFunction<t_RET, t_VISITOR, Variant, t_HEAD>::
2060 functionImpl),
2061 &(Variant_MoveFunction<t_RET, t_VISITOR, Variant, t_TAIL>::
2062 functionImpl)...};
2063 return s_mapArray;
2064 }
2065
2066 static const FuncPtr *mapId()
2067 // Return a pointer to the first element of an array of function
2068 // pointers where element 'i' invokes the visitor with a tag
2069 // representing the index of the first alternative whose type is the
2070 // same as that of alternative 'i', and an lvalue referring to
2071 // alternative 'i'.
2072 {
2073 static const FuncPtr s_mapArray[] = {
2074 &(Variant_FunctionId<t_RET, t_VISITOR, Variant, t_HEAD>::
2075 functionImpl),
2076 &(Variant_FunctionId<t_RET, t_VISITOR, Variant, t_TAIL>::
2077 functionImpl)...};
2078 return s_mapArray;
2079 }
2080};
2081
2082template <class t_RET, class t_VISITOR, class t_HEAD, class... t_TAIL>
2083struct Variant_VTable<t_RET,
2084 t_VISITOR,
2085 const bsl::variant<t_HEAD, t_TAIL...> > {
2086 // This partial specialization is used when the 'bsl::variant' is 'const'.
2087
2088 typedef t_RET (*FuncPtr)(t_VISITOR&,
2089 const bsl::variant<t_HEAD, t_TAIL...>&);
2090
2091 typedef const bsl::variant<t_HEAD, t_TAIL...> Variant;
2092
2093 static const FuncPtr *map()
2094 // Return a pointer to the first element of an array of function
2095 // pointers that invoke the visitor with an lvalue referring to the
2096 // corresponding alternative.
2097 {
2098 static const FuncPtr s_mapArray[] = {
2099 &(Variant_Function<t_RET, t_VISITOR, Variant, t_HEAD>::
2100 functionImpl),
2101 &(Variant_Function<t_RET, t_VISITOR, Variant, t_TAIL>::
2102 functionImpl)...};
2103 return s_mapArray;
2104 }
2105
2106 static const FuncPtr *mapId()
2107 // Return a pointer to the first element of an array of function
2108 // pointers where element 'i' invokes the visitor with a tag
2109 // representing the index of the first alternative whose type is the
2110 // same as that of alternative 'i', and an lvalue referring to
2111 // alternative 'i'.
2112 {
2113 static const FuncPtr s_mapArray[] = {
2114 &(Variant_FunctionId<t_RET, t_VISITOR, Variant, t_HEAD>::
2115 functionImpl),
2116 &(Variant_FunctionId<t_RET, t_VISITOR, Variant, t_TAIL>::
2117 functionImpl)...};
2118 return s_mapArray;
2119 }
2120};
2121
2122#endif
2123#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2124
2125} // close package namespace
2126
2127
2128namespace bsl {
2129#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2130/// Return the result of invoking the specified `visitor` with the currently
2131/// active alternative of the specified `variant`, implicitly converting the
2132/// result to the explicitly specified (template parameter) `t_RET`. If
2133/// `variant` does not hold a value, throw an exception of type
2134/// `bsl::bad_variant_access`. Note that unlike the `visit` overload below
2135/// that deduces its return type, this overload does not require the visitor
2136/// to yield the exact same type for each alternative, but only requires
2137/// each such type to be implicitly convertible to `t_RET`. This function
2138/// differs from the standard in the following ways:
2139/// * only one variant is supported
2140/// * constexpr is not implemented
2141/// * before C++17, only `t_VISITOR(ALTERNATIVE)` form of visitation is
2142/// supported; cases where the visitor is a pointer to member are not
2143/// supported.
2144template <class t_RET, class t_VISITOR, class t_VARIANT>
2145t_RET visit(t_VISITOR&& visitor, t_VARIANT&& variant)
2146{
2147 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2148
2149 if (variant.valueless_by_exception()) {
2150 BSLS_THROW(bsl::bad_variant_access());
2151 }
2152 return ImpUtil::visit<t_RET>(std::forward<t_VISITOR>(visitor),
2153 std::forward<t_VARIANT>(variant));
2154}
2155
2156/// Return the result of invoking the specified `visitor` with the currently
2157/// active alternative of the specified `variant`. If `variant` does not
2158/// hold a value, throw an exception of type `bsl::bad_variant_access`. For
2159/// each alternative, invocation of the visitor with that alternative shall
2160/// be of the same type and value category. This function differs from the
2161/// standard in the following ways:
2162/// * only one variant is supported
2163/// * constexpr is not implemented
2164/// * before C++17, only `t_VISITOR(ALTERNATIVE)` form of visitation is
2165/// supported; cases where the visitor is a pointer to member are not
2166/// supported.
2167template <class t_VISITOR, class t_VARIANT>
2168typename bsl::invoke_result<
2169 t_VISITOR,
2170 typename BloombergLP::bslstl::Variant_CVQualAlt<t_VARIANT, 0>::type>::type
2171visit(t_VISITOR&& visitor, t_VARIANT&& variant)
2172{
2173 typedef typename bsl::invoke_result<
2174 t_VISITOR&&,
2175 typename BloombergLP::bslstl::Variant_CVQualAlt<t_VARIANT&&,
2176 0>::type>::type RET;
2177 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2178
2179 static_assert(
2180 BloombergLP::bslstl::
2181 Variant_IsSameReturnType<RET, t_VISITOR&&, t_VARIANT&&>::value,
2182 "The value type and category of invoking the visitor with "
2183 "every alternative is not the same");
2184 if (variant.valueless_by_exception()) {
2185 BSLS_THROW(bsl::bad_variant_access());
2186 }
2187 return ImpUtil::visit<RET>(std::forward<t_VISITOR>(visitor),
2188 std::forward<t_VARIANT>(variant));
2189}
2190
2191/// Return the result of invoking the specified `visitor` with the currently
2192/// active alternative of the specified `variant`, implicitly converting the
2193/// result to the explicitly specified (template parameter) `t_RET`. If
2194/// `variant` does not hold a value, throw an exception of type
2195/// `bsl::bad_variant_access`. This function is provided in all language
2196/// versions for compatibility with the C++03 version (see below), but in
2197/// new code in C++11 and later, `bsl::visit` should be used instead of this
2198/// function.
2199template <class t_RET, class t_VISITOR, class t_VARIANT>
2200t_RET visitR(t_VISITOR& visitor, t_VARIANT&& variant)
2201{
2202 return visit<t_RET>(visitor, std::forward<t_VARIANT>(variant));
2203}
2204#else // BSL_VARIANT_FULL_IMPLEMENTATION
2205
2206template <class t_RET, class t_VISITOR, class t_VARIANT>
2207t_RET visitR(t_VISITOR& visitor, t_VARIANT& variant)
2208 // Return the result of invoking the specified 'visitor' with the currently
2209 // active alternative of the specified 'variant', implicitly converting the
2210 // result to the explicitly specified (template parameter) 't_RET'. If
2211 // 'variant' does not hold a value, throw an exception of type
2212 // 'bsl::bad_variant_access'. Unlike 'visit', which deduces its return
2213 // type, this function does not require the visitor to yield the exact same
2214 // type for each alternative, but only requires each such type to be
2215 // implicitly convertible to 't_RET'. Implementation note: Due to
2216 // limitations of the type deduction facility in C++03, this function can
2217 // not share the same name as the deduced type 'visit' because it is not
2218 // possible to discern between invocation of non deduced return type
2219 // 'visit' where the return type parameter is explicitly specified and
2220 // invocation of deduced return type 'visit' where the visitor type
2221 // parameter is explicitly specified.
2222{
2223 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2224
2225 if (variant.valueless_by_exception()) {
2226 BSLS_THROW(bsl::bad_variant_access());
2227 }
2228 return ImpUtil::visit<t_RET>(visitor, variant);
2229}
2230
2231template <class t_RET, class t_VISITOR, class t_VARIANT>
2232t_RET visitR(t_VISITOR& visitor,
2233 BloombergLP::bslmf::MovableRef<t_VARIANT> variant)
2234 // Return the result of invoking the specified 'visitor' with a
2235 // 'bslmf::MovableRef' referring to the currently active alternative of the
2236 // specified 'variant', implicitly converting the result to the explicitly
2237 // specified (template parameter) 't_RET'. If 'variant' does not hold a
2238 // value, throw an exception of type 'bsl::bad_variant_access'. Unlike
2239 // 'visit', which deduces its return type, this function does not require
2240 // the visitor to yield the exact same type for each alternative, but only
2241 // requires each such type to be implicitly convertible to 't_RET'.
2242 // Implementation note: Due to limitations of the type deduction facility
2243 // in C++03, this function can not share the same name as the deduced type
2244 // 'visit' because it is not possible to discern between invocation of non
2245 // deduced return type 'visit' where the return type parameter is
2246 // explicitly specified and invocation of deduced return type 'visit' where
2247 // the visitor type parameter is explicitly specified.
2248{
2249 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2250
2251 t_VARIANT& lvalue = variant;
2252 if (lvalue.valueless_by_exception()) {
2253 BSLS_THROW(bsl::bad_variant_access());
2254 }
2255 return ImpUtil::moveVisit<t_RET>(visitor, lvalue);
2256}
2257
2258template <class t_VISITOR, class t_VARIANT>
2259typename bsl::invoke_result<
2260 t_VISITOR&,
2261 typename bsl::variant_alternative<0, t_VARIANT>::type&>::type
2262visit(t_VISITOR& visitor, t_VARIANT& variant)
2263 // Return the result of invoking the specified 'visitor' with the currently
2264 // active alternative of the specified 'variant'. If 'variant' does not
2265 // hold a value, throw an exception of type 'bsl::bad_variant_access'. For
2266 // each alternative, invocation of the visitor with that alternative shall
2267 // be of the same type and value category.
2268{
2269 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2270
2271 if (variant.valueless_by_exception()) {
2272 BSLS_THROW(bsl::bad_variant_access());
2273 }
2274 typedef typename bsl::invoke_result<
2275 t_VISITOR&,
2276 typename bsl::variant_alternative<0, t_VARIANT>::type&>::type Ret;
2277
2278 BSLMF_ASSERT(
2279 (BloombergLP::bslstl::
2280 Variant_IsSameReturnType<Ret, t_VISITOR, t_VARIANT&>::value));
2281
2282 return ImpUtil::visit<Ret>(visitor, variant);
2283}
2284
2285template <class t_VISITOR, class t_VARIANT>
2286typename bsl::invoke_result<
2287 t_VISITOR&,
2288 BloombergLP::bslmf::MovableRef<
2289 typename bsl::variant_alternative<0, t_VARIANT>::type> >::type
2290visit(t_VISITOR& visitor, BloombergLP::bslmf::MovableRef<t_VARIANT> variant)
2291 // Return the result of invoking the specified 'visitor' with a
2292 // 'bslmf::MovableRef' referring to the currently active alternative of the
2293 // specified 'variant'. If 'variant' does not hold a value, throw an
2294 // exception of type 'bsl::bad_variant_access'. For each alternative,
2295 // invocation of the visitor with that alternative shall be of the same
2296 // type and value category.
2297{
2298 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2299
2300 t_VARIANT& lvalue = variant;
2301 if (lvalue.valueless_by_exception()) {
2302 BSLS_THROW(bsl::bad_variant_access());
2303 }
2304 typedef typename bsl::invoke_result<
2305 t_VISITOR&,
2306 BloombergLP::bslmf::MovableRef<
2307 typename bsl::variant_alternative<0, t_VARIANT>::type> >::type Ret;
2308
2309 BSLMF_ASSERT((BloombergLP::bslstl::Variant_IsSameReturnType<
2310 Ret,
2311 t_VISITOR,
2312 BloombergLP::bslmf::MovableRef<t_VARIANT> >::value));
2313
2314 return ImpUtil::moveVisit<Ret>(visitor, lvalue);
2315}
2316
2317#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2318
2319} // close namespace bsl
2320
2321
2322namespace bslstl {
2323
2324 // ========================
2325 // class Variant_NoSuchType
2326 // ========================
2327
2328/// This component-private trivial tag type is used to distinguish between
2329/// arguments passed by a user, and an `enable_if` argument. It is not
2330/// default constructible so the following construction never invokes a
2331/// constrained single parameter constructor:
2332/// @code
2333/// struct SomeType
2334/// {
2335/// SomeType(int, const std::string &s = "default"){}
2336/// };
2337///
2338/// variant<SomeType> o(1, {});
2339/// @endcode
2340struct Variant_NoSuchType {
2341
2342 // CREATORS
2343
2344 /// Create a `Variant_NoSuchType` object.
2345 explicit BSLS_KEYWORD_CONSTEXPR Variant_NoSuchType(
2346 int) BSLS_KEYWORD_NOEXCEPT;
2347};
2348
2349#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2350/// This component-private class manages an object of type (template
2351/// parameter) `t_TYPE` that is stored in a `variant` object. Note that
2352/// `t_TYPE` may be const-qualified, in which case the internally stored
2353/// object is not `const`, but the interface of this class prevents
2354/// modification thereof.
2355///
2356/// See @ref bslstl_variant
2357template <class t_TYPE>
2358class Variant_DataImp {
2359
2360 private:
2361 // PRIVATE TYPES
2362 typedef typename bsl::remove_const<t_TYPE>::type StoredType;
2363
2364 // DATA
2365 bsls::ObjectBuffer<StoredType> d_buffer; // in-place 't_TYPE' object
2366
2367 public:
2368 // CREATORS
2369 Variant_DataImp() = default;
2370 // Create a 'Variant_DataImp' object that holds an empty buffer.
2371
2372 // MANIPULATORS
2373
2374 /// Create a `Variant_DataImp` object whose stored `t_TYPE` object is
2375 /// constructed by forwarding the specified `args` to
2376 /// `ConstructionUtil::construct` directly. This means the first
2377 /// argument in `args` must be a pointer to `bslma::Allocator`, which
2378 /// will be ignored if `t_TYPE` is not allocator-aware.
2379 template <class... t_ARGS>
2380 Variant_DataImp(t_ARGS&&... args);
2381
2382 BSLS_KEYWORD_CONSTEXPR_CPP14 t_TYPE& value() &;
2383 BSLS_KEYWORD_CONSTEXPR_CPP14 t_TYPE&& value() &&;
2384 // Return a reference to the stored 't_TYPE' object. The behavior is
2385 // undefined unless this object contains a 't_TYPE' object (i.e., this
2386 // object is currently managing the active alternative of a 'bsl::variant'
2387 // object).
2388
2389 // ACCESSORS
2390 BSLS_KEYWORD_CONSTEXPR_CPP14 const t_TYPE& value() const&;
2391 BSLS_KEYWORD_CONSTEXPR_CPP14 const t_TYPE&& value() const&&;
2392 // Return a const reference to the stored 't_TYPE' object. The behavior is
2393 // undefined unless this object contains a 't_TYPE' object (i.e., this
2394 // object is currently managing the active alternative of a 'bsl::variant'
2395 // object).
2396};
2397
2398/// This component-private union can hold a `Variant_DataImp` object for any
2399/// alternative in (template parameters) `t_TYPES...`. The primary template
2400/// is used when `t_TYPES...` is empty.
2401template <class... t_TYPES>
2402union Variant_Union {
2403};
2404
2405/// This partial specialization uses template recursion because C++ does not
2406/// support member packs.
2407template <class t_HEAD, class... t_TAIL>
2408union Variant_Union<t_HEAD, t_TAIL...> {
2409
2410 // PUBLIC DATA
2411 Variant_DataImp<t_HEAD> d_head;
2412 Variant_Union<t_TAIL...> d_tail;
2413
2414 // CREATORS
2415 Variant_Union() = default;
2416 // Create a 'Variant_Union' object having no active alternative.
2417
2418 /// Create a `Variant_Union` object holding an object of type `t_HEAD`
2419 /// direct-initialized from the specified `args`.
2420 template <class... t_ARGS>
2421 Variant_Union(bsl::in_place_index_t<0>, t_ARGS&&... args)
2422 : d_head(std::forward<t_ARGS>(args)...)
2423 {
2424 }
2425
2426 /// Create a `Variant_Union` object holding the alternative at index
2427 /// (template parameter) `t_INDEX` in (template parameters) 't_HEAD,
2428 /// t_TAIL...`, direct-initialized from the specified `args'. Note that
2429 /// `t_INDEX` is not necessarily the absolute index of the desired
2430 /// alternative in the `bsl::variant` object. We use the tag to
2431 /// "unravel" the union until we get to the desired alternative type.
2432 ///
2433 /// See @ref bslstl_variant
2434 template <size_t t_INDEX, class... t_ARGS>
2435 Variant_Union(bsl::in_place_index_t<t_INDEX>, t_ARGS&&... args)
2436 : d_tail(bsl::in_place_index_t<t_INDEX - 1>(),
2437 std::forward<t_ARGS>(args)...)
2438 {
2439 }
2440};
2441#else // BSL_VARIANT_FULL_IMPLEMENTATION
2442template <class t_TYPE>
2443class Variant_DataImp {
2444 // This component-private class manages an object of type (template
2445 // parameter) 't_TYPE' that is stored in a 'variant' object. Note that
2446 // 't_TYPE' may be const-qualified, in which case the internally stored
2447 // object is not 'const', but the interface of this class prevents
2448 // modification thereof.
2449
2450 private:
2451 // PRIVATE TYPES
2452 typedef typename bsl::remove_const<t_TYPE>::type StoredType;
2453
2454 // DATA
2455 bsls::ObjectBuffer<StoredType> d_buffer; // in-place 't_TYPE' object
2456
2457 public:
2458 // CREATORS
2459 Variant_DataImp() = default;
2460 // Create a 'Variant_DataImp' object that holds an empty buffer.
2461
2462 // MANIPULATORS
2463 t_TYPE& value();
2464 // Return a reference to the stored 't_TYPE' object. The behavior is
2465 // undefined unless the enclosing union contains a 't_TYPE' object
2466 // (i.e., the enclosing 'bsl::variant' has an active alternative of
2467 // type 't_TYPE').
2468
2469 // ACCESSORS
2470 const t_TYPE& value() const;
2471 // Return a const reference to the stored 't_TYPE' object. The
2472 // behavior is undefined unless the enclosing union contains a 't_TYPE'
2473 // object (i.e., the enclosing 'bsl::variant' has an active alternative
2474 // of type 't_TYPE').
2475};
2476
2477#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2478template <class t_HEAD = void, class... t_TAIL0 = void, class... t_TAIL>
2479union Variant_Union;
2480 // This component-private union can hold a 'Variant_DataImp' object for any
2481 // alternative in (template parameters) 't_HEAD, t_TAIL0, t_TAIL...'. Note
2482 // that the declaration and definition of the primary template must be kept
2483 // separate in order for 'sim_cpp11_features.pl' to work properly. The
2484 // purpose of the 't_TAIL0' template parameter is explained below.
2485
2486template <>
2487union Variant_Union<void, void> {
2488 // This specialization is used when the type list is empty.
2489};
2490
2491template <>
2492union Variant_Union<BloombergLP::bsls::CompilerFeaturesNilT> {
2493};
2494
2495template <class t_HEAD, class t_TAIL0, class... t_TAIL>
2496union Variant_Union<t_HEAD, t_TAIL0, t_TAIL...> {
2497 // The implementation of this template uses template recursion because C++
2498 // does not support member packs. The 't_TAIL0' template parameter is
2499 // needed in order to avoid an empty template argument list in the type of
2500 // the 'd_tail' member, which causes an issue with the IBM compiler.
2501
2502 // PUBLIC DATA
2503 Variant_DataImp<t_HEAD> d_head;
2504 Variant_Union<t_TAIL0, t_TAIL...> d_tail;
2505};
2506#endif
2507#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2508
2509 // ==================================
2510 // class Variant_CopyConstructVisitor
2511 // ==================================
2512
2513/// This component-private class is a visitor that is used to implement the
2514/// copy constructor for `bsl::variant`.
2515///
2516/// See @ref bslstl_variant
2517template <class t_VARIANT_BASE>
2518class Variant_CopyConstructVisitor {
2519
2520 private:
2521 // DATA
2522 t_VARIANT_BASE *d_variant_p;
2523
2524 public:
2525 // CREATORS
2526 explicit Variant_CopyConstructVisitor(t_VARIANT_BASE *variant)
2527 // Create a 'Variant_CopyConstructVisitor' object that, when invoked,
2528 // will copy-construct an alternative in the specified 'variant'.
2529 : d_variant_p(variant)
2530 {
2531 BSLS_ASSERT_SAFE(d_variant_p);
2532 }
2533
2534 // ACCESSORS
2535
2536 /// Copy-construct the alternative at index (template parameter)
2537 /// `t_INDEX` from the specified `other` (i.e. the alternative that is
2538 /// being visited). Note that the allocator specified on construction
2539 /// of `*d_variant_p` will be used.
2540 template <size_t t_INDEX, class t_TYPE>
2541 void operator()(bsl::in_place_index_t<t_INDEX>, const t_TYPE& other) const
2542 {
2543 d_variant_p->template baseEmplace<t_INDEX>(other);
2544 }
2545};
2546
2547 // ==================================
2548 // class Variant_MoveConstructVisitor
2549 // ==================================
2550
2551/// This component-private class is a visitor that is used to implement the
2552/// move constructor for `bsl::variant`.
2553///
2554/// See @ref bslstl_variant
2555template <class t_VARIANT_BASE>
2557
2558 private:
2559 // PRIVATE TYPES
2560 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2561
2562 // DATA
2563 t_VARIANT_BASE *d_variant_p;
2564
2565 public:
2566 // CREATORS
2567
2568 /// Create a `Variant_MoveConstructVisitor` object that, when invoked,
2569 /// will move-construct an alternative in the specified `variant`.
2570 explicit Variant_MoveConstructVisitor(t_VARIANT_BASE *variant)
2571 : d_variant_p(variant)
2572 {
2573 BSLS_ASSERT_SAFE(d_variant_p);
2574 }
2575
2576 // ACCESSORS
2577
2578 /// Move-construct the alternative at index (template parameter)
2579 /// `t_INDEX` from the specified `other` (i.e. the alternative that is
2580 /// being visited). Note that the allocator specified on construction
2581 /// of `*d_variant_p` will be used.
2582 template <size_t t_INDEX, class t_TYPE>
2584 {
2585 d_variant_p->template baseEmplace<t_INDEX>(MoveUtil::move(other));
2586 }
2587};
2588
2589 // ===============================
2590 // class Variant_CopyAssignVisitor
2591 // ===============================
2592
2593/// This component-private class is a visitor that is used to implement the
2594/// copy assignment operator for `bsl::variant`.
2595///
2596/// See @ref bslstl_variant
2597template <class t_VARIANT>
2599
2600 private:
2601 // DATA
2602 t_VARIANT *d_variant_p;
2603
2604 public:
2605 // CREATORS
2606
2607 /// Create a `Variant_CopyAssignVisitor` object that, when invoked, will
2608 /// copy-assign to the active alternative of the specified `variant`.
2609 explicit Variant_CopyAssignVisitor(t_VARIANT *variant)
2610 : d_variant_p(variant)
2611 {
2612 BSLS_ASSERT_SAFE(d_variant_p);
2613 }
2614
2615
2616 public:
2617 // ACCESSORS
2618
2619 /// Copy-assign to the active alternative of `*d_variant_p` from the
2620 /// specified `value` (i.e. the alternative that is being visited). The
2621 /// behavior is undefined unless (template parameter) `t_INDEX` is the
2622 /// index of the active alternative of `*d_variant_p` (or, in C++03, the
2623 /// index of an alternative that has the same type as the active
2624 /// alternative).
2625 template <size_t t_INDEX, class t_TYPE>
2626 void operator()(bsl::in_place_index_t<t_INDEX>, const t_TYPE& value) const
2627 {
2628#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2629 bsl::get<t_INDEX>(*d_variant_p) = value;
2630#else
2631 // When invoking this visitor in C++03, 't_INDEX' may not be the index
2632 // of the active alternative, but it will be an index of an alternative
2633 // of same type. However, because 't_TYPE' is deduced, it may be
2634 // missing cv-qualifications. 't_ALT_TYPE' will give the correct
2635 // cv-qualification.
2637 Alt_Type;
2638 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2639
2640 ImpUtil::unsafeGet<Alt_Type>(*d_variant_p) = value;
2641#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2642 }
2643};
2644
2645 // ===============================
2646 // class Variant_MoveAssignVisitor
2647 // ===============================
2648
2649/// This component-private class is a visitor that is used to implement the
2650/// move assignment operator for `bsl::variant`.
2651///
2652/// See @ref bslstl_variant
2653template <class t_VARIANT>
2655
2656 private:
2657 // PRIVATE TYPES
2658 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2659
2660 // DATA
2661 t_VARIANT *d_variant_p;
2662
2663 public:
2664 // CREATORS
2665
2666 /// Create a `Variant_MoveAssignVisitor` object that, when invoked, will
2667 /// move-assign to the active alternative of the specified `variant`.
2668 explicit Variant_MoveAssignVisitor(t_VARIANT *variant)
2669 : d_variant_p(variant)
2670 {
2671 BSLS_ASSERT_SAFE(d_variant_p);
2672 }
2673
2674 public:
2675 // ACCESSORS
2676
2677 /// Move-assign to the active alternative of `*d_variant_p` from the
2678 /// specified `value` (i.e. the alternative that is being visited). The
2679 /// behavior is undefined unless (template parameter) `t_INDEX` is the
2680 /// index of the active alternative of `*d_variant_p` (or, in C++03, the
2681 /// index of an alternative that has the same type as the active
2682 /// alternative).
2683 template <size_t t_INDEX, class t_TYPE>
2685 {
2686#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2687 bsl::get<t_INDEX>(*d_variant_p) = MoveUtil::move(value);
2688#else
2689 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2690 ImpUtil::unsafeGet<t_TYPE>(*d_variant_p) = MoveUtil::move(value);
2691#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2692 }
2693};
2694
2695 // ================================
2696 // struct Variant_DestructorVisitor
2697 // ================================
2698
2699/// This component-private struct is a visitor that destroys the active
2700/// alternative of the visited `variant` object.
2702
2703 public:
2704 // ACCESSORS
2705
2706 /// Destroy the specified `object`, which is the alternative that is
2707 /// being visited.
2708 template <class t_TYPE>
2709 void operator()(t_TYPE& object) const
2710 {
2711 bslma::DestructionUtil::destroy(&object);
2712 }
2713};
2714
2715 // ==============================
2716 // struct Variant_##NAME##Visitor
2717 // ==============================
2718
2719#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2720#define BSLSTL_VARIANT_RELOP_VISITOR_DEFINITON(NAME, OP) \
2721 template <class t_VARIANT> \
2722 struct Variant_##NAME##Visitor { \
2723 /* When using this visitor, construct the visitor using the left */ \
2724 /* operand, and call visitation on the right operand. */ \
2725 explicit Variant_##NAME##Visitor(const t_VARIANT *variant) \
2726 : d_variant_p(variant) \
2727 { \
2728 BSLS_ASSERT_SAFE(d_variant_p); \
2729 } \
2730 \
2731 private: \
2732 const t_VARIANT *d_variant_p; \
2733 \
2734 public: \
2735 template <size_t t_INDEX, class t_TYPE> \
2736 bool operator()(bsl::in_place_index_t<t_INDEX>, \
2737 const t_TYPE& value) const \
2738 { \
2739 return (bsl::get<t_INDEX>(*d_variant_p) OP value); \
2740 } \
2741 }; \
2742 \
2743 template <class t_VARIANT> \
2744 bool Variant_ImpUtil::NAME(const t_VARIANT& lhs, const t_VARIANT& rhs) \
2745 { \
2746 BSLS_ASSERT(lhs.index() == rhs.index() && \
2747 !lhs.valueless_by_exception()); \
2748 \
2749 Variant_##NAME##Visitor<t_VARIANT> NAME##Visitor( \
2750 BSLS_UTIL_ADDRESSOF(lhs)); \
2751 return BSLSTL_VARIANT_VISITID(bool, NAME##Visitor, rhs); \
2752 }
2753#else
2754#define BSLSTL_VARIANT_RELOP_VISITOR_DEFINITON(NAME, OP) \
2755 template <class t_VARIANT> \
2756 struct Variant_##NAME##Visitor { \
2757 Variant_##NAME##Visitor(const t_VARIANT *variant) \
2758 : d_variant_p(variant) \
2759 { \
2760 BSLS_ASSERT_SAFE(d_variant_p); \
2761 } \
2762 \
2763 private: \
2764 const t_VARIANT *d_variant_p; \
2765 \
2766 public: \
2767 template <size_t t_INDEX, class t_TYPE> \
2768 bool operator()(bsl::in_place_index_t<t_INDEX>, \
2769 t_TYPE& value) const \
2770 { \
2771 /* When invoking this visitor in C++03, 't_INDEX' may not be */ \
2772 /* the index of the active alternative, but it will be an */ \
2773 /* index of an alternative of same type. However, because */ \
2774 /* 't_TYPE' is deduced, it may have incorrect */ \
2775 /* cv-qualifications. 't_ALT_TYPE' will give the correct */ \
2776 /* cv-qualification. */ \
2777 typedef \
2778 typename bsl::variant_alternative<t_INDEX, t_VARIANT>::type \
2779 Alt_Type; \
2780 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil; \
2781 return (ImpUtil::unsafeGet<Alt_Type>(*d_variant_p) OP value); \
2782 } \
2783 }; \
2784 \
2785 template <class t_VARIANT> \
2786 bool Variant_ImpUtil::NAME(const t_VARIANT& lhs, const t_VARIANT& rhs) \
2787 { \
2788 BSLS_ASSERT(lhs.index() == rhs.index() && \
2789 !lhs.valueless_by_exception()); \
2790 \
2791 Variant_##NAME##Visitor<t_VARIANT> NAME##Visitor( \
2792 BSLS_UTIL_ADDRESSOF(lhs)); \
2793 return BSLSTL_VARIANT_VISITID(bool, NAME##Visitor, rhs); \
2794 }
2795#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2796 // This macro is used to define the 'Variant_ImpUtil::*Impl' methods.
2797
2804
2805 // =========================
2806 // class Variant_SwapVisitor
2807 // =========================
2808
2809/// This component-private class is a visitor that is used to implement
2810/// `bsl::variant::swap`.
2811///
2812/// See @ref bslstl_variant
2813template <class t_VARIANT>
2815
2816 private:
2817 // DATA
2818 t_VARIANT *d_variant_p;
2819
2820 public:
2821 // CREATORS
2822
2823 /// Create a `Variant_SwapVisitor` object that, when invoked, will swap
2824 /// the visited alternative with the active alternative of the specified
2825 /// `variant`.
2826 explicit Variant_SwapVisitor(t_VARIANT *variant)
2827 : d_variant_p(variant)
2828 {
2829 BSLS_ASSERT_SAFE(d_variant_p);
2830 }
2831
2832 // ACCESSORS
2833
2834 /// Swap the alternative having index (template parameter) `t_INDEX` in
2835 /// `*d_variant_p` with the specified `value` (i.e. the alternative that
2836 /// is being visited). The behavior is undefined unless `t_INDEX` is the
2837 /// index of the active alternative of `*d_variant_p` (or, in C++03, the
2838 /// index of an alternative that has the same type as the active
2839 /// alternative).
2840 template <size_t t_INDEX, class t_TYPE>
2842 {
2843#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
2844 BloombergLP::bslalg::SwapUtil::swap(
2845 BSLS_UTIL_ADDRESSOF(value),
2846 BSLS_UTIL_ADDRESSOF(bsl::get<t_INDEX>(*d_variant_p)));
2847#else
2848 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
2849 // When invoking this visitor in C++03, 't_INDEX' may not be the
2850 // index of the active alternative, but it will be an index of an
2851 // alternative of same type. Swap can not be invoked on a constant
2852 // variant, so the cv qualifications will match.
2853 BloombergLP::bslalg::SwapUtil::swap(
2854 BSLS_UTIL_ADDRESSOF(value),
2855 BSLS_UTIL_ADDRESSOF((ImpUtil::unsafeGet<t_TYPE>(*d_variant_p))));
2856#endif // BSL_VARIANT_FULL_IMPLEMENTATION
2857 }
2858};
2859
2860 // =========================
2861 // class Variant_HashVisitor
2862 // =========================
2863
2864/// This component-private class is a visitor that is used to implement
2865/// `hashAppend` for `bsl::variant`.
2866///
2867/// See @ref bslstl_variant
2868template <class t_HASHALG>
2870
2871 private:
2872 // DATA
2873 t_HASHALG& d_hashAlg;
2874
2875 public:
2876 // CREATORS
2877
2878 /// Create a `Variant_HashVisitor` object that, when invoked, appends to
2879 /// the specified `hashAlg`.
2880 explicit Variant_HashVisitor(t_HASHALG& hashAlg)
2881 : d_hashAlg(hashAlg)
2882 {
2883 }
2884
2885 // ACCESSORS
2886
2887 /// Append the specified `value` (i.e., the alternative that is being
2888 /// visited) to `d_hashAlg`.
2889 template <class t_TYPE>
2890 void operator()(t_TYPE& value) const
2891 {
2892 using BloombergLP::bslh::hashAppend;
2893 hashAppend(d_hashAlg, value);
2894 }
2895};
2896
2897/// This component-private struct keeps track of the allocator for a
2898/// `bsl::variant` object. The primary template is used when the `variant`
2899/// is not allocator-aware (because it has no allocator-aware alternatives).
2900template <bool t_AA>
2902
2903 // ACCESSORS
2904
2905 /// Return a null pointer. Note that this method has the same return
2906 /// type as the allocator-aware version so that the remainder of the
2907 /// implementation of `bsl::variant` is abstracted with respect to
2908 /// whether or not the specialization is allocator-aware; this is why
2909 /// both methods return `bslma::Allocator*` instead of
2910 /// `bsl::allocator<char>`. The returned pointer will be ignored (and
2911 /// not dereferenced) when passed to
2912 /// `bslma::ConstructionUtil::construct`.
2913 BloombergLP::bslma::Allocator *mechanism() const
2914 {
2915 return NULL;
2916 }
2917};
2918
2919/// This specialization is used when the `variant` is allocator-aware.
2920template <>
2922
2923 // TYPES
2924 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2926
2927 // PUBLIC DATA
2929
2930 // CREATORS
2931
2932 /// Create a `Variant_AllocatorBase` object that holds the currently
2933 /// installed default allocator.
2935
2936 /// Create a `Variant_AllocatorBase` object that holds a copy of the
2937 /// allocator held by the specified `original`.
2939 : d_allocator(original.d_allocator)
2940 {
2941 }
2942
2943 /// Create a `Variant_AllocatorBase` object that holds a copy of the
2944 /// specified `allocator`.
2946 : d_allocator(allocator)
2947 {
2948 }
2949
2950 // ACCESSORS
2951
2952 /// Return the mechanism of the stored allocator.
2953 BloombergLP::bslma::Allocator *mechanism() const
2954 {
2955 return d_allocator.mechanism();
2956 }
2957};
2958
2959 // ===================
2960 // struct variant_base
2961 // ===================
2962
2963#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2964/// This component-private struct defines the data representation of
2965/// `bsl::variant` and contains the implementations of its special member
2966/// functions (which must be defaulted in `bsl::variant` itself). This
2967/// class also contains implementations of additional constructors and
2968/// methods needed for the correct functionality of the `variant` class
2969/// hierarchy.
2970template <class t_HEAD, class... t_TAIL>
2972: public BloombergLP::bslstl::Variant_AllocatorBase<
2973 BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny<t_HEAD,
2974 t_TAIL...>::value> {
2975
2976 // TYPES
2977 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
2978 typedef BloombergLP::bslstl::Variant_AllocatorBase<
2979 BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny<t_HEAD,
2980 t_TAIL...>::value>
2982 typedef BloombergLP::bslstl::Variant_Union<t_HEAD, t_TAIL...>
2984 typedef bsl::variant<t_HEAD, t_TAIL...> Variant;
2985
2986 /// This trivial tag type is used as a dummy when `Variant_Base` wraps a
2987 /// non-allocator-aware type.
2988 struct NoAlloc {
2989 };
2990
2991 /// Type alias to the allocator type used by `variant`.
2992 typedef typename bsl::conditional<
2993 BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny<t_HEAD,
2994 t_TAIL...>::value,
2997
2998 // PUBLIC DATA
2999
3000 /// Index of the currently active alternative in this variant object, or
3001 /// `bsl::variant_npos` if the variant is valueless by exception.
3002 size_t d_type;
3003
3004 /// Union holding the alternative object.
3006
3007 // TRAITS
3010 BloombergLP::bslma::UsesBslmaAllocator,
3011 (BloombergLP::bslstl::
3012 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value));
3015 BloombergLP::bslmf::UsesAllocatorArgT,
3016 (BloombergLP::bslstl::
3017 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value));
3020 BloombergLP::bslmf::IsBitwiseMoveable,
3021 (BloombergLP::bslstl::Variant_IsBitwiseMoveableAll<t_HEAD,
3022 t_TAIL...>::value));
3023
3024 // CREATORS
3025#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
3026 /// Create a `Variant_Base` object holding the 0th alternative, which is
3027 /// value-initialized. If this `Variant_Base` is allocator-aware, the
3028 /// currently installed default allocator is used to supply memory.
3029 Variant_Base();
3030
3031 /// Create a `Variant_Base` object holding the same alternative (if any)
3032 /// as the specified `original` object. If this `Variant_Base` is
3033 /// allocator-aware, the currently installed default allocator is used
3034 /// to supply memory. If the `original` object is not valueless by
3035 /// exception', the contained value is copy-constructed from the
3036 /// contained value of `original`. All alternatives shall be copy
3037 /// constructible.
3038 Variant_Base(const Variant_Base& original);
3039
3040 /// Create a `Variant_Base` object holding the same alternative (if any)
3041 /// held by the specified `original`. If this `Variant_Base` is
3042 /// allocator-aware, the allocator of `original` is used to supply
3043 /// memory. If the `original` object is not valueless by exception, the
3044 /// contained value is move-constructed from the contained value of
3045 /// `original`. All alternatives shall be move constructible.
3046 Variant_Base(Variant_Base&& original);
3047
3048#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3049 /// Create a `Variant_Base` object whose index is the specified `index`
3050 /// without constructing an alternative object. If this `Variant_Base`
3051 /// is allocator-aware, the default allocator is used to supply memory.
3053#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3054
3055 /// Create a `Variant_Base` object holding the alternative with index
3056 /// (template parameter) `t_INDEX`, direct-initialized from the
3057 /// specified `args`. If this `Variant_Base` is allocator-aware, the
3058 /// currently installed default allocator is used to supply memory.
3059 template <size_t t_INDEX, class... t_ARGS>
3060 explicit Variant_Base(bsl::in_place_index_t<t_INDEX>, t_ARGS&&... args);
3061
3062 // allocator-extended constructors
3063
3064 /// Create a `Variant_Base` object holding the 0th alternative, which is
3065 /// value-initialized. If this `Variant_Base` is allocator-aware, the
3066 /// specified `allocator` is used to supply memory.
3067 Variant_Base(bsl::allocator_arg_t, allocator_type allocator);
3068
3069 Variant_Base(bsl::allocator_arg_t,
3070 allocator_type allocator,
3071 const Variant& original);
3072 /// Create a `Variant_Base` object holding the same alternative (if any)
3073 /// held by the specified `original` object. If this `Variant_Base` is
3074 /// allocator-aware, the specified `allocator` is used to supply memory.
3075 /// If the `original` object is not valueless by exception, the
3076 /// contained value is copy/move constructed from the contained value of
3077 /// `original`. All alternatives shall be copy/move constructible.
3078 Variant_Base(bsl::allocator_arg_t,
3079 allocator_type allocator,
3080 Variant&& original);
3081
3082#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3083 /// Create a `Variant_Base` object whose index is the specified `index`
3084 /// without constructing an alternative object. If this `Variant_Base`
3085 /// is allocator-aware, the specified `allocator` is used to supply
3086 /// memory.
3087 Variant_Base(bsl::allocator_arg_t,
3088 allocator_type allocator,
3090 size_t index);
3091#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3092
3093 /// Create a `Variant_Base` object holding the alternative with index
3094 /// (template parameter) `t_INDEX`, direct-initialized from the
3095 /// specified `args`. If this `Variant_Base` is allocator-aware, the
3096 /// specified `allocator` is used to supply memory.
3097 template <size_t t_INDEX, class... t_ARGS>
3098 explicit Variant_Base(bsl::allocator_arg_t,
3099 allocator_type allocator,
3101 t_ARGS&&... args);
3102
3103#else // BSL_VARIANT_FULL_IMPLEMENTATION
3104
3105 Variant_Base();
3106 // Create a 'Variant_Base' object holding the 0th alternative, which is
3107 // value-initialized. If this 'Variant_Base' is allocator-aware, the
3108 // currently installed default constructor is used to supply memory.
3109
3110 Variant_Base(const Variant& original);
3111 // Create a 'Variant_Base' object holding the same alternative (if any)
3112 // as the specified 'original' object. If this 'Variant_Base' is
3113 // allocator-aware, the currently installed default allocator is used
3114 // to supply memory. If the 'original' object is not valueless by
3115 // exception', the contained value is copy-constructed from the
3116 // contained value of 'original'. All alternatives shall be copy
3117 // constructible.
3118
3119 Variant_Base(BloombergLP::bslmf::MovableRef<Variant> original);
3120 // Create a 'Variant_Base' object holding the same alternative (if any)
3121 // held by the specified 'original'. If this 'Variant_Base' is
3122 // allocator-aware, the allocator of 'original' is used to supply
3123 // memory. If the 'original' object is not valueless by exception, the
3124 // contained value is move-constructed from the contained value of
3125 // 'original'. All alternatives shall be move constructible.
3126
3127 template <size_t t_INDEX>
3129 // Create a 'Variant_Base' object holding the alternative with index
3130 // (template parameter) 't_INDEX', which is value-initialized. If this
3131 // 'Variant_Base' is allocator-aware, the currently installed default
3132 // constructor is used to supply memory.
3133
3134 template <size_t t_INDEX, class t_ARG_01>
3136 const t_ARG_01& arg_01);
3137
3138 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
3140 const t_ARG_01& arg_01,
3141 const t_ARG_02& arg_02);
3142
3143 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
3145 const t_ARG_01& arg_01,
3146 const t_ARG_02& arg_02,
3147 const t_ARG_03& arg_03);
3148
3149 template <size_t t_INDEX,
3150 class t_ARG_01,
3151 class t_ARG_02,
3152 class t_ARG_03,
3153 class t_ARG_04>
3155 const t_ARG_01& arg_01,
3156 const t_ARG_02& arg_02,
3157 const t_ARG_03& arg_03,
3158 const t_ARG_04& arg_04);
3159
3160 template <size_t t_INDEX,
3161 class t_ARG_01,
3162 class t_ARG_02,
3163 class t_ARG_03,
3164 class t_ARG_04,
3165 class t_ARG_05>
3167 const t_ARG_01& arg_01,
3168 const t_ARG_02& arg_02,
3169 const t_ARG_03& arg_03,
3170 const t_ARG_04& arg_04,
3171 const t_ARG_05& arg_05);
3172
3173 template <size_t t_INDEX,
3174 class t_ARG_01,
3175 class t_ARG_02,
3176 class t_ARG_03,
3177 class t_ARG_04,
3178 class t_ARG_05,
3179 class t_ARG_06>
3181 const t_ARG_01& arg_01,
3182 const t_ARG_02& arg_02,
3183 const t_ARG_03& arg_03,
3184 const t_ARG_04& arg_04,
3185 const t_ARG_05& arg_05,
3186 const t_ARG_06& arg_06);
3187
3188 template <size_t t_INDEX,
3189 class t_ARG_01,
3190 class t_ARG_02,
3191 class t_ARG_03,
3192 class t_ARG_04,
3193 class t_ARG_05,
3194 class t_ARG_06,
3195 class t_ARG_07>
3197 const t_ARG_01& arg_01,
3198 const t_ARG_02& arg_02,
3199 const t_ARG_03& arg_03,
3200 const t_ARG_04& arg_04,
3201 const t_ARG_05& arg_05,
3202 const t_ARG_06& arg_06,
3203 const t_ARG_07& arg_07);
3204
3205 template <size_t t_INDEX,
3206 class t_ARG_01,
3207 class t_ARG_02,
3208 class t_ARG_03,
3209 class t_ARG_04,
3210 class t_ARG_05,
3211 class t_ARG_06,
3212 class t_ARG_07,
3213 class t_ARG_08>
3215 const t_ARG_01& arg_01,
3216 const t_ARG_02& arg_02,
3217 const t_ARG_03& arg_03,
3218 const t_ARG_04& arg_04,
3219 const t_ARG_05& arg_05,
3220 const t_ARG_06& arg_06,
3221 const t_ARG_07& arg_07,
3222 const t_ARG_08& arg_08);
3223
3224 template <size_t t_INDEX,
3225 class t_ARG_01,
3226 class t_ARG_02,
3227 class t_ARG_03,
3228 class t_ARG_04,
3229 class t_ARG_05,
3230 class t_ARG_06,
3231 class t_ARG_07,
3232 class t_ARG_08,
3233 class t_ARG_09>
3235 const t_ARG_01& arg_01,
3236 const t_ARG_02& arg_02,
3237 const t_ARG_03& arg_03,
3238 const t_ARG_04& arg_04,
3239 const t_ARG_05& arg_05,
3240 const t_ARG_06& arg_06,
3241 const t_ARG_07& arg_07,
3242 const t_ARG_08& arg_08,
3243 const t_ARG_09& arg_09);
3244
3245 template <size_t t_INDEX,
3246 class t_ARG_01,
3247 class t_ARG_02,
3248 class t_ARG_03,
3249 class t_ARG_04,
3250 class t_ARG_05,
3251 class t_ARG_06,
3252 class t_ARG_07,
3253 class t_ARG_08,
3254 class t_ARG_09,
3255 class t_ARG_10>
3257 const t_ARG_01& arg_01,
3258 const t_ARG_02& arg_02,
3259 const t_ARG_03& arg_03,
3260 const t_ARG_04& arg_04,
3261 const t_ARG_05& arg_05,
3262 const t_ARG_06& arg_06,
3263 const t_ARG_07& arg_07,
3264 const t_ARG_08& arg_08,
3265 const t_ARG_09& arg_09,
3266 const t_ARG_10& arg_10);
3267 // Create a 'Variant_Base' object holding the alternative with index
3268 // (template parameter) 't_INDEX', which is direct-initialized from the
3269 // specified 'arg'. If this 'Variant_Base' is allocator-aware, the
3270 // currently installed default constructor is used to supply memory.
3271
3272 // allocator-extended constructors
3273 Variant_Base(bsl::allocator_arg_t, allocator_type allocator);
3274 // Create a 'Variant_Base' object holding the 0th alternative, which is
3275 // value-initialized. If this 'Variant_Base' is allocator-aware, the
3276 // specified 'allocator' is used to supply memory.
3277
3278 Variant_Base(bsl::allocator_arg_t,
3279 allocator_type allocator,
3280 const Variant& original);
3281 Variant_Base(bsl::allocator_arg_t,
3282 allocator_type allocator,
3283 BloombergLP::bslmf::MovableRef<Variant> original);
3284 // Create a 'Variant_Base' object holding the same alternative (if any)
3285 // held by the specified 'original' object. If this 'Variant_Base' is
3286 // allocator-aware, the specified 'allocator' is used to supply memory.
3287 // If the 'original' object is not valueless by exception, the
3288 // contained value is copy/move constructed from the contained value of
3289 // 'original'. All alternatives shall be copy/move constructible.
3290
3291 template <size_t t_INDEX>
3292 explicit Variant_Base(bsl::allocator_arg_t,
3293 allocator_type allocator,
3295 // Create a 'Variant_Base' object holding the alternative with index
3296 // (template parameter) 't_INDEX', which is value-initialized. If this
3297 // 'Variant_Base' is allocator-aware, the specified 'allocator' is used
3298 // to supply memory.
3299
3300 template <size_t t_INDEX, class t_ARG_01>
3301 explicit Variant_Base(bsl::allocator_arg_t,
3302 allocator_type allocator,
3304 const t_ARG_01& arg_01);
3305
3306 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
3307 explicit Variant_Base(bsl::allocator_arg_t,
3308 allocator_type allocator,
3310 const t_ARG_01& arg_01,
3311 const t_ARG_02& arg_02);
3312
3313 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
3314 explicit Variant_Base(bsl::allocator_arg_t,
3315 allocator_type allocator,
3317 const t_ARG_01& arg_01,
3318 const t_ARG_02& arg_02,
3319 const t_ARG_03& arg_03);
3320
3321 template <size_t t_INDEX,
3322 class t_ARG_01,
3323 class t_ARG_02,
3324 class t_ARG_03,
3325 class t_ARG_04>
3326 explicit Variant_Base(bsl::allocator_arg_t,
3327 allocator_type allocator,
3329 const t_ARG_01& arg_01,
3330 const t_ARG_02& arg_02,
3331 const t_ARG_03& arg_03,
3332 const t_ARG_04& arg_04);
3333
3334 template <size_t t_INDEX,
3335 class t_ARG_01,
3336 class t_ARG_02,
3337 class t_ARG_03,
3338 class t_ARG_04,
3339 class t_ARG_05>
3340 explicit Variant_Base(bsl::allocator_arg_t,
3341 allocator_type allocator,
3343 const t_ARG_01& arg_01,
3344 const t_ARG_02& arg_02,
3345 const t_ARG_03& arg_03,
3346 const t_ARG_04& arg_04,
3347 const t_ARG_05& arg_05);
3348
3349 template <size_t t_INDEX,
3350 class t_ARG_01,
3351 class t_ARG_02,
3352 class t_ARG_03,
3353 class t_ARG_04,
3354 class t_ARG_05,
3355 class t_ARG_06>
3356 explicit Variant_Base(bsl::allocator_arg_t,
3357 allocator_type allocator,
3359 const t_ARG_01& arg_01,
3360 const t_ARG_02& arg_02,
3361 const t_ARG_03& arg_03,
3362 const t_ARG_04& arg_04,
3363 const t_ARG_05& arg_05,
3364 const t_ARG_06& arg_06);
3365
3366 template <size_t t_INDEX,
3367 class t_ARG_01,
3368 class t_ARG_02,
3369 class t_ARG_03,
3370 class t_ARG_04,
3371 class t_ARG_05,
3372 class t_ARG_06,
3373 class t_ARG_07>
3374 explicit Variant_Base(bsl::allocator_arg_t,
3375 allocator_type allocator,
3377 const t_ARG_01& arg_01,
3378 const t_ARG_02& arg_02,
3379 const t_ARG_03& arg_03,
3380 const t_ARG_04& arg_04,
3381 const t_ARG_05& arg_05,
3382 const t_ARG_06& arg_06,
3383 const t_ARG_07& arg_07);
3384
3385 template <size_t t_INDEX,
3386 class t_ARG_01,
3387 class t_ARG_02,
3388 class t_ARG_03,
3389 class t_ARG_04,
3390 class t_ARG_05,
3391 class t_ARG_06,
3392 class t_ARG_07,
3393 class t_ARG_08>
3394 explicit Variant_Base(bsl::allocator_arg_t,
3395 allocator_type allocator,
3397 const t_ARG_01& arg_01,
3398 const t_ARG_02& arg_02,
3399 const t_ARG_03& arg_03,
3400 const t_ARG_04& arg_04,
3401 const t_ARG_05& arg_05,
3402 const t_ARG_06& arg_06,
3403 const t_ARG_07& arg_07,
3404 const t_ARG_08& arg_08);
3405
3406 template <size_t t_INDEX,
3407 class t_ARG_01,
3408 class t_ARG_02,
3409 class t_ARG_03,
3410 class t_ARG_04,
3411 class t_ARG_05,
3412 class t_ARG_06,
3413 class t_ARG_07,
3414 class t_ARG_08,
3415 class t_ARG_09>
3416 explicit Variant_Base(bsl::allocator_arg_t,
3417 allocator_type allocator,
3419 const t_ARG_01& arg_01,
3420 const t_ARG_02& arg_02,
3421 const t_ARG_03& arg_03,
3422 const t_ARG_04& arg_04,
3423 const t_ARG_05& arg_05,
3424 const t_ARG_06& arg_06,
3425 const t_ARG_07& arg_07,
3426 const t_ARG_08& arg_08,
3427 const t_ARG_09& arg_09);
3428
3429 template <size_t t_INDEX,
3430 class t_ARG_01,
3431 class t_ARG_02,
3432 class t_ARG_03,
3433 class t_ARG_04,
3434 class t_ARG_05,
3435 class t_ARG_06,
3436 class t_ARG_07,
3437 class t_ARG_08,
3438 class t_ARG_09,
3439 class t_ARG_10>
3440 explicit Variant_Base(bsl::allocator_arg_t,
3441 allocator_type allocator,
3443 const t_ARG_01& arg_01,
3444 const t_ARG_02& arg_02,
3445 const t_ARG_03& arg_03,
3446 const t_ARG_04& arg_04,
3447 const t_ARG_05& arg_05,
3448 const t_ARG_06& arg_06,
3449 const t_ARG_07& arg_07,
3450 const t_ARG_08& arg_08,
3451 const t_ARG_09& arg_09,
3452 const t_ARG_10& arg_10);
3453 // Create a 'Variant_Base' object holding the alternative with index
3454 // (template parameter) 't_INDEX', direct-initialized from 'arg'. If
3455 // this 'Variant_Base' is allocator-aware, the specified 'allocator' is
3456 // used to supply memory.
3457
3458#endif // BSL_VARIANT_FULL_IMPLEMENTATION
3459
3460 /// Destroy this object. The contained value, if any, is destroyed.
3461 ~Variant_Base();
3462
3463 // MANIPULATORS
3464#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
3465 /// Create the alternative with index (template parameter) `t_INDEX` in
3466 /// place, direct-initialized from the specified `args`. If this
3467 /// `Variant_Base` object already holds a value, that contained value is
3468 /// destroyed before the new object is created. If the alternative is
3469 /// allocator-aware, it uses the allocator specified upon the
3470 /// construction of this `Variant_Base` object to supply memory; passing
3471 /// an allocator argument to this method results in two allocators being
3472 /// passed to the alternative constructor, resulting in a likely
3473 /// compilation error. Note that if the constructor of the alternative
3474 /// exits via an exception, this object is left in the valueless by
3475 /// exception state.
3476 template <size_t t_INDEX, class... t_ARGS>
3477 void baseEmplace(t_ARGS&&...);
3478#else // BSL_VARIANT_FULL_IMPLEMENTATION
3479 template <size_t t_INDEX>
3480 void baseEmplace();
3481 // Create the alternative with index (template parameter) 't_INDEX' in
3482 // place, which is value-initialized. If this 'Variant_Base' object
3483 // already holds a value, that contained value is destroyed before the
3484 // new object is created. If the alternative is allocator-aware, it
3485 // uses the allocator specified upon the construction of this
3486 // 'Variant_Base' object to supply memory; passing an allocator
3487 // argument to this method results in two allocators being passed to
3488 // the alternative constructor, resulting in a likely compilation
3489 // error. Note that if the constructor of the alternative exits via an
3490 // exception, this object is left in the valueless by exception state.
3491 template <size_t t_INDEX, class t_ARG_01>
3492 void baseEmplace(const t_ARG_01& arg_01);
3493
3494 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
3495 void baseEmplace(const t_ARG_01& arg_01, const t_ARG_02& arg_02);
3496
3497 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
3498 void baseEmplace(const t_ARG_01& arg_01,
3499 const t_ARG_02& arg_02,
3500 const t_ARG_03& arg_03);
3501
3502 template <size_t t_INDEX,
3503 class t_ARG_01,
3504 class t_ARG_02,
3505 class t_ARG_03,
3506 class t_ARG_04>
3507 void baseEmplace(const t_ARG_01& arg_01,
3508 const t_ARG_02& arg_02,
3509 const t_ARG_03& arg_03,
3510 const t_ARG_04& arg_04);
3511
3512 template <size_t t_INDEX,
3513 class t_ARG_01,
3514 class t_ARG_02,
3515 class t_ARG_03,
3516 class t_ARG_04,
3517 class t_ARG_05>
3518 void baseEmplace(const t_ARG_01& arg_01,
3519 const t_ARG_02& arg_02,
3520 const t_ARG_03& arg_03,
3521 const t_ARG_04& arg_04,
3522 const t_ARG_05& arg_05);
3523
3524 template <size_t t_INDEX,
3525 class t_ARG_01,
3526 class t_ARG_02,
3527 class t_ARG_03,
3528 class t_ARG_04,
3529 class t_ARG_05,
3530 class t_ARG_06>
3531 void baseEmplace(const t_ARG_01& arg_01,
3532 const t_ARG_02& arg_02,
3533 const t_ARG_03& arg_03,
3534 const t_ARG_04& arg_04,
3535 const t_ARG_05& arg_05,
3536 const t_ARG_06& arg_06);
3537
3538 template <size_t t_INDEX,
3539 class t_ARG_01,
3540 class t_ARG_02,
3541 class t_ARG_03,
3542 class t_ARG_04,
3543 class t_ARG_05,
3544 class t_ARG_06,
3545 class t_ARG_07>
3546 void baseEmplace(const t_ARG_01& arg_01,
3547 const t_ARG_02& arg_02,
3548 const t_ARG_03& arg_03,
3549 const t_ARG_04& arg_04,
3550 const t_ARG_05& arg_05,
3551 const t_ARG_06& arg_06,
3552 const t_ARG_07& arg_07);
3553
3554 template <size_t t_INDEX,
3555 class t_ARG_01,
3556 class t_ARG_02,
3557 class t_ARG_03,
3558 class t_ARG_04,
3559 class t_ARG_05,
3560 class t_ARG_06,
3561 class t_ARG_07,
3562 class t_ARG_08>
3563 void baseEmplace(const t_ARG_01& arg_01,
3564 const t_ARG_02& arg_02,
3565 const t_ARG_03& arg_03,
3566 const t_ARG_04& arg_04,
3567 const t_ARG_05& arg_05,
3568 const t_ARG_06& arg_06,
3569 const t_ARG_07& arg_07,
3570 const t_ARG_08& arg_08);
3571
3572 template <size_t t_INDEX,
3573 class t_ARG_01,
3574 class t_ARG_02,
3575 class t_ARG_03,
3576 class t_ARG_04,
3577 class t_ARG_05,
3578 class t_ARG_06,
3579 class t_ARG_07,
3580 class t_ARG_08,
3581 class t_ARG_09>
3582 void baseEmplace(const t_ARG_01& arg_01,
3583 const t_ARG_02& arg_02,
3584 const t_ARG_03& arg_03,
3585 const t_ARG_04& arg_04,
3586 const t_ARG_05& arg_05,
3587 const t_ARG_06& arg_06,
3588 const t_ARG_07& arg_07,
3589 const t_ARG_08& arg_08,
3590 const t_ARG_09& arg_09);
3591
3592 template <size_t t_INDEX,
3593 class t_ARG_01,
3594 class t_ARG_02,
3595 class t_ARG_03,
3596 class t_ARG_04,
3597 class t_ARG_05,
3598 class t_ARG_06,
3599 class t_ARG_07,
3600 class t_ARG_08,
3601 class t_ARG_09,
3602 class t_ARG_10>
3603 void baseEmplace(const t_ARG_01& arg_01,
3604 const t_ARG_02& arg_02,
3605 const t_ARG_03& arg_03,
3606 const t_ARG_04& arg_04,
3607 const t_ARG_05& arg_05,
3608 const t_ARG_06& arg_06,
3609 const t_ARG_07& arg_07,
3610 const t_ARG_08& arg_08,
3611 const t_ARG_09& arg_09,
3612 const t_ARG_10& arg_10);
3613 // Create the alternative with index (template parameter) 't_INDEX' in
3614 // place, direct-initialized from the specified 'arg'. If this
3615 // 'Variant_Base' object already holds a value, that contained value is
3616 // destroyed before the new object is created. If the alternative is
3617 // allocator-aware, it uses the allocator specified upon the
3618 // construction of this 'Variant_Base' object to supply memory; passing
3619 // an allocator argument to this method results in two allocators being
3620 // passed to the alternative constructor, resulting in a likely
3621 // compilation error. Note that if the constructor of the alternative
3622 // exits via an exception, this object is left in the valueless by
3623 // exception state.
3624#endif // BSL_VARIANT_FULL_IMPLEMENTATION
3625
3626 /// If the specified `rhs` holds the same alternative type as this
3627 /// object, copy assign the contained value of `rhs` to the contained
3628 /// value of this object. Otherwise, destroy the contained value of
3629 /// this object (if any) and, if `rhs` holds a value, copy-construct the
3630 /// corresponding alternative of this object from the contained value of
3631 /// `rhs`. The allocators of this object and `rhs` both remain
3632 /// unchanged. If the construction of a new alternative object exits
3633 /// via an exception, this `Variant_Base` object is left in a valueless
3634 /// by exception state. This behavior differs from the standard, for
3635 /// reasons that are explained in the documentation for
3636 /// `variant::operator=`. All alternatives shall be copy constructible
3637 /// and copy assignable.
3638 Variant_Base& operator=(const Variant_Base& rhs);
3639
3640 /// If the specified `rhs` holds the same alternative type as this
3641 /// object, move assign the contained value of `rhs` to the contained
3642 /// value of this object. Otherwise, destroy the currently held
3643 /// alternative object (if any) and, if `rhs` holds a value,
3644 /// move-construct the corresponding alternative of this object from the
3645 /// contained value of `rhs`. The allocators of this object and `rhs`
3646 /// both remain unchanged. If the construction of a new alternative
3647 /// object exits via an exception, this `Variant_Base` object is left in
3648 /// a valueless by exception state. All alternatives shall be move
3649 /// constructible and move assignable.
3650 Variant_Base& operator=(BloombergLP::bslmf::MovableRef<Variant_Base> rhs);
3651
3652 /// Destroy the contained value, if any.
3653 void reset() BSLS_KEYWORD_NOEXCEPT;
3654};
3655#endif
3656
3657} // close package namespace
3658
3659
3660namespace bsl {
3661 // =============
3662 // class variant
3663 // =============
3664
3665#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3666template <class t_HEAD, class... t_TAIL>
3668: private BloombergLP::bslstl::Variant_Base<t_HEAD, t_TAIL...>
3669#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
3670,
3671 private BloombergLP::bslstl::Variant_SMFBase<
3672 BloombergLP::bslstl::Variant_IsCopyConstructibleAll<t_HEAD,
3673 t_TAIL...>::value,
3674 BloombergLP::bslstl::Variant_IsMoveConstructibleAll<t_HEAD,
3675 t_TAIL...>::value,
3676 BloombergLP::bslstl::Variant_IsCopyConstructibleAll<t_HEAD,
3677 t_TAIL...>::value &&
3678 BloombergLP::bslstl::Variant_IsCopyAssignableAll<t_HEAD,
3679 t_TAIL...>::value,
3680 BloombergLP::bslstl::Variant_IsMoveConstructibleAll<t_HEAD,
3681 t_TAIL...>::value &&
3682 BloombergLP::bslstl::Variant_IsMoveAssignableAll<t_HEAD,
3683 t_TAIL...>::value>
3684#endif // BSL_VARIANT_FULL_IMPLEMENTATION
3685{
3686 private:
3687 // PRIVATE TYPES
3688 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
3689 typedef BloombergLP::bslstl::Variant_Base<t_HEAD, t_TAIL...> Variant_Base;
3690 typedef BloombergLP::bslstl::Variant_Union<t_HEAD, t_TAIL...>
3691 Variant_Union;
3692
3693 // FRIENDS
3695 // This struct contains functions that require access to the
3696 // 'Variant_Union' subobject. Note that because 'variant' is not
3697 // standard-layout in the allocator-aware case, we cannot easily cast
3698 // between the variant object and its 'Variant_Union' subobject.
3699
3700 friend struct BloombergLP::bslstl::Variant_Base<t_HEAD, t_TAIL...>;
3701 // 'Variant_Base' must be able to downcast from 'Variant_Base' to
3702 // 'variant' (which is privately derived from 'Variant_Base').
3703
3704 public:
3705 // TRAITS
3707 variant,
3708 BloombergLP::bslma::UsesBslmaAllocator,
3709 (BloombergLP::bslstl::
3710 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value));
3712 variant,
3713 BloombergLP::bslmf::UsesAllocatorArgT,
3714 (BloombergLP::bslstl::
3715 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value));
3717 variant,
3718 BloombergLP::bslmf::IsBitwiseMoveable,
3719 (BloombergLP::bslstl::Variant_IsBitwiseMoveableAll<t_HEAD,
3720 t_TAIL...>::value));
3721
3722 // TYPES
3723
3724 /// Type alias to the allocator type used by `variant`.
3725 typedef typename Variant_Base::allocator_type allocator_type;
3726
3727 // CREATORS
3728
3729 // 20.7.3.1, constructors
3730#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
3731 /// Create a `variant` object holding the 0th alternative, which is
3732 /// value-initialized. If this `variant` is allocator-aware, the
3733 /// currently installed default allocator is used to supply memory.
3734 /// This constructor participates in overload resolution only if the 0th
3735 /// alternative is default constructible. For simplicity of
3736 /// implementation, this method differs from the standard in the
3737 /// following ways:
3738 /// * `constexpr` is not implemented
3739 /// * `noexcept` specification is not implemented
3740 template <class t_FIRST_ALT = t_HEAD,
3741 class = typename bsl::enable_if_t<
3742 std::is_default_constructible<t_FIRST_ALT>::value> >
3743 variant()
3744 : Variant_Base()
3745 {
3746 // This constructor template must be defined inline inside the class
3747 // definition, as Microsoft Visual C++ does not recognize the
3748 // definition as matching this signature when placed out-of-line.
3749 }
3750
3751 /// Create a `variant` object holding the same alternative (if any) as
3752 /// the specified `original` object. If this `variant` is
3753 /// allocator-aware, the currently installed default allocator is used
3754 /// to supply memory. If the `original` object is not valueless by
3755 /// exception', the contained value is copy-constructed from the
3756 /// contained value of `original`. This constructor is deleted unless
3757 /// all alternatives are copy constructible. For simplicity of
3758 /// implementation, this method differs from the standard in the
3759 /// following ways:
3760 /// * conditional triviality is not implemented
3761 /// * `constexpr` is not implemented
3762 /// * `noexcept` specification is not implemented
3763 variant(const variant& original) = default;
3764
3765 /// Create a `variant` object holding the same alternative (if any) held
3766 /// by the specified `original`. If this `variant` is allocator-aware,
3767 /// the allocator of `original` is used to supply memory. If `original`
3768 /// is not valueless by exception, the contained value is
3769 /// move-constructed from the contained value of `original`. This
3770 /// constructor participates in overload resolution only if all
3771 /// alternatives are move constructible. For simplicity of
3772 /// implementation, this method differs from the standard in the
3773 /// following ways:
3774 /// * conditional triviality is not implemented
3775 /// * `constexpr` is not implemented
3776 /// * `noexcept` specification is not implemented
3777 variant(variant&& original) = default;
3778
3779#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3780 /// Create a `variant` object holding the same alternative (if any) held
3781 /// by the specified `original`. If this `variant` is allocator-aware,
3782 /// the specified `allocator` is used to supply memory. If `original`
3783 /// is not valueless by exception, the contained value is
3784 /// copy/move-constructed from the contained value of `original`. This
3785 /// constructor participates in overload resolution only if all
3786 /// alternatives are copy/move-constructible.
3787 template <class t_STD_VARIANT>
3788 explicit variant(
3791 : Variant_Base(BloombergLP::bslstl::Variant_ConstructFromStdTag(),
3792 original.index())
3793 {
3794 // MSVC 19.22 and later has a bug where if this constructor is defined
3795 // out of line, it becomes non-explicit in copy-list-initialization.
3796 if (!valueless_by_exception()) {
3797 BloombergLP::bslstl::Variant_ImpUtil::
3798 ConstructFromStdVisitor<variant, decltype(original)>
3799 visitor(*this, original);
3800 BSLSTL_VARIANT_VISITID(void, visitor, *this);
3801 }
3802 }
3803#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3804
3805 /// Create a `variant` object whose contained value is
3806 /// direct-initialized from the specified `t`. The alternative selected
3807 /// is the best match among all alternatives for which the expression
3808 /// `t_ALT_TYPE x[] = {std::forward<t_TYPE>(t)};` is well formed, and
3809 /// this constructor participates in overload resolution only if there
3810 /// is a unique best matching alternative and that alternative is
3811 /// constructible from `t`. If this `variant` is allocator-aware, the
3812 /// currently installed default allocator is used to supply memory.
3813 /// Note that the cv-qualification of an alternative type does not
3814 /// affect how well the alternative type matches an argument type. For
3815 /// simplicity of implementation, this method differs from the standard
3816 /// in the following ways:
3817 /// * `constexpr` is not implemented
3818 /// * `noexcept` specification is not implemented
3819 template <class t_TYPE>
3820 variant(t_TYPE&& t,
3822
3823 /// Create a `variant` object holding a contained value of type
3824 /// (template parameter) `t_TYPE`, direct-initialized from the specified
3825 /// `args`. If this `variant` is allocator-aware, the currently
3826 /// installed default allocator is used to supply memory. This
3827 /// constructor participates in overload resolutionly if `t_TYPE`
3828 /// designates a unique alternative and is constructible from `args`.
3829 /// For simplicity of implementation, this method differs from the
3830 /// standard in the following way:
3831 /// * `constexpr` is not implemented
3832 template <class t_TYPE,
3833 class... t_ARGS,
3834 class = typename bsl::enable_if_t<
3836 std::is_constructible<t_TYPE, t_ARGS...>::value> >
3838 : Variant_Base(
3839 bsl::in_place_index_t<BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant)>(),
3840 std::forward<t_ARGS>(args)...)
3841 {
3842 // The implementation is placed here in the class definition to work
3843 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
3844 // cannot be matched to the declaration when an 'enable_if' is used.
3845 }
3846
3847 template <class t_TYPE,
3848 class INIT_LIST_TYPE,
3849 class... t_ARGS,
3850 class = typename bsl::enable_if_t<
3852 std::is_constructible<t_TYPE,
3853 std::initializer_list<INIT_LIST_TYPE>&,
3854 t_ARGS...>::value> >
3856 std::initializer_list<INIT_LIST_TYPE> il,
3857 t_ARGS&&... args)
3858 // Create a 'variant' object holding a contained value of type
3859 // (template parameter) 't_TYPE', direct-initialized from the specified
3860 // 'il' and 'args'. If this 'variant' is allocator-aware, the
3861 // currently installed default allocator is used to supply memory.
3862 // This constructor participates in overload resolutionly if 't_TYPE'
3863 // designates a unique alternative and is constructible from 'il' and
3864 // 'args'. For simplicity of implementation, this method differs from
3865 // the standard in the following way:
3866 //: o 'constexpr' is not implemented
3867 : Variant_Base(
3868 bsl::in_place_index_t<BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant)>(),
3869 il,
3870 std::forward<t_ARGS>(args)...)
3871 {
3872 // The implementation is placed here in the class definition to work
3873 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
3874 // cannot be matched to the declaration when an 'enable_if' is used.
3875 }
3876
3877 /// Create a `variant` object holding the alternative with index
3878 /// (template parameter) `t_INDEX`, direct-initialized from the
3879 /// specified `args`. If this `variant` is allocator-aware, the
3880 /// currently installed default allocator is used to supply memory.
3881 /// This constructor participates in overload resolution only if
3882 /// `t_INDEX` is a valid alternative index and the designated
3883 /// alternative is constructible from `args`. For simplicity of
3884 /// implementation, this method differs from the standard in the
3885 /// following ways:
3886 /// * `constexpr` is not implemented
3887 template <size_t t_INDEX,
3888 class... t_ARGS,
3889 class = typename bsl::enable_if_t<
3890 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
3891 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
3892 t_ARGS...>::value> >
3894 : Variant_Base(bsl::in_place_index_t<t_INDEX>(),
3895 std::forward<t_ARGS>(args)...)
3896 {
3897 // The implementation is placed here in the class definition to work
3898 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
3899 // cannot be matched to the declaration when an 'enable_if' is used.
3900 }
3901
3902 template <size_t t_INDEX,
3903 class INIT_LIST_TYPE,
3904 class... t_ARGS,
3905 class = typename bsl::enable_if_t<
3906 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
3907 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
3908 std::initializer_list<INIT_LIST_TYPE>&,
3909 t_ARGS...>::value> >
3911 std::initializer_list<INIT_LIST_TYPE> il,
3912 t_ARGS&&... args)
3913 // Create a 'variant' object holding the alternative with index
3914 // (template parameter) 't_INDEX', direct-initialized from the specified
3915 // 'il' and 'args'. If this 'variant' is allocator-aware, the
3916 // currently installed default allocator is used to supply memory.
3917 // This constructor participates in overload resolution only if 't_INDEX'
3918 // is a valid alternative index and the designated alternative is
3919 // constructible from 'il' and 'args'. For simplicity of
3920 // implementation, this method differs from the standard in the
3921 // following way:
3922 //: o 'constexpr' is not implemented
3923 : Variant_Base(bsl::in_place_index_t<t_INDEX>(),
3924 il,
3925 std::forward<t_ARGS>(args)...)
3926 {
3927 // The implementation is placed here in the class definition to work
3928 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
3929 // cannot be matched to the declaration when an 'enable_if' is used.
3930 }
3931
3932 // allocator-extended constructors
3933 template <class FIRST = t_HEAD,
3934 class = typename bsl::enable_if_t<
3935 std::is_default_constructible<FIRST>::value> >
3936 variant(bsl::allocator_arg_t, allocator_type allocator)
3937 // Create a 'variant' object holding the 0th alternative, which is
3938 // value-initialized. If this 'variant' is allocator-aware, the
3939 // specified 'allocator' is used to supply memory. This constructor
3940 // participates in overload resolution only if the 0th alternative is
3941 // default constructible.
3942 : Variant_Base(bsl::allocator_arg_t(), allocator)
3943 {
3944 // This constructor template must be defined inline inside the class
3945 // definition, as Microsoft Visual C++ does not recognize the
3946 // definition as matching this signature when placed out-of-line.
3947 }
3948
3949 /// Create a `variant` object holding the same alternative (if any) held
3950 /// by the specified `original`. If this `variant` is allocator-aware,
3951 /// the specified `allocator` is used to supply memory. If `original`
3952 /// is not valueless by exception, the contained value is
3953 /// move-constructed from the contained value of `original`. This
3954 /// constructor participates in overload resolution only if all
3955 /// alternatives are move constructible.
3956 template <
3957 class FIRST = t_HEAD,
3958 class = typename bsl::enable_if_t<
3959 BloombergLP::bslstl::
3960 Variant_IsCopyConstructibleAll<FIRST, t_TAIL...>::value> >
3961 variant(bsl::allocator_arg_t,
3962 allocator_type allocator,
3963 const variant& original)
3964 // Create a 'variant' object holding the same alternative (if any) as
3965 // the specified 'original' object. If this 'variant' is
3966 // allocator-aware, the specified 'allocator' is used to supply memory.
3967 // If the 'original' object is not valueless by exception', the
3968 // contained value is copy-constructed from the contained value of
3969 // 'original'. This constructor is deleted unless all alternatives are
3970 // copy constructible.
3971 : Variant_Base(bsl::allocator_arg_t(), allocator, original)
3972 {
3973 // This constructor template must be defined inline inside the class
3974 // definition, as Microsoft Visual C++ does not recognize the
3975 // definition as matching this signature when placed out-of-line.
3976 }
3977 template <
3978 class FIRST = t_HEAD,
3979 class = typename bsl::enable_if_t<
3980 BloombergLP::bslstl::
3981 Variant_IsMoveConstructibleAll<FIRST, t_TAIL...>::value> >
3982 variant(bsl::allocator_arg_t, allocator_type allocator, variant&& original)
3983 : Variant_Base(bsl::allocator_arg_t(), allocator, std::move(original))
3984 {
3985 // This constructor template must be defined inline inside the class
3986 // definition, as Microsoft Visual C++ does not recognize the
3987 // definition as matching this signature when placed out-of-line.
3988 }
3989
3990#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
3991 /// Create a `variant` object holding the same alternative (if any) held
3992 /// by the specified `original`. If this `variant` is allocator-aware,
3993 /// the specified `allocator` is used to supply memory. If `original`
3994 /// is not valueless by exception, the contained value is
3995 /// copy/move-constructed from the contained value of `original`. This
3996 /// constructor participates in overload resolution only if all
3997 /// alternatives are copy/move-constructible.
3998 template <class t_STD_VARIANT>
3999 explicit variant(
4000 bsl::allocator_arg_t,
4001 allocator_type allocator,
4004 : Variant_Base(bsl::allocator_arg_t(),
4005 allocator,
4006 BloombergLP::bslstl::Variant_ConstructFromStdTag(),
4007 original.index())
4008 {
4009 // MSVC 19.22 and later has a bug where if this constructor is defined
4010 // out of line, it becomes non-explicit in copy-list-initialization.
4011 if (!valueless_by_exception()) {
4012 BloombergLP::bslstl::Variant_ImpUtil::
4013 ConstructFromStdVisitor<variant, decltype(original)>
4014 visitor(*this, original);
4015 BSLSTL_VARIANT_VISITID(void, visitor, *this);
4016 }
4017 }
4018#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
4019
4020 /// Create a `variant` object whose contained value is
4021 /// direct-initialized from the specified `t`. The alternative selected
4022 /// is the best match among all alternatives for which the expression
4023 /// `t_ALT_TYPE x[] = {std::forward<t_TYPE>(t)};` is well formed, and
4024 /// this constructor participates in overload resolution only if there
4025 /// is a unique best matching alternative and that alternative is
4026 /// constructible from `t`. If this `variant` is allocator-aware, the
4027 /// specified `allocator` is used to supply memory. Note that the
4028 /// cv-qualification of an alternative type does not affect how well the
4029 /// alternative type matches an argument type.
4030 template <class t_TYPE>
4031 variant(
4032 bsl::allocator_arg_t,
4033 allocator_type allocator,
4034 t_TYPE&& t,
4036
4037 /// Create a `variant` object holding a contained value of type
4038 /// (template parameter) `t_TYPE`, direct-initialized from the specified
4039 /// `args`. If this `variant` is allocator-aware, the specified
4040 /// `allocator `is used to supply memory. This constructor participates
4041 /// in overload resolutionly if `t_TYPE` designates a unique alternative
4042 /// and is constructible from `args`.
4043 template <class t_TYPE,
4044 class... t_ARGS,
4045 class = typename bsl::enable_if_t<
4047 std::is_constructible<t_TYPE, t_ARGS...>::value> >
4048 explicit variant(bsl::allocator_arg_t,
4049 allocator_type allocator,
4051 t_ARGS&&... args)
4052 : Variant_Base(
4053 bsl::allocator_arg_t{},
4054 allocator,
4055 bsl::in_place_index_t<BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant)>(),
4056 std::forward<t_ARGS>(args)...)
4057 {
4058 // This constructor template must be defined inline inside the class
4059 // definition, as Microsoft Visual C++ does not recognize the
4060 // definition as matching this signature when placed out-of-line.
4061 }
4062
4063 template <class t_TYPE,
4064 class INIT_LIST_TYPE,
4065 class... t_ARGS,
4066 class = typename bsl::enable_if_t<
4068 std::is_constructible<t_TYPE,
4069 std::initializer_list<INIT_LIST_TYPE>&,
4070 t_ARGS...>::value> >
4071 explicit variant(bsl::allocator_arg_t,
4072 allocator_type allocator,
4074 std::initializer_list<INIT_LIST_TYPE> il,
4075 t_ARGS&&... args)
4076 // Create a 'variant' object holding a contained value of type
4077 // (template parameter) 't_TYPE', direct-initialized from the specified
4078 // 'il' and 'args'. If this 'variant' is allocator-aware, the
4079 // specified 'allocator 'is used to supply memory. This constructor
4080 // participates in overload resolutionly if 't_TYPE' designates a unique
4081 // alternative and is constructible from 'il' and 'args'.
4082 : Variant_Base(
4083 bsl::allocator_arg_t{},
4084 allocator,
4085 bsl::in_place_index_t<BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant)>(),
4086 il,
4087 std::forward<t_ARGS>(args)...)
4088 {
4089 // This constructor template must be defined inline inside the class
4090 // definition, as Microsoft Visual C++ does not recognize the
4091 // definition as matching this signature when placed out-of-line.
4092 }
4093
4094 template <size_t t_INDEX,
4095 class... t_ARGS,
4096 class = typename bsl::enable_if_t<
4097 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
4098 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
4099 t_ARGS...>::value> >
4100 explicit variant(bsl::allocator_arg_t,
4101 allocator_type allocator,
4103 t_ARGS&&... args)
4104 // Create a 'variant' object holding the alternative with index
4105 // (template parameter) 't_INDEX', direct-initialized from the specified
4106 // 'args'. If this 'variant' is allocator-aware, the specified
4107 // 'allocator' is used to supply memory. This constructor participates
4108 // in overload resolution only if 't_INDEX' is a valid alternative index
4109 // and the designated alternative is constructible from 'args'.
4110 : Variant_Base(bsl::allocator_arg_t{},
4111 allocator,
4112 bsl::in_place_index_t<t_INDEX>(),
4113 std::forward<t_ARGS>(args)...)
4114 {
4115 // This constructor template must be defined inline inside the class
4116 // definition, as Microsoft Visual C++ does not recognize the
4117 // definition as matching this signature when placed out-of-line.
4118 }
4119
4120 template <size_t t_INDEX,
4121 class INIT_LIST_TYPE,
4122 class... t_ARGS,
4123 class = typename bsl::enable_if_t<
4124 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
4125 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
4126 std::initializer_list<INIT_LIST_TYPE>&,
4127 t_ARGS...>::value> >
4128 explicit variant(bsl::allocator_arg_t,
4129 allocator_type allocator,
4131 std::initializer_list<INIT_LIST_TYPE> il,
4132 t_ARGS&&... args)
4133 // Create a 'variant' object holding the alternative with index
4134 // (template parameter) 't_INDEX', direct-initialized from the specified
4135 // 'il' and 'args'. If this 'variant' is allocator-aware, the
4136 // specified 'allocator' is used to supply memory. This constructor
4137 // participates in overload resolution only if 't_INDEX' is a valid
4138 // alternative index and the designated alternative is constructible
4139 // from 'il' and 'args'.
4140 : Variant_Base(bsl::allocator_arg_t{},
4141 allocator,
4142 bsl::in_place_index_t<t_INDEX>(),
4143 il,
4144 std::forward<t_ARGS>(args)...)
4145 {
4146 // This constructor template must be defined inline inside the class
4147 // definition, as Microsoft Visual C++ does not recognize the
4148 // definition as matching this signature when placed out-of-line.
4149 }
4150
4151#else // BSL_VARIANT_FULL_IMPLEMENTATION
4152
4153 variant();
4154 // Create a 'variant' object holding the 0th alternative, which is
4155 // value-initialized. If this 'variant' is allocator-aware, the
4156 // currently installed default allocator is used to supply memory.
4157
4158 variant(const variant& original);
4159 // Create a 'variant' object holding the same alternative (if any) as
4160 // the specified 'original' object. If this 'variant' is
4161 // allocator-aware, the currently installed default allocator is used
4162 // to supply memory. If the 'original' object is not valueless by
4163 // exception', the contained value is copy-constructed from the
4164 // contained value of 'original'. All alternatives shall be copy
4165 // constructible.
4166
4167 variant(BloombergLP::bslmf::MovableRef<variant> original);
4168 // Create a 'variant' object holding the same alternative (if any) held
4169 // by the specified 'original'. If this 'variant' is allocator-aware,
4170 // the allocator of 'original' is used to supply memory. If 'original'
4171 // is not valueless by exception, the contained value is
4172 // move-constructed from the contained value of 'original'. All
4173 // alternatives shall be move constructible.
4174
4175 template <class t_TYPE>
4176 variant(const t_TYPE& value,
4178 // Create a 'variant' object whose contained value is copy or move
4179 // constructed from the specified 'value'. If (template parameter)
4180 // 't_TYPE' is 'bslmf::MovableRef<T>', then the selected alternative is
4181 // the one whose type is the same as 'T' (modulo cv-qualification);
4182 // otherwise, the selected alternative is the one that is the same as
4183 // 't_TYPE' (modulo cv-qualification). This constructor participates
4184 // in overload resolution only if there is a unique such alternative.
4185 // If this 'variant' is allocator-aware, the current installed default
4186 // allocator is used to supply memory.
4187
4188 template <class t_TYPE>
4191 // Create a 'variant' object holding a contained value of type
4192 // (template parameter) 't_TYPE', which is value-initialized. If this
4193 // 'variant' is allocator-aware, the currently installed default
4194 // allocator is used to supply memory. This constructor participates
4195 // in overload resolutionly if 't_TYPE' designates a unique
4196 // alternative.
4197
4198 template <class t_TYPE, class t_ARG_01>
4200 const t_ARG_01& arg_01,
4202
4203 template <class t_TYPE, class t_ARG_01, class t_ARG_02>
4205 const t_ARG_01& arg_01,
4206 const t_ARG_02& arg_02,
4208
4209 template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
4211 const t_ARG_01& arg_01,
4212 const t_ARG_02& arg_02,
4213 const t_ARG_03& arg_03,
4215
4216 template <class t_TYPE,
4217 class t_ARG_01,
4218 class t_ARG_02,
4219 class t_ARG_03,
4220 class t_ARG_04>
4222 const t_ARG_01& arg_01,
4223 const t_ARG_02& arg_02,
4224 const t_ARG_03& arg_03,
4225 const t_ARG_04& arg_04,
4227
4228 template <class t_TYPE,
4229 class t_ARG_01,
4230 class t_ARG_02,
4231 class t_ARG_03,
4232 class t_ARG_04,
4233 class t_ARG_05>
4235 const t_ARG_01& arg_01,
4236 const t_ARG_02& arg_02,
4237 const t_ARG_03& arg_03,
4238 const t_ARG_04& arg_04,
4239 const t_ARG_05& arg_05,
4241
4242 template <class t_TYPE,
4243 class t_ARG_01,
4244 class t_ARG_02,
4245 class t_ARG_03,
4246 class t_ARG_04,
4247 class t_ARG_05,
4248 class t_ARG_06>
4250 const t_ARG_01& arg_01,
4251 const t_ARG_02& arg_02,
4252 const t_ARG_03& arg_03,
4253 const t_ARG_04& arg_04,
4254 const t_ARG_05& arg_05,
4255 const t_ARG_06& arg_06,
4257
4258 template <class t_TYPE,
4259 class t_ARG_01,
4260 class t_ARG_02,
4261 class t_ARG_03,
4262 class t_ARG_04,
4263 class t_ARG_05,
4264 class t_ARG_06,
4265 class t_ARG_07>
4267 const t_ARG_01& arg_01,
4268 const t_ARG_02& arg_02,
4269 const t_ARG_03& arg_03,
4270 const t_ARG_04& arg_04,
4271 const t_ARG_05& arg_05,
4272 const t_ARG_06& arg_06,
4273 const t_ARG_07& arg_07,
4275
4276 template <class t_TYPE,
4277 class t_ARG_01,
4278 class t_ARG_02,
4279 class t_ARG_03,
4280 class t_ARG_04,
4281 class t_ARG_05,
4282 class t_ARG_06,
4283 class t_ARG_07,
4284 class t_ARG_08>
4286 const t_ARG_01& arg_01,
4287 const t_ARG_02& arg_02,
4288 const t_ARG_03& arg_03,
4289 const t_ARG_04& arg_04,
4290 const t_ARG_05& arg_05,
4291 const t_ARG_06& arg_06,
4292 const t_ARG_07& arg_07,
4293 const t_ARG_08& arg_08,
4295
4296 template <class t_TYPE,
4297 class t_ARG_01,
4298 class t_ARG_02,
4299 class t_ARG_03,
4300 class t_ARG_04,
4301 class t_ARG_05,
4302 class t_ARG_06,
4303 class t_ARG_07,
4304 class t_ARG_08,
4305 class t_ARG_09>
4307 const t_ARG_01& arg_01,
4308 const t_ARG_02& arg_02,
4309 const t_ARG_03& arg_03,
4310 const t_ARG_04& arg_04,
4311 const t_ARG_05& arg_05,
4312 const t_ARG_06& arg_06,
4313 const t_ARG_07& arg_07,
4314 const t_ARG_08& arg_08,
4315 const t_ARG_09& arg_09,
4317
4318 template <class t_TYPE,
4319 class t_ARG_01,
4320 class t_ARG_02,
4321 class t_ARG_03,
4322 class t_ARG_04,
4323 class t_ARG_05,
4324 class t_ARG_06,
4325 class t_ARG_07,
4326 class t_ARG_08,
4327 class t_ARG_09,
4328 class t_ARG_10>
4330 const t_ARG_01& arg_01,
4331 const t_ARG_02& arg_02,
4332 const t_ARG_03& arg_03,
4333 const t_ARG_04& arg_04,
4334 const t_ARG_05& arg_05,
4335 const t_ARG_06& arg_06,
4336 const t_ARG_07& arg_07,
4337 const t_ARG_08& arg_08,
4338 const t_ARG_09& arg_09,
4339 const t_ARG_10& arg_10,
4341 // Create a 'variant' object holding a contained value of type
4342 // (template parameter) 't_TYPE', which is direct-initialized from the
4343 // specified 'arg'. If this 'variant' is allocator-aware, the
4344 // currently installed default allocator is used to supply memory.
4345 // This constructor participates in overload resolution only if
4346 // 't_TYPE' designates a unique alternative.
4347
4348 template <size_t t_INDEX>
4350 // Create a 'variant' object holding the alternative with index
4351 // (template parameter) 't_INDEX', which is value-initialized. If this
4352 // 'variant' is allocator-aware, the currently installed default
4353 // allocator is used to supply memory. 't_INDEX' shall be a valid
4354 // alternative index.
4355
4356 template <size_t t_INDEX, class t_ARG_01>
4358
4359 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
4361 const t_ARG_01& arg_01,
4362 const t_ARG_02& arg_02);
4363
4364 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
4366 const t_ARG_01& arg_01,
4367 const t_ARG_02& arg_02,
4368 const t_ARG_03& arg_03);
4369
4370 template <size_t t_INDEX,
4371 class t_ARG_01,
4372 class t_ARG_02,
4373 class t_ARG_03,
4374 class t_ARG_04>
4376 const t_ARG_01& arg_01,
4377 const t_ARG_02& arg_02,
4378 const t_ARG_03& arg_03,
4379 const t_ARG_04& arg_04);
4380
4381 template <size_t t_INDEX,
4382 class t_ARG_01,
4383 class t_ARG_02,
4384 class t_ARG_03,
4385 class t_ARG_04,
4386 class t_ARG_05>
4388 const t_ARG_01& arg_01,
4389 const t_ARG_02& arg_02,
4390 const t_ARG_03& arg_03,
4391 const t_ARG_04& arg_04,
4392 const t_ARG_05& arg_05);
4393
4394 template <size_t t_INDEX,
4395 class t_ARG_01,
4396 class t_ARG_02,
4397 class t_ARG_03,
4398 class t_ARG_04,
4399 class t_ARG_05,
4400 class t_ARG_06>
4402 const t_ARG_01& arg_01,
4403 const t_ARG_02& arg_02,
4404 const t_ARG_03& arg_03,
4405 const t_ARG_04& arg_04,
4406 const t_ARG_05& arg_05,
4407 const t_ARG_06& arg_06);
4408
4409 template <size_t t_INDEX,
4410 class t_ARG_01,
4411 class t_ARG_02,
4412 class t_ARG_03,
4413 class t_ARG_04,
4414 class t_ARG_05,
4415 class t_ARG_06,
4416 class t_ARG_07>
4418 const t_ARG_01& arg_01,
4419 const t_ARG_02& arg_02,
4420 const t_ARG_03& arg_03,
4421 const t_ARG_04& arg_04,
4422 const t_ARG_05& arg_05,
4423 const t_ARG_06& arg_06,
4424 const t_ARG_07& arg_07);
4425
4426 template <size_t t_INDEX,
4427 class t_ARG_01,
4428 class t_ARG_02,
4429 class t_ARG_03,
4430 class t_ARG_04,
4431 class t_ARG_05,
4432 class t_ARG_06,
4433 class t_ARG_07,
4434 class t_ARG_08>
4436 const t_ARG_01& arg_01,
4437 const t_ARG_02& arg_02,
4438 const t_ARG_03& arg_03,
4439 const t_ARG_04& arg_04,
4440 const t_ARG_05& arg_05,
4441 const t_ARG_06& arg_06,
4442 const t_ARG_07& arg_07,
4443 const t_ARG_08& arg_08);
4444
4445 template <size_t t_INDEX,
4446 class t_ARG_01,
4447 class t_ARG_02,
4448 class t_ARG_03,
4449 class t_ARG_04,
4450 class t_ARG_05,
4451 class t_ARG_06,
4452 class t_ARG_07,
4453 class t_ARG_08,
4454 class t_ARG_09>
4456 const t_ARG_01& arg_01,
4457 const t_ARG_02& arg_02,
4458 const t_ARG_03& arg_03,
4459 const t_ARG_04& arg_04,
4460 const t_ARG_05& arg_05,
4461 const t_ARG_06& arg_06,
4462 const t_ARG_07& arg_07,
4463 const t_ARG_08& arg_08,
4464 const t_ARG_09& arg_09);
4465
4466 template <size_t t_INDEX,
4467 class t_ARG_01,
4468 class t_ARG_02,
4469 class t_ARG_03,
4470 class t_ARG_04,
4471 class t_ARG_05,
4472 class t_ARG_06,
4473 class t_ARG_07,
4474 class t_ARG_08,
4475 class t_ARG_09,
4476 class t_ARG_10>
4478 const t_ARG_01& arg_01,
4479 const t_ARG_02& arg_02,
4480 const t_ARG_03& arg_03,
4481 const t_ARG_04& arg_04,
4482 const t_ARG_05& arg_05,
4483 const t_ARG_06& arg_06,
4484 const t_ARG_07& arg_07,
4485 const t_ARG_08& arg_08,
4486 const t_ARG_09& arg_09,
4487 const t_ARG_10& arg_10);
4488 // Create a 'variant' object holding the alternative with index
4489 // (template parameter) 't_INDEX', which is direct-initialized from the
4490 // specified 'arg'. If this 'variant' is allocator-aware, the
4491 // currently installed default allocator is used to supply memory.
4492 // 't_INDEX' shall be a valid alternative index.
4493
4494 // allocator-extended constructors
4495 variant(bsl::allocator_arg_t, allocator_type allocator);
4496 // Create a 'variant' object holding the 0th alternative, which is
4497 // value-initialized. If this 'variant' is allocator-aware, the
4498 // specified 'allocator' is used to supply memory.
4499
4500 variant(bsl::allocator_arg_t,
4502 const variant& original);
4503 variant(bsl::allocator_arg_t,
4505 BloombergLP::bslmf::MovableRef<variant> original);
4506 // Create a 'variant' object holding the same alternative as the
4507 // specified 'original' object. If this 'variant' is allocator-aware,
4508 // the specified 'allocator' is used to supply memory. If the
4509 // 'original' object is not valueless by exception, the contained value
4510 // is copy/move constructed from the contained value of 'original'.
4511 // All alternatives shall be copy/move constructible.
4512
4513 template <class t_TYPE>
4515 bsl::allocator_arg_t,
4517 const t_TYPE& value,
4519 // Create a 'variant' object whose contained value is copy or move
4520 // constructed from the specified 'value'. If (template parameter)
4521 // 't_TYPE' is 'bslmf::MovableRef<T>', then the selected alternative is
4522 // the one whose type is the same as 'T' (modulo cv-qualification);
4523 // otherwise, the selected alternative is the one that is the same as
4524 // 't_TYPE' (modulo cv-qualification). This constructor participates
4525 // in overload resolution only if there is a unique such alternative.
4526 // If this 'variant' is allocator-aware, the specified 'allocator' is
4527 // used to supply memory.
4528
4529 template <class t_TYPE>
4530 explicit variant(
4531 bsl::allocator_arg_t,
4535 // Create a 'variant' object holding a contained value of type
4536 // (template parameter) 't_TYPE', which is value-initialized. If this
4537 // 'variant' is allocator-aware, the currently installed default
4538 // allocator is used to supply memory. If this 'variant' is
4539 // allocator-aware, the specified 'allocator' is used to supply memory.
4540 // This constructor participates in overload resolution only if
4541 // 't_TYPE' designates a unique alternative.
4542
4543 template <class t_TYPE, class t_ARG_01>
4544 explicit variant(
4545 bsl::allocator_arg_t,
4548 const t_ARG_01& arg_01,
4550
4551 template <class t_TYPE, class t_ARG_01, class t_ARG_02>
4552 explicit variant(
4553 bsl::allocator_arg_t,
4556 const t_ARG_01& arg_01,
4557 const t_ARG_02& arg_02,
4559
4560 template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
4561 explicit variant(
4562 bsl::allocator_arg_t,
4565 const t_ARG_01& arg_01,
4566 const t_ARG_02& arg_02,
4567 const t_ARG_03& arg_03,
4569
4570 template <class t_TYPE,
4571 class t_ARG_01,
4572 class t_ARG_02,
4573 class t_ARG_03,
4574 class t_ARG_04>
4575 explicit variant(bsl::allocator_arg_t,
4578 const t_ARG_01& arg_01,
4579 const t_ARG_02& arg_02,
4580 const t_ARG_03& arg_03,
4581 const t_ARG_04& arg_04,
4583
4584 template <class t_TYPE,
4585 class t_ARG_01,
4586 class t_ARG_02,
4587 class t_ARG_03,
4588 class t_ARG_04,
4589 class t_ARG_05>
4590 explicit variant(bsl::allocator_arg_t,
4593 const t_ARG_01& arg_01,
4594 const t_ARG_02& arg_02,
4595 const t_ARG_03& arg_03,
4596 const t_ARG_04& arg_04,
4597 const t_ARG_05& arg_05,
4599
4600 template <class t_TYPE,
4601 class t_ARG_01,
4602 class t_ARG_02,
4603 class t_ARG_03,
4604 class t_ARG_04,
4605 class t_ARG_05,
4606 class t_ARG_06>
4607 explicit variant(bsl::allocator_arg_t,
4610 const t_ARG_01& arg_01,
4611 const t_ARG_02& arg_02,
4612 const t_ARG_03& arg_03,
4613 const t_ARG_04& arg_04,
4614 const t_ARG_05& arg_05,
4615 const t_ARG_06& arg_06,
4617
4618 template <class t_TYPE,
4619 class t_ARG_01,
4620 class t_ARG_02,
4621 class t_ARG_03,
4622 class t_ARG_04,
4623 class t_ARG_05,
4624 class t_ARG_06,
4625 class t_ARG_07>
4626 explicit variant(bsl::allocator_arg_t,
4629 const t_ARG_01& arg_01,
4630 const t_ARG_02& arg_02,
4631 const t_ARG_03& arg_03,
4632 const t_ARG_04& arg_04,
4633 const t_ARG_05& arg_05,
4634 const t_ARG_06& arg_06,
4635 const t_ARG_07& arg_07,
4637
4638 template <class t_TYPE,
4639 class t_ARG_01,
4640 class t_ARG_02,
4641 class t_ARG_03,
4642 class t_ARG_04,
4643 class t_ARG_05,
4644 class t_ARG_06,
4645 class t_ARG_07,
4646 class t_ARG_08>
4647 explicit variant(bsl::allocator_arg_t,
4650 const t_ARG_01& arg_01,
4651 const t_ARG_02& arg_02,
4652 const t_ARG_03& arg_03,
4653 const t_ARG_04& arg_04,
4654 const t_ARG_05& arg_05,
4655 const t_ARG_06& arg_06,
4656 const t_ARG_07& arg_07,
4657 const t_ARG_08& arg_08,
4659
4660 template <class t_TYPE,
4661 class t_ARG_01,
4662 class t_ARG_02,
4663 class t_ARG_03,
4664 class t_ARG_04,
4665 class t_ARG_05,
4666 class t_ARG_06,
4667 class t_ARG_07,
4668 class t_ARG_08,
4669 class t_ARG_09>
4670 explicit variant(bsl::allocator_arg_t,
4673 const t_ARG_01& arg_01,
4674 const t_ARG_02& arg_02,
4675 const t_ARG_03& arg_03,
4676 const t_ARG_04& arg_04,
4677 const t_ARG_05& arg_05,
4678 const t_ARG_06& arg_06,
4679 const t_ARG_07& arg_07,
4680 const t_ARG_08& arg_08,
4681 const t_ARG_09& arg_09,
4683
4684 template <class t_TYPE,
4685 class t_ARG_01,
4686 class t_ARG_02,
4687 class t_ARG_03,
4688 class t_ARG_04,
4689 class t_ARG_05,
4690 class t_ARG_06,
4691 class t_ARG_07,
4692 class t_ARG_08,
4693 class t_ARG_09,
4694 class t_ARG_10>
4695 explicit variant(bsl::allocator_arg_t,
4698 const t_ARG_01& arg_01,
4699 const t_ARG_02& arg_02,
4700 const t_ARG_03& arg_03,
4701 const t_ARG_04& arg_04,
4702 const t_ARG_05& arg_05,
4703 const t_ARG_06& arg_06,
4704 const t_ARG_07& arg_07,
4705 const t_ARG_08& arg_08,
4706 const t_ARG_09& arg_09,
4707 const t_ARG_10& arg_10,
4709 // Create a 'variant' object holding a contained value of type
4710 // (template parameter) 't_TYPE', which is direct-initialized from the
4711 // specified 'arg'. If this 'variant' is allocator-aware, the
4712 // specified 'allocator' is used to supply memory. This constructor
4713 // participates in overload resolution only if 't_TYPE' designates a
4714 // unique alternative.
4715
4716 template <size_t t_INDEX>
4717 explicit variant(bsl::allocator_arg_t,
4720 // Create a 'variant' object holding the alternative with index
4721 // (template parameter) 't_INDEX', which is value-initialized. If this
4722 // 'variant' is allocator-aware, the specified 'allocator' is used to
4723 // supply memory. 't_INDEX' shall be a valid alternative index.
4724
4725 template <size_t t_INDEX, class t_ARG_01>
4726 explicit variant(bsl::allocator_arg_t,
4729 const t_ARG_01& arg_01);
4730
4731 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
4732 explicit variant(bsl::allocator_arg_t,
4735 const t_ARG_01& arg_01,
4736 const t_ARG_02& arg_02);
4737
4738 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
4739 explicit variant(bsl::allocator_arg_t,
4742 const t_ARG_01& arg_01,
4743 const t_ARG_02& arg_02,
4744 const t_ARG_03& arg_03);
4745
4746 template <size_t t_INDEX,
4747 class t_ARG_01,
4748 class t_ARG_02,
4749 class t_ARG_03,
4750 class t_ARG_04>
4751 explicit variant(bsl::allocator_arg_t,
4754 const t_ARG_01& arg_01,
4755 const t_ARG_02& arg_02,
4756 const t_ARG_03& arg_03,
4757 const t_ARG_04& arg_04);
4758
4759 template <size_t t_INDEX,
4760 class t_ARG_01,
4761 class t_ARG_02,
4762 class t_ARG_03,
4763 class t_ARG_04,
4764 class t_ARG_05>
4765 explicit variant(bsl::allocator_arg_t,
4768 const t_ARG_01& arg_01,
4769 const t_ARG_02& arg_02,
4770 const t_ARG_03& arg_03,
4771 const t_ARG_04& arg_04,
4772 const t_ARG_05& arg_05);
4773
4774 template <size_t t_INDEX,
4775 class t_ARG_01,
4776 class t_ARG_02,
4777 class t_ARG_03,
4778 class t_ARG_04,
4779 class t_ARG_05,
4780 class t_ARG_06>
4781 explicit variant(bsl::allocator_arg_t,
4784 const t_ARG_01& arg_01,
4785 const t_ARG_02& arg_02,
4786 const t_ARG_03& arg_03,
4787 const t_ARG_04& arg_04,
4788 const t_ARG_05& arg_05,
4789 const t_ARG_06& arg_06);
4790
4791 template <size_t t_INDEX,
4792 class t_ARG_01,
4793 class t_ARG_02,
4794 class t_ARG_03,
4795 class t_ARG_04,
4796 class t_ARG_05,
4797 class t_ARG_06,
4798 class t_ARG_07>
4799 explicit variant(bsl::allocator_arg_t,
4802 const t_ARG_01& arg_01,
4803 const t_ARG_02& arg_02,
4804 const t_ARG_03& arg_03,
4805 const t_ARG_04& arg_04,
4806 const t_ARG_05& arg_05,
4807 const t_ARG_06& arg_06,
4808 const t_ARG_07& arg_07);
4809
4810 template <size_t t_INDEX,
4811 class t_ARG_01,
4812 class t_ARG_02,
4813 class t_ARG_03,
4814 class t_ARG_04,
4815 class t_ARG_05,
4816 class t_ARG_06,
4817 class t_ARG_07,
4818 class t_ARG_08>
4819 explicit variant(bsl::allocator_arg_t,
4822 const t_ARG_01& arg_01,
4823 const t_ARG_02& arg_02,
4824 const t_ARG_03& arg_03,
4825 const t_ARG_04& arg_04,
4826 const t_ARG_05& arg_05,
4827 const t_ARG_06& arg_06,
4828 const t_ARG_07& arg_07,
4829 const t_ARG_08& arg_08);
4830
4831 template <size_t t_INDEX,
4832 class t_ARG_01,
4833 class t_ARG_02,
4834 class t_ARG_03,
4835 class t_ARG_04,
4836 class t_ARG_05,
4837 class t_ARG_06,
4838 class t_ARG_07,
4839 class t_ARG_08,
4840 class t_ARG_09>
4841 explicit variant(bsl::allocator_arg_t,
4844 const t_ARG_01& arg_01,
4845 const t_ARG_02& arg_02,
4846 const t_ARG_03& arg_03,
4847 const t_ARG_04& arg_04,
4848 const t_ARG_05& arg_05,
4849 const t_ARG_06& arg_06,
4850 const t_ARG_07& arg_07,
4851 const t_ARG_08& arg_08,
4852 const t_ARG_09& arg_09);
4853
4854 template <size_t t_INDEX,
4855 class t_ARG_01,
4856 class t_ARG_02,
4857 class t_ARG_03,
4858 class t_ARG_04,
4859 class t_ARG_05,
4860 class t_ARG_06,
4861 class t_ARG_07,
4862 class t_ARG_08,
4863 class t_ARG_09,
4864 class t_ARG_10>
4865 explicit variant(bsl::allocator_arg_t,
4868 const t_ARG_01& arg_01,
4869 const t_ARG_02& arg_02,
4870 const t_ARG_03& arg_03,
4871 const t_ARG_04& arg_04,
4872 const t_ARG_05& arg_05,
4873 const t_ARG_06& arg_06,
4874 const t_ARG_07& arg_07,
4875 const t_ARG_08& arg_08,
4876 const t_ARG_09& arg_09,
4877 const t_ARG_10& arg_10);
4878 // Create a 'variant' object holding the alternative with index
4879 // (template parameter) 't_INDEX', which is direct-initialized from the
4880 // specified 'arg'. If this 'variant' is allocator-aware, the
4881 // specified 'allocator' is used to supply memory. 't_INDEX' shall be
4882 // a valid alternative index.
4883
4884#endif // BSL_VARIANT_FULL_IMPLEMENTATION
4885
4886 // 20.7.3.2, destructor
4887 ~variant() = default;
4888 // Destroy this object. The contained value (if any) is destroyed.
4889 // For simplicity of implementation, this method differs from the
4890 // standard in the following ways:
4891 //: o conditional triviality is not implemented
4892 //: o 'constexpr' is not implemented
4893
4894 // MANIPULATORS
4895 // 20.7.3.4, modifiers
4896#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
4897 /// Create an object of alternative (template parameter) `t_TYPE` in
4898 /// place, direct-initialized from the specified `args`, destroying any
4899 /// previously contained value first. Return a reference to the newly
4900 /// created `t_TYPE` object. If `t_TYPE` is allocator-aware, it uses
4901 /// the allocator specified upon the construction of this `variant`
4902 /// object to supply memory; passing an allocator argument to this
4903 /// method results in two allocators being passed to the alternative
4904 /// constructor, resulting in a likely compilation error. If the
4905 /// constructor of `t_TYPE` exits via an exception, this object may be
4906 /// left in the valueless by exception state. This method participates
4907 /// in overload resolution only if `t_TYPE` designates a unique
4908 /// alternative and is constructible from `args`. For simplicity of
4909 /// implementation, this method differs from the standard in the
4910 /// following way:
4911 /// * `constexpr` is not implemented
4912 template <class t_TYPE,
4913 class... t_ARGS,
4914 class = typename bsl::enable_if_t<
4916 std::is_constructible<t_TYPE, t_ARGS...>::value> >
4917 t_TYPE& emplace(t_ARGS&&... args)
4918 {
4919 // This function template must be defined inline inside the class
4920 // definition, as Microsoft Visual C++ does not recognize the
4921 // definition as matching this signature when placed out-of-line.
4922 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
4923 Variant_Base::template baseEmplace<index>(
4924 std::forward<t_ARGS>(args)...);
4925
4926 return bsl::get<index>(*this);
4927 }
4928
4929 /// Create an object of alternative (template parameter) `t_TYPE` in
4930 /// place, direct-initialized from the specified `il` and `args`,
4931 /// destroying any previously contained value first. Return a reference
4932 /// to the newly created `t_TYPE` object. If `t_TYPE` is
4933 /// allocator-aware, it uses the allocator specified upon the
4934 /// construction of this `variant` object to supply memory; passing an
4935 /// allocator argument to this method results in two allocators being
4936 /// passed to the alternative constructor, resulting in a likely
4937 /// compilation error. If the constructor of `t_TYPE` exits via an
4938 /// exception, this object may be left in the valueless by exception
4939 /// state. This method participates in overload resolution only if
4940 /// `t_TYPE` designates a unique alternative and is constructible from
4941 /// `il` and `args`. For simplicity of implementation, this method
4942 /// differs from the standard in the following way:
4943 /// * `constexpr` is not implemented
4944 template <class t_TYPE,
4945 class INIT_LIST_TYPE,
4946 class... t_ARGS,
4947 class = typename bsl::enable_if_t<
4949 std::is_constructible<t_TYPE,
4950 std::initializer_list<INIT_LIST_TYPE>&,
4951 t_ARGS...>::value> >
4952 t_TYPE& emplace(std::initializer_list<INIT_LIST_TYPE> il, t_ARGS&&... args)
4953 {
4954 // This function template must be defined inline inside the class
4955 // definition, as Microsoft Visual C++ does not recognize the
4956 // definition as matching this signature when placed out-of-line.
4957 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
4958 Variant_Base::template baseEmplace<index>(
4959 il, std::forward<t_ARGS>(args)...);
4960
4961 return bsl::get<index>(*this);
4962 }
4963
4964 /// Create the alternative with index (template parameter) `t_INDEX` in
4965 /// place, direct-initialized from the specified `args`, destroying any
4966 /// previously contained value first. Return a reference to the newly
4967 /// created contained value. If the alternative is allocator-aware, it
4968 /// uses the allocator specified upon the construction of this `variant`
4969 /// object to supply memory; passing an allocator argument to this
4970 /// method results in two allocators being passed to the alternative
4971 /// constructor, resulting in a likely compilation error. If the
4972 /// alternative constructor exits via an exception, this object may be
4973 /// left in the valueless by exception state. This method participates
4974 /// in overload resolution only if `t_INDEX` is a valid alternative
4975 /// index and the designated alternative is constructible from `args`.
4976 /// For simplicity of implementation, this method differs from the
4977 /// standard in the following way:
4978 /// * `constexpr` is not implemented
4979 template <size_t t_INDEX,
4980 class... t_ARGS,
4981 class = typename bsl::enable_if_t<
4982 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
4983 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
4984 t_ARGS...>::value> >
4985 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
4986 emplace(t_ARGS&&... args)
4987 {
4988 // This function template must be defined inline inside the class
4989 // definition, as Microsoft Visual C++ does not recognize the
4990 // definition as matching this signature when placed out-of-line.
4991 Variant_Base::template baseEmplace<t_INDEX>(
4992 std::forward<t_ARGS>(args)...);
4993
4994 return bsl::get<t_INDEX>(*this);
4995 }
4996
4997 /// Create the alternative with index (template parameter) `t_INDEX` in
4998 /// place, direct-initialized from the specified `il` and args',
4999 /// destroying any previously contained value first. Return a reference
5000 /// to the newly created contained value. If the alternative is
5001 /// allocator-aware, it uses the allocator specified upon the
5002 /// construction of this `variant` object to supply memory; passing an
5003 /// allocator argument to this method results in two allocators being
5004 /// passed to the alternative constructor, resulting in a likely
5005 /// compilation error. If the alternative constructor exits via an
5006 /// exception, this object may be left in the valueless by exception
5007 /// state. This method participates in overload resolution only if
5008 /// `t_INDEX` is a valid alternative index and the designated
5009 /// alternative is constructible from `il` and `args`. For simplicity
5010 /// of implementation, this method differs from the standard in the
5011 /// following way:
5012 /// * `constexpr` is not implemented
5013 template <size_t t_INDEX,
5014 class INIT_LIST_TYPE,
5015 class... t_ARGS,
5016 class = typename bsl::enable_if_t<
5017 (t_INDEX < 1 + sizeof...(t_TAIL)) &&
5018 std::is_constructible<BSLSTL_VARIANT_TYPE_AT_INDEX(t_INDEX),
5019 std::initializer_list<INIT_LIST_TYPE>&,
5020 t_ARGS...>::value> >
5021 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5022 emplace(std::initializer_list<INIT_LIST_TYPE> il, t_ARGS&&... args)
5023 {
5024 // This function template must be defined inline inside the class
5025 // definition, as Microsoft Visual C++ does not recognize the
5026 // definition as matching this signature when placed out-of-line.
5027 Variant_Base::template baseEmplace<t_INDEX>(
5028 il, std::forward<t_ARGS>(args)...);
5029
5030 return bsl::get<t_INDEX>(*this);
5031 }
5032
5033#else // BSL_VARIANT_FULL_IMPLEMENTATION
5034
5035 template <class t_TYPE>
5036 typename bsl::enable_if<
5037 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5038 t_TYPE&>::type
5039 emplace();
5040 // Create an object of alternative (template parameter) 't_TYPE' in
5041 // place, which is value-initialized; any previously contained value is
5042 // destroyed first. Return a reference to the newly created 't_TYPE'
5043 // object. If 't_TYPE' is allocator-aware, it uses the allocator
5044 // specified upon the construction of this 'variant' object to supply
5045 // memory; passing an allocator argument to this method results in two
5046 // allocators being passed to the alternative constructor, resulting in
5047 // a likely compilation error. Note that if the constructor of
5048 // 't_TYPE' exits via an exception, this object is left in a valueless
5049 // by exception state. This function participates in overload
5050 // resolution only if 't_TYPE' is a unique alternative.
5051
5052 template <class t_TYPE, class t_ARG_01>
5053 typename bsl::enable_if<
5054 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5055 t_TYPE&>::type
5056 emplace(const t_ARG_01& arg_01);
5057
5058 template <class t_TYPE, class t_ARG_01, class t_ARG_02>
5059 typename bsl::enable_if<
5060 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5061 t_TYPE&>::type
5062 emplace(const t_ARG_01& arg_01, const t_ARG_02& arg_02);
5063
5064 template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
5065 typename bsl::enable_if<
5066 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5067 t_TYPE&>::type
5068 emplace(const t_ARG_01& arg_01,
5069 const t_ARG_02& arg_02,
5070 const t_ARG_03& arg_03);
5071
5072 template <class t_TYPE,
5073 class t_ARG_01,
5074 class t_ARG_02,
5075 class t_ARG_03,
5076 class t_ARG_04>
5077 typename bsl::enable_if<
5078 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5079 t_TYPE&>::type
5080 emplace(const t_ARG_01& arg_01,
5081 const t_ARG_02& arg_02,
5082 const t_ARG_03& arg_03,
5083 const t_ARG_04& arg_04);
5084
5085 template <class t_TYPE,
5086 class t_ARG_01,
5087 class t_ARG_02,
5088 class t_ARG_03,
5089 class t_ARG_04,
5090 class t_ARG_05>
5091 typename bsl::enable_if<
5092 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5093 t_TYPE&>::type
5094 emplace(const t_ARG_01& arg_01,
5095 const t_ARG_02& arg_02,
5096 const t_ARG_03& arg_03,
5097 const t_ARG_04& arg_04,
5098 const t_ARG_05& arg_05);
5099
5100 template <class t_TYPE,
5101 class t_ARG_01,
5102 class t_ARG_02,
5103 class t_ARG_03,
5104 class t_ARG_04,
5105 class t_ARG_05,
5106 class t_ARG_06>
5107 typename bsl::enable_if<
5108 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5109 t_TYPE&>::type
5110 emplace(const t_ARG_01& arg_01,
5111 const t_ARG_02& arg_02,
5112 const t_ARG_03& arg_03,
5113 const t_ARG_04& arg_04,
5114 const t_ARG_05& arg_05,
5115 const t_ARG_06& arg_06);
5116
5117 template <class t_TYPE,
5118 class t_ARG_01,
5119 class t_ARG_02,
5120 class t_ARG_03,
5121 class t_ARG_04,
5122 class t_ARG_05,
5123 class t_ARG_06,
5124 class t_ARG_07>
5125 typename bsl::enable_if<
5126 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5127 t_TYPE&>::type
5128 emplace(const t_ARG_01& arg_01,
5129 const t_ARG_02& arg_02,
5130 const t_ARG_03& arg_03,
5131 const t_ARG_04& arg_04,
5132 const t_ARG_05& arg_05,
5133 const t_ARG_06& arg_06,
5134 const t_ARG_07& arg_07);
5135
5136 template <class t_TYPE,
5137 class t_ARG_01,
5138 class t_ARG_02,
5139 class t_ARG_03,
5140 class t_ARG_04,
5141 class t_ARG_05,
5142 class t_ARG_06,
5143 class t_ARG_07,
5144 class t_ARG_08>
5145 typename bsl::enable_if<
5146 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5147 t_TYPE&>::type
5148 emplace(const t_ARG_01& arg_01,
5149 const t_ARG_02& arg_02,
5150 const t_ARG_03& arg_03,
5151 const t_ARG_04& arg_04,
5152 const t_ARG_05& arg_05,
5153 const t_ARG_06& arg_06,
5154 const t_ARG_07& arg_07,
5155 const t_ARG_08& arg_08);
5156
5157 template <class t_TYPE,
5158 class t_ARG_01,
5159 class t_ARG_02,
5160 class t_ARG_03,
5161 class t_ARG_04,
5162 class t_ARG_05,
5163 class t_ARG_06,
5164 class t_ARG_07,
5165 class t_ARG_08,
5166 class t_ARG_09>
5167 typename bsl::enable_if<
5168 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5169 t_TYPE&>::type
5170 emplace(const t_ARG_01& arg_01,
5171 const t_ARG_02& arg_02,
5172 const t_ARG_03& arg_03,
5173 const t_ARG_04& arg_04,
5174 const t_ARG_05& arg_05,
5175 const t_ARG_06& arg_06,
5176 const t_ARG_07& arg_07,
5177 const t_ARG_08& arg_08,
5178 const t_ARG_09& arg_09);
5179
5180 template <class t_TYPE,
5181 class t_ARG_01,
5182 class t_ARG_02,
5183 class t_ARG_03,
5184 class t_ARG_04,
5185 class t_ARG_05,
5186 class t_ARG_06,
5187 class t_ARG_07,
5188 class t_ARG_08,
5189 class t_ARG_09,
5190 class t_ARG_10>
5191 typename bsl::enable_if<
5192 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, variant>::value,
5193 t_TYPE&>::type
5194 emplace(const t_ARG_01& arg_01,
5195 const t_ARG_02& arg_02,
5196 const t_ARG_03& arg_03,
5197 const t_ARG_04& arg_04,
5198 const t_ARG_05& arg_05,
5199 const t_ARG_06& arg_06,
5200 const t_ARG_07& arg_07,
5201 const t_ARG_08& arg_08,
5202 const t_ARG_09& arg_09,
5203 const t_ARG_10& arg_10);
5204 // Create an object of alternative (template parameter) 't_TYPE' in
5205 // place, which is direct-initialized from 'arg'; any previously
5206 // contained value is destroyed first. Return a reference to the newly
5207 // created 't_TYPE' object. If 't_TYPE' is allocator-aware, it uses
5208 // the allocator specified upon the construction of this 'variant'
5209 // object to supply memory; passing an allocator argument to this
5210 // method results in two allocators being passed to the alternative
5211 // constructor, resulting in a likely compilation error. Note that if
5212 // the constructor of 't_TYPE' exits via an exception, this object is
5213 // left in a valueless by exception state. This function participates
5214 // in overload resolution only if 't_TYPE' is a unique alternative.
5215
5216 template <size_t t_INDEX>
5217 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5218 emplace();
5219 // Create the alternative with index (template parameter) 't_INDEX' in
5220 // place, which is value-initialized; any previously contained value is
5221 // destroyed first. Return a reference to the newly created contained
5222 // value. If the alternative is allocator-aware, it uses the allocator
5223 // specified upon the construction of this 'variant' object to supply
5224 // memory; passing an allocator argument to this method results in two
5225 // allocators being passed to the alternative constructor, resulting in
5226 // a likely compilation error. Note that if the alternative
5227 // constructor exits via an exception, this object is left in the
5228 // valueless by exception state. 't_INDEX' shall be a valid
5229 // alternative index.
5230
5231 template <size_t t_INDEX, class t_ARG_01>
5232 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5233 emplace(const t_ARG_01& arg_01);
5234
5235 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
5236 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5237 emplace(const t_ARG_01& arg_01, const t_ARG_02& arg_02);
5238
5239 template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
5240 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5241 emplace(const t_ARG_01& arg_01,
5242 const t_ARG_02& arg_02,
5243 const t_ARG_03& arg_03);
5244
5245 template <size_t t_INDEX,
5246 class t_ARG_01,
5247 class t_ARG_02,
5248 class t_ARG_03,
5249 class t_ARG_04>
5250 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5251 emplace(const t_ARG_01& arg_01,
5252 const t_ARG_02& arg_02,
5253 const t_ARG_03& arg_03,
5254 const t_ARG_04& arg_04);
5255
5256 template <size_t t_INDEX,
5257 class t_ARG_01,
5258 class t_ARG_02,
5259 class t_ARG_03,
5260 class t_ARG_04,
5261 class t_ARG_05>
5262 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5263 emplace(const t_ARG_01& arg_01,
5264 const t_ARG_02& arg_02,
5265 const t_ARG_03& arg_03,
5266 const t_ARG_04& arg_04,
5267 const t_ARG_05& arg_05);
5268
5269 template <size_t t_INDEX,
5270 class t_ARG_01,
5271 class t_ARG_02,
5272 class t_ARG_03,
5273 class t_ARG_04,
5274 class t_ARG_05,
5275 class t_ARG_06>
5276 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5277 emplace(const t_ARG_01& arg_01,
5278 const t_ARG_02& arg_02,
5279 const t_ARG_03& arg_03,
5280 const t_ARG_04& arg_04,
5281 const t_ARG_05& arg_05,
5282 const t_ARG_06& arg_06);
5283
5284 template <size_t t_INDEX,
5285 class t_ARG_01,
5286 class t_ARG_02,
5287 class t_ARG_03,
5288 class t_ARG_04,
5289 class t_ARG_05,
5290 class t_ARG_06,
5291 class t_ARG_07>
5292 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5293 emplace(const t_ARG_01& arg_01,
5294 const t_ARG_02& arg_02,
5295 const t_ARG_03& arg_03,
5296 const t_ARG_04& arg_04,
5297 const t_ARG_05& arg_05,
5298 const t_ARG_06& arg_06,
5299 const t_ARG_07& arg_07);
5300
5301 template <size_t t_INDEX,
5302 class t_ARG_01,
5303 class t_ARG_02,
5304 class t_ARG_03,
5305 class t_ARG_04,
5306 class t_ARG_05,
5307 class t_ARG_06,
5308 class t_ARG_07,
5309 class t_ARG_08>
5310 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5311 emplace(const t_ARG_01& arg_01,
5312 const t_ARG_02& arg_02,
5313 const t_ARG_03& arg_03,
5314 const t_ARG_04& arg_04,
5315 const t_ARG_05& arg_05,
5316 const t_ARG_06& arg_06,
5317 const t_ARG_07& arg_07,
5318 const t_ARG_08& arg_08);
5319
5320 template <size_t t_INDEX,
5321 class t_ARG_01,
5322 class t_ARG_02,
5323 class t_ARG_03,
5324 class t_ARG_04,
5325 class t_ARG_05,
5326 class t_ARG_06,
5327 class t_ARG_07,
5328 class t_ARG_08,
5329 class t_ARG_09>
5330 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5331 emplace(const t_ARG_01& arg_01,
5332 const t_ARG_02& arg_02,
5333 const t_ARG_03& arg_03,
5334 const t_ARG_04& arg_04,
5335 const t_ARG_05& arg_05,
5336 const t_ARG_06& arg_06,
5337 const t_ARG_07& arg_07,
5338 const t_ARG_08& arg_08,
5339 const t_ARG_09& arg_09);
5340
5341 template <size_t t_INDEX,
5342 class t_ARG_01,
5343 class t_ARG_02,
5344 class t_ARG_03,
5345 class t_ARG_04,
5346 class t_ARG_05,
5347 class t_ARG_06,
5348 class t_ARG_07,
5349 class t_ARG_08,
5350 class t_ARG_09,
5351 class t_ARG_10>
5352 typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
5353 emplace(const t_ARG_01& arg_01,
5354 const t_ARG_02& arg_02,
5355 const t_ARG_03& arg_03,
5356 const t_ARG_04& arg_04,
5357 const t_ARG_05& arg_05,
5358 const t_ARG_06& arg_06,
5359 const t_ARG_07& arg_07,
5360 const t_ARG_08& arg_08,
5361 const t_ARG_09& arg_09,
5362 const t_ARG_10& arg_10);
5363 // Create the alternative with index (template parameter) 't_INDEX' in
5364 // place, direct-initialized from the specified 'arg'; any previously
5365 // contained value is destroyed first. Return a reference to the newly
5366 // created contained value. If the alternative is allocator-aware, it
5367 // uses the allocator specified upon the construction of this 'variant'
5368 // object to supply memory; passing an allocator argument to this
5369 // method results in two allocators being passed to the alternative
5370 // constructor, resulting in a likely compilation error. Note that if
5371 // the alternative constructor exits via an exception, this object is
5372 // left in the valueless by exception state. 't_INDEX' shall be a
5373 // valid alternative index.
5374#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5375
5376 // MANIPULATORS
5377 // 20.7.3.3, assignment
5378#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5379 variant& operator=(const variant& rhs) = default;
5380 // If 'rhs' holds the same alternative type as this object, copy assign the
5381 // contained value of 'rhs' to the contained value of this object.
5382 // Otherwise, destroy the contained value of this object (if any) and, if
5383 // 'rhs' holds a value, copy-construct the corresponding alternative of
5384 // this object from the contained value of 'rhs'. The allocators of this
5385 // object and 'rhs' both remain unchanged. This operator is deleted unless
5386 // all alternatives are copy constructible and copy assignable. If the
5387 // construction of a new alternative object exits via an exception, this
5388 // 'variant' object is left in a valueless by exception state. This is
5389 // different from the standard, which requires a temporary copy of 'rhs' to
5390 // be made if copy construction of the active alternative is not 'noexcept'
5391 // (see [variant.assign] for details). The standard behavior causes
5392 // unnecessary performance degradation in cases where the alternative
5393 // constructor does not throw, yet is not marked 'noexcept'; this behavior
5394 // is therefore not implemented in 'bsl::variant'. For simplicity of
5395 // implementation, this method also differs from the standard in the
5396 // following ways:
5397 //: o conditional triviality is not implemented
5398 //: o 'constexpr' is not implemented
5399 //: o 'noexcept' specification is not implemented
5400
5401 variant& operator=(variant&& rhs) = default;
5402 // If 'rhs' holds the same alternative type as this object, move assign the
5403 // contained value of 'rhs' to the contained value of this object.
5404 // Otherwise, destroy the contained value of this object (if any) and, if
5405 // 'rhs' holds a value, move-construct the corresponding alternative of
5406 // this object from the contained value of 'rhs'. The allocators of this
5407 // object and 'rhs' both remain unchanged. If the construction of a new
5408 // alternative object throws an exception, this 'variant' object is left in
5409 // a valueless by exception state. This operator participes in overload
5410 // resolution only if all alternatives are move constructible and mvoe
5411 // assignable. For simplicity of implementation, this method differs from
5412 // the standard in the following ways:
5413 //: o conditional triviality is not implemented
5414 //: o 'constexpr' is not implemented
5415 //: o 'noexcept' specification is not implemented
5416
5417 /// Assign to this object the specified `value`. The alternative
5418 /// corresponding to `value` is the best match among all alternatives
5419 /// for which the expression
5420 /// `t_ALT_TYPE x[] = {std::forward<t_TYPE>(value)};` is well formed,
5421 /// and this operator participates in overload resolution only if there
5422 /// is a unique best matching alternative and that alternative is both
5423 /// constructible and assignable from `value`. If this `variant`
5424 /// already holds the alternative corresponding to `value`, the
5425 /// contained value is assigned to from `value`; otherwise, any
5426 /// contained value is destroyed and the alternative corresponding to
5427 /// `value` is direct-initialized from `value`. Note that if the
5428 /// construction of a new alternative object exits via an exception,
5429 /// this `variant` object may be left in a valueless by exception state.
5430 /// This is different from the standard, which requires a temporary
5431 /// alternative object to be constructed if such construction is not
5432 /// `noexcept` (see [variant.assign] for details). The standard
5433 /// behavior causes unnecessary performance degradation in cases where
5434 /// the alternative constructor does not throw, yet is not marked
5435 /// `noexcept`; this behavior is therefore not implemented in
5436 /// `bsl::variant`. For simplicity of implementation, this method also
5437 /// differs from the standard in the following ways:
5438 /// * `constexpr` is not implemented
5439 /// * `noexcept` specification is not implemented
5440 template <class t_TYPE>
5441 typename bsl::enable_if<
5442 BloombergLP::bslstl::Variant_AssignsFromType<variant, t_TYPE>::value,
5443 variant&>::type
5444 operator=(t_TYPE&& value)
5445 {
5446 // This function template must be defined inline inside the class
5447 // definition, as Microsoft Visual C++ does not recognize the
5448 // definition as matching this signature when placed out-of-line.
5449 const size_t altIndex =
5451
5452 if (index() == altIndex) {
5453 bsl::get<altIndex>(*this) = std::forward<t_TYPE>(value);
5454 }
5455 else {
5456 // 'altIndex' can not be @ref variant_npos if
5457 // 'Variant_AssignsFromType' is satisfied
5458 Variant_Base::template baseEmplace<altIndex>(
5459 std::forward<t_TYPE>(value));
5460 }
5461
5462 return *this;
5463 }
5464#else // BSL_VARIANT_FULL_IMPLEMENTATION
5465 variant& operator=(const variant& rhs);
5466 // If 'rhs' holds the same alternative type as this object, copy assign
5467 // the contained value of 'rhs' to the contained value of this object.
5468 // Otherwise, destroy the contained value of this object (if any) and,
5469 // if 'rhs' holds a value, copy-construct the corresponding alternative
5470 // of this object from the contained value of 'rhs'. The allocators of
5471 // this object and 'rhs' both remain unchanged. If the construction of
5472 // a new alternative object exits via an exception, this 'variant'
5473 // object is left in a valueless by exception state. All alternatives
5474 // shall be copy constructible and copy assignable.
5475
5476 variant& operator=(BloombergLP::bslmf::MovableRef<variant> rhs);
5477 // If 'rhs' holds the same alternative type as this object, move assign
5478 // the contained value of 'rhs' to the contained value of this object.
5479 // Otherwise, destroy the contained value of this object (if any) and,
5480 // if 'rhs' holds a value, move-construct the corresponding alternative
5481 // of this object from the contained value of 'rhs'. The allocators of
5482 // this object and 'rhs' both remain unchanged. If the construction of
5483 // a new alternative object throws an exception, this 'variant' object
5484 // is left in a valueless by exception state. All alternatives shall
5485 // be move constructible and move assignable.
5486
5487 template <class t_TYPE>
5488 typename bsl::enable_if<
5489 BloombergLP::bslstl::Variant_AssignsFromType<variant, t_TYPE>::value,
5490 variant&>::type
5491 operator=(const t_TYPE& value);
5492 // Assign to this object the specified 'value'. If (template
5493 // parameter) 't_TYPE' is 'bslmf::MovableRef<T>', then the alternative
5494 // corresponding to 'value' is the one whose type is the same as 'T'
5495 // (modulo cv-qualification); otherwise, the selected alternative is
5496 // the one that is the same as 't_TYPE' (modulo cv-qualification).
5497 // This operator participates in overload resolution only if there is a
5498 // unique such alternative. If this 'variant' object already holds
5499 // that alternative, then the contained value is assigned from 'value';
5500 // otherwise, any contained value is destroyed and the selected
5501 // alternative is direct-initialized from 'value'. The selected
5502 // alternative shall be constructible and assignable from 'value'. If
5503 // the construction of a new alternative object exits via an exception,
5504 // this 'variant' object is left in the valueless by exception state.
5505
5506#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5507 // 20.7.3.6, swap
5508
5509 /// Efficiently exchange the value of this object with the value of the
5510 /// specified `other` object. This method provides the no-throw
5511 /// exception-safety guarantee if the two swapped objects contain the
5512 /// same alternative and if that alternative `t_TYPE` provides that
5513 /// guarantee. If `*this` and `other` do not have the same active
5514 /// alternative and this method exits via an exception, either or both
5515 /// `variant` objects may be left in a valueless state or with an
5516 /// contained value in a moved-from state. The behavior is undefined
5517 /// unless `*this` has the same allocator as `other`. All alternatives
5518 /// shall be move constructible and swappable. For simplicity of
5519 /// implementation, this method differs from the standard in the
5520 /// following ways:
5521 /// * `constexpr` is not implemented
5522 /// * `noexcept` specification is not implemented
5523 void swap(variant& other);
5524
5525 // ACCESSORS
5526#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5527 template <bool t_USES_BSLMA_ALLOC = BloombergLP::bslstl::
5528 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value,
5529 class = typename bsl::enable_if_t<t_USES_BSLMA_ALLOC> >
5530#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5532 // Return a copy of this object's allocator. At least one alternative of
5533 // this 'variant' object shall be allocator-aware; in C++03, due to
5534 // language limitations, this method can be called even if no alternative
5535 // is allocator-aware, but returns a non-allocator type in that case.
5536 {
5537 // This function template must be defined inline inside the class
5538 // definition, as Microsoft Visual C++ does not recognize the
5539 // definition as matching this signature when placed out-of-line.
5540 return allocator_type(Variant_Base::AllocBase::mechanism());
5541 }
5542
5543 // 20.7.3.5, value status
5544
5545 /// Return the index of the alternative currently managed by this
5546 /// `variant` object, or `bsl::variant_npos` if this object is valueless
5547 /// by exception. This method differs from the standard in the
5548 /// following way:
5549 /// * `constexpr` is not implemented This is because no constructors
5550 /// are currently constexpr and there is no way to test the constexpr
5551 /// property of this function.
5553
5554 /// Return `false` if there is an alternative object currently managed
5555 /// by this `variant` object, and `true` otherwise. A `variant` object
5556 /// can become valueless by exception if the creation of an alternative
5557 /// object exits via an exception, or if it is copied or assigned from
5558 /// another `variant` object that is valueless by exception. This
5559 /// method differs from the standard in the following way:
5560 /// * `constexpr` is not implemented This is because no constructors
5561 /// are currently constexpr and there is no way to test the constexpr
5562 /// property of this function.
5564};
5565
5566#endif
5567
5568} // close namespace bsl
5569
5570// ============================================================================
5571// INLINE DEFINITIONS
5572// ============================================================================
5573
5574
5575namespace bslstl {
5576
5577 // ---------------------
5578 // class Variant_ImpUtil
5579 // ---------------------
5580
5581template <class t_RET, class t_VARIANT_UNION>
5582t_RET& Variant_ImpUtil::getAlternative(
5584 t_VARIANT_UNION& variantUnion) BSLS_KEYWORD_NOEXCEPT
5585{
5586 return variantUnion.d_head.value();
5587}
5588
5589template <class t_RET, size_t t_INDEX, class t_VARIANT_UNION>
5590t_RET& Variant_ImpUtil::getAlternative(
5592 t_VARIANT_UNION& variantUnion) BSLS_KEYWORD_NOEXCEPT
5593{
5594 return getAlternative<t_RET>(bsl::in_place_index_t<t_INDEX - 1>(),
5595 variantUnion.d_tail);
5596}
5597
5598template <class t_RET, size_t t_INDEX, class t_VARIANT>
5599t_RET& Variant_ImpUtil::get(t_VARIANT& variant)
5600{
5601 if (variant.index() != t_INDEX) {
5602 BSLS_THROW(bsl::bad_variant_access());
5603 }
5604
5605 return getAlternative<t_RET>(bsl::in_place_index_t<t_INDEX>(),
5606 variant.d_union);
5607}
5608
5609template <class t_RET, size_t t_INDEX, class t_VARIANT>
5610t_RET& Variant_ImpUtil::get(const t_VARIANT& variant)
5611{
5612 if (variant.index() != t_INDEX) {
5613 BSLS_THROW(bsl::bad_variant_access());
5614 }
5615
5616 return getAlternative<t_RET>(bsl::in_place_index_t<t_INDEX>(),
5617 variant.d_union);
5618}
5619
5620#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5621template <class t_RET, class t_VISITOR, class t_VARIANT>
5622t_RET Variant_ImpUtil::visit(t_VISITOR&& visitor, t_VARIANT&& variant)
5623{
5624 static constexpr size_t varSize =
5626
5627 typedef typename Variant_VTable<
5628 t_RET,
5629 t_VISITOR&&,
5630 t_VARIANT&&,
5631 bslmf::MakeIntegerSequence<std::size_t, varSize> >::FuncPtr FuncPtr;
5632
5633 // Generate the table of all function pointers for 't_VISITOR' and
5634 // 't_VARIANT', then invoke the one corresponding to the active index.
5635 FuncPtr funcPtr =
5636 Variant_VTable<t_RET,
5637 t_VISITOR&&,
5638 t_VARIANT&&,
5639 bslmf::MakeIntegerSequence<std::size_t, varSize> >::
5640 s_map[variant.index()];
5641
5642 return (*funcPtr)(std::forward<t_VISITOR>(visitor),
5643 std::forward<t_VARIANT>(variant));
5644}
5645template <class t_RET, class t_VISITOR, class t_VARIANT>
5646t_RET Variant_ImpUtil::visitId(t_VISITOR&& visitor, t_VARIANT&& variant)
5647{
5648 static constexpr size_t varSize =
5650
5651 typedef typename Variant_VTableId<
5652 t_RET,
5653 t_VISITOR&&,
5654 t_VARIANT&&,
5655 bslmf::MakeIntegerSequence<std::size_t, varSize> >::FuncPtr FuncPtr;
5656
5657 FuncPtr funcPtr =
5658 Variant_VTableId<t_RET,
5659 t_VISITOR&&,
5660 t_VARIANT&&,
5661 bslmf::MakeIntegerSequence<std::size_t, varSize> >::
5662 s_mapId[variant.index()];
5663
5664 return (*funcPtr)(std::forward<t_VISITOR>(visitor),
5665 std::forward<t_VARIANT>(variant));
5666}
5667
5668#else
5669template <class t_RET, size_t t_INDEX, class t_VARIANT>
5670t_RET& Variant_ImpUtil::unsafeGet(t_VARIANT& variant)
5671{
5672 return getAlternative<t_RET>(bsl::in_place_index_t<t_INDEX>(),
5673 variant.d_union);
5674}
5675
5676template <class t_RET, size_t t_INDEX, class t_VARIANT>
5677t_RET& Variant_ImpUtil::unsafeGet(const t_VARIANT& variant)
5678{
5679 return getAlternative<t_RET>(bsl::in_place_index_t<t_INDEX>(),
5680 variant.d_union);
5681}
5682
5683template <class t_TYPE, class t_VARIANT>
5684t_TYPE& Variant_ImpUtil::unsafeGet(t_VARIANT& obj)
5685{
5686 return unsafeGet<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
5687 obj);
5688}
5689
5690template <class t_TYPE, class t_VARIANT>
5691const t_TYPE& Variant_ImpUtil::unsafeGet(const t_VARIANT& obj)
5692{
5693 return unsafeGet<const t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
5694 obj);
5695}
5696
5697template <class t_RET, class t_VISITOR, class t_VARIANT>
5698t_RET Variant_ImpUtil::visit(t_VISITOR& visitor, t_VARIANT& variant)
5699{
5700 typedef
5702
5703 // Generate the table of all function pointers for 't_VISITOR' and
5704 // 't_VARIANT', then invoke the one corresponding to the active index.
5705 FuncPtr funcPtr =
5707
5708 return (*funcPtr)(visitor, variant);
5709}
5710
5711template <class t_RET, class t_VISITOR, class t_VARIANT>
5712t_RET Variant_ImpUtil::visit(t_VISITOR& visitor, const t_VARIANT& variant)
5713{
5715 FuncPtr;
5716
5717 // Generate the table of all function pointers for 't_VISITOR' and
5718 // 't_VARIANT', then invoke the one corresponding to the active index.
5719 FuncPtr funcPtr =
5721 .index()];
5722
5723 return (*funcPtr)(visitor, variant);
5724}
5725
5726template <class t_RET, class t_VISITOR, class t_VARIANT>
5727t_RET Variant_ImpUtil::moveVisit(t_VISITOR& visitor, t_VARIANT& variant)
5728{
5729 typedef
5731
5732 // Generate the table of all function pointers for 't_VISITOR' and
5733 // 't_VARIANT', then invoke the one corresponding to the active index.
5734 FuncPtr funcPtr =
5736 .index()];
5737
5738 return (*funcPtr)(visitor, variant);
5739}
5740
5741// The visitation functions below are the same as the ones above except that
5742// the visitor is invoked with an additional argument of type
5743// 'bsl::in_place_index_t'. They are used internally for visitors that
5744// participate in the 'variant' implementation.
5745template <class t_RET, class t_VISITOR, class t_VARIANT>
5746t_RET Variant_ImpUtil::visitId(t_VISITOR& visitor, t_VARIANT& variant)
5747{
5748 typedef
5750
5751 FuncPtr funcPtr =
5753
5754 return (*funcPtr)(visitor, variant);
5755}
5756
5757template <class t_RET, class t_VISITOR, class t_VARIANT>
5758t_RET Variant_ImpUtil::visitId(t_VISITOR& visitor, const t_VARIANT& variant)
5759{
5761 FuncPtr;
5762
5764 mapId()[variant.index()];
5765
5766 return (*funcPtr)(visitor, variant);
5767}
5768
5769#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5770
5771#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5772 // ----------------------------------------------
5773 // class Variant_ImpUtil::ConstructFromStdVisitor
5774 // ----------------------------------------------
5775
5776template <class t_VARIANT, class t_STD_VARIANT>
5777Variant_ImpUtil::ConstructFromStdVisitor<t_VARIANT, t_STD_VARIANT>::
5778 ConstructFromStdVisitor(t_VARIANT& target, t_STD_VARIANT& original)
5779: d_target(target)
5780, d_original(original)
5781{
5782}
5783
5784template <class t_VARIANT, class t_STD_VARIANT>
5785template <size_t t_INDEX, class t_TYPE>
5786void
5787Variant_ImpUtil::ConstructFromStdVisitor<t_VARIANT, t_STD_VARIANT>::
5788 operator()(bsl::in_place_index_t<t_INDEX>, t_TYPE&) const
5789{
5790 // Implementation note: calling the correct overload of 'operator()' is
5791 // made possible only by the fact that we have set 'd_target.d_type' to
5792 // 'd_original.index()' prior to invoking the visitor. But we must now use
5793 // private access to 'd_target' to set the index to -1 before we call
5794 // 'baseEmplace' (otherwise, 'baseEmplace' would attempt to destroy the
5795 // alternative first before constructing a new one).
5796
5797 d_target.d_type = bsl::variant_npos;
5798 d_target.template baseEmplace<t_INDEX>(
5799 std::get<t_INDEX>(std::forward<t_STD_VARIANT>(d_original)));
5800}
5801#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5802
5803 // ------------------------
5804 // class Variant_NoSuchType
5805 // ------------------------
5806
5807// CREATORS
5808inline
5813
5814 // ---------------------
5815 // class Variant_DataImp
5816 // ---------------------
5817
5818#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5819// CREATORS
5820template <class t_TYPE>
5821template <class... t_ARGS>
5822inline
5824{
5825 BloombergLP::bslma::ConstructionUtil::construct(
5826 d_buffer.address(), std::forward<t_ARGS>(args)...);
5827}
5828#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5829
5830// MANIPULATORS
5831#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5832template <class t_TYPE>
5833inline
5835{
5836 return d_buffer.object();
5837}
5838
5839template <class t_TYPE>
5840inline
5842{
5843 return std::move(d_buffer.object());
5844}
5845#else // BSL_VARIANT_FULL_IMPLEMENTATION
5846template <class t_TYPE>
5847inline
5849{
5850 return d_buffer.object();
5851}
5852#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5853
5854// ACCESSORS
5855#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5856template <class t_TYPE>
5857inline
5859const&
5860{
5861 return d_buffer.object();
5862}
5863
5864template <class t_TYPE>
5865inline
5867const&&
5868{
5869 return std::move(d_buffer.object());
5870}
5871#else // BSL_VARIANT_FULL_IMPLEMENTATION
5872template <class t_TYPE>
5873inline
5875{
5876 return d_buffer.object();
5877}
5878#endif // BSL_VARIANT_FULL_IMPLEMENTATION
5879
5880/// This component-private function swaps the values of the specified `lhs`
5881/// and `rhs` when the type (template parameter) `t_VARIANT` is an
5882/// allocator-aware variant.
5883template <class t_VARIANT>
5884void variant_swapImpl(bsl::true_type, t_VARIANT& lhs, t_VARIANT& rhs)
5885{
5886 if (lhs.get_allocator() == rhs.get_allocator()) {
5887 lhs.swap(rhs);
5888 return; // RETURN
5889 }
5890
5891 t_VARIANT futureLhs(bsl::allocator_arg, lhs.get_allocator(), rhs);
5892 t_VARIANT futureRhs(bsl::allocator_arg, rhs.get_allocator(), lhs);
5893
5894 futureLhs.swap(lhs);
5895 futureRhs.swap(rhs);
5896}
5897
5898/// This component-private function swaps the values of the specified `lhs`
5899/// and `rhs` when the type (template parameter) `t_VARIANT` is a
5900/// non-allocator-aware variant.
5901template <class t_VARIANT>
5902void variant_swapImpl(bsl::false_type, t_VARIANT& lhs, t_VARIANT& rhs)
5903{
5904 lhs.swap(rhs);
5905}
5906
5907 // -------------------
5908 // struct Variant_Base
5909 // -------------------
5910
5911// CREATORS
5912#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
5913template <class t_HEAD, class... t_TAIL>
5914inline
5916: AllocBase()
5917, d_type(0)
5918, d_union(bsl::in_place_index_t<0>(), AllocBase::mechanism())
5919{
5920}
5921
5922template <class t_HEAD, class... t_TAIL>
5923inline
5924Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(const Variant_Base& original)
5925: AllocBase()
5926, d_type(bsl::variant_npos)
5927{
5928 if (original.d_type != bsl::variant_npos) {
5929 BloombergLP::bslstl::Variant_CopyConstructVisitor<Variant_Base>
5930 copyConstructor(this);
5932 void, copyConstructor, static_cast<const Variant&>(original));
5933 }
5934}
5935
5936template <class t_HEAD, class... t_TAIL>
5937inline
5938Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(Variant_Base&& original)
5939: AllocBase(original)
5940, d_type(bsl::variant_npos)
5941{
5942 if (original.d_type != bsl::variant_npos) {
5943 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
5944 moveConstructor(this);
5946 void, moveConstructor, static_cast<Variant&>(original));
5947 }
5948}
5949
5950#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5951template <class t_HEAD, class... t_TAIL>
5952Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(Variant_ConstructFromStdTag,
5953 size_t index)
5954: AllocBase()
5955, d_type(index)
5956{
5957}
5958#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
5959
5960template <class t_HEAD, class... t_TAIL>
5961inline
5962Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::allocator_arg_t,
5963 allocator_type allocator)
5964: AllocBase(allocator)
5965, d_type(0)
5966, d_union(bsl::in_place_index_t<0>(), AllocBase::mechanism())
5967{
5968}
5969
5970template <class t_HEAD, class... t_TAIL>
5971inline
5972Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::allocator_arg_t,
5973 allocator_type allocator,
5974 const Variant& original)
5975: AllocBase(allocator)
5976, d_type(bsl::variant_npos)
5977{
5978 if (original.index() != bsl::variant_npos) {
5979 BloombergLP::bslstl::Variant_CopyConstructVisitor<Variant_Base>
5980 copyConstructor(this);
5981 BSLSTL_VARIANT_VISITID(void, copyConstructor, original);
5982 }
5983}
5984
5985template <class t_HEAD, class... t_TAIL>
5986inline
5987Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::allocator_arg_t,
5988 allocator_type allocator,
5989 Variant&& original)
5990: AllocBase(allocator)
5991, d_type(bsl::variant_npos)
5992{
5993 if (original.index() != bsl::variant_npos) {
5994 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
5995 moveConstructor(this);
5996 BSLSTL_VARIANT_VISITID(void, moveConstructor, original);
5997 }
5998}
5999
6000#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
6001template <class t_HEAD, class... t_TAIL>
6002Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::allocator_arg_t,
6003 allocator_type allocator,
6004 Variant_ConstructFromStdTag,
6005 size_t index)
6006: AllocBase(allocator)
6007, d_type(index)
6008{
6009}
6010#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
6011
6012template <class t_HEAD, class... t_TAIL>
6013template <size_t t_INDEX, class... t_ARGS>
6014inline
6015Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::in_place_index_t<t_INDEX>,
6016 t_ARGS&&... args)
6017: d_type(t_INDEX)
6018, d_union(bsl::in_place_index_t<t_INDEX>(),
6019 AllocBase::mechanism(),
6020 std::forward<t_ARGS>(args)...)
6021{
6022}
6023
6024template <class t_HEAD, class... t_TAIL>
6025template <size_t t_INDEX, class... t_ARGS>
6026inline
6027Variant_Base<t_HEAD, t_TAIL...>::Variant_Base(bsl::allocator_arg_t,
6028 allocator_type allocator,
6030 t_ARGS&&... args)
6031: AllocBase(allocator)
6032, d_type(t_INDEX)
6033, d_union(bsl::in_place_index_t<t_INDEX>(),
6034 AllocBase::mechanism(),
6035 std::forward<t_ARGS>(args)...)
6036{
6037}
6038#else // BSL_VARIANT_FULL_IMPLEMENTATION
6039#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6040template <class t_HEAD, class... t_TAIL>
6041inline
6043: AllocBase()
6044, d_type(0)
6045{
6046 typedef typename bsl::remove_cv<t_HEAD>::type Alt_Type;
6047
6048 BloombergLP::bslma::ConstructionUtil::construct(
6049 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6050 AllocBase::mechanism());
6051}
6052
6053template <class t_HEAD, class... t_TAIL>
6054inline
6056: AllocBase()
6057, d_type(bsl::variant_npos)
6058{
6059 if (!original.valueless_by_exception()) {
6060 BloombergLP::bslstl::Variant_CopyConstructVisitor<Variant_Base>
6061 copyConstructor(this);
6062 BSLSTL_VARIANT_VISITID(void, copyConstructor, original);
6063 // In C++03, if there are nonunique alternatives,
6064 // 'BSLSTL_VARIANT_VISITID' will always use the first nonunique
6065 // alternative, which may result in the wrong 'd_type' being set.
6066 d_type = original.d_type;
6067 }
6068}
6069
6070template <class t_HEAD, class... t_TAIL>
6071inline
6073 BloombergLP::bslmf::MovableRef<Variant> original)
6074: AllocBase(MoveUtil::access(original))
6075, d_type(bsl::variant_npos)
6076{
6077 Variant& lvalue = original;
6078 if (!lvalue.valueless_by_exception()) {
6079 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
6080 moveConstructor(this);
6081 BSLSTL_VARIANT_VISITID(void, moveConstructor, lvalue);
6082 // In C++03, if there are nonunique alternatives,
6083 // 'BSLSTL_VARIANT_VISITID' will always use the first nonunique
6084 // alternative, which may result in the wrong 'd_type' being set.
6085 d_type = lvalue.d_type;
6086 }
6087}
6088
6089template <class t_HEAD, class... t_TAIL>
6090template <size_t t_INDEX>
6091inline
6093: AllocBase()
6094, d_type(t_INDEX)
6095{
6096 typedef typename bsl::remove_cv<
6098 Alt_Type;
6099
6100 BloombergLP::bslma::ConstructionUtil::construct(
6101 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6102 AllocBase::mechanism());
6103}
6104
6105template <class t_HEAD, class... t_TAIL>
6106template <size_t t_INDEX, class t_ARG_01>
6107inline
6110 const t_ARG_01& arg_01)
6111: AllocBase()
6112, d_type(t_INDEX)
6113{
6114 typedef typename bsl::remove_cv<
6116 Alt_Type;
6117
6118 BloombergLP::bslma::ConstructionUtil::construct(
6119 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6120 AllocBase::mechanism(),
6121 arg_01);
6122}
6123
6124template <class t_HEAD, class... t_TAIL>
6125template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
6126inline
6129 const t_ARG_01& arg_01,
6130 const t_ARG_02& arg_02)
6131: AllocBase()
6132, d_type(t_INDEX)
6133{
6134 typedef typename bsl::remove_cv<
6136 Alt_Type;
6137
6138 BloombergLP::bslma::ConstructionUtil::construct(
6139 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6140 AllocBase::mechanism(),
6141 arg_01,
6142 arg_02);
6143}
6144
6145template <class t_HEAD, class... t_TAIL>
6146template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
6147inline
6150 const t_ARG_01& arg_01,
6151 const t_ARG_02& arg_02,
6152 const t_ARG_03& arg_03)
6153: AllocBase()
6154, d_type(t_INDEX)
6155{
6156 typedef typename bsl::remove_cv<
6158 Alt_Type;
6159
6160 BloombergLP::bslma::ConstructionUtil::construct(
6161 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6162 AllocBase::mechanism(),
6163 arg_01,
6164 arg_02,
6165 arg_03);
6166}
6167
6168template <class t_HEAD, class... t_TAIL>
6169template <size_t t_INDEX,
6170 class t_ARG_01,
6171 class t_ARG_02,
6172 class t_ARG_03,
6173 class t_ARG_04>
6174inline
6176 const t_ARG_01& arg_01,
6177 const t_ARG_02& arg_02,
6178 const t_ARG_03& arg_03,
6179 const t_ARG_04& arg_04)
6180: AllocBase()
6181, d_type(t_INDEX)
6182{
6183 typedef typename bsl::remove_cv<
6185 Alt_Type;
6186
6187 BloombergLP::bslma::ConstructionUtil::construct(
6188 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6189 AllocBase::mechanism(),
6190 arg_01,
6191 arg_02,
6192 arg_03,
6193 arg_04);
6194}
6195
6196template <class t_HEAD, class... t_TAIL>
6197template <size_t t_INDEX,
6198 class t_ARG_01,
6199 class t_ARG_02,
6200 class t_ARG_03,
6201 class t_ARG_04,
6202 class t_ARG_05>
6203inline
6205 const t_ARG_01& arg_01,
6206 const t_ARG_02& arg_02,
6207 const t_ARG_03& arg_03,
6208 const t_ARG_04& arg_04,
6209 const t_ARG_05& arg_05)
6210: AllocBase()
6211, d_type(t_INDEX)
6212{
6213 typedef typename bsl::remove_cv<
6215 Alt_Type;
6216
6217 BloombergLP::bslma::ConstructionUtil::construct(
6218 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6219 AllocBase::mechanism(),
6220 arg_01,
6221 arg_02,
6222 arg_03,
6223 arg_04,
6224 arg_05);
6225}
6226
6227template <class t_HEAD, class... t_TAIL>
6228template <size_t t_INDEX,
6229 class t_ARG_01,
6230 class t_ARG_02,
6231 class t_ARG_03,
6232 class t_ARG_04,
6233 class t_ARG_05,
6234 class t_ARG_06>
6235inline
6237 const t_ARG_01& arg_01,
6238 const t_ARG_02& arg_02,
6239 const t_ARG_03& arg_03,
6240 const t_ARG_04& arg_04,
6241 const t_ARG_05& arg_05,
6242 const t_ARG_06& arg_06)
6243: AllocBase()
6244, d_type(t_INDEX)
6245{
6246 typedef typename bsl::remove_cv<
6248 Alt_Type;
6249
6250 BloombergLP::bslma::ConstructionUtil::construct(
6251 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6252 AllocBase::mechanism(),
6253 arg_01,
6254 arg_02,
6255 arg_03,
6256 arg_04,
6257 arg_05,
6258 arg_06);
6259}
6260
6261template <class t_HEAD, class... t_TAIL>
6262template <size_t t_INDEX,
6263 class t_ARG_01,
6264 class t_ARG_02,
6265 class t_ARG_03,
6266 class t_ARG_04,
6267 class t_ARG_05,
6268 class t_ARG_06,
6269 class t_ARG_07>
6270inline
6272 const t_ARG_01& arg_01,
6273 const t_ARG_02& arg_02,
6274 const t_ARG_03& arg_03,
6275 const t_ARG_04& arg_04,
6276 const t_ARG_05& arg_05,
6277 const t_ARG_06& arg_06,
6278 const t_ARG_07& arg_07)
6279: AllocBase()
6280, d_type(t_INDEX)
6281{
6282 typedef typename bsl::remove_cv<
6284 Alt_Type;
6285
6286 BloombergLP::bslma::ConstructionUtil::construct(
6287 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6288 AllocBase::mechanism(),
6289 arg_01,
6290 arg_02,
6291 arg_03,
6292 arg_04,
6293 arg_05,
6294 arg_06,
6295 arg_07);
6296}
6297
6298template <class t_HEAD, class... t_TAIL>
6299template <size_t t_INDEX,
6300 class t_ARG_01,
6301 class t_ARG_02,
6302 class t_ARG_03,
6303 class t_ARG_04,
6304 class t_ARG_05,
6305 class t_ARG_06,
6306 class t_ARG_07,
6307 class t_ARG_08>
6308inline
6310 const t_ARG_01& arg_01,
6311 const t_ARG_02& arg_02,
6312 const t_ARG_03& arg_03,
6313 const t_ARG_04& arg_04,
6314 const t_ARG_05& arg_05,
6315 const t_ARG_06& arg_06,
6316 const t_ARG_07& arg_07,
6317 const t_ARG_08& arg_08)
6318: AllocBase()
6319, d_type(t_INDEX)
6320{
6321 typedef typename bsl::remove_cv<
6323 Alt_Type;
6324
6325 BloombergLP::bslma::ConstructionUtil::construct(
6326 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6327 AllocBase::mechanism(),
6328 arg_01,
6329 arg_02,
6330 arg_03,
6331 arg_04,
6332 arg_05,
6333 arg_06,
6334 arg_07,
6335 arg_08);
6336}
6337
6338template <class t_HEAD, class... t_TAIL>
6339template <size_t t_INDEX,
6340 class t_ARG_01,
6341 class t_ARG_02,
6342 class t_ARG_03,
6343 class t_ARG_04,
6344 class t_ARG_05,
6345 class t_ARG_06,
6346 class t_ARG_07,
6347 class t_ARG_08,
6348 class t_ARG_09>
6349inline
6351 const t_ARG_01& arg_01,
6352 const t_ARG_02& arg_02,
6353 const t_ARG_03& arg_03,
6354 const t_ARG_04& arg_04,
6355 const t_ARG_05& arg_05,
6356 const t_ARG_06& arg_06,
6357 const t_ARG_07& arg_07,
6358 const t_ARG_08& arg_08,
6359 const t_ARG_09& arg_09)
6360: AllocBase()
6361, d_type(t_INDEX)
6362{
6363 typedef typename bsl::remove_cv<
6365 Alt_Type;
6366
6367 BloombergLP::bslma::ConstructionUtil::construct(
6368 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6369 AllocBase::mechanism(),
6370 arg_01,
6371 arg_02,
6372 arg_03,
6373 arg_04,
6374 arg_05,
6375 arg_06,
6376 arg_07,
6377 arg_08,
6378 arg_09);
6379}
6380
6381template <class t_HEAD, class... t_TAIL>
6382template <size_t t_INDEX,
6383 class t_ARG_01,
6384 class t_ARG_02,
6385 class t_ARG_03,
6386 class t_ARG_04,
6387 class t_ARG_05,
6388 class t_ARG_06,
6389 class t_ARG_07,
6390 class t_ARG_08,
6391 class t_ARG_09,
6392 class t_ARG_10>
6393inline
6395 const t_ARG_01& arg_01,
6396 const t_ARG_02& arg_02,
6397 const t_ARG_03& arg_03,
6398 const t_ARG_04& arg_04,
6399 const t_ARG_05& arg_05,
6400 const t_ARG_06& arg_06,
6401 const t_ARG_07& arg_07,
6402 const t_ARG_08& arg_08,
6403 const t_ARG_09& arg_09,
6404 const t_ARG_10& arg_10)
6405: AllocBase()
6406, d_type(t_INDEX)
6407{
6408 typedef typename bsl::remove_cv<
6410 Alt_Type;
6411
6412 BloombergLP::bslma::ConstructionUtil::construct(
6413 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6414 AllocBase::mechanism(),
6415 arg_01,
6416 arg_02,
6417 arg_03,
6418 arg_04,
6419 arg_05,
6420 arg_06,
6421 arg_07,
6422 arg_08,
6423 arg_09,
6424 arg_10);
6425}
6426
6427template <class t_HEAD, class... t_TAIL>
6428inline
6430 allocator_type allocator)
6431: AllocBase(allocator)
6432, d_type(0)
6433{
6434 BloombergLP::bslma::ConstructionUtil::construct(
6435 reinterpret_cast<t_HEAD *>(BSLS_UTIL_ADDRESSOF(d_union)),
6436 AllocBase::mechanism());
6437}
6438
6439template <class t_HEAD, class... t_TAIL>
6440inline
6442 allocator_type allocator,
6443 const Variant& original)
6444: AllocBase(allocator)
6445, d_type(bsl::variant_npos)
6446{
6447 if (!original.valueless_by_exception()) {
6448 BloombergLP::bslstl::Variant_CopyConstructVisitor<Variant_Base>
6449 copyConstructor(this);
6450 BSLSTL_VARIANT_VISITID(void, copyConstructor, original);
6451
6452 // In C++03, if there are nonunique alternatives,
6453 // 'BSLSTL_VARIANT_VISITID' will always use the first nonunique
6454 // alternative, which may result in the wrong 'd_type' being set.
6455 d_type = original.d_type;
6456 }
6457}
6458
6459template <class t_HEAD, class... t_TAIL>
6460inline
6462 bsl::allocator_arg_t,
6463 allocator_type allocator,
6464 BloombergLP::bslmf::MovableRef<Variant> original)
6465: AllocBase(allocator)
6466, d_type(bsl::variant_npos)
6467{
6468 Variant& lvalue = original;
6469 if (!lvalue.valueless_by_exception()) {
6470 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
6471 moveConstructor(this);
6472 BSLSTL_VARIANT_VISITID(void, moveConstructor, lvalue);
6473
6474 // In C++03, if there are nonunique alternatives,
6475 // 'BSLSTL_VARIANT_VISITID' will always use the first nonunique
6476 // alternative, which may result in the wrong 'd_type' being set.
6477 d_type = lvalue.d_type;
6478 }
6479}
6480
6481template <class t_HEAD, class... t_TAIL>
6482template <size_t t_INDEX>
6483inline
6485 bsl::allocator_arg_t,
6486 allocator_type allocator,
6488: AllocBase(allocator)
6489, d_type(t_INDEX)
6490{
6491 typedef typename bsl::remove_cv<
6493 Alt_Type;
6494
6495 BloombergLP::bslma::ConstructionUtil::construct(
6496 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6497 AllocBase::mechanism());
6498}
6499
6500template <class t_HEAD, class... t_TAIL>
6501template <size_t t_INDEX, class t_ARG_01>
6502inline
6504 bsl::allocator_arg_t,
6505 allocator_type allocator,
6507 const t_ARG_01& arg_01)
6508: AllocBase(allocator)
6509, d_type(t_INDEX)
6510{
6511 typedef typename bsl::remove_cv<
6513 Alt_Type;
6514
6515 BloombergLP::bslma::ConstructionUtil::construct(
6516 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6517 AllocBase::mechanism(),
6518 arg_01);
6519}
6520
6521template <class t_HEAD, class... t_TAIL>
6522template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
6523inline
6525 bsl::allocator_arg_t,
6526 allocator_type allocator,
6528 const t_ARG_01& arg_01,
6529 const t_ARG_02& arg_02)
6530: AllocBase(allocator)
6531, d_type(t_INDEX)
6532{
6533 typedef typename bsl::remove_cv<
6535 Alt_Type;
6536
6537 BloombergLP::bslma::ConstructionUtil::construct(
6538 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6539 AllocBase::mechanism(),
6540 arg_01,
6541 arg_02);
6542}
6543
6544template <class t_HEAD, class... t_TAIL>
6545template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
6546inline
6548 bsl::allocator_arg_t,
6549 allocator_type allocator,
6551 const t_ARG_01& arg_01,
6552 const t_ARG_02& arg_02,
6553 const t_ARG_03& arg_03)
6554: AllocBase(allocator)
6555, d_type(t_INDEX)
6556{
6557 typedef typename bsl::remove_cv<
6559 Alt_Type;
6560
6561 BloombergLP::bslma::ConstructionUtil::construct(
6562 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6563 AllocBase::mechanism(),
6564 arg_01,
6565 arg_02,
6566 arg_03);
6567}
6568
6569template <class t_HEAD, class... t_TAIL>
6570template <size_t t_INDEX,
6571 class t_ARG_01,
6572 class t_ARG_02,
6573 class t_ARG_03,
6574 class t_ARG_04>
6575inline
6577 allocator_type allocator,
6579 const t_ARG_01& arg_01,
6580 const t_ARG_02& arg_02,
6581 const t_ARG_03& arg_03,
6582 const t_ARG_04& arg_04)
6583: AllocBase(allocator)
6584, d_type(t_INDEX)
6585{
6586 typedef typename bsl::remove_cv<
6588 Alt_Type;
6589
6590 BloombergLP::bslma::ConstructionUtil::construct(
6591 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6592 AllocBase::mechanism(),
6593 arg_01,
6594 arg_02,
6595 arg_03,
6596 arg_04);
6597}
6598
6599template <class t_HEAD, class... t_TAIL>
6600template <size_t t_INDEX,
6601 class t_ARG_01,
6602 class t_ARG_02,
6603 class t_ARG_03,
6604 class t_ARG_04,
6605 class t_ARG_05>
6606inline
6608 allocator_type allocator,
6610 const t_ARG_01& arg_01,
6611 const t_ARG_02& arg_02,
6612 const t_ARG_03& arg_03,
6613 const t_ARG_04& arg_04,
6614 const t_ARG_05& arg_05)
6615: AllocBase(allocator)
6616, d_type(t_INDEX)
6617{
6618 typedef typename bsl::remove_cv<
6620 Alt_Type;
6621
6622 BloombergLP::bslma::ConstructionUtil::construct(
6623 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6624 AllocBase::mechanism(),
6625 arg_01,
6626 arg_02,
6627 arg_03,
6628 arg_04,
6629 arg_05);
6630}
6631
6632template <class t_HEAD, class... t_TAIL>
6633template <size_t t_INDEX,
6634 class t_ARG_01,
6635 class t_ARG_02,
6636 class t_ARG_03,
6637 class t_ARG_04,
6638 class t_ARG_05,
6639 class t_ARG_06>
6640inline
6642 allocator_type allocator,
6644 const t_ARG_01& arg_01,
6645 const t_ARG_02& arg_02,
6646 const t_ARG_03& arg_03,
6647 const t_ARG_04& arg_04,
6648 const t_ARG_05& arg_05,
6649 const t_ARG_06& arg_06)
6650: AllocBase(allocator)
6651, d_type(t_INDEX)
6652{
6653 typedef typename bsl::remove_cv<
6655 Alt_Type;
6656
6657 BloombergLP::bslma::ConstructionUtil::construct(
6658 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6659 AllocBase::mechanism(),
6660 arg_01,
6661 arg_02,
6662 arg_03,
6663 arg_04,
6664 arg_05,
6665 arg_06);
6666}
6667
6668template <class t_HEAD, class... t_TAIL>
6669template <size_t t_INDEX,
6670 class t_ARG_01,
6671 class t_ARG_02,
6672 class t_ARG_03,
6673 class t_ARG_04,
6674 class t_ARG_05,
6675 class t_ARG_06,
6676 class t_ARG_07>
6677inline
6679 allocator_type allocator,
6681 const t_ARG_01& arg_01,
6682 const t_ARG_02& arg_02,
6683 const t_ARG_03& arg_03,
6684 const t_ARG_04& arg_04,
6685 const t_ARG_05& arg_05,
6686 const t_ARG_06& arg_06,
6687 const t_ARG_07& arg_07)
6688: AllocBase(allocator)
6689, d_type(t_INDEX)
6690{
6691 typedef typename bsl::remove_cv<
6693 Alt_Type;
6694
6695 BloombergLP::bslma::ConstructionUtil::construct(
6696 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6697 AllocBase::mechanism(),
6698 arg_01,
6699 arg_02,
6700 arg_03,
6701 arg_04,
6702 arg_05,
6703 arg_06,
6704 arg_07);
6705}
6706
6707template <class t_HEAD, class... t_TAIL>
6708template <size_t t_INDEX,
6709 class t_ARG_01,
6710 class t_ARG_02,
6711 class t_ARG_03,
6712 class t_ARG_04,
6713 class t_ARG_05,
6714 class t_ARG_06,
6715 class t_ARG_07,
6716 class t_ARG_08>
6717inline
6719 allocator_type allocator,
6721 const t_ARG_01& arg_01,
6722 const t_ARG_02& arg_02,
6723 const t_ARG_03& arg_03,
6724 const t_ARG_04& arg_04,
6725 const t_ARG_05& arg_05,
6726 const t_ARG_06& arg_06,
6727 const t_ARG_07& arg_07,
6728 const t_ARG_08& arg_08)
6729: AllocBase(allocator)
6730, d_type(t_INDEX)
6731{
6732 typedef typename bsl::remove_cv<
6734 Alt_Type;
6735
6736 BloombergLP::bslma::ConstructionUtil::construct(
6737 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6738 AllocBase::mechanism(),
6739 arg_01,
6740 arg_02,
6741 arg_03,
6742 arg_04,
6743 arg_05,
6744 arg_06,
6745 arg_07,
6746 arg_08);
6747}
6748
6749template <class t_HEAD, class... t_TAIL>
6750template <size_t t_INDEX,
6751 class t_ARG_01,
6752 class t_ARG_02,
6753 class t_ARG_03,
6754 class t_ARG_04,
6755 class t_ARG_05,
6756 class t_ARG_06,
6757 class t_ARG_07,
6758 class t_ARG_08,
6759 class t_ARG_09>
6760inline
6762 allocator_type allocator,
6764 const t_ARG_01& arg_01,
6765 const t_ARG_02& arg_02,
6766 const t_ARG_03& arg_03,
6767 const t_ARG_04& arg_04,
6768 const t_ARG_05& arg_05,
6769 const t_ARG_06& arg_06,
6770 const t_ARG_07& arg_07,
6771 const t_ARG_08& arg_08,
6772 const t_ARG_09& arg_09)
6773: AllocBase(allocator)
6774, d_type(t_INDEX)
6775{
6776 typedef typename bsl::remove_cv<
6778 Alt_Type;
6779
6780 BloombergLP::bslma::ConstructionUtil::construct(
6781 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6782 AllocBase::mechanism(),
6783 arg_01,
6784 arg_02,
6785 arg_03,
6786 arg_04,
6787 arg_05,
6788 arg_06,
6789 arg_07,
6790 arg_08,
6791 arg_09);
6792}
6793
6794template <class t_HEAD, class... t_TAIL>
6795template <size_t t_INDEX,
6796 class t_ARG_01,
6797 class t_ARG_02,
6798 class t_ARG_03,
6799 class t_ARG_04,
6800 class t_ARG_05,
6801 class t_ARG_06,
6802 class t_ARG_07,
6803 class t_ARG_08,
6804 class t_ARG_09,
6805 class t_ARG_10>
6806inline
6808 allocator_type allocator,
6810 const t_ARG_01& arg_01,
6811 const t_ARG_02& arg_02,
6812 const t_ARG_03& arg_03,
6813 const t_ARG_04& arg_04,
6814 const t_ARG_05& arg_05,
6815 const t_ARG_06& arg_06,
6816 const t_ARG_07& arg_07,
6817 const t_ARG_08& arg_08,
6818 const t_ARG_09& arg_09,
6819 const t_ARG_10& arg_10)
6820: AllocBase(allocator)
6821, d_type(t_INDEX)
6822{
6823 typedef typename bsl::remove_cv<
6825 Alt_Type;
6826
6827 BloombergLP::bslma::ConstructionUtil::construct(
6828 reinterpret_cast<Alt_Type *>(BSLS_UTIL_ADDRESSOF(d_union)),
6829 AllocBase::mechanism(),
6830 arg_01,
6831 arg_02,
6832 arg_03,
6833 arg_04,
6834 arg_05,
6835 arg_06,
6836 arg_07,
6837 arg_08,
6838 arg_09,
6839 arg_10);
6840}
6841#endif
6842#endif // BSL_VARIANT_FULL_IMPLEMENTATION
6843
6844#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6845template <class t_HEAD, class... t_TAIL>
6850#endif
6851// MANIPULATORS
6852#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
6853template <class t_HEAD, class... t_TAIL>
6854template <size_t t_INDEX, class... t_ARGS>
6856{
6857 reset();
6858
6859 // We need to assemble the construction arguments for the underlying
6860 //'Variant_DataImp' object here. They require that allocator pointer is
6861 // the leading argument after 'Variant_Union' strips the 't_INDEX'. To be
6862 // able to get such argument set, we say that 'Variant_Union' is not
6863 // allocator aware. If we were to have 'Variant_Union' be allocator aware
6864 // and use trailing allocator construction, we wouldn't be able to extract
6865 // the allocator to move it to the right position for the 'Variant_DataImp'
6866 // construct invocation. If we were to have either 'Variant_Union' or
6867 // 'Variant_DataImp' use 'allocator_arg_t' semantics, it wouldn't work for
6868 // the non allocator aware variant where there is no allocator object.
6869 BloombergLP::bslma::ConstructionUtil::construct(
6870 BSLS_UTIL_ADDRESSOF(d_union),
6871 (void *)0,
6873 AllocBase::mechanism(),
6874 std::forward<t_ARGS>(args)...);
6875 d_type = t_INDEX;
6876}
6877
6878#else // BSL_VARIANT_FULL_IMPLEMENTATION
6879#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
6880template <class t_HEAD, class... t_TAIL>
6881template <size_t t_INDEX>
6883{
6884 typedef typename bsl::remove_cv<
6886 Alt_Type;
6887
6888 reset();
6889
6890 BloombergLP::bslma::ConstructionUtil::construct(
6891 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
6892 AllocBase::mechanism());
6893 d_type = t_INDEX;
6894}
6895
6896template <class t_HEAD, class... t_TAIL>
6897template <size_t t_INDEX, class t_ARG_01>
6899{
6900 typedef typename bsl::remove_cv<
6902 Alt_Type;
6903
6904 reset();
6905
6906 BloombergLP::bslma::ConstructionUtil::construct(
6907 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
6908 AllocBase::mechanism(),
6909 arg_01);
6910 d_type = t_INDEX;
6911}
6912
6913template <class t_HEAD, class... t_TAIL>
6914template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
6916 const t_ARG_02& arg_02)
6917{
6918 typedef typename bsl::remove_cv<
6920 Alt_Type;
6921
6922 reset();
6923
6924 BloombergLP::bslma::ConstructionUtil::construct(
6925 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
6926 AllocBase::mechanism(),
6927 arg_01,
6928 arg_02);
6929 d_type = t_INDEX;
6930}
6931
6932template <class t_HEAD, class... t_TAIL>
6933template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
6935 const t_ARG_02& arg_02,
6936 const t_ARG_03& arg_03)
6937{
6938 typedef typename bsl::remove_cv<
6940 Alt_Type;
6941
6942 reset();
6943
6944 BloombergLP::bslma::ConstructionUtil::construct(
6945 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
6946 AllocBase::mechanism(),
6947 arg_01,
6948 arg_02,
6949 arg_03);
6950 d_type = t_INDEX;
6951}
6952
6953template <class t_HEAD, class... t_TAIL>
6954template <size_t t_INDEX,
6955 class t_ARG_01,
6956 class t_ARG_02,
6957 class t_ARG_03,
6958 class t_ARG_04>
6960 const t_ARG_02& arg_02,
6961 const t_ARG_03& arg_03,
6962 const t_ARG_04& arg_04)
6963{
6964 typedef typename bsl::remove_cv<
6966 Alt_Type;
6967
6968 reset();
6969
6970 BloombergLP::bslma::ConstructionUtil::construct(
6971 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
6972 AllocBase::mechanism(),
6973 arg_01,
6974 arg_02,
6975 arg_03,
6976 arg_04);
6977 d_type = t_INDEX;
6978}
6979
6980template <class t_HEAD, class... t_TAIL>
6981template <size_t t_INDEX,
6982 class t_ARG_01,
6983 class t_ARG_02,
6984 class t_ARG_03,
6985 class t_ARG_04,
6986 class t_ARG_05>
6988 const t_ARG_02& arg_02,
6989 const t_ARG_03& arg_03,
6990 const t_ARG_04& arg_04,
6991 const t_ARG_05& arg_05)
6992{
6993 typedef typename bsl::remove_cv<
6995 Alt_Type;
6996
6997 reset();
6998
6999 BloombergLP::bslma::ConstructionUtil::construct(
7000 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7001 AllocBase::mechanism(),
7002 arg_01,
7003 arg_02,
7004 arg_03,
7005 arg_04,
7006 arg_05);
7007 d_type = t_INDEX;
7008}
7009
7010template <class t_HEAD, class... t_TAIL>
7011template <size_t t_INDEX,
7012 class t_ARG_01,
7013 class t_ARG_02,
7014 class t_ARG_03,
7015 class t_ARG_04,
7016 class t_ARG_05,
7017 class t_ARG_06>
7019 const t_ARG_02& arg_02,
7020 const t_ARG_03& arg_03,
7021 const t_ARG_04& arg_04,
7022 const t_ARG_05& arg_05,
7023 const t_ARG_06& arg_06)
7024{
7025 typedef typename bsl::remove_cv<
7027 Alt_Type;
7028
7029 reset();
7030
7031 BloombergLP::bslma::ConstructionUtil::construct(
7032 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7033 AllocBase::mechanism(),
7034 arg_01,
7035 arg_02,
7036 arg_03,
7037 arg_04,
7038 arg_05,
7039 arg_06);
7040 d_type = t_INDEX;
7041}
7042
7043template <class t_HEAD, class... t_TAIL>
7044template <size_t t_INDEX,
7045 class t_ARG_01,
7046 class t_ARG_02,
7047 class t_ARG_03,
7048 class t_ARG_04,
7049 class t_ARG_05,
7050 class t_ARG_06,
7051 class t_ARG_07>
7053 const t_ARG_02& arg_02,
7054 const t_ARG_03& arg_03,
7055 const t_ARG_04& arg_04,
7056 const t_ARG_05& arg_05,
7057 const t_ARG_06& arg_06,
7058 const t_ARG_07& arg_07)
7059{
7060 typedef typename bsl::remove_cv<
7062 Alt_Type;
7063
7064 reset();
7065
7066 BloombergLP::bslma::ConstructionUtil::construct(
7067 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7068 AllocBase::mechanism(),
7069 arg_01,
7070 arg_02,
7071 arg_03,
7072 arg_04,
7073 arg_05,
7074 arg_06,
7075 arg_07);
7076 d_type = t_INDEX;
7077}
7078
7079template <class t_HEAD, class... t_TAIL>
7080template <size_t t_INDEX,
7081 class t_ARG_01,
7082 class t_ARG_02,
7083 class t_ARG_03,
7084 class t_ARG_04,
7085 class t_ARG_05,
7086 class t_ARG_06,
7087 class t_ARG_07,
7088 class t_ARG_08>
7090 const t_ARG_02& arg_02,
7091 const t_ARG_03& arg_03,
7092 const t_ARG_04& arg_04,
7093 const t_ARG_05& arg_05,
7094 const t_ARG_06& arg_06,
7095 const t_ARG_07& arg_07,
7096 const t_ARG_08& arg_08)
7097{
7098 typedef typename bsl::remove_cv<
7100 Alt_Type;
7101
7102 reset();
7103
7104 BloombergLP::bslma::ConstructionUtil::construct(
7105 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7106 AllocBase::mechanism(),
7107 arg_01,
7108 arg_02,
7109 arg_03,
7110 arg_04,
7111 arg_05,
7112 arg_06,
7113 arg_07,
7114 arg_08);
7115 d_type = t_INDEX;
7116}
7117
7118template <class t_HEAD, class... t_TAIL>
7119template <size_t t_INDEX,
7120 class t_ARG_01,
7121 class t_ARG_02,
7122 class t_ARG_03,
7123 class t_ARG_04,
7124 class t_ARG_05,
7125 class t_ARG_06,
7126 class t_ARG_07,
7127 class t_ARG_08,
7128 class t_ARG_09>
7130 const t_ARG_02& arg_02,
7131 const t_ARG_03& arg_03,
7132 const t_ARG_04& arg_04,
7133 const t_ARG_05& arg_05,
7134 const t_ARG_06& arg_06,
7135 const t_ARG_07& arg_07,
7136 const t_ARG_08& arg_08,
7137 const t_ARG_09& arg_09)
7138{
7139 typedef typename bsl::remove_cv<
7141 Alt_Type;
7142
7143 reset();
7144
7145 BloombergLP::bslma::ConstructionUtil::construct(
7146 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7147 AllocBase::mechanism(),
7148 arg_01,
7149 arg_02,
7150 arg_03,
7151 arg_04,
7152 arg_05,
7153 arg_06,
7154 arg_07,
7155 arg_08,
7156 arg_09);
7157 d_type = t_INDEX;
7158}
7159
7160template <class t_HEAD, class... t_TAIL>
7161template <size_t t_INDEX,
7162 class t_ARG_01,
7163 class t_ARG_02,
7164 class t_ARG_03,
7165 class t_ARG_04,
7166 class t_ARG_05,
7167 class t_ARG_06,
7168 class t_ARG_07,
7169 class t_ARG_08,
7170 class t_ARG_09,
7171 class t_ARG_10>
7173 const t_ARG_02& arg_02,
7174 const t_ARG_03& arg_03,
7175 const t_ARG_04& arg_04,
7176 const t_ARG_05& arg_05,
7177 const t_ARG_06& arg_06,
7178 const t_ARG_07& arg_07,
7179 const t_ARG_08& arg_08,
7180 const t_ARG_09& arg_09,
7181 const t_ARG_10& arg_10)
7182{
7183 typedef typename bsl::remove_cv<
7185 Alt_Type;
7186
7187 reset();
7188
7189 BloombergLP::bslma::ConstructionUtil::construct(
7190 reinterpret_cast<Alt_Type *> BSLS_UTIL_ADDRESSOF(d_union),
7191 AllocBase::mechanism(),
7192 arg_01,
7193 arg_02,
7194 arg_03,
7195 arg_04,
7196 arg_05,
7197 arg_06,
7198 arg_07,
7199 arg_08,
7200 arg_09,
7201 arg_10);
7202 d_type = t_INDEX;
7203}
7204#endif
7205#endif // BSL_VARIANT_FULL_IMPLEMENTATION
7206
7207#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
7208template <class t_HEAD, class... t_TAIL>
7209inline
7211 const Variant_Base& rhs)
7212{
7213 if (&rhs != this) {
7214 if (this->d_type == rhs.d_type) {
7215 if (d_type != bsl::variant_npos) {
7216 Variant& self = static_cast<Variant&>(*this);
7217 BloombergLP::bslstl::Variant_CopyAssignVisitor<Variant>
7218 copyAssign(BSLS_UTIL_ADDRESSOF(self));
7220 void, copyAssign, static_cast<const Variant&>(rhs));
7221 }
7222 }
7223 else {
7224 reset();
7225 if (rhs.d_type != bsl::variant_npos) {
7226 BloombergLP::bslstl::Variant_CopyConstructVisitor<Variant_Base>
7227 copyConstructor(this);
7229 void, copyConstructor, static_cast<const Variant&>(rhs));
7230 }
7231 d_type = rhs.d_type;
7232 }
7233 }
7234 return *this;
7235}
7236
7237template <class t_HEAD, class... t_TAIL>
7238inline
7240 BloombergLP::bslmf::MovableRef<Variant_Base> rhs)
7241{
7242 Variant_Base& lvalue = rhs;
7243 if (&lvalue != this) {
7244 if (this->d_type == lvalue.d_type) {
7245 if (d_type != bsl::variant_npos) {
7246 Variant& self = static_cast<Variant&>(*this);
7247 BloombergLP::bslstl::Variant_MoveAssignVisitor<Variant>
7248 moveAssign(BSLS_UTIL_ADDRESSOF(self));
7250 void, moveAssign, static_cast<Variant&>(lvalue));
7251 }
7252 }
7253 else {
7254 reset();
7255 if (lvalue.d_type != bsl::variant_npos) {
7256 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
7257 moveConstructor(this);
7259 void, moveConstructor, static_cast<Variant&>(lvalue));
7260 }
7261 d_type = lvalue.d_type;
7262 }
7263 }
7264 return *this;
7265}
7266template <class t_HEAD, class... t_TAIL>
7268{
7269 if (d_type != bsl::variant_npos) {
7270 BloombergLP::bslstl::Variant_DestructorVisitor destructor;
7271 bsl::visit(destructor, static_cast<Variant&>(*this));
7272 d_type = bsl::variant_npos;
7273 }
7274}
7275#endif
7276} // close package namespace
7277
7278
7279namespace bsl {
7280
7281 // -------------
7282 // class variant
7283 // -------------
7284
7285// CREATORS
7286#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
7287template <class t_HEAD, class... t_TAIL>
7288template <class t_TYPE>
7289inline
7290variant<t_HEAD, t_TAIL...>::variant(
7291 t_TYPE&& value,
7293: Variant_Base(
7294 bsl::in_place_index_t<BSLSTL_VARIANT_CONVERT_INDEX_OF(t_TYPE,
7295 variant)>(),
7296 std::forward<t_TYPE>(value))
7297{
7298}
7299
7300template <class t_HEAD, class... t_TAIL>
7301template <class t_TYPE>
7302inline
7303variant<t_HEAD, t_TAIL...>::variant(
7304 bsl::allocator_arg_t,
7305 allocator_type allocator,
7306 t_TYPE&& value,
7308: Variant_Base(
7309 bsl::allocator_arg_t{},
7310 allocator,
7311 bsl::in_place_index_t<BSLSTL_VARIANT_CONVERT_INDEX_OF(t_TYPE,
7312 variant)>(),
7313 std::forward<t_TYPE>(value))
7314{
7315}
7316#else // BSL_VARIANT_FULL_IMPLEMENTATION
7317#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
7318template <class t_HEAD, class... t_TAIL>
7319inline
7321: Variant_Base()
7322{
7323}
7324
7325template <class t_HEAD, class... t_TAIL>
7326inline
7328: Variant_Base(original)
7329{
7330}
7331
7332template <class t_HEAD, class... t_TAIL>
7333inline
7335 BloombergLP::bslmf::MovableRef<variant> original)
7336: Variant_Base(original)
7337{
7338}
7339
7340template <class t_HEAD, class... t_TAIL>
7341template <class t_TYPE>
7342inline
7344 const t_TYPE& value,
7346: Variant_Base(
7348 variant)>(),
7349 value)
7350{
7351}
7352
7353template <class t_HEAD, class... t_TAIL>
7354template <class t_TYPE>
7355inline
7363
7364template <class t_HEAD, class... t_TAIL>
7365template <class t_TYPE, class t_ARG_01>
7366inline
7369 const t_ARG_01& arg_01,
7371: Variant_Base(
7373 arg_01)
7374{
7375}
7376
7377template <class t_HEAD, class... t_TAIL>
7378template <class t_TYPE, class t_ARG_01, class t_ARG_02>
7379inline
7382 const t_ARG_01& arg_01,
7383 const t_ARG_02& arg_02,
7385: Variant_Base(
7387 arg_01,
7388 arg_02)
7389{
7390}
7391
7392template <class t_HEAD, class... t_TAIL>
7393template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
7394inline
7397 const t_ARG_01& arg_01,
7398 const t_ARG_02& arg_02,
7399 const t_ARG_03& arg_03,
7401: Variant_Base(
7403 arg_01,
7404 arg_02,
7405 arg_03)
7406{
7407}
7408
7409template <class t_HEAD, class... t_TAIL>
7410template <class t_TYPE,
7411 class t_ARG_01,
7412 class t_ARG_02,
7413 class t_ARG_03,
7414 class t_ARG_04>
7415inline
7418 const t_ARG_01& arg_01,
7419 const t_ARG_02& arg_02,
7420 const t_ARG_03& arg_03,
7421 const t_ARG_04& arg_04,
7423: Variant_Base(
7425 arg_01,
7426 arg_02,
7427 arg_03,
7428 arg_04)
7429{
7430}
7431
7432template <class t_HEAD, class... t_TAIL>
7433template <class t_TYPE,
7434 class t_ARG_01,
7435 class t_ARG_02,
7436 class t_ARG_03,
7437 class t_ARG_04,
7438 class t_ARG_05>
7439inline
7442 const t_ARG_01& arg_01,
7443 const t_ARG_02& arg_02,
7444 const t_ARG_03& arg_03,
7445 const t_ARG_04& arg_04,
7446 const t_ARG_05& arg_05,
7448: Variant_Base(
7450 arg_01,
7451 arg_02,
7452 arg_03,
7453 arg_04,
7454 arg_05)
7455{
7456}
7457
7458template <class t_HEAD, class... t_TAIL>
7459template <class t_TYPE,
7460 class t_ARG_01,
7461 class t_ARG_02,
7462 class t_ARG_03,
7463 class t_ARG_04,
7464 class t_ARG_05,
7465 class t_ARG_06>
7466inline
7469 const t_ARG_01& arg_01,
7470 const t_ARG_02& arg_02,
7471 const t_ARG_03& arg_03,
7472 const t_ARG_04& arg_04,
7473 const t_ARG_05& arg_05,
7474 const t_ARG_06& arg_06,
7476: Variant_Base(
7478 arg_01,
7479 arg_02,
7480 arg_03,
7481 arg_04,
7482 arg_05,
7483 arg_06)
7484{
7485}
7486
7487template <class t_HEAD, class... t_TAIL>
7488template <class t_TYPE,
7489 class t_ARG_01,
7490 class t_ARG_02,
7491 class t_ARG_03,
7492 class t_ARG_04,
7493 class t_ARG_05,
7494 class t_ARG_06,
7495 class t_ARG_07>
7496inline
7499 const t_ARG_01& arg_01,
7500 const t_ARG_02& arg_02,
7501 const t_ARG_03& arg_03,
7502 const t_ARG_04& arg_04,
7503 const t_ARG_05& arg_05,
7504 const t_ARG_06& arg_06,
7505 const t_ARG_07& arg_07,
7507: Variant_Base(
7509 arg_01,
7510 arg_02,
7511 arg_03,
7512 arg_04,
7513 arg_05,
7514 arg_06,
7515 arg_07)
7516{
7517}
7518
7519template <class t_HEAD, class... t_TAIL>
7520template <class t_TYPE,
7521 class t_ARG_01,
7522 class t_ARG_02,
7523 class t_ARG_03,
7524 class t_ARG_04,
7525 class t_ARG_05,
7526 class t_ARG_06,
7527 class t_ARG_07,
7528 class t_ARG_08>
7529inline
7532 const t_ARG_01& arg_01,
7533 const t_ARG_02& arg_02,
7534 const t_ARG_03& arg_03,
7535 const t_ARG_04& arg_04,
7536 const t_ARG_05& arg_05,
7537 const t_ARG_06& arg_06,
7538 const t_ARG_07& arg_07,
7539 const t_ARG_08& arg_08,
7541: Variant_Base(
7543 arg_01,
7544 arg_02,
7545 arg_03,
7546 arg_04,
7547 arg_05,
7548 arg_06,
7549 arg_07,
7550 arg_08)
7551{
7552}
7553
7554template <class t_HEAD, class... t_TAIL>
7555template <class t_TYPE,
7556 class t_ARG_01,
7557 class t_ARG_02,
7558 class t_ARG_03,
7559 class t_ARG_04,
7560 class t_ARG_05,
7561 class t_ARG_06,
7562 class t_ARG_07,
7563 class t_ARG_08,
7564 class t_ARG_09>
7565inline
7568 const t_ARG_01& arg_01,
7569 const t_ARG_02& arg_02,
7570 const t_ARG_03& arg_03,
7571 const t_ARG_04& arg_04,
7572 const t_ARG_05& arg_05,
7573 const t_ARG_06& arg_06,
7574 const t_ARG_07& arg_07,
7575 const t_ARG_08& arg_08,
7576 const t_ARG_09& arg_09,
7578: Variant_Base(
7580 arg_01,
7581 arg_02,
7582 arg_03,
7583 arg_04,
7584 arg_05,
7585 arg_06,
7586 arg_07,
7587 arg_08,
7588 arg_09)
7589{
7590}
7591
7592template <class t_HEAD, class... t_TAIL>
7593template <class t_TYPE,
7594 class t_ARG_01,
7595 class t_ARG_02,
7596 class t_ARG_03,
7597 class t_ARG_04,
7598 class t_ARG_05,
7599 class t_ARG_06,
7600 class t_ARG_07,
7601 class t_ARG_08,
7602 class t_ARG_09,
7603 class t_ARG_10>
7604inline
7607 const t_ARG_01& arg_01,
7608 const t_ARG_02& arg_02,
7609 const t_ARG_03& arg_03,
7610 const t_ARG_04& arg_04,
7611 const t_ARG_05& arg_05,
7612 const t_ARG_06& arg_06,
7613 const t_ARG_07& arg_07,
7614 const t_ARG_08& arg_08,
7615 const t_ARG_09& arg_09,
7616 const t_ARG_10& arg_10,
7618: Variant_Base(
7620 arg_01,
7621 arg_02,
7622 arg_03,
7623 arg_04,
7624 arg_05,
7625 arg_06,
7626 arg_07,
7627 arg_08,
7628 arg_09,
7629 arg_10)
7630{
7631}
7632
7633template <class t_HEAD, class... t_TAIL>
7634template <size_t t_INDEX>
7635inline
7640
7641template <class t_HEAD, class... t_TAIL>
7642template <size_t t_INDEX, class t_ARG_01>
7643inline
7645 const t_ARG_01& arg_01)
7646: Variant_Base(bsl::in_place_index_t<t_INDEX>(), arg_01)
7647{
7648}
7649
7650template <class t_HEAD, class... t_TAIL>
7651template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
7652inline
7654 const t_ARG_01& arg_01,
7655 const t_ARG_02& arg_02)
7656: Variant_Base(bsl::in_place_index_t<t_INDEX>(), arg_01, arg_02)
7657{
7658}
7659
7660template <class t_HEAD, class... t_TAIL>
7661template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
7662inline
7664 const t_ARG_01& arg_01,
7665 const t_ARG_02& arg_02,
7666 const t_ARG_03& arg_03)
7667: Variant_Base(bsl::in_place_index_t<t_INDEX>(), arg_01, arg_02, arg_03)
7668{
7669}
7670
7671template <class t_HEAD, class... t_TAIL>
7672template <size_t t_INDEX,
7673 class t_ARG_01,
7674 class t_ARG_02,
7675 class t_ARG_03,
7676 class t_ARG_04>
7677inline
7679 const t_ARG_01& arg_01,
7680 const t_ARG_02& arg_02,
7681 const t_ARG_03& arg_03,
7682 const t_ARG_04& arg_04)
7683: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7684 arg_01,
7685 arg_02,
7686 arg_03,
7687 arg_04)
7688{
7689}
7690
7691template <class t_HEAD, class... t_TAIL>
7692template <size_t t_INDEX,
7693 class t_ARG_01,
7694 class t_ARG_02,
7695 class t_ARG_03,
7696 class t_ARG_04,
7697 class t_ARG_05>
7698inline
7700 const t_ARG_01& arg_01,
7701 const t_ARG_02& arg_02,
7702 const t_ARG_03& arg_03,
7703 const t_ARG_04& arg_04,
7704 const t_ARG_05& arg_05)
7705: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7706 arg_01,
7707 arg_02,
7708 arg_03,
7709 arg_04,
7710 arg_05)
7711{
7712}
7713
7714template <class t_HEAD, class... t_TAIL>
7715template <size_t t_INDEX,
7716 class t_ARG_01,
7717 class t_ARG_02,
7718 class t_ARG_03,
7719 class t_ARG_04,
7720 class t_ARG_05,
7721 class t_ARG_06>
7722inline
7724 const t_ARG_01& arg_01,
7725 const t_ARG_02& arg_02,
7726 const t_ARG_03& arg_03,
7727 const t_ARG_04& arg_04,
7728 const t_ARG_05& arg_05,
7729 const t_ARG_06& arg_06)
7730: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7731 arg_01,
7732 arg_02,
7733 arg_03,
7734 arg_04,
7735 arg_05,
7736 arg_06)
7737{
7738}
7739
7740template <class t_HEAD, class... t_TAIL>
7741template <size_t t_INDEX,
7742 class t_ARG_01,
7743 class t_ARG_02,
7744 class t_ARG_03,
7745 class t_ARG_04,
7746 class t_ARG_05,
7747 class t_ARG_06,
7748 class t_ARG_07>
7749inline
7751 const t_ARG_01& arg_01,
7752 const t_ARG_02& arg_02,
7753 const t_ARG_03& arg_03,
7754 const t_ARG_04& arg_04,
7755 const t_ARG_05& arg_05,
7756 const t_ARG_06& arg_06,
7757 const t_ARG_07& arg_07)
7758: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7759 arg_01,
7760 arg_02,
7761 arg_03,
7762 arg_04,
7763 arg_05,
7764 arg_06,
7765 arg_07)
7766{
7767}
7768
7769template <class t_HEAD, class... t_TAIL>
7770template <size_t t_INDEX,
7771 class t_ARG_01,
7772 class t_ARG_02,
7773 class t_ARG_03,
7774 class t_ARG_04,
7775 class t_ARG_05,
7776 class t_ARG_06,
7777 class t_ARG_07,
7778 class t_ARG_08>
7779inline
7781 const t_ARG_01& arg_01,
7782 const t_ARG_02& arg_02,
7783 const t_ARG_03& arg_03,
7784 const t_ARG_04& arg_04,
7785 const t_ARG_05& arg_05,
7786 const t_ARG_06& arg_06,
7787 const t_ARG_07& arg_07,
7788 const t_ARG_08& arg_08)
7789: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7790 arg_01,
7791 arg_02,
7792 arg_03,
7793 arg_04,
7794 arg_05,
7795 arg_06,
7796 arg_07,
7797 arg_08)
7798{
7799}
7800
7801template <class t_HEAD, class... t_TAIL>
7802template <size_t t_INDEX,
7803 class t_ARG_01,
7804 class t_ARG_02,
7805 class t_ARG_03,
7806 class t_ARG_04,
7807 class t_ARG_05,
7808 class t_ARG_06,
7809 class t_ARG_07,
7810 class t_ARG_08,
7811 class t_ARG_09>
7812inline
7814 const t_ARG_01& arg_01,
7815 const t_ARG_02& arg_02,
7816 const t_ARG_03& arg_03,
7817 const t_ARG_04& arg_04,
7818 const t_ARG_05& arg_05,
7819 const t_ARG_06& arg_06,
7820 const t_ARG_07& arg_07,
7821 const t_ARG_08& arg_08,
7822 const t_ARG_09& arg_09)
7823: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7824 arg_01,
7825 arg_02,
7826 arg_03,
7827 arg_04,
7828 arg_05,
7829 arg_06,
7830 arg_07,
7831 arg_08,
7832 arg_09)
7833{
7834}
7835
7836template <class t_HEAD, class... t_TAIL>
7837template <size_t t_INDEX,
7838 class t_ARG_01,
7839 class t_ARG_02,
7840 class t_ARG_03,
7841 class t_ARG_04,
7842 class t_ARG_05,
7843 class t_ARG_06,
7844 class t_ARG_07,
7845 class t_ARG_08,
7846 class t_ARG_09,
7847 class t_ARG_10>
7848inline
7850 const t_ARG_01& arg_01,
7851 const t_ARG_02& arg_02,
7852 const t_ARG_03& arg_03,
7853 const t_ARG_04& arg_04,
7854 const t_ARG_05& arg_05,
7855 const t_ARG_06& arg_06,
7856 const t_ARG_07& arg_07,
7857 const t_ARG_08& arg_08,
7858 const t_ARG_09& arg_09,
7859 const t_ARG_10& arg_10)
7860: Variant_Base(bsl::in_place_index_t<t_INDEX>(),
7861 arg_01,
7862 arg_02,
7863 arg_03,
7864 arg_04,
7865 arg_05,
7866 arg_06,
7867 arg_07,
7868 arg_08,
7869 arg_09,
7870 arg_10)
7871{
7872}
7873
7874template <class t_HEAD, class... t_TAIL>
7875inline
7878: Variant_Base(bsl::allocator_arg_t(), allocator)
7879{
7880}
7881
7882template <class t_HEAD, class... t_TAIL>
7883inline
7886 const variant& original)
7887: Variant_Base(bsl::allocator_arg_t(), allocator, original)
7888{
7889}
7890
7891template <class t_HEAD, class... t_TAIL>
7892inline
7894 bsl::allocator_arg_t,
7896 BloombergLP::bslmf::MovableRef<variant> original)
7897: Variant_Base(bsl::allocator_arg_t(), allocator, original)
7898{
7899}
7900
7901template <class t_HEAD, class... t_TAIL>
7902template <class t_TYPE>
7903inline
7905 bsl::allocator_arg_t,
7907 const t_TYPE& value,
7909: Variant_Base(
7910 bsl::allocator_arg_t(),
7911 allocator,
7913 variant)>(),
7914 value)
7915{
7916}
7917
7918template <class t_HEAD, class... t_TAIL>
7919template <class t_TYPE>
7920inline
7922 bsl::allocator_arg_t,
7926: Variant_Base(
7927 bsl::allocator_arg_t(),
7928 allocator,
7930{
7931}
7932
7933template <class t_HEAD, class... t_TAIL>
7934template <class t_TYPE, class t_ARG_01>
7935inline
7937 bsl::allocator_arg_t,
7940 const t_ARG_01& arg_01,
7942: Variant_Base(
7943 bsl::allocator_arg_t(),
7944 allocator,
7946 arg_01)
7947{
7948}
7949
7950template <class t_HEAD, class... t_TAIL>
7951template <class t_TYPE, class t_ARG_01, class t_ARG_02>
7952inline
7954 bsl::allocator_arg_t,
7957 const t_ARG_01& arg_01,
7958 const t_ARG_02& arg_02,
7960: Variant_Base(
7961 bsl::allocator_arg_t(),
7962 allocator,
7964 arg_01,
7965 arg_02)
7966{
7967}
7968
7969template <class t_HEAD, class... t_TAIL>
7970template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
7971inline
7973 bsl::allocator_arg_t,
7976 const t_ARG_01& arg_01,
7977 const t_ARG_02& arg_02,
7978 const t_ARG_03& arg_03,
7980: Variant_Base(
7981 bsl::allocator_arg_t(),
7982 allocator,
7984 arg_01,
7985 arg_02,
7986 arg_03)
7987{
7988}
7989
7990template <class t_HEAD, class... t_TAIL>
7991template <class t_TYPE,
7992 class t_ARG_01,
7993 class t_ARG_02,
7994 class t_ARG_03,
7995 class t_ARG_04>
7996inline
7998 bsl::allocator_arg_t,
8001 const t_ARG_01& arg_01,
8002 const t_ARG_02& arg_02,
8003 const t_ARG_03& arg_03,
8004 const t_ARG_04& arg_04,
8006: Variant_Base(
8007 bsl::allocator_arg_t(),
8008 allocator,
8010 arg_01,
8011 arg_02,
8012 arg_03,
8013 arg_04)
8014{
8015}
8016
8017template <class t_HEAD, class... t_TAIL>
8018template <class t_TYPE,
8019 class t_ARG_01,
8020 class t_ARG_02,
8021 class t_ARG_03,
8022 class t_ARG_04,
8023 class t_ARG_05>
8024inline
8026 bsl::allocator_arg_t,
8029 const t_ARG_01& arg_01,
8030 const t_ARG_02& arg_02,
8031 const t_ARG_03& arg_03,
8032 const t_ARG_04& arg_04,
8033 const t_ARG_05& arg_05,
8035: Variant_Base(
8036 bsl::allocator_arg_t(),
8037 allocator,
8039 arg_01,
8040 arg_02,
8041 arg_03,
8042 arg_04,
8043 arg_05)
8044{
8045}
8046
8047template <class t_HEAD, class... t_TAIL>
8048template <class t_TYPE,
8049 class t_ARG_01,
8050 class t_ARG_02,
8051 class t_ARG_03,
8052 class t_ARG_04,
8053 class t_ARG_05,
8054 class t_ARG_06>
8055inline
8057 bsl::allocator_arg_t,
8060 const t_ARG_01& arg_01,
8061 const t_ARG_02& arg_02,
8062 const t_ARG_03& arg_03,
8063 const t_ARG_04& arg_04,
8064 const t_ARG_05& arg_05,
8065 const t_ARG_06& arg_06,
8067: Variant_Base(
8068 bsl::allocator_arg_t(),
8069 allocator,
8071 arg_01,
8072 arg_02,
8073 arg_03,
8074 arg_04,
8075 arg_05,
8076 arg_06)
8077{
8078}
8079
8080template <class t_HEAD, class... t_TAIL>
8081template <class t_TYPE,
8082 class t_ARG_01,
8083 class t_ARG_02,
8084 class t_ARG_03,
8085 class t_ARG_04,
8086 class t_ARG_05,
8087 class t_ARG_06,
8088 class t_ARG_07>
8089inline
8091 bsl::allocator_arg_t,
8094 const t_ARG_01& arg_01,
8095 const t_ARG_02& arg_02,
8096 const t_ARG_03& arg_03,
8097 const t_ARG_04& arg_04,
8098 const t_ARG_05& arg_05,
8099 const t_ARG_06& arg_06,
8100 const t_ARG_07& arg_07,
8102: Variant_Base(
8103 bsl::allocator_arg_t(),
8104 allocator,
8106 arg_01,
8107 arg_02,
8108 arg_03,
8109 arg_04,
8110 arg_05,
8111 arg_06,
8112 arg_07)
8113{
8114}
8115
8116template <class t_HEAD, class... t_TAIL>
8117template <class t_TYPE,
8118 class t_ARG_01,
8119 class t_ARG_02,
8120 class t_ARG_03,
8121 class t_ARG_04,
8122 class t_ARG_05,
8123 class t_ARG_06,
8124 class t_ARG_07,
8125 class t_ARG_08>
8126inline
8128 bsl::allocator_arg_t,
8131 const t_ARG_01& arg_01,
8132 const t_ARG_02& arg_02,
8133 const t_ARG_03& arg_03,
8134 const t_ARG_04& arg_04,
8135 const t_ARG_05& arg_05,
8136 const t_ARG_06& arg_06,
8137 const t_ARG_07& arg_07,
8138 const t_ARG_08& arg_08,
8140: Variant_Base(
8141 bsl::allocator_arg_t(),
8142 allocator,
8144 arg_01,
8145 arg_02,
8146 arg_03,
8147 arg_04,
8148 arg_05,
8149 arg_06,
8150 arg_07,
8151 arg_08)
8152{
8153}
8154
8155template <class t_HEAD, class... t_TAIL>
8156template <class t_TYPE,
8157 class t_ARG_01,
8158 class t_ARG_02,
8159 class t_ARG_03,
8160 class t_ARG_04,
8161 class t_ARG_05,
8162 class t_ARG_06,
8163 class t_ARG_07,
8164 class t_ARG_08,
8165 class t_ARG_09>
8166inline
8168 bsl::allocator_arg_t,
8171 const t_ARG_01& arg_01,
8172 const t_ARG_02& arg_02,
8173 const t_ARG_03& arg_03,
8174 const t_ARG_04& arg_04,
8175 const t_ARG_05& arg_05,
8176 const t_ARG_06& arg_06,
8177 const t_ARG_07& arg_07,
8178 const t_ARG_08& arg_08,
8179 const t_ARG_09& arg_09,
8181: Variant_Base(
8182 bsl::allocator_arg_t(),
8183 allocator,
8185 arg_01,
8186 arg_02,
8187 arg_03,
8188 arg_04,
8189 arg_05,
8190 arg_06,
8191 arg_07,
8192 arg_08,
8193 arg_09)
8194{
8195}
8196
8197template <class t_HEAD, class... t_TAIL>
8198template <class t_TYPE,
8199 class t_ARG_01,
8200 class t_ARG_02,
8201 class t_ARG_03,
8202 class t_ARG_04,
8203 class t_ARG_05,
8204 class t_ARG_06,
8205 class t_ARG_07,
8206 class t_ARG_08,
8207 class t_ARG_09,
8208 class t_ARG_10>
8209inline
8211 bsl::allocator_arg_t,
8214 const t_ARG_01& arg_01,
8215 const t_ARG_02& arg_02,
8216 const t_ARG_03& arg_03,
8217 const t_ARG_04& arg_04,
8218 const t_ARG_05& arg_05,
8219 const t_ARG_06& arg_06,
8220 const t_ARG_07& arg_07,
8221 const t_ARG_08& arg_08,
8222 const t_ARG_09& arg_09,
8223 const t_ARG_10& arg_10,
8225: Variant_Base(
8226 bsl::allocator_arg_t(),
8227 allocator,
8229 arg_01,
8230 arg_02,
8231 arg_03,
8232 arg_04,
8233 arg_05,
8234 arg_06,
8235 arg_07,
8236 arg_08,
8237 arg_09,
8238 arg_10)
8239{
8240}
8241
8242template <class t_HEAD, class... t_TAIL>
8243template <size_t t_INDEX>
8244inline
8248: Variant_Base(bsl::allocator_arg_t(),
8249 allocator,
8250 bsl::in_place_index_t<t_INDEX>())
8251{
8252}
8253
8254template <class t_HEAD, class... t_TAIL>
8255template <size_t t_INDEX, class t_ARG_01>
8256inline
8260 const t_ARG_01& arg_01)
8261: Variant_Base(bsl::allocator_arg_t(),
8262 allocator,
8263 bsl::in_place_index_t<t_INDEX>(),
8264 arg_01)
8265{
8266}
8267
8268template <class t_HEAD, class... t_TAIL>
8269template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
8270inline
8274 const t_ARG_01& arg_01,
8275 const t_ARG_02& arg_02)
8276: Variant_Base(bsl::allocator_arg_t(),
8277 allocator,
8278 bsl::in_place_index_t<t_INDEX>(),
8279 arg_01,
8280 arg_02)
8281{
8282}
8283
8284template <class t_HEAD, class... t_TAIL>
8285template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
8286inline
8290 const t_ARG_01& arg_01,
8291 const t_ARG_02& arg_02,
8292 const t_ARG_03& arg_03)
8293: Variant_Base(bsl::allocator_arg_t(),
8294 allocator,
8295 bsl::in_place_index_t<t_INDEX>(),
8296 arg_01,
8297 arg_02,
8298 arg_03)
8299{
8300}
8301
8302template <class t_HEAD, class... t_TAIL>
8303template <size_t t_INDEX,
8304 class t_ARG_01,
8305 class t_ARG_02,
8306 class t_ARG_03,
8307 class t_ARG_04>
8308inline
8312 const t_ARG_01& arg_01,
8313 const t_ARG_02& arg_02,
8314 const t_ARG_03& arg_03,
8315 const t_ARG_04& arg_04)
8316: Variant_Base(bsl::allocator_arg_t(),
8317 allocator,
8318 bsl::in_place_index_t<t_INDEX>(),
8319 arg_01,
8320 arg_02,
8321 arg_03,
8322 arg_04)
8323{
8324}
8325
8326template <class t_HEAD, class... t_TAIL>
8327template <size_t t_INDEX,
8328 class t_ARG_01,
8329 class t_ARG_02,
8330 class t_ARG_03,
8331 class t_ARG_04,
8332 class t_ARG_05>
8333inline
8337 const t_ARG_01& arg_01,
8338 const t_ARG_02& arg_02,
8339 const t_ARG_03& arg_03,
8340 const t_ARG_04& arg_04,
8341 const t_ARG_05& arg_05)
8342: Variant_Base(bsl::allocator_arg_t(),
8343 allocator,
8344 bsl::in_place_index_t<t_INDEX>(),
8345 arg_01,
8346 arg_02,
8347 arg_03,
8348 arg_04,
8349 arg_05)
8350{
8351}
8352
8353template <class t_HEAD, class... t_TAIL>
8354template <size_t t_INDEX,
8355 class t_ARG_01,
8356 class t_ARG_02,
8357 class t_ARG_03,
8358 class t_ARG_04,
8359 class t_ARG_05,
8360 class t_ARG_06>
8361inline
8365 const t_ARG_01& arg_01,
8366 const t_ARG_02& arg_02,
8367 const t_ARG_03& arg_03,
8368 const t_ARG_04& arg_04,
8369 const t_ARG_05& arg_05,
8370 const t_ARG_06& arg_06)
8371: Variant_Base(bsl::allocator_arg_t(),
8372 allocator,
8373 bsl::in_place_index_t<t_INDEX>(),
8374 arg_01,
8375 arg_02,
8376 arg_03,
8377 arg_04,
8378 arg_05,
8379 arg_06)
8380{
8381}
8382
8383template <class t_HEAD, class... t_TAIL>
8384template <size_t t_INDEX,
8385 class t_ARG_01,
8386 class t_ARG_02,
8387 class t_ARG_03,
8388 class t_ARG_04,
8389 class t_ARG_05,
8390 class t_ARG_06,
8391 class t_ARG_07>
8392inline
8396 const t_ARG_01& arg_01,
8397 const t_ARG_02& arg_02,
8398 const t_ARG_03& arg_03,
8399 const t_ARG_04& arg_04,
8400 const t_ARG_05& arg_05,
8401 const t_ARG_06& arg_06,
8402 const t_ARG_07& arg_07)
8403: Variant_Base(bsl::allocator_arg_t(),
8404 allocator,
8405 bsl::in_place_index_t<t_INDEX>(),
8406 arg_01,
8407 arg_02,
8408 arg_03,
8409 arg_04,
8410 arg_05,
8411 arg_06,
8412 arg_07)
8413{
8414}
8415
8416template <class t_HEAD, class... t_TAIL>
8417template <size_t t_INDEX,
8418 class t_ARG_01,
8419 class t_ARG_02,
8420 class t_ARG_03,
8421 class t_ARG_04,
8422 class t_ARG_05,
8423 class t_ARG_06,
8424 class t_ARG_07,
8425 class t_ARG_08>
8426inline
8430 const t_ARG_01& arg_01,
8431 const t_ARG_02& arg_02,
8432 const t_ARG_03& arg_03,
8433 const t_ARG_04& arg_04,
8434 const t_ARG_05& arg_05,
8435 const t_ARG_06& arg_06,
8436 const t_ARG_07& arg_07,
8437 const t_ARG_08& arg_08)
8438: Variant_Base(bsl::allocator_arg_t(),
8439 allocator,
8440 bsl::in_place_index_t<t_INDEX>(),
8441 arg_01,
8442 arg_02,
8443 arg_03,
8444 arg_04,
8445 arg_05,
8446 arg_06,
8447 arg_07,
8448 arg_08)
8449{
8450}
8451
8452template <class t_HEAD, class... t_TAIL>
8453template <size_t t_INDEX,
8454 class t_ARG_01,
8455 class t_ARG_02,
8456 class t_ARG_03,
8457 class t_ARG_04,
8458 class t_ARG_05,
8459 class t_ARG_06,
8460 class t_ARG_07,
8461 class t_ARG_08,
8462 class t_ARG_09>
8463inline
8467 const t_ARG_01& arg_01,
8468 const t_ARG_02& arg_02,
8469 const t_ARG_03& arg_03,
8470 const t_ARG_04& arg_04,
8471 const t_ARG_05& arg_05,
8472 const t_ARG_06& arg_06,
8473 const t_ARG_07& arg_07,
8474 const t_ARG_08& arg_08,
8475 const t_ARG_09& arg_09)
8476: Variant_Base(bsl::allocator_arg_t(),
8477 allocator,
8478 bsl::in_place_index_t<t_INDEX>(),
8479 arg_01,
8480 arg_02,
8481 arg_03,
8482 arg_04,
8483 arg_05,
8484 arg_06,
8485 arg_07,
8486 arg_08,
8487 arg_09)
8488{
8489}
8490
8491template <class t_HEAD, class... t_TAIL>
8492template <size_t t_INDEX,
8493 class t_ARG_01,
8494 class t_ARG_02,
8495 class t_ARG_03,
8496 class t_ARG_04,
8497 class t_ARG_05,
8498 class t_ARG_06,
8499 class t_ARG_07,
8500 class t_ARG_08,
8501 class t_ARG_09,
8502 class t_ARG_10>
8503inline
8507 const t_ARG_01& arg_01,
8508 const t_ARG_02& arg_02,
8509 const t_ARG_03& arg_03,
8510 const t_ARG_04& arg_04,
8511 const t_ARG_05& arg_05,
8512 const t_ARG_06& arg_06,
8513 const t_ARG_07& arg_07,
8514 const t_ARG_08& arg_08,
8515 const t_ARG_09& arg_09,
8516 const t_ARG_10& arg_10)
8517: Variant_Base(bsl::allocator_arg_t(),
8518 allocator,
8519 bsl::in_place_index_t<t_INDEX>(),
8520 arg_01,
8521 arg_02,
8522 arg_03,
8523 arg_04,
8524 arg_05,
8525 arg_06,
8526 arg_07,
8527 arg_08,
8528 arg_09,
8529 arg_10)
8530{
8531}
8532
8533template <class t_HEAD, class... t_TAIL>
8534template <class t_TYPE>
8535typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8536 t_TYPE,
8537 variant<t_HEAD, t_TAIL...> >::value,
8538 t_TYPE&>::type
8540{
8541 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8542
8543 Variant_Base::template baseEmplace<index>();
8544
8545 return bsl::get<index>(*this);
8546}
8547
8548template <class t_HEAD, class... t_TAIL>
8549template <class t_TYPE, class t_ARG_01>
8550typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8551 t_TYPE,
8552 variant<t_HEAD, t_TAIL...> >::value,
8553 t_TYPE&>::type
8555{
8556 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8557
8558 Variant_Base::template baseEmplace<index>(arg_01);
8559
8560 return bsl::get<index>(*this);
8561}
8562
8563template <class t_HEAD, class... t_TAIL>
8564template <class t_TYPE, class t_ARG_01, class t_ARG_02>
8565typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8566 t_TYPE,
8567 variant<t_HEAD, t_TAIL...> >::value,
8568 t_TYPE&>::type
8570 const t_ARG_02& arg_02)
8571{
8572 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8573
8574 Variant_Base::template baseEmplace<index>(arg_01, arg_02);
8575
8576 return bsl::get<index>(*this);
8577}
8578
8579template <class t_HEAD, class... t_TAIL>
8580template <class t_TYPE, class t_ARG_01, class t_ARG_02, class t_ARG_03>
8581typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8582 t_TYPE,
8583 variant<t_HEAD, t_TAIL...> >::value,
8584 t_TYPE&>::type
8586 const t_ARG_02& arg_02,
8587 const t_ARG_03& arg_03)
8588{
8589 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8590
8591 Variant_Base::template baseEmplace<index>(arg_01, arg_02, arg_03);
8592
8593 return bsl::get<index>(*this);
8594}
8595
8596template <class t_HEAD, class... t_TAIL>
8597template <class t_TYPE,
8598 class t_ARG_01,
8599 class t_ARG_02,
8600 class t_ARG_03,
8601 class t_ARG_04>
8602typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8603 t_TYPE,
8604 variant<t_HEAD, t_TAIL...> >::value,
8605 t_TYPE&>::type
8607 const t_ARG_02& arg_02,
8608 const t_ARG_03& arg_03,
8609 const t_ARG_04& arg_04)
8610{
8611 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8612
8613 Variant_Base::template baseEmplace<index>(arg_01, arg_02, arg_03, arg_04);
8614
8615 return bsl::get<index>(*this);
8616}
8617
8618template <class t_HEAD, class... t_TAIL>
8619template <class t_TYPE,
8620 class t_ARG_01,
8621 class t_ARG_02,
8622 class t_ARG_03,
8623 class t_ARG_04,
8624 class t_ARG_05>
8625typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8626 t_TYPE,
8627 variant<t_HEAD, t_TAIL...> >::value,
8628 t_TYPE&>::type
8630 const t_ARG_02& arg_02,
8631 const t_ARG_03& arg_03,
8632 const t_ARG_04& arg_04,
8633 const t_ARG_05& arg_05)
8634{
8635 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8636
8637 Variant_Base::template baseEmplace<index>(
8638 arg_01, arg_02, arg_03, arg_04, arg_05);
8639
8640 return bsl::get<index>(*this);
8641}
8642
8643template <class t_HEAD, class... t_TAIL>
8644template <class t_TYPE,
8645 class t_ARG_01,
8646 class t_ARG_02,
8647 class t_ARG_03,
8648 class t_ARG_04,
8649 class t_ARG_05,
8650 class t_ARG_06>
8651typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8652 t_TYPE,
8653 variant<t_HEAD, t_TAIL...> >::value,
8654 t_TYPE&>::type
8656 const t_ARG_02& arg_02,
8657 const t_ARG_03& arg_03,
8658 const t_ARG_04& arg_04,
8659 const t_ARG_05& arg_05,
8660 const t_ARG_06& arg_06)
8661{
8662 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8663
8664 Variant_Base::template baseEmplace<index>(
8665 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06);
8666
8667 return bsl::get<index>(*this);
8668}
8669
8670template <class t_HEAD, class... t_TAIL>
8671template <class t_TYPE,
8672 class t_ARG_01,
8673 class t_ARG_02,
8674 class t_ARG_03,
8675 class t_ARG_04,
8676 class t_ARG_05,
8677 class t_ARG_06,
8678 class t_ARG_07>
8679typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8680 t_TYPE,
8681 variant<t_HEAD, t_TAIL...> >::value,
8682 t_TYPE&>::type
8684 const t_ARG_02& arg_02,
8685 const t_ARG_03& arg_03,
8686 const t_ARG_04& arg_04,
8687 const t_ARG_05& arg_05,
8688 const t_ARG_06& arg_06,
8689 const t_ARG_07& arg_07)
8690{
8691 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8692
8693 Variant_Base::template baseEmplace<index>(
8694 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06, arg_07);
8695
8696 return bsl::get<index>(*this);
8697}
8698
8699template <class t_HEAD, class... t_TAIL>
8700template <class t_TYPE,
8701 class t_ARG_01,
8702 class t_ARG_02,
8703 class t_ARG_03,
8704 class t_ARG_04,
8705 class t_ARG_05,
8706 class t_ARG_06,
8707 class t_ARG_07,
8708 class t_ARG_08>
8709typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8710 t_TYPE,
8711 variant<t_HEAD, t_TAIL...> >::value,
8712 t_TYPE&>::type
8714 const t_ARG_02& arg_02,
8715 const t_ARG_03& arg_03,
8716 const t_ARG_04& arg_04,
8717 const t_ARG_05& arg_05,
8718 const t_ARG_06& arg_06,
8719 const t_ARG_07& arg_07,
8720 const t_ARG_08& arg_08)
8721{
8722 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8723
8724 Variant_Base::template baseEmplace<index>(
8725 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06, arg_07, arg_08);
8726
8727 return bsl::get<index>(*this);
8728}
8729
8730template <class t_HEAD, class... t_TAIL>
8731template <class t_TYPE,
8732 class t_ARG_01,
8733 class t_ARG_02,
8734 class t_ARG_03,
8735 class t_ARG_04,
8736 class t_ARG_05,
8737 class t_ARG_06,
8738 class t_ARG_07,
8739 class t_ARG_08,
8740 class t_ARG_09>
8741typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8742 t_TYPE,
8743 variant<t_HEAD, t_TAIL...> >::value,
8744 t_TYPE&>::type
8746 const t_ARG_02& arg_02,
8747 const t_ARG_03& arg_03,
8748 const t_ARG_04& arg_04,
8749 const t_ARG_05& arg_05,
8750 const t_ARG_06& arg_06,
8751 const t_ARG_07& arg_07,
8752 const t_ARG_08& arg_08,
8753 const t_ARG_09& arg_09)
8754{
8755 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8756
8757 Variant_Base::template baseEmplace<index>(arg_01,
8758 arg_02,
8759 arg_03,
8760 arg_04,
8761 arg_05,
8762 arg_06,
8763 arg_07,
8764 arg_08,
8765 arg_09);
8766
8767 return bsl::get<index>(*this);
8768}
8769
8770template <class t_HEAD, class... t_TAIL>
8771template <class t_TYPE,
8772 class t_ARG_01,
8773 class t_ARG_02,
8774 class t_ARG_03,
8775 class t_ARG_04,
8776 class t_ARG_05,
8777 class t_ARG_06,
8778 class t_ARG_07,
8779 class t_ARG_08,
8780 class t_ARG_09,
8781 class t_ARG_10>
8782typename bsl::enable_if<BloombergLP::bslstl::Variant_HasUniqueType<
8783 t_TYPE,
8784 variant<t_HEAD, t_TAIL...> >::value,
8785 t_TYPE&>::type
8787 const t_ARG_02& arg_02,
8788 const t_ARG_03& arg_03,
8789 const t_ARG_04& arg_04,
8790 const t_ARG_05& arg_05,
8791 const t_ARG_06& arg_06,
8792 const t_ARG_07& arg_07,
8793 const t_ARG_08& arg_08,
8794 const t_ARG_09& arg_09,
8795 const t_ARG_10& arg_10)
8796{
8797 const size_t index = BSLSTL_VARIANT_INDEX_OF(t_TYPE, variant);
8798
8799 Variant_Base::template baseEmplace<index>(arg_01,
8800 arg_02,
8801 arg_03,
8802 arg_04,
8803 arg_05,
8804 arg_06,
8805 arg_07,
8806 arg_08,
8807 arg_09,
8808 arg_10);
8809
8810 return bsl::get<index>(*this);
8811}
8812
8813template <class t_HEAD, class... t_TAIL>
8814template <size_t t_INDEX>
8815typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8817{
8818 Variant_Base::template baseEmplace<t_INDEX>();
8819
8820 return bsl::get<t_INDEX>(*this);
8821}
8822
8823template <class t_HEAD, class... t_TAIL>
8824template <size_t t_INDEX, class t_ARG_01>
8825typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8827{
8828 Variant_Base::template baseEmplace<t_INDEX>(arg_01);
8829
8830 return bsl::get<t_INDEX>(*this);
8831}
8832
8833template <class t_HEAD, class... t_TAIL>
8834template <size_t t_INDEX, class t_ARG_01, class t_ARG_02>
8835typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8837 const t_ARG_02& arg_02)
8838{
8839 Variant_Base::template baseEmplace<t_INDEX>(arg_01, arg_02);
8840
8841 return bsl::get<t_INDEX>(*this);
8842}
8843
8844template <class t_HEAD, class... t_TAIL>
8845template <size_t t_INDEX, class t_ARG_01, class t_ARG_02, class t_ARG_03>
8846typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8848 const t_ARG_02& arg_02,
8849 const t_ARG_03& arg_03)
8850{
8851 Variant_Base::template baseEmplace<t_INDEX>(arg_01, arg_02, arg_03);
8852
8853 return bsl::get<t_INDEX>(*this);
8854}
8855
8856template <class t_HEAD, class... t_TAIL>
8857template <size_t t_INDEX,
8858 class t_ARG_01,
8859 class t_ARG_02,
8860 class t_ARG_03,
8861 class t_ARG_04>
8862typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8864 const t_ARG_02& arg_02,
8865 const t_ARG_03& arg_03,
8866 const t_ARG_04& arg_04)
8867{
8868 Variant_Base::template baseEmplace<t_INDEX>(
8869 arg_01, arg_02, arg_03, arg_04);
8870
8871 return bsl::get<t_INDEX>(*this);
8872}
8873
8874template <class t_HEAD, class... t_TAIL>
8875template <size_t t_INDEX,
8876 class t_ARG_01,
8877 class t_ARG_02,
8878 class t_ARG_03,
8879 class t_ARG_04,
8880 class t_ARG_05>
8881typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8883 const t_ARG_02& arg_02,
8884 const t_ARG_03& arg_03,
8885 const t_ARG_04& arg_04,
8886 const t_ARG_05& arg_05)
8887{
8888 Variant_Base::template baseEmplace<t_INDEX>(
8889 arg_01, arg_02, arg_03, arg_04, arg_05);
8890
8891 return bsl::get<t_INDEX>(*this);
8892}
8893
8894template <class t_HEAD, class... t_TAIL>
8895template <size_t t_INDEX,
8896 class t_ARG_01,
8897 class t_ARG_02,
8898 class t_ARG_03,
8899 class t_ARG_04,
8900 class t_ARG_05,
8901 class t_ARG_06>
8902typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8904 const t_ARG_02& arg_02,
8905 const t_ARG_03& arg_03,
8906 const t_ARG_04& arg_04,
8907 const t_ARG_05& arg_05,
8908 const t_ARG_06& arg_06)
8909{
8910 Variant_Base::template baseEmplace<t_INDEX>(
8911 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06);
8912
8913 return bsl::get<t_INDEX>(*this);
8914}
8915
8916template <class t_HEAD, class... t_TAIL>
8917template <size_t t_INDEX,
8918 class t_ARG_01,
8919 class t_ARG_02,
8920 class t_ARG_03,
8921 class t_ARG_04,
8922 class t_ARG_05,
8923 class t_ARG_06,
8924 class t_ARG_07>
8925typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8927 const t_ARG_02& arg_02,
8928 const t_ARG_03& arg_03,
8929 const t_ARG_04& arg_04,
8930 const t_ARG_05& arg_05,
8931 const t_ARG_06& arg_06,
8932 const t_ARG_07& arg_07)
8933{
8934 Variant_Base::template baseEmplace<t_INDEX>(
8935 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06, arg_07);
8936
8937 return bsl::get<t_INDEX>(*this);
8938}
8939
8940template <class t_HEAD, class... t_TAIL>
8941template <size_t t_INDEX,
8942 class t_ARG_01,
8943 class t_ARG_02,
8944 class t_ARG_03,
8945 class t_ARG_04,
8946 class t_ARG_05,
8947 class t_ARG_06,
8948 class t_ARG_07,
8949 class t_ARG_08>
8950typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8952 const t_ARG_02& arg_02,
8953 const t_ARG_03& arg_03,
8954 const t_ARG_04& arg_04,
8955 const t_ARG_05& arg_05,
8956 const t_ARG_06& arg_06,
8957 const t_ARG_07& arg_07,
8958 const t_ARG_08& arg_08)
8959{
8960 Variant_Base::template baseEmplace<t_INDEX>(
8961 arg_01, arg_02, arg_03, arg_04, arg_05, arg_06, arg_07, arg_08);
8962
8963 return bsl::get<t_INDEX>(*this);
8964}
8965
8966template <class t_HEAD, class... t_TAIL>
8967template <size_t t_INDEX,
8968 class t_ARG_01,
8969 class t_ARG_02,
8970 class t_ARG_03,
8971 class t_ARG_04,
8972 class t_ARG_05,
8973 class t_ARG_06,
8974 class t_ARG_07,
8975 class t_ARG_08,
8976 class t_ARG_09>
8977typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
8979 const t_ARG_02& arg_02,
8980 const t_ARG_03& arg_03,
8981 const t_ARG_04& arg_04,
8982 const t_ARG_05& arg_05,
8983 const t_ARG_06& arg_06,
8984 const t_ARG_07& arg_07,
8985 const t_ARG_08& arg_08,
8986 const t_ARG_09& arg_09)
8987{
8988 Variant_Base::template baseEmplace<t_INDEX>(arg_01,
8989 arg_02,
8990 arg_03,
8991 arg_04,
8992 arg_05,
8993 arg_06,
8994 arg_07,
8995 arg_08,
8996 arg_09);
8997
8998 return bsl::get<t_INDEX>(*this);
8999}
9000
9001template <class t_HEAD, class... t_TAIL>
9002template <size_t t_INDEX,
9003 class t_ARG_01,
9004 class t_ARG_02,
9005 class t_ARG_03,
9006 class t_ARG_04,
9007 class t_ARG_05,
9008 class t_ARG_06,
9009 class t_ARG_07,
9010 class t_ARG_08,
9011 class t_ARG_09,
9012 class t_ARG_10>
9013typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
9015 const t_ARG_02& arg_02,
9016 const t_ARG_03& arg_03,
9017 const t_ARG_04& arg_04,
9018 const t_ARG_05& arg_05,
9019 const t_ARG_06& arg_06,
9020 const t_ARG_07& arg_07,
9021 const t_ARG_08& arg_08,
9022 const t_ARG_09& arg_09,
9023 const t_ARG_10& arg_10)
9024{
9025 Variant_Base::template baseEmplace<t_INDEX>(arg_01,
9026 arg_02,
9027 arg_03,
9028 arg_04,
9029 arg_05,
9030 arg_06,
9031 arg_07,
9032 arg_08,
9033 arg_09,
9034 arg_10);
9035
9036 return bsl::get<t_INDEX>(*this);
9037}
9038
9039template <class t_HEAD, class... t_TAIL>
9040inline
9042 const variant& rhs)
9043{
9044 Variant_Base::operator=(static_cast<const Variant_Base&>(rhs));
9045 return *this;
9046}
9047
9048template <class t_HEAD, class... t_TAIL>
9049inline
9051 BloombergLP::bslmf::MovableRef<variant> rhs)
9052{
9053 variant<t_HEAD, t_TAIL...>& lvalue = rhs;
9054 Variant_Base::operator=(
9055 MoveUtil::move(static_cast<Variant_Base&>(lvalue)));
9056 return *this;
9057}
9058template <class t_HEAD, class... t_TAIL>
9059template <class t_TYPE>
9060inline
9061typename bsl::enable_if<
9062 BloombergLP::bslstl::Variant_AssignsFromType<variant<t_HEAD, t_TAIL...>,
9063 t_TYPE>::value,
9064 variant<t_HEAD, t_TAIL...>&>::type
9066{
9067 const size_t altIndex = BSLSTL_VARIANT_CONVERT_INDEX_OF(t_TYPE, variant);
9068
9069 if (index() == altIndex) {
9070 bsl::get<altIndex>(*this) = rhs;
9071 }
9072 else {
9073 // 'altIndex' can not be @ref variant_npos if 'Variant_AssignsFromType' is
9074 // satisfied
9075 emplace<altIndex>(rhs);
9076 }
9077
9078 return *this;
9079}
9080#endif
9081#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9082
9083#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
9084template <class t_HEAD, class... t_TAIL>
9085inline
9087{
9088 if (!valueless_by_exception()) {
9089 if (index() == other.index()) {
9090 BloombergLP::bslstl::Variant_SwapVisitor<variant> swapper(this);
9091 BSLSTL_VARIANT_VISITID(void, swapper, other);
9092 }
9093 else {
9094 variant tmpThis(MoveUtil::move(*this));
9095 this->reset();
9096 if (!other.valueless_by_exception()) {
9097 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
9098 moveConstructor(this);
9099 BSLSTL_VARIANT_VISITID(void, moveConstructor, other);
9100 }
9101#ifndef BSL_VARIANT_FULL_IMPLEMENTATION
9102 // In C++03, if there are nonunique alternatives,
9103 // 'BSLSTL_VARIANT_VISITID' will always use the first nonunique
9104 // alternative, which may result in the wrong 'd_type' being set.
9105 this->d_type = other.index();
9106#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9107 other.reset();
9108 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
9109 moveConstructor(BSLS_UTIL_ADDRESSOF(other));
9110 BSLSTL_VARIANT_VISITID(void, moveConstructor, tmpThis);
9111#ifndef BSL_VARIANT_FULL_IMPLEMENTATION
9112 other.d_type = tmpThis.index();
9113#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9114 }
9115 }
9116 else {
9117 if (!other.valueless_by_exception()) {
9118 BloombergLP::bslstl::Variant_MoveConstructVisitor<Variant_Base>
9119 moveConstructor(this);
9120 BSLSTL_VARIANT_VISITID(void, moveConstructor, other);
9121#ifndef BSL_VARIANT_FULL_IMPLEMENTATION
9122 this->d_type = other.index();
9123#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9124 other.reset();
9125 }
9126 }
9127}
9128
9129// ACCESSORS
9130template <class t_HEAD, class... t_TAIL>
9131inline
9133{
9134 return this->d_type;
9135}
9136
9137template <class t_HEAD, class... t_TAIL>
9138inline
9144
9145#endif
9146
9147// FREE FUNCTIONS
9148#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
9149template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9150typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type& get(
9152{
9154
9155 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9156 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9158
9159 return ImpUtil::get<Ret, t_INDEX>(obj);
9160}
9161
9162template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9163const typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&
9164get(const variant<t_HEAD, t_TAIL...>& obj)
9165{
9166 BSLMF_ASSERT((t_INDEX < variant_size<variant<t_HEAD, t_TAIL...> >::value));
9167
9168 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9169 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9171
9172 return ImpUtil::get<const Ret, t_INDEX>(obj);
9173}
9174
9175template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9176typename variant_alternative<t_INDEX, variant<t_HEAD, t_TAIL...> >::type&& get(
9177 variant<t_HEAD, t_TAIL...>&& obj)
9178{
9179 BSLMF_ASSERT((t_INDEX < variant_size<variant<t_HEAD, t_TAIL...> >::value));
9180
9181 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9182 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9184
9185 return std::move(ImpUtil::get<Ret, t_INDEX>(obj));
9186}
9187
9188template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9189const typename variant_alternative<t_INDEX,
9190 variant<t_HEAD, t_TAIL...> >::type&&
9191get(const variant<t_HEAD, t_TAIL...>&& obj)
9192{
9193 BSLMF_ASSERT((t_INDEX < variant_size<variant<t_HEAD, t_TAIL...> >::value));
9194
9195 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9196 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9198
9199 return std::move(ImpUtil::get<const Ret, t_INDEX>(obj));
9200}
9201#else // BSL_VARIANT_FULL_IMPLEMENTATION
9202#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
9203template <size_t t_INDEX, class t_VARIANT>
9204typename Variant_GetIndexReturnType<t_INDEX, t_VARIANT>::type
9205get(t_VARIANT& obj)
9206{
9208
9209 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9211
9212 return ImpUtil::get<Ret, t_INDEX>(obj);
9213}
9214
9215template <size_t t_INDEX, class t_VARIANT>
9216typename Variant_GetIndexReturnType<
9217 t_INDEX,
9218 BloombergLP::bslmf::MovableRef<t_VARIANT> >::type
9219get(BloombergLP::bslmf::MovableRef<t_VARIANT> obj)
9220{
9221 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
9222 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9224
9225 t_VARIANT& lvalue = obj;
9226
9227 return MoveUtil::move(ImpUtil::get<Ret, t_INDEX>(lvalue));
9228}
9229#endif
9230#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9231
9232#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
9233template <class t_TYPE, class t_HEAD, class... t_TAIL>
9234t_TYPE& get(variant<t_HEAD, t_TAIL...>& obj)
9235{
9236 BSLMF_ASSERT((BloombergLP::bslstl::Variant_HasUniqueType<
9237 t_TYPE,
9238 variant<t_HEAD, t_TAIL...> >::value));
9239
9240 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9241 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9242
9243 return ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(obj);
9244}
9245
9246template <class t_TYPE, class t_HEAD, class... t_TAIL>
9247const t_TYPE& get(const variant<t_HEAD, t_TAIL...>& obj)
9248{
9249 BSLMF_ASSERT((BloombergLP::bslstl::Variant_HasUniqueType<
9250 t_TYPE,
9251 variant<t_HEAD, t_TAIL...> >::value));
9252
9253 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9254 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9255
9256 return ImpUtil::get<const t_TYPE,
9257 BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(obj);
9258}
9259
9260template <class t_TYPE, class t_HEAD, class... t_TAIL>
9261t_TYPE&& get(variant<t_HEAD, t_TAIL...>&& obj)
9262{
9263 static_assert(
9264 BloombergLP::bslstl::
9265 Variant_HasUniqueType<t_TYPE, variant<t_HEAD, t_TAIL...> >::value,
9266 "Type is not unique in variant");
9267
9268 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9269 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9270
9271 return std::move(
9272 ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(obj));
9273}
9274
9275template <class t_TYPE, class t_HEAD, class... t_TAIL>
9276const t_TYPE&& get(const variant<t_HEAD, t_TAIL...>&& obj)
9277{
9278 static_assert(
9279 BloombergLP::bslstl::
9280 Variant_HasUniqueType<t_TYPE, variant<t_HEAD, t_TAIL...> >::value,
9281 "Type is not unique in variant");
9282
9283 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9284 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9285
9286 return std::move(
9287 ImpUtil::get<const t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(
9288 obj));
9289}
9290#else // BSL_VARIANT_FULL_IMPLEMENTATION
9291#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
9292template <class t_TYPE, class t_VARIANT>
9293typename Variant_GetTypeReturnType<t_TYPE&, t_VARIANT>::type
9294get(t_VARIANT& obj)
9295{
9296 BSLMF_ASSERT((
9297 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, t_VARIANT>::value));
9298
9299 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9300
9301 return ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
9302 obj);
9303}
9304
9305template <class t_TYPE, class t_VARIANT>
9306typename Variant_GetTypeReturnType<const t_TYPE&, t_VARIANT>::type
9307get(const t_VARIANT& obj)
9308{
9309 BSLMF_ASSERT((
9310 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, t_VARIANT>::value));
9311
9312 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9313
9314 return ImpUtil::get<const t_TYPE,
9315 BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(obj);
9316}
9317
9318template <class t_TYPE, class t_VARIANT>
9319typename Variant_GetTypeReturnType<BloombergLP::bslmf::MovableRef<t_TYPE>,
9320 t_VARIANT>::type
9321get(BloombergLP::bslmf::MovableRef<t_VARIANT> obj)
9322{
9323 BSLMF_ASSERT((
9324 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, t_VARIANT>::value));
9325
9326 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
9327 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9328
9329 t_VARIANT& lvalue = obj;
9330 return MoveUtil::move(
9331 ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
9332 lvalue));
9333}
9334#endif
9335#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9336
9337#ifdef BSL_VARIANT_FULL_IMPLEMENTATION
9338template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9339typename add_pointer<
9340 typename variant_alternative<t_INDEX,
9341 variant<t_HEAD, t_TAIL...> >::type>::type
9342get_if(variant<t_HEAD, t_TAIL...> *ptr) BSLS_KEYWORD_NOEXCEPT
9343{
9344 BSLMF_ASSERT((t_INDEX < variant_size<variant<t_HEAD, t_TAIL...> >::value));
9345
9346 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9347 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9349
9350 if (ptr == 0 || ptr->index() != t_INDEX) {
9351 return NULL; // RETURN
9352 }
9353
9354 return BSLS_UTIL_ADDRESSOF((ImpUtil::get<Ret, t_INDEX>(*ptr)));
9355}
9356
9357template <size_t t_INDEX, class t_HEAD, class... t_TAIL>
9358typename add_pointer<const typename variant_alternative<
9359 t_INDEX,
9360 variant<t_HEAD, t_TAIL...> >::type>::type
9361get_if(const variant<t_HEAD, t_TAIL...> *ptr) BSLS_KEYWORD_NOEXCEPT
9362{
9363 BSLMF_ASSERT((t_INDEX < variant_size<variant<t_HEAD, t_TAIL...> >::value));
9364
9365 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9366 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9368
9369 if (ptr == 0 || ptr->index() != t_INDEX) {
9370 return NULL; // RETURN
9371 }
9372 return BSLS_UTIL_ADDRESSOF((ImpUtil::get<const Ret, t_INDEX>(*ptr)));
9373}
9374
9375template <class t_TYPE, class t_HEAD, class... t_TAIL>
9377 variant<t_HEAD, t_TAIL...> *ptr) BSLS_KEYWORD_NOEXCEPT
9378{
9379 BSLMF_ASSERT((BloombergLP::bslstl::Variant_HasUniqueType<
9380 t_TYPE,
9381 variant<t_HEAD, t_TAIL...> >::value));
9382
9383 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9384 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9385
9386 if (ptr == 0 || ptr->index() != BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)) {
9387 return NULL; // RETURN
9388 }
9389 return BSLS_UTIL_ADDRESSOF((
9390 ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(*ptr)));
9391}
9392
9393template <class t_TYPE, class t_HEAD, class... t_TAIL>
9395 const variant<t_HEAD, t_TAIL...> *ptr) BSLS_KEYWORD_NOEXCEPT
9396{
9397 BSLMF_ASSERT((BloombergLP::bslstl::Variant_HasUniqueType<
9398 t_TYPE,
9399 variant<t_HEAD, t_TAIL...> >::value));
9400
9401 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9402 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9403
9404 if (ptr == 0 || ptr->index() != BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)) {
9405 return NULL; // RETURN
9406 }
9407 return BSLS_UTIL_ADDRESSOF(
9408 (ImpUtil::get<const t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant)>(
9409 *ptr)));
9410}
9411#else
9412#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
9413template <size_t t_INDEX, class t_VARIANT>
9414typename Variant_GetIndexReturnType<t_INDEX, t_VARIANT>::pointer
9416{
9418
9419 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9421
9422 if (ptr == 0 || ptr->index() != t_INDEX) {
9423 return NULL; // RETURN
9424 }
9425
9426 return BSLS_UTIL_ADDRESSOF((ImpUtil::get<Ret, t_INDEX>(*ptr)));
9427}
9428
9429template <class t_TYPE, class t_VARIANT>
9430typename Variant_GetTypeReturnType<t_TYPE, t_VARIANT>::pointer
9432{
9433 BSLMF_ASSERT((
9434 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, t_VARIANT>::value));
9435
9436 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9437
9438 if (ptr == 0 ||
9439 ptr->index() != BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)) {
9440 return NULL; // RETURN
9441 }
9442 return BSLS_UTIL_ADDRESSOF(
9443 (ImpUtil::get<t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
9444 *ptr)));
9445}
9446
9447template <class t_TYPE, class t_VARIANT>
9448typename Variant_GetTypeReturnType<const t_TYPE, t_VARIANT>::pointer
9449get_if(const t_VARIANT *ptr) BSLS_KEYWORD_NOEXCEPT
9450{
9451 BSLMF_ASSERT((
9452 BloombergLP::bslstl::Variant_HasUniqueType<t_TYPE, t_VARIANT>::value));
9453
9454 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9455
9456 if (ptr == 0 ||
9457 ptr->index() != BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)) {
9458 return NULL; // RETURN
9459 }
9460 return BSLS_UTIL_ADDRESSOF((
9461 ImpUtil::get<const t_TYPE, BSLSTL_VARIANT_INDEX_OF(t_TYPE, t_VARIANT)>(
9462 *ptr)));
9463}
9464#endif
9465#endif // BSL_VARIANT_FULL_IMPLEMENTATION
9466
9467#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
9468// HASH SPECIALIZATIONS
9469template <class t_HASHALG, class t_HEAD, class... t_TAIL>
9470void hashAppend(t_HASHALG& hashAlg, const variant<t_HEAD, t_TAIL...>& input)
9471{
9472 if (!input.valueless_by_exception()) {
9473 hashAppend(hashAlg, input.index());
9474 BloombergLP::bslstl::Variant_HashVisitor<t_HASHALG> hashVisitor(
9475 hashAlg);
9476 visit(hashVisitor, input);
9477 }
9478 else {
9479 hashAppend(hashAlg, false);
9480 }
9481}
9482
9483template <class t_TYPE, class t_HEAD, class... t_TAIL>
9486{
9487 BSLMF_ASSERT((BloombergLP::bslstl::Variant_HasUniqueType<
9488 t_TYPE,
9489 variant<t_HEAD, t_TAIL...> >::value));
9490 typedef typename bsl::variant<t_HEAD, t_TAIL...> Variant;
9491 return obj.index() == BSLSTL_VARIANT_INDEX_OF(t_TYPE, Variant);
9492}
9493
9494template <class t_HEAD, class... t_TAIL>
9497{
9498 BloombergLP::bslstl::variant_swapImpl(
9500 bool,
9501 BloombergLP::bslstl::
9502 Variant_UsesBslmaAllocatorAny<t_HEAD, t_TAIL...>::value>(),
9503 lhs,
9504 rhs);
9505}
9506
9507// FREE OPERATORS
9508template <class t_HEAD, class... t_TAIL>
9509bool operator==(const variant<t_HEAD, t_TAIL...>& lhs,
9510 const variant<t_HEAD, t_TAIL...>& rhs)
9511{
9512 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9513
9514 if (lhs.index() != rhs.index()) {
9515 return false; // RETURN
9516 }
9517 else if (lhs.valueless_by_exception()) {
9518 return true; // RETURN
9519 }
9520 return ImpUtil::Equal(lhs, rhs);
9521}
9522
9523template <class t_HEAD, class... t_TAIL>
9524bool operator!=(const variant<t_HEAD, t_TAIL...>& lhs,
9525 const variant<t_HEAD, t_TAIL...>& rhs)
9526{
9527 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9528
9529 if (lhs.index() != rhs.index()) {
9530 return true; // RETURN
9531 }
9532 else if (lhs.valueless_by_exception()) {
9533 return false; // RETURN
9534 }
9535 return ImpUtil::NotEqual(lhs, rhs);
9536}
9537
9538template <class t_HEAD, class... t_TAIL>
9539bool operator<(const variant<t_HEAD, t_TAIL...>& lhs,
9540 const variant<t_HEAD, t_TAIL...>& rhs)
9541{
9542 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9543
9544 if (rhs.valueless_by_exception()) {
9545 return false; // RETURN
9546 }
9547 else if (lhs.valueless_by_exception()) {
9548 return true; // RETURN
9549 }
9550 else if (lhs.index() != rhs.index()) {
9551 return lhs.index() < rhs.index(); // RETURN
9552 }
9553 return ImpUtil::LessThan(lhs, rhs);
9554}
9555
9556template <class t_HEAD, class... t_TAIL>
9557bool operator>(const variant<t_HEAD, t_TAIL...>& lhs,
9558 const variant<t_HEAD, t_TAIL...>& rhs)
9559{
9560 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9561
9562 if (lhs.valueless_by_exception()) {
9563 return false; // RETURN
9564 }
9565 else if (rhs.valueless_by_exception()) {
9566 return true; // RETURN
9567 }
9568 else if (lhs.index() != rhs.index()) {
9569 return lhs.index() > rhs.index(); // RETURN
9570 }
9571 return ImpUtil::GreaterThan(lhs, rhs);
9572}
9573
9574template <class t_HEAD, class... t_TAIL>
9575bool operator<=(const variant<t_HEAD, t_TAIL...>& lhs,
9576 const variant<t_HEAD, t_TAIL...>& rhs)
9577{
9578 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9579
9580 if (lhs.valueless_by_exception()) {
9581 return true; // RETURN
9582 }
9583 else if (rhs.valueless_by_exception()) {
9584 return false; // RETURN
9585 }
9586 else if (lhs.index() != rhs.index()) {
9587 return lhs.index() < rhs.index(); // RETURN
9588 }
9589 return ImpUtil::LessOrEqual(lhs, rhs);
9590}
9591
9592template <class t_HEAD, class... t_TAIL>
9593bool operator>=(const variant<t_HEAD, t_TAIL...>& lhs,
9594 const variant<t_HEAD, t_TAIL...>& rhs)
9595{
9596 typedef BloombergLP::bslstl::Variant_ImpUtil ImpUtil;
9597
9598 if (rhs.valueless_by_exception()) {
9599 return true; // RETURN
9600 }
9601 else if (lhs.valueless_by_exception()) {
9602 return false; // RETURN
9603 }
9604 else if (lhs.index() != rhs.index()) {
9605 return lhs.index() > rhs.index(); // RETURN
9606 }
9607
9608 return ImpUtil::GreaterOrEqual(lhs, rhs);
9609}
9610
9611#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON && \
9612 defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
9613
9614template <class... t_ALTS>
9615 requires(std::three_way_comparable<t_ALTS> && ...)
9616constexpr std::common_comparison_category_t<
9617 std::compare_three_way_result_t<t_ALTS>...>
9618operator<=>(const variant<t_ALTS...>& lhs, const variant<t_ALTS...>& rhs)
9619{
9620 using RET = std::common_comparison_category_t<
9621 std::compare_three_way_result_t<t_ALTS>...>;
9622
9623 const size_t lhs_index = lhs.index();
9624 const size_t rhs_index = rhs.index();
9625 if ((lhs_index != variant_npos) && (rhs_index != variant_npos)) {
9626 if (lhs_index == rhs_index) {
9627 return BloombergLP::bslstl::Variant_ImpUtil::visitId<RET>(
9628 [&lhs]<size_t t_INDEX>(bsl::in_place_index_t<t_INDEX>,
9629 auto&& rhs_value) {
9630 return bsl::get<t_INDEX>(lhs) <=> rhs_value; // RETURN
9631 },
9632 rhs);
9633 }
9634 else {
9635 return lhs_index <=> rhs_index; // RETURN
9636 }
9637 }
9638 else {
9639 if (lhs_index == variant_npos) {
9640 if (rhs_index == variant_npos)
9641 return std::strong_ordering::equal; // RETURN
9642 else
9643 return std::strong_ordering::less; // RETURN
9644 }
9645 else
9646 return std::strong_ordering::greater; // RETURN
9647 }
9648}
9649#endif
9650
9651#endif
9652} // close namespace bsl
9653
9654#endif // End C++11 code
9655
9656#undef BSL_VARIANT_FULL_IMPLEMENTATION
9657#undef BSLSTL_VARIANT_NOT_A_TYPE
9658#undef BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM
9659#undef BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM
9660#undef BSLSTL_VARIANT_DEFINE_IF_HAS_UNIQUE_TYPE
9661#undef BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE
9662#undef BSLSTL_VARIANT_HAS_UNIQUE_TYPE
9663#undef BSLSTL_VARIANT_TYPE_AT_INDEX
9664#undef BSLSTL_VARIANT_INDEX_OF
9665#undef BSLSTL_VARIANT_CONVERT_INDEX_OF
9666#undef BSLSTL_VARIANT_CONVERT_TYPE_OF
9667#undef BSLSTL_VARIANT_VISITID
9668#undef BSLSTL_VARIANT_RELOP_VISITOR_DEFINITON
9669
9670#endif // End C++11 code
9671
9672// ----------------------------------------------------------------------------
9673// Copyright 2023 Bloomberg Finance L.P.
9674//
9675// Licensed under the Apache License, Version 2.0 (the "License");
9676// you may not use this file except in compliance with the License.
9677// You may obtain a copy of the License at
9678//
9679// http://www.apache.org/licenses/LICENSE-2.0
9680//
9681// Unless required by applicable law or agreed to in writing, software
9682// distributed under the License is distributed on an "AS IS" BASIS,
9683// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9684// See the License for the specific language governing permissions and
9685// limitations under the License.
9686// ----------------------------- END-OF-FILE ----------------------------------
9687
9688/** @} */
9689/** @} */
9690/** @} */
#define BSLSTL_VARIANT_DEFINE_IF_HAS_UNIQUE_TYPE(TYPE)
Definition bslstl_variant.h:890
#define BSLSTL_VARIANT_DEFINE_IF_CONSTRUCTS_FROM(VARIANT, TYPE)
Definition bslstl_variant.h:857
#define BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM_STD(STD_VARIANT)
Definition bslstl_variant.h:880
#define BSLSTL_VARIANT_HAS_UNIQUE_TYPE(TYPE)
Definition bslstl_variant.h:906
#define BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM(VARIANT, TYPE)
Definition bslstl_variant.h:866
#define BSLSTL_VARIANT_INDEX_OF(TYPE, VARIANT)
Definition bslstl_variant.h:920
#define BSLSTL_VARIANT_TYPE_AT_INDEX(INDEX)
Definition bslstl_variant.h:913
#define BSLSTL_VARIANT_RELOP_VISITOR_DEFINITON(NAME, OP)
Definition bslstl_variant.h:2754
#define BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(TYPE)
Definition bslstl_variant.h:898
#define BSLSTL_VARIANT_VISITID(RET, VISITOR, VAROBJ)
Definition bslstl_variant.h:943
#define BSLSTL_VARIANT_CONVERT_INDEX_OF(TYPE, VARIANT)
Definition bslstl_variant.h:927
Definition bslma_bslallocator.h:580
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1126
Definition bslstl_variant.h:3685
size_t index() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_variant.h:9132
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
void swap(variant &other)
Definition bslstl_variant.h:9086
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, const t_ARG_09 &arg_09, const t_ARG_10 &arg_10, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
BSLMF_NESTED_TRAIT_DECLARATION_IF(variant, BloombergLP::bslma::UsesBslmaAllocator,(BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value))
bool valueless_by_exception() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_variant.h:9139
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
~variant()=default
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
BSLMF_NESTED_TRAIT_DECLARATION_IF(variant, BloombergLP::bslmf::UsesAllocatorArgT,(BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
BSLMF_NESTED_TRAIT_DECLARATION_IF(variant, BloombergLP::bslmf::IsBitwiseMoveable,(BloombergLP::bslstl::Variant_IsBitwiseMoveableAll< t_HEAD, t_TAIL... >::value))
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, const t_ARG_09 &arg_09, const t_ARG_10 &arg_10, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, const t_TYPE &value, BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM(variant, t_TYPE))
variant(const t_TYPE &value, BSLSTL_VARIANT_DECLARE_IF_CONSTRUCTS_FROM(variant, t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
Variant_Base::allocator_type allocator_type
Type alias to the allocator type used by variant.
Definition bslstl_variant.h:3725
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_variant.h:5531
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant()
Definition bslstl_variant.h:7320
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
friend struct BloombergLP::bslstl::Variant_ImpUtil
Definition bslstl_variant.h:3694
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant & operator=(const variant &rhs)
Definition bslstl_variant.h:9041
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, const t_ARG_09 &arg_09, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
bsl::enable_if< BloombergLP::bslstl::Variant_HasUniqueType< t_TYPE, variant >::value, t_TYPE & >::type emplace()
Definition bslstl_variant.h:8539
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, const t_ARG_02 &arg_02, const t_ARG_03 &arg_03, const t_ARG_04 &arg_04, const t_ARG_05 &arg_05, const t_ARG_06 &arg_06, const t_ARG_07 &arg_07, const t_ARG_08 &arg_08, const t_ARG_09 &arg_09, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::in_place_type_t< t_TYPE >, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::allocator_arg_t, allocator_type allocator, bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
variant(bsl::in_place_type_t< t_TYPE >, const t_ARG_01 &arg_01, BSLSTL_VARIANT_DECLARE_IF_HAS_UNIQUE_TYPE(t_TYPE))
Definition bslmf_movableref.h:751
Definition bslstl_variant.h:2598
void operator()(bsl::in_place_index_t< t_INDEX >, const t_TYPE &value) const
Definition bslstl_variant.h:2626
Variant_CopyAssignVisitor(t_VARIANT *variant)
Definition bslstl_variant.h:2609
t_TYPE & value()
Definition bslstl_variant.h:5848
Definition bslstl_variant.h:2869
void operator()(t_TYPE &value) const
Definition bslstl_variant.h:2890
Variant_HashVisitor(t_HASHALG &hashAlg)
Definition bslstl_variant.h:2880
Definition bslstl_variant.h:2654
void operator()(bsl::in_place_index_t< t_INDEX >, t_TYPE &value) const
Definition bslstl_variant.h:2684
Variant_MoveAssignVisitor(t_VARIANT *variant)
Definition bslstl_variant.h:2668
Definition bslstl_variant.h:2556
void operator()(bsl::in_place_index_t< t_INDEX >, t_TYPE &other) const
Definition bslstl_variant.h:2583
Variant_MoveConstructVisitor(t_VARIANT_BASE *variant)
Definition bslstl_variant.h:2570
Definition bslstl_variant.h:2814
Variant_SwapVisitor(t_VARIANT *variant)
Definition bslstl_variant.h:2826
void operator()(bsl::in_place_index_t< t_INDEX >, t_TYPE &value) const
Definition bslstl_variant.h:2841
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_THROW(X)
Definition bsls_exceptionutil.h:374
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR_CPP14
Definition bsls_keyword.h:595
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_INLINE_CONSTEXPR
Definition bsls_keyword.h:617
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_INLINE_VARIABLE
Definition bsls_keyword.h:623
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
void BSLSTL_VARIANT_NOT_A_TYPE
Definition bslstl_variant.h:322
Definition bdlb_printmethods.h:283
bool holds_alternative(const variant< t_HEAD, t_TAIL... > &obj) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_variant.h:9484
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:950
Variant_GetIndexReturnType< t_INDEX, t_VARIANT >::pointer get_if(t_VARIANT *obj) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_variant.h:9415
BSLS_KEYWORD_CONSTEXPR_CPP14 TYPE & get(array< TYPE, SIZE > &a) BSLS_KEYWORD_NOEXCEPT
BSLS_KEYWORD_INLINE_CONSTEXPR size_t variant_npos
Definition bslstl_variant.h:373
bsl::invoke_result< t_VISITOR &, typenamebsl::variant_alternative< 0, t_VARIANT >::type & >::type visit(t_VISITOR &visitor, t_VARIANT &variant)
Definition bslstl_variant.h:2262
Definition bslstl_algorithm.h:82
void variant_swapImpl(bsl::true_type, t_VARIANT &lhs, t_VARIANT &rhs)
Definition bslstl_variant.h:5884
Definition bdldfp_decimal.h:5188
BloombergLP::bslmf::MovableRef< typename bsl::variant_alternative< t_INDEX, t_VARIANT >::type > type
Definition bslstl_variant.h:582
bsl::variant_alternative< t_INDEX, constt_VARIANT >::type * pointer
Definition bslstl_variant.h:571
bsl::variant_alternative< t_INDEX, constt_VARIANT >::type & type
Definition bslstl_variant.h:568
bsl::variant_alternative< t_INDEX, t_VARIANT >::type & type
Definition bslstl_variant.h:556
bsl::variant_alternative< t_INDEX, t_VARIANT >::type * pointer
Definition bslstl_variant.h:559
Definition bslstl_variant.h:544
Definition bslstl_variant.h:589
Definition bslstl_variant.h:412
Definition bslmf_addpointer.h:169
BloombergLP::bslmf::AddPointer_Impl< t_TYPE >::type type
Definition bslmf_addpointer.h:175
Definition bslmf_conditional.h:120
Definition bslmf_enableif.h:525
Definition bslstl_inplace.h:175
Definition bslstl_inplace.h:137
Definition bslmf_integralconstant.h:244
Definition bslmf_removecv.h:118
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:126
variant_alternative< t_INDEX, t_TYPE >::type const type
Definition bslstl_variant.h:388
variant_alternative< t_INDEX, t_TYPE >::type const volatile type
Definition bslstl_variant.h:399
BSLMF_ASSERT((t_INDEX< bsl::variant_size< variant< t_HEAD, t_TAIL... > >::value))
variant_alternative< t_INDEX, t_TYPE >::type volatile type
Definition bslstl_variant.h:393
Definition bslstl_variant.h:384
Definition bslstl_variant.h:341
BloombergLP::bslmf::MovableRefUtil MoveUtil
Definition bslstl_variant.h:2924
BloombergLP::bslma::Allocator * mechanism() const
Return the mechanism of the stored allocator.
Definition bslstl_variant.h:2953
bsl::allocator< char > allocator_type
Definition bslstl_variant.h:2925
Variant_AllocatorBase()
Definition bslstl_variant.h:2934
allocator_type d_allocator
Definition bslstl_variant.h:2928
Variant_AllocatorBase(allocator_type allocator)
Definition bslstl_variant.h:2945
Variant_AllocatorBase(const Variant_AllocatorBase &original)
Definition bslstl_variant.h:2938
Definition bslstl_variant.h:2901
BloombergLP::bslma::Allocator * mechanism() const
Definition bslstl_variant.h:2913
Definition bslstl_variant.h:2988
Definition bslstl_variant.h:2974
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant_Base, BloombergLP::bslma::UsesBslmaAllocator,(BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value))
Variant_Base()
Definition bslstl_variant.h:6042
bsl::conditional< BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value, bsl::allocator< char >, NoAlloc >::type allocator_type
Type alias to the allocator type used by variant.
Definition bslstl_variant.h:2996
size_t d_type
Definition bslstl_variant.h:3002
void baseEmplace()
Definition bslstl_variant.h:6882
bsl::variant< t_HEAD, t_TAIL... > Variant
Definition bslstl_variant.h:2984
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant_Base, BloombergLP::bslmf::IsBitwiseMoveable,(BloombergLP::bslstl::Variant_IsBitwiseMoveableAll< t_HEAD, t_TAIL... >::value))
Variant_Union d_union
Union holding the alternative object.
Definition bslstl_variant.h:3005
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant_Base, BloombergLP::bslmf::UsesAllocatorArgT,(BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value))
~Variant_Base()
Destroy this object. The contained value, if any, is destroyed.
Definition bslstl_variant.h:6846
BloombergLP::bslmf::MovableRefUtil MoveUtil
Definition bslstl_variant.h:2977
void reset() BSLS_KEYWORD_NOEXCEPT
Destroy the contained value, if any.
Definition bslstl_variant.h:7267
BloombergLP::bslstl::Variant_Union< t_HEAD, t_TAIL... > Variant_Union
Definition bslstl_variant.h:2983
Variant_Base & operator=(const Variant_Base &rhs)
Definition bslstl_variant.h:7210
BloombergLP::bslstl::Variant_AllocatorBase< BloombergLP::bslstl::Variant_UsesBslmaAllocatorAny< t_HEAD, t_TAIL... >::value > AllocBase
Definition bslstl_variant.h:2981
Definition bslstl_variant.h:762
Definition bslstl_variant.h:2701
void operator()(t_TYPE &object) const
Definition bslstl_variant.h:2709
BSLS_KEYWORD_CONSTEXPR Variant_NoSuchType(int) BSLS_KEYWORD_NOEXCEPT
Create a Variant_NoSuchType object.
Definition bslstl_variant.h:5809
Definition bslstl_variant.h:782
Definition bslstl_variant.h:2022