BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_variant.h
Go to the documentation of this file.
1/// @file bdlb_variant.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_variant.h -*-C++-*-
8#ifndef INCLUDED_BDLB_VARIANT
9#define INCLUDED_BDLB_VARIANT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_variant bdlb_variant
15/// @brief Provide a variant (discriminated `union`-like) type.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_variant
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_variant-purpose"> Purpose</a>
25/// * <a href="#bdlb_variant-classes"> Classes </a>
26/// * <a href="#bdlb_variant-description"> Description </a>
27/// * <a href="#bdlb_variant-default-construction"> Default Construction </a>
28/// * <a href="#bdlb_variant-visitors"> Visitors </a>
29/// * <a href="#bdlb_variant-bdex-streamability"> BDEX Streamability </a>
30/// * <a href="#bdlb_variant-class-synopsis"> Class Synopsis </a>
31/// * <a href="#bdlb_variant-creators"> Creators </a>
32/// * <a href="#bdlb_variant-manipulators"> Manipulators </a>
33/// * <a href="#bdlb_variant-accessors"> Accessors </a>
34/// * <a href="#bdlb_variant-usage"> Usage </a>
35/// * <a href="#bdlb_variant-example-1-variant-construction"> Example 1: Variant Construction </a>
36/// * <a href="#bdlb_variant-example-2-variant-assignment"> Example 2: Variant Assignment </a>
37/// * <a href="#bdlb_variant-operator="> operator= </a>
38/// * <a href="#bdlb_variant-assignto<type>"> assignTo<TYPE> </a>
39/// * <a href="#bdlb_variant-assign"> assign </a>
40/// * <a href="#bdlb_variant-example-3-visiting-a-variant-via-apply"> Example 3: Visiting a Variant via apply </a>
41/// * <a href="#bdlb_variant-bslmf-nil-passed-to-visitor"> bslmf::Nil Passed to Visitor </a>
42/// * <a href="#bdlb_variant-user-specified-default-value-passed-to-visitor"> User-Specified Default Value Passed to Visitor </a>
43/// * <a href="#bdlb_variant-applyraw-undefined-if-variant-is-unset"> applyRaw Undefined If Variant Is Unset </a>
44/// * <a href="#bdlb_variant-return-value-specified-in-visitor"> Return Value Specified in Visitor </a>
45/// * <a href="#bdlb_variant-return-value-specified-with-function-call"> Return Value Specified with Function Call </a>
46///
47/// # Purpose {#bdlb_variant-purpose}
48/// Provide a variant (discriminated `union`-like) type.
49///
50/// # Classes {#bdlb_variant-classes}
51///
52/// - bdlb::Variant: variant of up to 20 types
53/// - bdlb::Variant2: variant of exactly 2 types
54/// - bdlb::Variant3: variant of exactly 3 types
55/// - bdlb::Variant4: variant of exactly 4 types
56/// - bdlb::Variant5: variant of exactly 5 types
57/// - bdlb::Variant6: variant of exactly 6 types
58/// - bdlb::Variant7: variant of exactly 7 types
59/// - bdlb::Variant8: variant of exactly 8 types
60/// - bdlb::Variant9: variant of exactly 9 types
61/// - bdlb::Variant10: variant of exactly 10 types
62/// - bdlb::Variant11: variant of exactly 11 types
63/// - bdlb::Variant12: variant of exactly 12 types
64/// - bdlb::Variant13: variant of exactly 13 types
65/// - bdlb::Variant14: variant of exactly 14 types
66/// - bdlb::Variant15: variant of exactly 15 types
67/// - bdlb::Variant16: variant of exactly 16 types
68/// - bdlb::Variant17: variant of exactly 17 types
69/// - bdlb::Variant18: variant of exactly 18 types
70/// - bdlb::Variant19: variant of exactly 19 types
71/// - bdlb::VariantImp: variant from a type list
72///
73/// @see
74///
75/// # Description {#bdlb_variant-description}
76/// This component provides: (1) a variant class template,
77/// `bdlb::Variant`, that can store an instance of one of up to some
78/// (implementation-defined) number of parameter types (currently 20), (2)
79/// several variant class templates that accommodate a *fixed* number (from 2
80/// to 19) of types, `bdlb::Variant2`, `bdlb::Variant3`, `bdlb::Variant4`,
81/// `bdlb::Variant5`, `bdlb::Variant6`, `bdlb::Variant7`, `bdlb::Variant8`,
82/// `bdlb::Variant9`, `bdlb::Variant10`, `bdlb::Variant11`, `bdlb::Variant12`,
83/// `bdlb::Variant13`, `bdlb::Variant14`, `bdlb::Variant15`, `bdlb::Variant16`,
84/// `bdlb::Variant17`, `bdlb::Variant18`, and `bdlb::Variant19`, and (3) a final
85/// variant class template, `bdlb::VariantImp`, whose supported types are
86/// specified via a `bslmf::TypeList`. A variant (of any of the aforementioned
87/// classes) can hold any one of the types defined in its signature at any point
88/// in time. Clients can retrieve the value and type that a variant currently
89/// holds, assign a new value to the variant, or apply a visitor to the variant.
90/// A visitor's action is based on the value and type the variant currently
91/// holds. Assigning a value of a new type destroys the object of the old type
92/// and constructs the new value by copy constructing the supplied value.
93///
94/// When the number (`N`) of types that needs to be supported is known, it is
95/// better to use the `bdlb::VariantN` templates that use an identical
96/// implementation, but generate shorter symbols and debugging information due
97/// to the lack of defaulted template argument types. Note that
98/// `bdlb::VariantN<T1, ..., TN>` and `bdlb::Variant<T1, ..., TN>` are,
99/// nevertheless, distinct types.
100///
101/// When the variant types are (directly) supplied as a type list (of type
102/// `bslmf::TypeList`), the type `bdlb::VariantImp<TYPELIST>` can be used in
103/// place of:
104/// @code
105/// bdlb::Variant<typename TYPELIST::Type1, typename TYPELIST::Type2, ...>
106/// @endcode
107///
108/// Lastly, move constructors (taking an optional allocator) and move-assignment
109/// operators are also provided. Note that move semantics are emulated with
110/// C++03 compilers.
111///
112/// ## Default Construction {#bdlb_variant-default-construction}
113///
114///
115/// The `bdlb::Variant` class, when default constructed, does not hold a value
116/// and `isUnset` returns `true`. This state is the same as that of a
117/// `bdlb::Variant` that is reset by the `reset` method.
118///
119/// ## Visitors {#bdlb_variant-visitors}
120///
121///
122/// `bdlb::Variant` provides an `apply` method that implements the visitor
123/// design pattern. `apply` accepts a visitor (functor) that provides an
124/// `operator()` that is invoked with the value that the variant currently
125/// holds.
126///
127/// Note, that visitor must satisfy the following requirements:
128/// * The visitor's `operator()` must be callable with any of the types that
129/// might be contained in the variant.
130/// * For the `apply` methods (but not `applyRaw`) the visitor's `operator()`
131/// must be callable with an argument of type `bslmf::Nil`.
132/// * For the `apply` and `applyRaw` methods returning non-void type the return
133/// value of all callable overloads of `operator()` must be convertible to
134/// this type.
135///
136/// The `apply` method should be preferred over a `switch` statement based on
137/// the type index of a variant. If the order or types contained by the variant
138/// is changed in the future, every place where the type index is hard-coded
139/// needs to be updated. Whereas if `apply` were used, no change would be
140/// needed because function overloading will automatically resolve to the proper
141/// `operator()` to invoke.
142///
143/// There are several variations of the `apply` method, varying based on the
144/// return type and the handling of unset variants. Firstly,
145/// the method varies based on whether `apply` returns a value or not.
146/// There can either be:
147/// * No return value.
148/// * A return type specified in the visitor interface.
149/// * A return type specified explicitly when invoking `apply`.
150///
151/// The default is no return value. Even if visitor's `operator()` returns any
152/// non-void value, it will not be passed to the user. If users would like to
153/// return a value from the visitor's `operator()`, they can specify a public
154/// alias `ResultType` to the desired return type in the functor class. For
155/// example, if `operator()` were to return an `int`, the functor class should
156/// specify:
157/// @code
158/// typedef int ResultType;
159/// @endcode
160/// If `ResultType` cannot be determined, users also have the option of
161/// explicitly specifying the return type when invoking apply:
162/// @code
163/// apply<int>(visitor);
164/// @endcode
165/// Secondly, the `apply` method varies based on how the method handles an unset
166/// variant. A user can choose to:
167/// * Pass a default-constructed `bslmf::Nil` to the visitor.
168/// * Pass a user-specified "default" value to the visitor.
169///
170/// Furthermore, if the user is sure that the variant cannot be unset, the user
171/// can invoke `applyRaw`, which is slightly more efficient. However, if the
172/// variant is, in fact, unset, the behavior of `applyRaw` is undefined.
173///
174/// ## BDEX Streamability {#bdlb_variant-bdex-streamability}
175///
176///
177/// BDEX streaming is not implemented for any of the variant classes.
178///
179/// ## Class Synopsis {#bdlb_variant-class-synopsis}
180///
181///
182/// Due to the complexity of the implementation, the following synopsis is
183/// provided to aid users in locating documentation for functions. Note that
184/// this is not a complete summary of all available methods; only the key
185/// methods are shown. For more information, refer to the function-level
186/// documentation.
187///
188/// ### Creators {#bdlb_variant-creators}
189///
190///
191/// @code
192/// bdlb::Variant()
193/// bdlb::Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator);
194/// bdlb::Variant(const TYPE& value, bslma::Allocator *basicAllocator);
195/// @endcode
196/// Create a variant. Users can choose to initialize a variant with a specified
197/// value, or leave the variant in the unset state (via default construction).
198/// Users can also supply a `bslma::Allocator *` for memory allocation.
199///
200/// ### Manipulators {#bdlb_variant-manipulators}
201///
202///
203/// @code
204/// bdlb::Variant& operator=(const TYPE& value);
205/// @endcode
206/// Assign a different value of template parameter `TYPE` to the variant.
207/// @code
208/// bdlb::Variant& operator=(const bdlb::Variant& rhs);
209/// @endcode
210/// Assign another variant to a variant.
211/// @code
212/// void apply(VISITOR& visitor);
213/// VISITOR::ResultType apply(VISITOR& visitor);
214/// RET_TYPE apply(VISITOR& visitor);
215/// @endcode
216/// Access a variant's value using a specified visitor functor whereby
217/// `bslmf::Nil` is passed to the visitor's `operator()` if the variant is
218/// unset.
219/// @code
220/// void apply(VISITOR& visitor, const TYPE& defaultValue);
221/// VISITOR::ResultType apply(VISITOR& visitor, const TYPE& defaultValue);
222/// RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue);
223/// @endcode
224/// Access a variant's value using a specified visitor functor whereby a
225/// user-specified default value is passed to the visitor's `operator()` if the
226/// variant is unset.
227/// @code
228/// void applyRaw(VISITOR& visitor);
229/// VISITOR::ResultType applyRaw(VISITOR& visitor);
230/// RET_TYPE applyRaw(VISITOR& visitor);
231/// @endcode
232/// Access a variant's value using a specified visitor functor whereby the
233/// behavior is undefined if the variant is unset.
234/// @code
235/// template <class TYPE>
236/// TYPE& createInPlace();
237/// TYPE& createInPlace(const A1& a1);
238/// // ...
239/// TYPE& createInPlace(const A1& a1, const A2& a2, ..., const A14& a14);
240/// @endcode
241/// Create a new value of template parameter `TYPE` in-place, with up to 14
242/// constructor arguments.
243/// @code
244/// void reset();
245/// @endcode
246/// Reset a variant to the unset state.
247/// @code
248/// template <class TYPE>
249/// TYPE& the();
250/// @endcode
251/// Access the value of template parameter `TYPE` currently held by a variant.
252/// This method should be invoked using the syntax `the<TYPE>()`, e.g.,
253/// `the<int>()`.
254///
255/// ### Accessors {#bdlb_variant-accessors}
256///
257///
258/// @code
259/// template <class TYPE>
260/// bool is() const;
261/// @endcode
262/// Check whether a variant is currently holding a particular type. This
263/// method should be invoked using the syntax `is<TYPE>()`, e.g., `is<int>()`.
264/// @code
265/// bool isUnset() const;
266/// @endcode
267/// Return `true` if a variant is currently unset, and `false` otherwise.
268/// @code
269/// bsl::ostream& print(bsl::ostream& stream,
270/// int level = 0,
271/// int spacesPerLevel = 4) const;
272/// @endcode
273/// Write a description of a variant to a specified `stream`.
274///
275/// ## Usage {#bdlb_variant-usage}
276///
277///
278/// This section illustrates intended use of this component.
279///
280/// ### Example 1: Variant Construction {#bdlb_variant-example-1-variant-construction}
281///
282///
283/// The following example illustrates the different ways of constructing a
284/// `bdlb::Variant`:
285/// @code
286/// typedef bdlb::Variant <int, double, bsl::string> List;
287/// typedef bdlb::Variant3<int, double, bsl::string> List3; // equivalent
288/// @endcode
289/// The contained types can be retrieved as a `bslmf::TypeList` (using the
290/// `TypeList` nested type), or individually (using `TypeN`, for `N` varying
291/// from 1 to the length of the `TypeList`). In the example below, we use the
292/// `List` variant, but this could be substituted with `List3` with no change
293/// to the code:
294/// @code
295/// assert(3 == List::TypeList::LENGTH);
296/// assert(3 == List3::TypeList::LENGTH);
297/// @endcode
298/// We can check that the variant defaults to the unset state by using the
299/// `is<TYPE>` and `typeIndex` methods:
300/// @code
301/// List x;
302///
303/// assert(!x.is<int>());
304/// assert(!x.is<double>());
305/// assert(!x.is<bsl::string>());
306/// assert(0 == x.typeIndex());
307/// @endcode
308/// Single-argument construction from a type in the `TypeList` of a variant is
309/// also supported. This is more efficient than creating an unset variant and
310/// assigning a value to it:
311/// @code
312/// List3 y(bsl::string("Hello"));
313///
314/// assert(!y.is<int>());
315/// assert(!y.is<double>());
316/// assert( y.is<bsl::string>());
317///
318/// assert("Hello" == y.the<bsl::string>());
319/// @endcode
320/// Furthermore, `createInPlace` is provided to support direct in-place
321/// construction. This method allows users to directly construct the target
322/// type inside the variant, instead of first creating a temporary object, then
323/// copy constructing the object to initialize the variant:
324/// @code
325/// List z;
326/// z.createInPlace<bsl::string>("Hello", 5);
327///
328/// assert(!z.is<int>());
329/// assert(!z.is<double>());
330/// assert( z.is<bsl::string>());
331///
332/// assert("Hello" == z.the<bsl::string>());
333/// @endcode
334/// Up to 14 constructor arguments are supported for in-place construction of
335/// an object. Users can also safely create another object of the same or
336/// different type in a variant that already holds a value using the
337/// `createInPlace` method. No memory is leaked in all cases and the destructor
338/// for the currently held object is invoked:
339/// @code
340/// z.createInPlace<bsl::string>("Hello", 5);
341/// assert(z.is<bsl::string>());
342/// assert("Hello" == z.the<bsl::string>());
343///
344/// z.createInPlace<double>(10.0);
345/// assert(z.is<double>());
346/// assert(10.0 == z.the<double>());
347///
348/// z.createInPlace<int>(10);
349/// assert(z.is<int>());
350/// assert(10 == z.the<int>());
351/// @endcode
352/// `createInPlace` returns a reference providing modifiable access to the
353/// created object:
354/// @code
355/// bsl::string& ref = z.createInPlace<bsl::string>("Goodbye");
356/// assert("Goodbye" == z.the<bsl::string>());
357/// assert("Goodbye" == ref);
358/// assert(&ref == &z.the<bsl::string>());
359///
360/// ref = "Hello again!";
361/// assert("Hello again!" == z.the<bsl::string>());
362/// @endcode
363///
364/// ### Example 2: Variant Assignment {#bdlb_variant-example-2-variant-assignment}
365///
366///
367/// A value of a given type can be stored in a variant in three different ways:
368///
369/// * `operator=`
370/// * `assignTo<TYPE>`
371/// * `assign`
372///
373/// `operator=` automatically deduces the type that the user is trying to assign
374/// to the variant. This should be used most of the time. The `assignTo<TYPE>`
375/// method should be used when conversion to the type that the user is assigning
376/// to is necessary (see the first two examples below for more details).
377/// Finally, `assign` is equivalent to `operator=` and exists simply for
378/// backwards compatibility.
379///
380/// #### operator= {#bdlb_variant-operator=}
381///
382///
383/// The following example illustrates how to use `operator=`:
384/// @code
385/// typedef bdlb::Variant<int, double, bsl::string> List;
386///
387/// List x;
388///
389/// List::Type1 v1 = 1; // 'int'
390/// List::Type2 v2 = 2.0; // 'double'
391/// List::Type3 v3("hello"); // 'bsl::string'
392///
393/// x = v1;
394/// assert( x.is<int>());
395/// assert(!x.is<double>());
396/// assert(!x.is<bsl::string>());
397/// assert(v1 == x.the<int>());
398///
399/// x = v2;
400/// assert(!x.is<int>());
401/// assert( x.is<double>());
402/// assert(!x.is<bsl::string>());
403/// assert(v2 == x.the<double>());
404///
405/// x = v3;
406/// assert(!x.is<int>());
407/// assert(!x.is<double>());
408/// assert( x.is<bsl::string>());
409/// assert(v3 == x.the<bsl::string>());
410/// @endcode
411/// Note that the type of the object is deduced automatically during assignment,
412/// as in:
413/// @code
414/// x = v1;
415/// @endcode
416/// This automatic deduction, however, cannot be extended to conversion
417/// constructors, such as:
418/// @code
419/// x = static_cast<const char *>("Bye"); // ERROR
420/// @endcode
421/// The compiler will diagnose that `const char *` is not a variant type
422/// specified in the list of parameter types used in the definition of `List`,
423/// and will trigger a compile-time assertion. To overcome this problem, see
424/// the next usage example of `assignTo<TYPE>`.
425///
426/// #### assignTo<TYPE> {#bdlb_variant-assignto<type>}
427///
428///
429/// In the previous example, `const char *` was not part of the variant's type
430/// list, which resulted in a compilation diagnostic. The use of
431/// `assignTo<TYPE>` explicitly informs the compiler of the intended type to
432/// assign to the variant:
433/// @code
434/// x.assignTo<bsl::string>(static_cast<const char *>("Bye"));
435///
436/// assert(!x.is<int>());
437/// assert(!x.is<double>());
438/// assert( x.is<bsl::string>());
439///
440/// assert("Bye" == x.the<bsl::string>());
441/// @endcode
442///
443/// #### assign {#bdlb_variant-assign}
444///
445///
446/// Finally, for backwards compatibility, `assign` can also be used in place of
447/// `operator=` (but not `assignTo`):
448/// @code
449/// x.assign<int>(v1);
450/// assert( x.is<int>());
451/// assert(!x.is<double>());
452/// assert(!x.is<bsl::string>());
453/// assert(v1 == x.the<int>());
454///
455/// x.assign<double>(v2);
456/// assert(!x.is<int>());
457/// assert( x.is<double>());
458/// assert(!x.is<bsl::string>());
459/// assert(v2 == x.the<double>());
460///
461/// x.assign<bsl::string>(v3);
462/// assert(!x.is<int>());
463/// assert(!x.is<double>());
464/// assert( x.is<bsl::string>());
465/// assert(v3 == x.the<bsl::string>());
466/// @endcode
467///
468/// ### Example 3: Visiting a Variant via apply {#bdlb_variant-example-3-visiting-a-variant-via-apply}
469///
470///
471/// As described in {Visitors} (above), there are different ways to invoke the
472/// `apply` method. The first two examples below illustrate the different ways
473/// to invoke `apply` (with no return value) to control the behavior of visiting
474/// an unset variant:
475/// * `bslmf::Nil` is passed to the visitor.
476/// * A user-specified default value is passed to the visitor.
477///
478/// A third example illustrates use of `applyRaw`, the behavior of which is
479/// undefined if the variant is unset. Two final examples illustrate different
480/// ways to specify the return value from `apply`:
481/// * The return value is specified in the visitor.
482/// * The return value is specified with the function call.
483///
484/// #### bslmf::Nil Passed to Visitor {#bdlb_variant-bslmf-nil-passed-to-visitor}
485///
486///
487/// A simple visitor that does not require any return value might be one that
488/// prints the value of the variant to `stdout`:
489/// @code
490/// class my_PrintVisitor {
491/// public:
492/// template <class TYPE>
493/// void operator()(const TYPE& value) const
494/// {
495/// bsl::cout << value << bsl::endl;
496/// }
497///
498/// void operator()(bslmf::Nil value) const
499/// {
500/// bsl::cout << "null" << bsl::endl;
501/// }
502/// };
503///
504/// typedef bdlb::Variant<int, double, bsl::string> List;
505///
506/// List x[4];
507///
508/// // Note that 'x[3]' is uninitialized.
509///
510/// x[0].assign(1);
511/// x[1].assign(1.1);
512/// x[2].assignTo<bsl::string>(static_cast<const char *>("Hello"));
513///
514/// my_PrintVisitor printVisitor;
515///
516/// for (int i = 0; i < 4; ++i) {
517/// x[i].apply(printVisitor);
518/// }
519/// @endcode
520/// The above prints the following on `stdout`:
521/// @code
522/// 1
523/// 1.1
524/// Hello
525/// null
526/// @endcode
527/// Note that `operator()` is overloaded with `bslmf::Nil`. A direct match has
528/// higher precedence than a template parameter match. When the variant is
529/// unset (such as `x[3]`), a `bslmf::Nil` is passed to the visitor.
530///
531/// #### User-Specified Default Value Passed to Visitor {#bdlb_variant-user-specified-default-value-passed-to-visitor}
532///
533///
534/// Instead of using `bslmf::Nil`, users can also specify a default value to
535/// pass to the visitor when the variant is currently unset. Using the same
536/// `my_PrintVisitor` class from the previous example:
537/// @code
538/// for (int i = 0; i < 4; ++i) {
539/// x[i].apply(printVisitor, "Print this when unset");
540/// }
541/// @endcode
542/// Now, the above code prints the following on `stdout`:
543/// @code
544/// 1
545/// 1.1
546/// Hello
547/// Print this when unset
548/// @endcode
549/// This variation of `apply` is useful since the user can provide a default
550/// value to the visitor without incurring the cost of initializing the variant
551/// itself.
552///
553/// #### applyRaw Undefined If Variant Is Unset {#bdlb_variant-applyraw-undefined-if-variant-is-unset}
554///
555///
556/// If it is certain that a variant is not unset, then the `applyRaw` method can
557/// be used instead of `apply`. `applyRaw` is slightly more efficient than
558/// `apply`, but the behavior of `applyRaw` is undefined if the variant is
559/// unset. In the following application of `applyRaw`, we purposely circumvent
560/// `x[3]` from being visited because we know that it is unset:
561/// @code
562/// for (int i = 0; i < 3; ++i) { // NOT 'i < 4' as above.
563/// assert(!x[i].isUnset());
564/// x[i].applyRaw(printVisitor); // undefined behavior for 'x[3]'
565/// }
566/// assert(x[3].isUnset());
567/// @endcode
568///
569/// #### Return Value Specified in Visitor {#bdlb_variant-return-value-specified-in-visitor}
570///
571///
572/// Users can also specify a return type that `operator()` will return by
573/// specifying a `typedef` with the name `ResultType` in their functor class.
574/// This is necessary in order for the `apply` method to know what type to
575/// return at compile time:
576/// @code
577/// class my_AddVisitor {
578/// public:
579/// typedef bool ResultType;
580///
581/// // Note that the return type of 'operator()' is 'ResultType'.
582///
583/// template <class TYPE>
584/// ResultType operator()(TYPE& value) const
585/// // Return 'true' when addition is performed successfully, and
586/// // 'false' otherwise.
587/// {
588/// if (bsl::is_convertible<TYPE, double>::value) {
589///
590/// // Add certain values to the variant. The details are elided
591/// // as it is the return value that is the focus of this example.
592///
593/// return true; // RETURN
594/// }
595/// return false;
596/// }
597/// };
598///
599/// typedef bdlb::Variant<int, double, bsl::string> List;
600///
601/// List x[3];
602///
603/// x[0].assign(1);
604/// x[1].assign(1.1);
605/// x[2].assignTo<bsl::string>(static_cast<const char *>("Hello"));
606///
607/// my_AddVisitor addVisitor;
608///
609/// bool ret[3];
610///
611/// for (int i = 0; i < 3; ++i) {
612/// ret[i] = x[i].apply(addVisitor);
613/// if (!ret[i]) {
614/// bsl::cout << "Cannot add to types not convertible to 'double'."
615/// << bsl::endl;
616/// }
617/// }
618/// assert(true == ret[0]);
619/// assert(true == ret[1]);
620/// assert(false == ret[2]);
621/// @endcode
622/// The above prints the following on `stdout`:
623/// @code
624/// Cannot add to types not convertible to 'double'.
625/// @endcode
626/// Note that if no `typedef` is provided (as in the `my_PrintVisitor` class),
627/// then the default return value is `void`.
628///
629/// #### Return Value Specified with Function Call {#bdlb_variant-return-value-specified-with-function-call}
630///
631///
632/// There may be some cases when a visitor interface is not owned by a client
633/// (hence the client cannot add a `typedef` to the visitor), or the visitor
634/// could not determine the return type at design time. In these scenarios,
635/// users can explicitly specify the return type when invoking `apply`:
636/// @code
637/// class ThirdPartyVisitor {
638/// public:
639/// template <class TYPE>
640/// bsl::string operator()(const TYPE& value) const;
641/// // Return the name of the specified 'value' as a 'bsl::string'.
642/// // Note that the implementation of this class is deliberately not
643/// // shown since this class belongs to a third-party library.
644/// };
645///
646/// typedef bdlb::Variant<int, double, bsl::string> List;
647///
648/// List x[3];
649///
650/// x[0].assign(1);
651/// x[1].assign(1.1);
652/// x[2].assignTo<bsl::string>(static_cast<const char *>("Hello"));
653///
654/// ThirdPartyVisitor visitor;
655///
656/// for (int i = 0; i < 3; ++i) {
657///
658/// // Note that the return type is explicitly specified.
659///
660/// bsl::string ret = x[i].apply<bsl::string>(visitor);
661/// bsl::cout << ret << bsl::endl;
662/// }
663/// @endcode
664/// @}
665/** @} */
666/** @} */
667
668/** @addtogroup bdl
669 * @{
670 */
671/** @addtogroup bdlb
672 * @{
673 */
674/** @addtogroup bdlb_variant
675 * @{
676 */
677
678#include <bdlscm_version.h>
679
680#include <bdlb_printmethods.h>
681
682#include <bslalg_swaputil.h>
683
684#include <bslma_allocator.h>
686#include <bslma_default.h>
689
690#include <bslmf_assert.h>
691#include <bslmf_conditional.h>
692#include <bslmf_enableif.h>
696#include <bslmf_isconvertible.h>
697#include <bslmf_issame.h>
698#include <bslmf_movableref.h>
700#include <bslmf_nil.h>
701#include <bslmf_removeconst.h>
702#include <bslmf_removecvref.h>
704#include <bslmf_typelist.h>
705#include <bslmf_util.h> // 'forward(V)'
706
710
711#include <bsls_assert.h>
713#include <bsls_objectbuffer.h>
714#include <bsls_util.h> // 'forward<T>(V)'
715
716#include <bsl_algorithm.h>
717#include <bsl_iosfwd.h>
718
719#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
720#include <bslmf_if.h>
721#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
722
723#ifndef BDE_OMIT_INTERNAL_DEPRECATED
726
727#include <bsl_typeinfo.h>
728#endif // BDE_OMIT_INTERNAL_DEPRECATED
729
730#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
731// Include version that can be compiled with C++03
732// Generated on Fri Jul 14 13:20:25 2023
733// Command line: sim_cpp11_features.pl bdlb_variant.h
734# define COMPILING_BDLB_VARIANT_H
735# include <bdlb_variant_cpp03.h>
736# undef COMPILING_BDLB_VARIANT_H
737#else
738
739#if defined(BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES) \
740 && defined(BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES)
741/// Note that this macro definition parallels that of a similar macro
742/// defined in `bslmf_typelist.h`.
743#define BDLB_VARIANT_USING_VARIADIC_TEMPLATES
744#endif
745
746
747namespace bdlb {
748
749struct Variant_CopyAssignVisitor;
750struct Variant_CopyConstructVisitor;
751struct Variant_DefaultConstructVisitor;
752struct Variant_DestructorVisitor;
753struct Variant_EqualityTestVisitor;
754struct Variant_MoveAssignVisitor;
755struct Variant_MoveConstructVisitor;
756struct Variant_PrintVisitor;
757
758template <class TYPES>
759class VariantImp;
760
761template <class TYPES, class TYPE>
762struct Variant_TypeIndex;
763
764 // ================================
765 // struct Variant_ReturnValueHelper
766 // ================================
767
768// These definitions are provided outside of 'Variant_ReturnValueHelper'
769// because of a bug in the IBM xlC compiler.
771typedef struct { char a[2]; } Variant_ReturnValueHelper_NoType;
772
775
776/// This struct is a component-private struct. Do *not* use. This provides
777/// functions, the matching of which are used by Variant_ReturnValueHelper
778/// to determine whether the template parameter type `VISITOR` has the
779/// member `ResultType` defined.
781
782 /// Return `YesType` if `T::ResultType` exists, and `NoType` otherwise.
783 /// Note that if `T::ResultType` exists, then the first function is a
784 /// better match than the ellipsis version.
785 template <class T>
787 typename bsl::remove_reference<typename T::ResultType>::type *);
788 template <class T>
790};
791
792/// This struct is a component-private meta-function. Do *not* use. This
793/// meta-function checks whether the template parameter type `VISITOR` has
794/// the member `ResultType` defined using "SFINAE" (Substitution Failure Is
795/// Not An Error). A `value` of `true` indicates `VISITOR::ResultType`
796/// exists, and `false` otherwise.
797template <class VISITOR>
800 bool,
801 sizeof(Variant_ReturnValueHelper_Matcher::match<VISITOR>(0)) ==
802 sizeof(Variant_ReturnValueHelper_YesType)> {
803};
804
805 // =====================================
806 // class VariantImp_AllocatorBase<TYPES>
807 // =====================================
808
809/// This class is component-private. Do not use. This class contains the
810/// `typedef`s and data members of the `Variant` class, and serves as the
811/// base class for the variant when any one of the types held by the variant
812/// has the `bslma::UsesBslmaAllocator` type trait.
813///
814/// See @ref bdlb_variant
815template <class TYPES>
817
818 public:
819 // TYPES
820
821 /// `TypeList` is an alias for the `bslmf::TypeList` type serving as the
822 /// template parameter to this variant implementation.
823 typedef TYPES TypeList;
824
844
845 /// `TypeN` is an alias for the `N`th type in the `TypeList` of this
846 /// variant implementation. If less than `N` template arguments were
847 /// given to the `Variant` type, then `TypeN` is `bslmf::Nil`.
849
850 private:
851 union Value {
872 };
873 // 'Value' is a union of 'bsls::ObjectBuffer' of all types contained by
874 // the variant. 'bsls::ObjectBuffer' is used to: 1) wrap non-POD types
875 // within the union, and 2) ensure proper alignment of the types.
876
877 // DATA
878 Value d_value; // value of the object, initialized by
879 // derived class
880
881 int d_type; // current type the variant is holding (0
882 // if unset)
883
884 bslma::Allocator *d_allocator_p; // pointer to allocator (held, not owned)
885
886 // FRIENDS
887 template <class VARIANT_TYPES>
888 friend class VariantImp;
889
890 template <class VARIANT_TYPES>
893
894 public:
895 // TRAITS
898
899 // CREATORS
900 VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator);
901
902 /// Create a `VariantImp_AllocatorBase` with the specified `type`
903 /// indicating the type of the object that the variant will initially
904 /// hold, and the specified `basicAllocator` to supply memory.
906 bslma::Allocator *basicAllocator,
908
909 template <class TYPE>
910 VariantImp_AllocatorBase(int type, const TYPE&, bsl::false_type);
911
912 // ACCESSORS
913
914 /// Return the allocator used by this object to supply memory.
916};
917
918 // =======================================
919 // class VariantImp_NoAllocatorBase<TYPES>
920 // =======================================
921
922/// This class is component-private. Do not use. This class contains the
923/// `typedef`s and data members of the `Variant` class, and serves as the
924/// base class for the variant when none of the types held by the variant
925/// has the `bslma::UsesBslmaAllocator` type trait. The goal is to optimize
926/// the size of the variant to avoid holding an unnecessary allocator
927/// pointer.
928///
929/// See @ref bdlb_variant
930template <class TYPES>
932
933 public:
934 // TYPES
935
936 /// `TypeList` is an alias for the `bslmf::TypeList` type serving as the
937 /// template parameter to this variant implementation.
938 typedef TYPES TypeList;
939
959
960 /// `TypeN` is an alias for the `N`th type in the `TypeList` of this
961 /// variant implementation. If less than `N` template arguments were
962 /// given to the `Variant` type, then `TypeN` is `bslmf::Nil`.
964
965 private:
966 union Value {
987 };
988 // 'Value' is a union of 'bsls::ObjectBuffer' of all types contained by
989 // the variant. 'bsls::ObjectBuffer' is used to: 1) wrap non-POD types
990 // within the union, and 2) ensure proper alignment of the types.
991
992 // DATA
993 Value d_value; // value of the object, initialized by derived class
994 int d_type; // current type the variant is holding (0 if unset)
995
996 // FRIENDS
997 template <class VARIANT_TYPES>
998 friend class VariantImp;
999
1000 template <class VARIANT_TYPES>
1003
1004 public:
1005 // CREATORS
1007
1008 /// Create a `VariantImp_NoAllocatorBase` with the specified `type`
1009 /// indicating the type of the object that the variant will initially
1010 /// hold.
1012
1013 template <class TYPE>
1014 VariantImp_NoAllocatorBase(int type, const TYPE&, bsl::false_type);
1015
1016 // ACCESSORS
1017
1018 /// Return 0. Note that this object does not hold an allocator pointer.
1020};
1021
1022 // ========================
1023 // struct VariantImp_Traits
1024 // ========================
1025
1026/// This struct is component-private. Do not use. This meta-function
1027/// selects `VariantImp_AllocatorBase` as a base class type if any one of
1028/// the types held by a variant has the `bslma::UsesBslmaAllocator` trait,
1029/// and `VariantImp_NoAllocatorBase` otherwise.
1030template <class TYPES>
1032
1033 // TYPES
1054
1055 enum {
1077
1099
1121#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1125#endif // BDE_OMIT_INTERNAL_DEPRECATED
1127
1128 /// Determines what the base type is.
1133};
1134
1135 // ==============================
1136 // class Variant_RawVisitorHelper
1137 // ==============================
1138
1139/// This `struct` provides a helper for implementing `Variant::applyRaw`
1140/// that enables `applyRaw` to support visitor functors that do not provide
1141/// an overload for `operator()(bslmf::Nil)`. Objects of this type are
1142/// constructed using a functor of (template parameter) type `VISITOR`,
1143/// whose `operator()` returns the (template parameter) type `RESULT_TYPE`.
1144/// A `Variant_RawVisitorHelper` wraps a functor of type `VISITOR` and
1145/// provides an implementation of `operator()(bslmf::Nil)` that performs a
1146/// `BSLS_ASSERT_OPT(false)`. Note that this overload is needed to enable
1147/// compilation (specifically, to instantiate `doApply` and `doApplyR`), but
1148/// is never invoked by any code path at runtime.
1149///
1150/// See @ref bdlb_variant
1151template <class RESULT_TYPE, class VISITOR>
1153
1154 // DATA
1155 VISITOR *d_visitor; // visitor to which this helper delegates
1156
1157 public:
1158 // CREATORS
1159
1160 /// Create a `RawVisitorHelper` functor that delegates to the specified
1161 /// `visitor`.
1162 explicit
1163 Variant_RawVisitorHelper(VISITOR *visitor);
1164
1165 // MANIPULATORS
1166
1167 /// Invoke the functor supplied at construction with the specified
1168 /// `argument`, and return the result.
1169 template <class ARGUMENT_TYPE>
1170 RESULT_TYPE operator()(ARGUMENT_TYPE& argument);
1171 template <class ARGUMENT_TYPE>
1172 RESULT_TYPE operator()(const ARGUMENT_TYPE& argument);
1173
1174 // ACCESSORS
1175
1176 /// Invoke the functor supplied at construction with the specified
1177 /// `argument`, and return the result.
1178 template <class ARGUMENT_TYPE>
1179 RESULT_TYPE operator()(ARGUMENT_TYPE& argument) const;
1180 template <class ARGUMENT_TYPE>
1181 RESULT_TYPE operator()(const ARGUMENT_TYPE& argument) const;
1182
1183 /// Do not call. The behavior of this method is undefined.
1184 RESULT_TYPE operator()(bslmf::Nil) const;
1185};
1186
1187 // =======================
1188 // class VariantImp<TYPES>
1189 // =======================
1190
1191/// This class provides the implementation of `Variant` (except for the
1192/// creators) given a list of template parameter `TYPES`.
1193///
1194/// More generally, if each of the types in the list of `TYPES` is
1195/// value semantic, then this class also supports a complete set of *value*
1196/// *semantic* operations, including copy construction, assignment, equality
1197/// comparison, and `ostream` printing. A precise operational definition of
1198/// when two instances have the same value can be found in the description
1199/// of `operator==` for the class. This class is *exception* *neutral* with
1200/// no guarantee of rollback: if an exception is thrown during the
1201/// invocation of a method on a pre-existing instance, the object is left in
1202/// a valid state, but its value is undefined. In no event is memory
1203/// leaked. Finally, *aliasing* (e.g., using all or part of an object as
1204/// both source and destination) is supported in all cases.
1205///
1206/// If any of the types in the list of `TYPES` does not support
1207/// `operator==`, or any of the value-semantic operations mentioned above,
1208/// then this variant also does not support that operation and attempts to
1209/// invoke it will trigger a compilation diagnostic.
1210///
1211/// See @ref bdlb_variant
1212template <class TYPES>
1213class VariantImp : public VariantImp_Traits<TYPES>::BaseType {
1214
1215 // PRIVATE TYPES
1217 typedef typename Traits::BaseType Base;
1219
1220 /// `SelfType` is an alias to this class.
1222
1223 private:
1224 // PRIVATE MANIPULATORS
1225
1226 /// Invoke `operator()` of the specified `visitor` on the current value
1227 /// (of template parameter `TYPE`) held by this variant. `TYPE` must be
1228 /// the same as one of the types that this variant can hold. The
1229 /// behavior is undefined unless this variant holds a value of template
1230 /// parameter `TYPE`. Note that the second argument is for resolving
1231 /// overloading ambiguity and is not used.
1232 template <class TYPE, class VISITOR_REF>
1233 void applyImp(VISITOR_REF visitor, bsl::false_type);
1234 template <class TYPE, class VISITOR_REF>
1235 void applyImp(VISITOR_REF visitor, bsl::true_type);
1236 template <class TYPE, class VISITOR_REF>
1237 void applyImp(VISITOR_REF visitor);
1238
1239 /// Invoke `operator()` of the specified `visitor` on the current value
1240 /// (of template parameter `TYPE`) held by this variant, and return the
1241 /// value (of template parameter `RET_TYPE`) returned by the `visitor`.
1242 /// `TYPE` must be the same as one of the types that this variant can
1243 /// hold. The behavior is undefined unless this variant holds a value
1244 /// of template parameter `TYPE`. Note that the second argument is for
1245 /// resolving overloading ambiguity and is not used.
1246 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1247 RET_TYPE applyImpR(VISITOR_REF visitor, bsl::false_type);
1248 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1249 RET_TYPE applyImpR(VISITOR_REF visitor, bsl::true_type);
1250 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1251 RET_TYPE applyImpR(VISITOR_REF visitor);
1252
1253 /// Assign to this variant the specified `value` of template parameter
1254 /// `SOURCE_TYPE` converted to template parameter `TYPE`. `TYPE` must
1255 /// be the same as one of the types that this variant can hold and
1256 /// `SOURCE_TYPE` must be convertible to `TYPE`.
1257 template <class TYPE, class SOURCE_TYPE>
1258 void assignImp(const SOURCE_TYPE& value);
1259
1260 template <class TYPE>
1261#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
1262 void assignImp(TYPE&& value);
1263#else
1264 void assignImp(bslmf::MovableRef<TYPE> value);
1265#endif
1266 // Assign to this variant the specified 'value' of template parameter
1267 // 'TYPE'. The contents of 'value' are moved to this object with
1268 // 'value' left in a valid but unspecified state. 'TYPE' must be the
1269 // same as one of the types that this variant can hold.
1270
1271 /// Construct this variant object to initially hold the specified
1272 /// `value` of template parameter `TYPE`. `TYPE` must be the same as
1273 /// one of the types that this variant can hold. Note that the second
1274 /// parameter is for resolving overloading ambiguity and is not used.
1275 template <class TYPE>
1276 void create(const TYPE& value, bsl::false_type);
1277
1278 /// Construct this variant object to be initially in the unset state.
1279 void create(bslma::Allocator *, bsl::true_type);
1280
1281 /// Apply the specified `visitor` on the current value held by this
1282 /// variant by invoking `applyImp` with the appropriate template
1283 /// arguments, determined by the specified `type`. The behavior is
1284 /// undefined unless `type != 0`.
1285 template <class VISITOR_REF>
1286 void doApply(VISITOR_REF visitor, int type);
1287
1288 /// Apply the specified `visitor` on the current value held by this
1289 /// variant by invoking `applyImpR` with the appropriate template
1290 /// arguments, determined by the specified `type`, and return the value
1291 /// (of template parameter `RET_TYPE`) returned by the `visitor`. The
1292 /// behavior is undefined unless `type != 0`.
1293 template <class VISITOR_REF, class RET_TYPE>
1294 RET_TYPE doApplyR(VISITOR_REF visitor, int type);
1295
1296 // PRIVATE ACCESSORS
1297
1298 /// Invoke `operator()` of the specified `visitor` on the current value
1299 /// (of template parameter `TYPE`) held by this variant. `TYPE` must be
1300 /// the same as one of the types that this variant can hold. The
1301 /// behavior is undefined unless this variant holds a value of template
1302 /// parameter `TYPE`. Note that the second argument is for resolving
1303 /// overloading ambiguity and is not used.
1304 template <class TYPE, class VISITOR_REF>
1305 void applyImp(VISITOR_REF visitor, bsl::false_type) const;
1306 template <class TYPE, class VISITOR_REF>
1307 void applyImp(VISITOR_REF visitor, bsl::true_type) const;
1308 template <class TYPE, class VISITOR_REF>
1309 void applyImp(VISITOR_REF visitor) const;
1310
1311 /// Invoke `operator()` of the specified `visitor` on the current value
1312 /// (of template parameter `TYPE`) held by this variant, and return the
1313 /// value (of template parameter `RET_TYPE`) returned by the `visitor`.
1314 /// `TYPE` must be the same as one of the types that this variant can
1315 /// hold. The behavior is undefined unless this variant holds a value
1316 /// of template parameter `TYPE`. Note that the second argument is for
1317 /// resolving overloading ambiguity and is not used.
1318 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1319 RET_TYPE applyImpR(VISITOR_REF visitor, bsl::false_type) const;
1320 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1321 RET_TYPE applyImpR(VISITOR_REF visitor, bsl::true_type) const;
1322 template <class TYPE, class VISITOR_REF, class RET_TYPE>
1323 RET_TYPE applyImpR(VISITOR_REF visitor) const;
1324
1325 /// Apply the specified `visitor` on the current value held by this
1326 /// variant by invoking `applyImp` with the appropriate template
1327 /// arguments, determined by the specified `type`. The behavior is
1328 /// undefined unless `type != 0`.
1329 template <class VISITOR_REF>
1330 void doApply(VISITOR_REF visitor, int type) const;
1331
1332 /// Apply the specified `visitor` on the current value held by this
1333 /// variant by invoking `applyImpR` with the appropriate template
1334 /// arguments, determined by the specified `type`, and return the value
1335 /// (of template parameter `RET_TYPE`) returned by the `visitor`. The
1336 /// behavior is undefined unless `type != 0`.
1337 template <class VISITOR_REF, class RET_TYPE>
1338 RET_TYPE doApplyR(VISITOR_REF visitor, int type) const;
1339
1340 public:
1341 // TRAITS
1352
1353 // CREATORS
1354
1355 /// Create a variant object in the unset state that uses the currently
1356 /// installed default allocator to supply memory.
1358
1359 /// Create a variant object with the specified `valueOrAllocator` that
1360 /// can be either a value of a type that the variant can hold or an
1361 /// allocator to supply memory. If `valueOrAllocator` is not a
1362 /// `bslma::Allocator *`, then the variant will hold the value and type
1363 /// of `valueOrAllocator`, and use the currently installed default
1364 /// allocator to supply memory. Otherwise, the variant will be unset
1365 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
1366 /// must be the same as one of the types that this variant can hold or
1367 /// be convertible to `bslma::Allocator *`. Note that this
1368 /// parameterized constructor is defined instead of two constructors
1369 /// (one taking a `bslma::Allocator *` and the other not) because
1370 /// template parameter arguments are always a better match than
1371 /// derived-to-base conversion (a concrete allocator pointer converted
1372 /// to `bslma::Allocator *`).
1373 template <class TYPE_OR_ALLOCATOR>
1374 explicit
1375 VariantImp(const TYPE_OR_ALLOCATOR& valueOrAllocator);
1376
1377 /// Create a variant object having the specified `value` of template
1378 /// parameter `TYPE` and that uses the specified `basicAllocator` to
1379 /// supply memory. If `basicAllocator` is 0, the currently installed
1380 /// default allocator is used. `TYPE` must be the same as one of the
1381 /// types that this variant can hold.
1382 template <class TYPE>
1383 VariantImp(const TYPE& value, bslma::Allocator *basicAllocator);
1384
1385 template <class TYPE>
1386 explicit
1387#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
1388 VariantImp(TYPE&& value,
1389 typename bsl::enable_if<
1390 !bsl::is_same<
1391 SelfType,
1392 typename bsl::remove_const<
1393 typename bsl::remove_reference<TYPE>::type>::type>::value
1394 &&
1396 void>::type * = 0);
1397#else
1399#endif
1400 // Create a variant object having the specified 'value' of template
1401 // parameter 'TYPE' by moving the contents of 'value' to the
1402 // newly-created object. Use the currently installed default allocator
1403 // to supply memory. 'value' is left in a valid but unspecified state.
1404 // 'TYPE' must be the same as one of the types that this variant can
1405 // hold. Note that in C++11 mode, this method does not participate in
1406 // overload resolution if it would lead to ambiguity with the move
1407 // constructor that does not take an allocator (below) or with the
1408 // constructor taking a 'valueOrAllocator' (above).
1409
1410 template <class TYPE>
1411#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
1412 VariantImp(TYPE&& value,
1413 typename bsl::enable_if<
1414 !bsl::is_same<
1415 SelfType,
1416 typename bsl::remove_const<
1417 typename bsl::remove_reference<TYPE>::type>::type>::value,
1418 bslma::Allocator>::type *basicAllocator);
1419#else
1421 bslma::Allocator *basicAllocator);
1422#endif
1423 // Create a variant object having the specified 'value' of template
1424 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
1425 // memory. If 'basicAllocator' is 0, the currently installed default
1426 // allocator is used. The contents of 'value' are moved to the
1427 // newly-created object with 'value' left in a valid but unspecified
1428 // state. 'TYPE' must be the same as one of the types that this
1429 // variant can hold. Note that in C++11 mode, this method does not
1430 // participate in overload resolution if it would lead to ambiguity
1431 // with the move constructor that takes an allocator (below).
1432
1433 /// Create a variant object having the type and value of the specified
1434 /// `original` variant. Optionally specify a `basicAllocator` used to
1435 /// supply memory. If `basicAllocator` is 0, the currently installed
1436 /// default allocator is used.
1437 VariantImp(const VariantImp& original,
1438 bslma::Allocator *basicAllocator = 0);
1439
1440 /// Create a variant object having the type and value of the specified
1441 /// `original` object by moving the contents of `original` to the
1442 /// newly-created object. The allocator associated with `original` (if
1443 /// any) is propagated for use in the newly-created object. `original`
1444 /// is left in a valid but unspecified state.
1446
1447 /// Create a variant object having the type and value of the specified
1448 /// `original` object that uses the specified `basicAllocator` to supply
1449 /// memory. If `basicAllocator` is 0, the currently installed default
1450 /// allocator is used. The contents of `original` are moved to the
1451 /// newly-created object with `original` left in a valid but unspecified
1452 /// state.
1454 bslma::Allocator *basicAllocator);
1455
1456 /// Destroy this variant object, invoking the destructor of the type of
1457 /// object contained (if any) on the value of that type.
1459
1460 // MANIPULATORS
1461
1462 /// Assign to this object the specified `value` of template parameter
1463 /// `TYPE`, and return a reference providing modifiable access to this
1464 /// object. The value currently held by this variant (if any) is
1465 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
1466 /// must be the same as one of the types that this variant can hold.
1467 template <class TYPE>
1468 VariantImp& operator=(const TYPE& value);
1469
1470 template <class TYPE>
1471#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
1472 typename bsl::enable_if<
1474 typename bsl::remove_cvref<TYPE>::type>::value,
1475 SelfType>::type&
1476 operator=(TYPE&& value);
1477#else
1478 VariantImp&
1480#endif
1481 // Assign to this object the specified 'value' of template parameter
1482 // 'TYPE', and return a reference providing modifiable access to this
1483 // object. The contents of 'value' are moved to this object with
1484 // 'value' left in a valid but unspecified state. The value currently
1485 // held by this variant (if any) is destroyed if that value's type is
1486 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
1487 // that this variant can hold. Note that in C++11 mode, this method
1488 // does not participate in overload resolution if it would lead to
1489 // ambiguity with the move-assignment operator (below).
1490
1491 /// Assign to this object the type and value currently held by the
1492 /// specified `rhs` object, and return a reference providing modifiable
1493 /// access to this object. The value currently held by this variant
1494 /// (if any) is destroyed if that value's type is not the same as the
1495 /// type held by the `rhs` object.
1497
1498 /// Assign to this object the type and value currently held by the
1499 /// specified `rhs` object, and return a reference providing modifiable
1500 /// access to this object. The contents of `rhs` are either
1501 /// move-inserted into or move-assigned to this object with `rhs` left
1502 /// in a valid but unspecified state.
1504
1505 /// Apply the specified `visitor` to this modifiable variant by passing
1506 /// the value this variant currently holds to the `visitor` object's
1507 /// `operator()`, and return the value returned by the `visitor`. If
1508 /// this variant is unset, a default constructed `bslmf::Nil` is passed
1509 /// to the `visitor`. Note that this method is selected only if the
1510 /// template parameter type `VISITOR` defines a `typedef` of
1511 /// `ResultType` in its public interface. Also note that this method is
1512 /// defined inline to work around a Windows compiler bug with SFINAE
1513 /// functions.
1514 template <class VISITOR>
1516 typename VISITOR::ResultType>::type
1517 apply(VISITOR& visitor) {
1518
1519 if (this->d_type) {
1520 return doApplyR<VISITOR&,
1521 typename VISITOR::ResultType>(visitor, this->d_type);
1522 // RETURN
1523 }
1524
1525 bslmf::Nil nil = bslmf::Nil();
1526 return visitor(nil);
1527 }
1528
1529 /// Apply the specified `visitor` to this modifiable variant by passing
1530 /// the value this variant currently holds to the `visitor` object's
1531 /// `operator()`, and return the value returned by the `visitor`. If
1532 /// If this variant is unset, a default constructed `bslmf::Nil` is
1533 /// passed to the `visitor`. Note that this method is selected only if
1534 /// the template parameter type `VISITOR` defines a `typedef` of
1535 /// `ResultType` in its public interface. Also note that this method is
1536 /// defined inline to work around a Windows compiler bug with SFINAE
1537 /// functions.
1538 template <class VISITOR>
1540 typename VISITOR::ResultType>::type
1541 apply(const VISITOR& visitor) {
1542
1543 if (this->d_type) {
1544 return doApplyR<const VISITOR&,
1545 typename VISITOR::ResultType>(visitor, this->d_type);
1546 // RETURN
1547 }
1548
1549 bslmf::Nil nil = bslmf::Nil();
1550 return visitor(nil);
1551 }
1552
1553 /// Apply the specified `visitor` to this modifiable variant by passing
1554 /// the value (of template parameter `TYPE`) this variant currently
1555 /// holds to the `visitor` object's `operator()`, and return the value
1556 /// returned by the `visitor`. If this variant is unset, the specified
1557 /// `defaultValue` of template parameter `TYPE` is passed to the
1558 /// `visitor`. `TYPE` must be the same as one of the types that this
1559 /// variant can hold. The behavior is undefined unless this variant is
1560 /// unset or holds a value of template parameter `TYPE`. Note that this
1561 /// method is selected only if the template parameter type `VISITOR`
1562 /// defines a `typedef` of `ResultType` in its public interface. Also
1563 /// note that this method is defined inline to work around a Windows
1564 /// compiler bug with SFINAE functions.
1565 template <class VISITOR, class TYPE>
1567 typename VISITOR::ResultType>::type
1568 apply(VISITOR& visitor, const TYPE& defaultValue) {
1569
1570 if (this->d_type) {
1571 return doApplyR<VISITOR&,
1572 typename VISITOR::ResultType>(visitor, this->d_type);
1573 // RETURN
1574 }
1575
1576 return visitor(defaultValue);
1577 }
1578
1579 /// Apply the specified `visitor` to this modifiable variant by passing
1580 /// the value (of template parameter `TYPE`) this variant currently
1581 /// holds to the `visitor` object's `operator()`, and return the value
1582 /// returned by the `visitor`. If this variant is unset, the specified
1583 /// `defaultValue` of template parameter `TYPE` is passed to the
1584 /// `visitor`. `TYPE` must be the same as one of the types that this
1585 /// variant can hold. The behavior is undefined unless this variant is
1586 /// unset or holds a value of template parameter `TYPE`. Note that this
1587 /// method is selected only if the template parameter type `VISITOR`
1588 /// defines a `typedef` of `ResultType` in its public interface. Also
1589 /// note that this method is defined inline to work around a Windows
1590 /// compiler bug with SFINAE functions.
1591 template <class VISITOR, class TYPE>
1593 typename VISITOR::ResultType>::type
1594 apply(const VISITOR& visitor, const TYPE& defaultValue) {
1595
1596 if (this->d_type) {
1597 return doApplyR<const VISITOR&,
1598 typename VISITOR::ResultType>(visitor, this->d_type);
1599 // RETURN
1600 }
1601
1602 return visitor(defaultValue);
1603 }
1604
1605 /// Apply the specified `visitor` to this modifiable variant by passing
1606 /// the value this variant currently holds to the `visitor` object's
1607 /// `operator()`. This method does not return a value. If this variant
1608 /// is unset, a default constructed `bslmf::Nil` is passed to the
1609 /// `visitor`. Note that this method is selected only if the template
1610 /// parameter type `VISITOR` does not define a `typedef` of `ResultType`
1611 /// in its public interface. Also note that this method is defined
1612 /// inline to work around a Windows compiler bug with SFINAE functions.
1613 template <class VISITOR>
1615 void>::type
1616 apply(VISITOR& visitor) {
1617
1618 if (this->d_type) {
1619 doApply<VISITOR&>(visitor, this->d_type);
1620 return; // RETURN
1621 }
1622
1623 bslmf::Nil nil = bslmf::Nil();
1624 visitor(nil);
1625 }
1626
1627 /// Apply the specified `visitor` to this modifiable variant by passing
1628 /// the value this variant currently holds to the `visitor` object's
1629 /// `operator()`. This method does not return a value. If this variant
1630 /// is unset, a default constructed `bslmf::Nil` is passed to the
1631 /// `visitor`. Note that this method is selected only if the template
1632 /// parameter type `VISITOR` does not define a `typedef` of `ResultType`
1633 /// in its public interface. Also note that this method is defined
1634 /// inline to work around a Windows compiler bug with SFINAE functions.
1635 template <class VISITOR>
1637 void>::type
1638 apply(const VISITOR& visitor) {
1639
1640 if (this->d_type) {
1641 doApply<const VISITOR&>(visitor, this->d_type);
1642 return; // RETURN
1643 }
1644
1645 bslmf::Nil nil = bslmf::Nil();
1646 visitor(nil);
1647 }
1648
1649 /// Apply the specified `visitor` to this modifiable variant by passing
1650 /// the value (of template parameter `TYPE`) this variant currently
1651 /// holds to the `visitor` object's `operator()`. This method does not
1652 /// return a value. If this variant is unset, the specified
1653 /// `defaultValue` of template parameter `TYPE` is passed to the
1654 /// `visitor`. `TYPE` must be the same as one of the types that this
1655 /// variant can hold. The behavior is undefined unless this variant is
1656 /// unset or holds a value of template parameter `TYPE`. Note that this
1657 /// method is selected only if the template parameter type `VISITOR`
1658 /// does not define a `typedef` of `ResultType` in its public interface.
1659 /// Also note that this method is defined inline to work around a
1660 /// Windows compiler bug with SFINAE functions.
1661 template <class VISITOR, class TYPE>
1663 void>::type
1664 apply(VISITOR& visitor, const TYPE& defaultValue) {
1665
1666 if (this->d_type) {
1667 doApply<VISITOR&>(visitor, this->d_type);
1668 return; // RETURN
1669 }
1670
1671 visitor(defaultValue);
1672 }
1673
1674 /// Apply the specified `visitor` to this modifiable variant by passing
1675 /// the value (of template parameter `TYPE`) this variant currently
1676 /// holds to the `visitor` object's `operator()`. This method does not
1677 /// return a value. If this variant is unset, the specified
1678 /// `defaultValue` of template parameter `TYPE` is passed to the
1679 /// `visitor`. `TYPE` must be the same as one of the types that this
1680 /// variant can hold. The behavior is undefined unless this variant is
1681 /// unset or holds a value of template parameter `TYPE`. Note that this
1682 /// method is selected only if the template parameter type `VISITOR`
1683 /// does not define a `typedef` of `ResultType` in its public interface.
1684 /// Also note that this method is defined inline to work around a
1685 /// Windows compiler bug with SFINAE functions.
1686 template <class VISITOR, class TYPE>
1688 void>::type
1689 apply(const VISITOR& visitor, const TYPE& defaultValue) {
1690
1691 if (this->d_type) {
1692 doApply<const VISITOR&>(visitor, this->d_type);
1693 return; // RETURN
1694 }
1695
1696 visitor(defaultValue);
1697 }
1698
1699 /// Apply the specified `visitor` to this modifiable variant by passing
1700 /// the value (of template parameter `TYPE`) this variant currently
1701 /// holds to the `visitor` object's `operator()`, and return the value
1702 /// (of template parameter `RET_TYPE`) returned by the `visitor`. If
1703 /// this variant is unset, a default constructed `bslmf::Nil` is passed
1704 /// to the `visitor`.
1705 template <class RET_TYPE, class VISITOR>
1706 RET_TYPE apply(VISITOR& visitor);
1707 template <class RET_TYPE, class VISITOR>
1708 RET_TYPE apply(const VISITOR& visitor);
1709
1710 /// Apply the specified `visitor` to this modifiable variant by passing
1711 /// the value (of template parameter `TYPE`) this variant currently
1712 /// holds to the `visitor` object's `operator()`, and return the value
1713 /// (of template parameter `RET_TYPE`) returned by the `visitor`. If
1714 /// this variant is unset, the specified `defaultValue` of template
1715 /// parameter `TYPE` is passed to the `visitor`. `TYPE` must be the
1716 /// same as one of the types that this variant can hold. The behavior
1717 /// is undefined unless this variant is unset or holds a value of
1718 /// template parameter `TYPE`.
1719 template <class RET_TYPE, class VISITOR, class TYPE>
1720 RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue);
1721 template <class RET_TYPE, class VISITOR, class TYPE>
1722 RET_TYPE apply(const VISITOR& visitor, const TYPE& defaultValue);
1723
1724 /// Apply the specified `visitor` to this modifiable variant by passing
1725 /// the value (of template parameter `TYPE`) this variant currently
1726 /// holds to the `visitor` object's `operator()`, and return the value
1727 /// returned by the `visitor`. The behavior is undefined if this
1728 /// variant is unset. Note that this method is selected only if the
1729 /// template parameter type `VISITOR` defines a `typedef` of
1730 /// `ResultType` in its public interface. Also note that this method is
1731 /// defined inline to work around a Windows compiler bug with SFINAE
1732 /// functions.
1733 template <class VISITOR>
1735 typename VISITOR::ResultType>::type
1736 applyRaw(VISITOR& visitor) {
1737
1738 typedef Variant_RawVisitorHelper<typename VISITOR::ResultType,
1739 VISITOR> Helper;
1740
1741 return doApplyR<const Helper&,
1742 typename VISITOR::ResultType>(Helper(&visitor),
1743 this->d_type);
1744 }
1745
1746 /// Apply the specified `visitor` to this modifiable variant by passing
1747 /// the value (of template parameter `TYPE`) this variant currently
1748 /// holds to the `visitor` object's `operator()`, and return the value
1749 /// returned by the `visitor`. The behavior is undefined if this
1750 /// variant is unset. Note that this method is selected only if the
1751 /// template parameter type `VISITOR` defines a `typedef` of
1752 /// `ResultType` in its public interface. Also note that this method is
1753 /// defined inline to work around a Windows compiler bug with SFINAE
1754 /// functions.
1755 template <class VISITOR>
1757 typename VISITOR::ResultType>::type
1758 applyRaw(const VISITOR& visitor) {
1759
1760 typedef Variant_RawVisitorHelper<typename VISITOR::ResultType,
1761 const VISITOR> Helper;
1762
1763 return doApplyR<const Helper&,
1764 typename VISITOR::ResultType>(Helper(&visitor),
1765 this->d_type);
1766 }
1767
1768 /// Apply the specified `visitor` to this modifiable variant by passing
1769 /// the value (of template parameter `TYPE`) this variant currently
1770 /// holds to the `visitor` object's `operator()`. This method does not
1771 /// return a value. The behavior is undefined if this variant is unset.
1772 /// Note that this method is selected only if the template parameter
1773 /// type `VISITOR` does not define a `typedef` of `ResultType` in its
1774 /// public interface. Also note that this method is defined inline to
1775 /// work around a Windows compiler bug with SFINAE functions.
1776 template <class VISITOR>
1778 void>::type
1779 applyRaw(VISITOR& visitor) {
1780
1782
1783 doApply<const Helper&>(Helper(&visitor), this->d_type);
1784 }
1785
1786 /// Apply the specified `visitor` to this modifiable variant by passing
1787 /// the value (of template parameter `TYPE`) this variant currently
1788 /// holds to the `visitor` object's `operator()`. This method does not
1789 /// return a value. The behavior is undefined if this variant is unset.
1790 /// Note that this method is selected only if the template parameter
1791 /// type `VISITOR` does not define a `typedef` of `ResultType` in its
1792 /// public interface. Also note that this method is defined inline to
1793 /// work around a Windows compiler bug with SFINAE functions.
1794 template <class VISITOR>
1796 void>::type
1797 applyRaw(const VISITOR& visitor) {
1798
1800
1801 doApply<const Helper&>(Helper(&visitor), this->d_type);
1802 }
1803
1804 /// Apply the specified `visitor` to this modifiable variant by passing
1805 /// the value this variant currently holds to the `visitor` object's
1806 /// `operator()`, and return the value (of template parameter
1807 /// `RET_TYPE`) returned by the `visitor`. The behavior is undefined if
1808 /// this variant is unset.
1809 template <class RET_TYPE, class VISITOR>
1810 RET_TYPE applyRaw(VISITOR& visitor);
1811 template <class RET_TYPE, class VISITOR>
1812 RET_TYPE applyRaw(const VISITOR& visitor);
1813
1814 /// Assign to this object the specified `value` of template parameter
1815 /// `TYPE`, and return a reference providing modifiable access to this
1816 /// object. The value currently held by this variant (if any) is
1817 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
1818 /// must be the same as one of the types that this variant can hold.
1819 template <class TYPE>
1820 VariantImp& assign(const TYPE& value);
1821
1822 template <class TYPE>
1823#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
1824 VariantImp& assign(TYPE&& value);
1825#else
1827#endif
1828 // Assign to this object the specified 'value' of template parameter
1829 // 'TYPE', and return a reference providing modifiable access to this
1830 // object. The contents of 'value' are moved to this object with
1831 // 'value' left in a valid but unspecified state. The value currently
1832 // held by this variant (if any) is destroyed if that value's type is
1833 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
1834 // that this variant can hold.
1835
1836 /// Assign to this object the specified `value` of template parameter
1837 /// `SOURCE_TYPE` converted to template parameter `TYPE`, and return a
1838 /// reference providing modifiable access to this object. The value
1839 /// currently held by this variant (if any) is destroyed if that value's
1840 /// type is not the same as `TYPE`. `TYPE` must be the same as one of
1841 /// the types that this variant can hold and `SOURCE_TYPE` must be
1842 /// convertible to `TYPE`.
1843 template <class TYPE, class SOURCE_TYPE>
1844 VariantImp& assignTo(const SOURCE_TYPE& value);
1845
1846#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
1847
1848 /// Create an instance of template parameter `TYPE` in this variant
1849 /// object with up to 14 parameters using the allocator currently held
1850 /// by this variant to supply memory, and return a reference providing
1851 /// modifiable access to the created instance. This method first
1852 /// destroys the current value held by this variant (even if `TYPE` is
1853 /// the same as the type currently held). `TYPE` must be the same as
1854 /// one of the types that this variant can hold. Note the order of the
1855 /// template arguments was chosen so that `TYPE` must always be
1856 /// specified.
1857 template <class TYPE, class... ARGS>
1858 TYPE& createInPlace(ARGS&&... arguments);
1859#endif
1860
1861 /// Destroy the current value held by this variant (if any), and reset
1862 /// this variant to the unset state.
1863 void reset();
1864
1865 /// Swap the value of this object with the value of the specified
1866 /// `other` object. This method provides the no-throw guarantee if the
1867 /// `TYPE` template parameter has a no-throw `swap` and the two variant
1868 /// objects being swapped have the same type; otherwise this method
1869 /// provides the basic guarantee.
1870 void swap(VariantImp& other);
1871
1872 /// Return a reference providing modifiable access to the value of
1873 /// template parameter `TYPE` held by this variant object. `TYPE` must
1874 /// be the same as one of the types that this variant can hold. The
1875 /// behavior is undefined unless `is<TYPE>()` returns `true` and `TYPE`
1876 /// is not `void`. Note that `TYPE` must be specified explicitly, e.g.,
1877 /// `myValue.the<int>()`.
1878 template <class TYPE>
1879 TYPE& the();
1880
1881 // ACCESSORS
1882
1883 /// Apply the specified `visitor` to this variant by passing the value
1884 /// this variant currently holds to the `visitor` object's `operator()`,
1885 /// and return the value returned by the `visitor`. If this variant is
1886 /// unset, a default constructed `bslmf::Nil` is passed to the
1887 /// `visitor`. Note that this method is selected only if the template
1888 /// parameter type `VISITOR` defines a `typedef` of `ResultType` in its
1889 /// public interface. Also note that this method is defined inline to
1890 /// work around a Windows compiler bug with SFINAE functions.
1891 template <class VISITOR>
1893 typename VISITOR::ResultType>::type
1894 apply(VISITOR& visitor) const {
1895
1896 if (this->d_type) {
1897 return doApplyR<VISITOR&,
1898 typename VISITOR::ResultType>(visitor, this->d_type);
1899 // RETURN
1900 }
1901
1902 bslmf::Nil nil = bslmf::Nil();
1903 return visitor(nil);
1904 }
1905
1906 /// Apply the specified `visitor` to this variant by passing the value
1907 /// this variant currently holds to the `visitor` object's `operator()`,
1908 /// and return the value returned by the 'visitor. If this variant is
1909 /// unset, a default constructed `bslmf::Nil` is passed to the
1910 /// `visitor`. Note that this method is selected only if the template
1911 /// parameter type `VISITOR` defines a `typedef` of `ResultType` in its
1912 /// public interface. Also note that this method is defined inline to
1913 /// work around a Windows compiler bug with SFINAE functions.
1914 template <class VISITOR>
1916 typename VISITOR::ResultType>::type
1917 apply(const VISITOR& visitor) const {
1918
1919 if (this->d_type) {
1920 return doApplyR<const VISITOR&,
1921 typename VISITOR::ResultType>(visitor, this->d_type);
1922 // RETURN
1923 }
1924
1925 bslmf::Nil nil = bslmf::Nil();
1926 return visitor(nil);
1927 }
1928
1929 /// Apply the specified `visitor` to this variant by passing the value
1930 /// (of template parameter `TYPE`) this variant currently holds to the
1931 /// `visitor` object's `operator()`, and return the value returned by
1932 /// the `visitor`. If this variant is unset, the specified
1933 /// `defaultValue` of template parameter `TYPE` is passed to the
1934 /// `visitor`. `TYPE` must be the same as one of the types that this
1935 /// variant can hold. The behavior is undefined unless this variant is
1936 /// unset or holds a value of template parameter `TYPE`. Note that this
1937 /// method is selected only if the template parameter type `VISITOR`
1938 /// defines a `typedef` of `ResultType` in its public interface. Also
1939 /// note that this method is defined inline to work around a Windows
1940 /// compiler bug with SFINAE functions.
1941 template <class VISITOR, class TYPE>
1943 typename VISITOR::ResultType>::type
1944 apply(VISITOR& visitor, const TYPE& defaultValue) const {
1945
1946 if (this->d_type) {
1947 return doApplyR<VISITOR&,
1948 typename VISITOR::ResultType>(visitor, this->d_type);
1949 // RETURN
1950 }
1951
1952 return visitor(defaultValue);
1953 }
1954
1955 /// Apply the specified `visitor` to this variant by passing the value
1956 /// (of template parameter `TYPE`) this variant currently holds to the
1957 /// `visitor` object's `operator()`, and return the value returned by
1958 /// the `visitor`. If this variant is unset, the specified
1959 /// `defaultValue` of template parameter `TYPE` is passed to the
1960 /// `visitor`. `TYPE` must be the same as one of the types that this
1961 /// variant can hold. The behavior is undefined unless this variant is
1962 /// unset or holds a value of template parameter `TYPE`. Note that this
1963 /// method is selected only if the template parameter type `VISITOR`
1964 /// defines a `typedef` of `ResultType` in its public interface. Also
1965 /// note that this method is defined inline to work around a Windows
1966 /// compiler bug with SFINAE functions.
1967 template <class VISITOR, class TYPE>
1969 typename VISITOR::ResultType>::type
1970 apply(const VISITOR& visitor, const TYPE& defaultValue) const {
1971
1972 if (this->d_type) {
1973 return doApplyR<const VISITOR&,
1974 typename VISITOR::ResultType>(visitor, this->d_type);
1975 // RETURN
1976 }
1977
1978 return visitor(defaultValue);
1979 }
1980
1981 /// Apply the specified `visitor` to this variant by passing the value
1982 /// this variant currently holds to the `visitor` object's `operator()`.
1983 /// This method does not return a value. If this variant is unset, a
1984 /// default constructed `bslmf::Nil` is passed to the `visitor`. Note
1985 /// that this method is selected only if the template parameter type
1986 /// `VISITOR` does not define a `typedef` of `ResultType` in its public
1987 /// interface. Also note that this method is defined inline to work
1988 /// around a Windows compiler bug with SFINAE functions.
1989 template <class VISITOR>
1991 void>::type
1992 apply(VISITOR& visitor) const {
1993
1994 if (this->d_type) {
1995 doApply<VISITOR&>(visitor, this->d_type);
1996 return; // RETURN
1997 }
1998
1999 bslmf::Nil nil = bslmf::Nil();
2000 visitor(nil);
2001 }
2002
2003 /// Apply the specified `visitor` to this variant by passing the value
2004 /// this variant currently holds to the `visitor` object's `operator()`.
2005 /// This method does not return a value. If this variant is unset, a
2006 /// default constructed `bslmf::Nil` is passed to the `visitor`. Note
2007 /// that this method is selected only if the template parameter type
2008 /// `VISITOR` does not define a `typedef` of `ResultType` in its public
2009 /// interface. Also note that this method is defined inline to work
2010 /// around a Windows compiler bug with SFINAE functions.
2011 template <class VISITOR>
2013 void>::type
2014 apply(const VISITOR& visitor) const {
2015
2016 if (this->d_type) {
2017 doApply<const VISITOR&>(visitor, this->d_type);
2018 return; // RETURN
2019 }
2020
2021 bslmf::Nil nil = bslmf::Nil();
2022 visitor(nil);
2023 }
2024
2025 /// Apply the specified `visitor` to this variant by passing the value
2026 /// (of template parameter `TYPE`) this variant currently holds to the
2027 /// `visitor` object's `operator()`. This method does not return a
2028 /// value. If this variant is unset, the specified `defaultValue` of
2029 /// template parameter `TYPE` is passed to the `visitor`. `TYPE` must
2030 /// be the same as one of the types that this variant can hold. The
2031 /// behavior is undefined unless this variant is unset or holds a value
2032 /// of template parameter `TYPE`. Note that this method is selected
2033 /// only if the template parameter type `VISITOR` does not define a
2034 /// `typedef` of `ResultType` in its public interface. Also note that
2035 /// this method is defined inline to work around a Windows compiler bug
2036 /// with SFINAE functions.
2037 template <class VISITOR, class TYPE>
2039 void>::type
2040 apply(VISITOR& visitor, const TYPE& defaultValue) const {
2041
2042 if (this->d_type) {
2043 doApply<VISITOR&>(visitor, this->d_type);
2044 return; // RETURN
2045 }
2046
2047 visitor(defaultValue);
2048 }
2049
2050 /// Apply the specified `visitor` to this variant by passing the value
2051 /// (of template parameter `TYPE`) this variant currently holds to the
2052 /// `visitor` object's `operator()`. This method does not return a
2053 /// value. If this variant is unset, the specified `defaultValue` of
2054 /// template parameter `TYPE` is passed to the `visitor`. `TYPE` must
2055 /// be the same as one of the types that this variant can hold. The
2056 /// behavior is undefined unless this variant is unset or holds a value
2057 /// of template parameter `TYPE`. Note that this method is selected
2058 /// only if the template parameter type `VISITOR` does not define a
2059 /// `typedef` of `ResultType` in its public interface. Also note that
2060 /// this method is defined inline to work around a Windows compiler bug
2061 /// with SFINAE functions.
2062 template <class VISITOR, class TYPE>
2064 void>::type
2065 apply(const VISITOR& visitor, const TYPE& defaultValue) const {
2066
2067 if (this->d_type) {
2068 doApply<const VISITOR&>(visitor, this->d_type);
2069 return; // RETURN
2070 }
2071
2072 visitor(defaultValue);
2073 }
2074
2075 /// Apply the specified `visitor` to this variant by passing the value
2076 /// this variant currently holds to the `visitor` object's `operator()`,
2077 /// and return the value (of template parameter `RET_TYPE`) returned by
2078 /// the `visitor`. If this variant is unset, a default constructed
2079 /// `bslmf::Nil` is passed to the `visitor`.
2080 template <class RET_TYPE, class VISITOR>
2081 RET_TYPE apply(VISITOR& visitor) const;
2082 template <class RET_TYPE, class VISITOR>
2083 RET_TYPE apply(const VISITOR& visitor) const;
2084
2085 /// Apply the specified `visitor` to this variant by passing the value
2086 /// (of template parameter `TYPE`) this variant currently holds to the
2087 /// `visitor` object's `operator()`, and return the value (of template
2088 /// parameter `RET_TYPE`) returned by the `visitor`. If this variant is
2089 /// unset, the specified `defaultValue` of template parameter `TYPE` is
2090 /// passed to the `visitor`. `TYPE` must be the same as one of the
2091 /// types that this variant can hold. The behavior is undefined unless
2092 /// this variant is unset or holds a value of template parameter `TYPE`.
2093 template <class RET_TYPE, class VISITOR, class TYPE>
2094 RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue) const;
2095 template <class RET_TYPE, class VISITOR, class TYPE>
2096 RET_TYPE apply(const VISITOR& visitor, const TYPE& defaultValue) const;
2097
2098 /// Apply the specified `visitor` to this variant by passing the value
2099 /// this variant currently holds to the `visitor` object's `operator()`,
2100 /// and return the value (of template parameter `RET_TYPE`) returned by
2101 /// the `visitor`. The behavior is undefined if this variant is unset.
2102 /// Note that this method is selected only if the template parameter
2103 /// type `VISITOR` defines a `typedef` of `ResultType` in its public
2104 /// interface. Also note that this method is defined inline to work
2105 /// around a Windows compiler bug with SFINAE functions.
2106 template <class VISITOR>
2108 typename VISITOR::ResultType>::type
2109 applyRaw(VISITOR& visitor) const {
2110
2111 typedef Variant_RawVisitorHelper<typename VISITOR::ResultType,
2112 VISITOR> Helper;
2113
2114 return doApplyR<const Helper&,
2115 typename VISITOR::ResultType>(Helper(&visitor),
2116 this->d_type);
2117 }
2118
2119 /// Apply the specified `visitor` to this variant by passing the value
2120 /// this variant currently holds to the `visitor` object's `operator()`,
2121 /// and return the value returned by the `visitor`. The behavior is
2122 /// undefined if this variant is unset. Note that this method is
2123 /// selected only if the template parameter type `VISITOR` defines a
2124 /// `typedef` of `ResultType` in its public interface. Also note that
2125 /// this method is defined inline to work around a Windows compiler bug
2126 /// with SFINAE functions.
2127 template <class VISITOR>
2129 typename VISITOR::ResultType>::type
2130 applyRaw(const VISITOR& visitor) const {
2131
2132 typedef Variant_RawVisitorHelper<typename VISITOR::ResultType,
2133 const VISITOR> Helper;
2134
2135 return doApplyR<const Helper&,
2136 typename VISITOR::ResultType>(Helper(&visitor),
2137 this->d_type);
2138 }
2139
2140 /// Apply the specified `visitor` to this variant by passing the value
2141 /// this variant currently holds to the `visitor` object's `operator()`.
2142 /// This method does not return a value. The behavior is undefined if
2143 /// this variant is unset. Note that this method is selected only if
2144 /// the template parameter type `VISITOR` does not define a `typedef` of
2145 /// `ResultType` in its public interface. Also note that this method is
2146 /// defined inline to work around a Windows compiler bug with SFINAE
2147 /// functions.
2148 template <class VISITOR>
2150 void>::type
2151 applyRaw(VISITOR& visitor) const {
2152
2154
2155 return doApply<const Helper&>(Helper(&visitor), this->d_type);
2156 }
2157
2158 /// Apply the specified `visitor` to this variant by passing the value
2159 /// this variant currently holds to the `visitor` object's `operator()`.
2160 /// This method does not return a value. The behavior is undefined if
2161 /// this variant is unset. Note that this method is selected only if
2162 /// the template parameter type `VISITOR` does not define a `typedef` of
2163 /// `ResultType` in its public interface. Also note that this method is
2164 /// defined inline to work around a Windows compiler bug with SFINAE
2165 /// functions.
2166 template <class VISITOR>
2168 void>::type
2169 applyRaw(const VISITOR& visitor) const {
2170
2172
2173 return doApply<const Helper&>(Helper(&visitor), this->d_type);
2174 }
2175
2176 /// Apply the specified `visitor` to this variant by passing the value
2177 /// this variant currently holds to the `visitor` object's `operator()`,
2178 /// and return the value (of template parameter `RET_TYPE`) returned by
2179 /// the `visitor`. The behavior is undefined if this variant is unset.
2180 template <class RET_TYPE, class VISITOR>
2181 RET_TYPE applyRaw(VISITOR& visitor) const;
2182 template <class RET_TYPE, class VISITOR>
2183 RET_TYPE applyRaw(const VISITOR& visitor) const;
2184
2185 /// Return `true` if the value held by this variant object is of
2186 /// template parameter `TYPE`, and `false` otherwise. `TYPE` must be
2187 /// the same as one of the types that this variant can hold. Note that
2188 /// `TYPE` must be specified explicitly, e.g., `myValue.is<int>()`.
2189 template <class TYPE>
2190 bool is() const;
2191
2192 /// Return `true` if this variant is currently unset, and `false`
2193 /// otherwise. An unset variant does not hold a value or type. Note
2194 /// that this method should be preferred over checking the type index of
2195 /// the variant.
2196 bool isUnset() const;
2197
2198 /// Format this object to the specified output `stream` at the (absolute
2199 /// value of) the optionally specified indentation `level`, and return a
2200 /// reference to `stream`. If `level` is specified, optionally specify
2201 /// `spacesPerLevel`, the number of spaces per indentation level for
2202 /// this and all of its nested objects. If `level` is negative,
2203 /// suppress indentation of the first line. If `spacesPerLevel` is
2204 /// negative, format the entire output on one line, suppressing all but
2205 /// the initial indentation (as governed by `level`). If `stream` is
2206 /// not valid on entry, this operation has no effect. Nothing is
2207 /// printed if this variant is unset. Each type that may be contained
2208 /// by this variant shall be printable with `bdlb::PrintMethods`
2209 /// (typically meaning that they either declare the
2210 /// `bdlb::HasPrintMethod` trait or provide the `<<` output streaming
2211 /// operator). See @ref bdlb_printmethods . The compiler will emit an
2212 /// error if `bdlb::PrintMethods::print` cannot be instantiated for each
2213 /// type that may be contained by this variant.
2214 bsl::ostream& print(bsl::ostream& stream,
2215 int level = 0,
2216 int spacesPerLevel = 4) const;
2217
2218 /// Return a reference providing non-modifiable access to the value of
2219 /// template parameter `TYPE` held by this variant object. `TYPE` must
2220 /// be the same as one of the types that this variant can hold. The
2221 /// behavior is undefined unless `is<TYPE>()` returns `true` and `TYPE`
2222 /// is not `void`. Note that `TYPE` must be specified explicitly, e.g.,
2223 /// `myValue.the<int>()`.
2224 template <class TYPE>
2225 const TYPE& the() const;
2226
2227 /// Return the index in the list of `TYPES` corresponding to the type of
2228 /// the value currently held by this variant object (starting at 1), or
2229 /// 0 if this object is unset. Note that instead of switching code on
2230 /// the type index, calling `apply` is the preferred method of
2231 /// manipulating different types stored inside a variant.
2232 int typeIndex() const;
2233
2234#ifndef BDE_OMIT_INTERNAL_DEPRECATED
2235 /// Return `typeid(void)`.
2236 ///
2237 /// DEPRECATED: Do not use.
2238 const bsl::type_info& typeInfo() const;
2239
2240 /// DEPRECATED: Do not use.
2241 template <class STREAM>
2242 STREAM& bdexStreamIn(STREAM& stream, int version);
2243
2244 /// DEPRECATED: Do not use.
2246
2247 /// DEPRECATED: Do not use.
2248 template <class STREAM>
2249 STREAM& bdexStreamOut(STREAM& stream, int version) const;
2250
2251#endif // BDE_OMIT_INTERNAL_DEPRECATED
2252};
2253
2254// FREE OPERATORS
2255
2256/// Return `true` if the specified `lhs` variant object has the same value
2257/// as the specified `rhs` variant object, and `false` otherwise. Two
2258/// variant objects have the same value if they are both set and hold
2259/// objects of the same type and same value, or are both unset.
2260template <class TYPES>
2261bool operator==(const VariantImp<TYPES>& lhs,
2262 const VariantImp<TYPES>& rhs);
2263
2264/// Return `true` if the specified `lhs` variant object does not have the
2265/// same value as the specified `rhs` variant object, and `false` otherwise.
2266/// Two variant objects do not have the same value if one is set and the
2267/// other is unset, or if they are both set but hold objects that differ in
2268/// type or value.
2269template <class TYPES>
2270bool operator!=(const VariantImp<TYPES>& lhs,
2271 const VariantImp<TYPES>& rhs);
2272
2273/// Write the specified variant `object` to the specified output `stream` in
2274/// a single-line (human-readable) format, and return a reference to
2275/// `stream`.
2276template <class TYPES>
2277bsl::ostream& operator<<(bsl::ostream& stream,
2278 const VariantImp<TYPES>& object);
2279
2280// FREE FUNCTIONS
2281
2282/// Swap the values of the specified `a` and `b` objects. This method
2283/// provides the no-throw guarantee if the `TYPE` template parameter has a
2284/// no-throw `swap` and the two variant objects being swapped has the same
2285/// type; otherwise this method provides the basic guarantee.
2286template <class TYPES>
2288
2289 // ==================
2290 // class Variant<...>
2291 // ==================
2292
2293#if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES)
2294template <class ...TYPES>
2295class Variant : public VariantImp<typename bslmf::TypeList<TYPES...>::ListType>
2296 {
2297#else
2298template <class A1 = bslmf::Nil, class A2 = bslmf::Nil,
2299 class A3 = bslmf::Nil, class A4 = bslmf::Nil,
2300 class A5 = bslmf::Nil, class A6 = bslmf::Nil,
2301 class A7 = bslmf::Nil, class A8 = bslmf::Nil,
2302 class A9 = bslmf::Nil, class A10 = bslmf::Nil,
2303 class A11 = bslmf::Nil, class A12 = bslmf::Nil,
2304 class A13 = bslmf::Nil, class A14 = bslmf::Nil,
2305 class A15 = bslmf::Nil, class A16 = bslmf::Nil,
2306 class A17 = bslmf::Nil, class A18 = bslmf::Nil,
2307 class A19 = bslmf::Nil, class A20 = bslmf::Nil>
2308class Variant : public VariantImp<typename bslmf::TypeList<
2309 A1, A2, A3, A4, A5,
2310 A6, A7, A8, A9, A10,
2311 A11, A12, A13, A14, A15,
2312 A16, A17, A18, A19, A20>::ListType> {
2313#endif
2314 // This class provides a "variant" type, i.e., a type capable of storing
2315 // values from a list of template parameter types 'A1' to 'A20'. Note that
2316 // if the number 'N' of types is smaller than 20, 'AN+1' up to 'A20'
2317 // default to 'bslmf::Nil', but it is more economical to use 'VariantN',
2318 // which accepts exactly 'N' template arguments, as this leads to shorter
2319 // symbols and debug string information.
2320
2321 // PRIVATE TYPES
2322#if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES)
2323 typedef VariantImp<typename bslmf::TypeList<TYPES...>::ListType> Imp;
2324
2325 /// `SelfType` is an alias to this class.
2326 typedef Variant<TYPES...> SelfType;
2327#else
2328 typedef VariantImp<typename bslmf::TypeList<A1, A2, A3, A4, A5, A6,
2329 A7, A8, A9, A10, A11, A12,
2330 A13, A14, A15, A16, A17, A18,
2331 A19, A20>::ListType> Imp;
2332
2333 typedef Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
2334 A11, A12, A13, A14, A15, A16, A17, A18, A19, A20> SelfType;
2335 // 'SelfType' is an alias to this class.
2336#endif
2337
2340
2341 public:
2342 // TRAITS
2353
2354 // CREATORS
2355
2356 /// Create a variant object in the unset state that uses the currently
2357 /// installed default allocator to supply memory.
2359
2360 /// Create a variant object with the specified `valueOrAllocator` that
2361 /// can be either a value of a type that the variant can hold or an
2362 /// allocator to supply memory. If `valueOrAllocator` is not a
2363 /// `bslma::Allocator *`, then the variant will hold the value and type
2364 /// of `valueOrAllocator`, and use the currently installed default
2365 /// allocator to supply memory. Otherwise, the variant will be unset
2366 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
2367 /// must be the same as one of the types that this variant can hold or
2368 /// be convertible to `bslma::Allocator *`. Note that this
2369 /// parameterized constructor is defined instead of two constructors
2370 /// (one taking a `bslma::Allocator *` and the other not) because
2371 /// template parameter arguments are always a better match than
2372 /// derived-to-base conversion (a concrete allocator pointer converted
2373 /// to `bslma::Allocator *`).
2374 template <class TYPE_OR_ALLOCATOR>
2375 explicit
2376 Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator);
2377
2378 /// Create a variant object having the specified `value` of template
2379 /// parameter `TYPE` and that uses the specified `basicAllocator` to
2380 /// supply memory. If `basicAllocator` is 0, the currently installed
2381 /// default allocator is used. `TYPE` must be the same as one of the
2382 /// types that this variant can hold.
2383 template <class TYPE>
2384 Variant(const TYPE& value, bslma::Allocator *basicAllocator);
2385
2386 template <class TYPE>
2387 explicit
2388#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2389 Variant(TYPE&& value,
2390 typename bsl::enable_if<
2391 !bsl::is_same<
2392 SelfType,
2393 typename bsl::remove_const<
2394 typename bsl::remove_reference<TYPE>::type>::type>::value
2395 &&
2397 void>::type * = 0);
2398#else
2400#endif
2401 // Create a variant object having the specified 'value' of template
2402 // parameter 'TYPE' by moving the contents of 'value' to the
2403 // newly-created object. Use the currently installed default allocator
2404 // to supply memory. 'value' is left in a valid but unspecified state.
2405 // 'TYPE' must be the same as one of the types that this variant can
2406 // hold. Note that in C++11 mode, this method does not participate in
2407 // overload resolution if it would lead to ambiguity with the move
2408 // constructor that does not take an allocator (below) or with the
2409 // constructor taking a 'valueOrAllocator' (above).
2410
2411 template <class TYPE>
2412#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2413 Variant(TYPE&& value,
2414 typename bsl::enable_if<
2415 !bsl::is_same<
2416 SelfType,
2417 typename bsl::remove_const<
2418 typename bsl::remove_reference<TYPE>::type>::type>::value,
2419 bslma::Allocator>::type *basicAllocator);
2420#else
2422 bslma::Allocator *basicAllocator);
2423#endif
2424 // Create a variant object having the specified 'value' of template
2425 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
2426 // memory. If 'basicAllocator' is 0, the currently installed default
2427 // allocator is used. The contents of 'value' are moved to the
2428 // newly-created object with 'value' left in a valid but unspecified
2429 // state. 'TYPE' must be the same as one of the types that this
2430 // variant can hold. Note that in C++11 mode, this method does not
2431 // participate in overload resolution if it would lead to ambiguity
2432 // with the move constructor that takes an allocator (below).
2433
2434 /// Create a variant object having the type and value of the specified
2435 /// `original` variant. Optionally specify a `basicAllocator` used to
2436 /// supply memory. If `basicAllocator` is 0, the currently installed
2437 /// default allocator is used.
2438 Variant(const Variant& original, bslma::Allocator *basicAllocator = 0);
2439
2440 /// Create a variant object having the type and value of the specified
2441 /// `original` object by moving the contents of `original` to the
2442 /// newly-created object. The allocator associated with `original` (if
2443 /// any) is propagated for use in the newly-created object. `original`
2444 /// is left in a valid but unspecified state.
2446
2447 /// Create a variant object having the type and value of the specified
2448 /// `original` object that uses the specified `basicAllocator` to supply
2449 /// memory. If `basicAllocator` is 0, the currently installed default
2450 /// allocator is used. The contents of `original` are moved to the
2451 /// newly-created object with `original` left in a valid but unspecified
2452 /// state.
2454 bslma::Allocator *basicAllocator);
2455
2456 // MANIPULATORS
2457
2458 /// Assign to this object the specified `value` of template parameter
2459 /// `TYPE`, and return a reference providing modifiable access to this
2460 /// object. The value currently held by this variant (if any) is
2461 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
2462 /// must be the same as one of the types that this variant can hold.
2463 template <class TYPE>
2464 Variant& operator=(const TYPE& value);
2465
2466 template <class TYPE>
2467#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2468 typename bsl::enable_if<
2470 typename bsl::remove_cvref<TYPE>::type>::value,
2471 SelfType>::type&
2472 operator=(TYPE&& value);
2473#else
2474 Variant&
2476#endif
2477 // Assign to this object the specified 'value' of template parameter
2478 // 'TYPE', and return a reference providing modifiable access to this
2479 // object. The contents of 'value' are moved to this object with
2480 // 'value' left in a valid but unspecified state. The value currently
2481 // held by this variant (if any) is destroyed if that value's type is
2482 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
2483 // that this variant can hold. Note that in C++11 mode, this method
2484 // does not participate in overload resolution if it would lead to
2485 // ambiguity with the move-assignment operator (below).
2486
2487 /// Assign to this object the type and value currently held by the
2488 /// specified `rhs` object, and return a reference providing modifiable
2489 /// access to this object. The value currently held by this variant
2490 /// (if any) is destroyed if that value's type is not the same as the
2491 /// type held by the `rhs` object.
2493
2494 /// Assign to this object the type and value currently held by the
2495 /// specified `rhs` object, and return a reference providing modifiable
2496 /// access to this object. The value currently held by this variant
2497 /// (if any) is destroyed if that value's type is not the same as the
2498 /// type held by the `rhs` object. The contents of `rhs` are either
2499 /// move-inserted into or move-assigned to this object with `rhs` left
2500 /// in a valid but unspecified state.
2502};
2503
2504 // ===================
2505 // class Variant2<...>
2506 // ===================
2507
2508/// This class is a "specialization" of `Variant` for a fixed number (2) of
2509/// types. Its 2 template arguments *must* all be specified (none are
2510/// defaulted to `bslmf::Nil`). It provides the same functionality as
2511/// `Variant<A1, A2>`.
2512template <class A1, class A2>
2513class Variant2 : public VariantImp<typename bslmf::TypeList2<
2514 A1, A2>::ListType> {
2515
2516 // PRIVATE TYPES
2518
2519 /// `SelfType` is an alias to this class.
2520 typedef Variant2<A1, A2> SelfType;
2521
2524
2525 public:
2526 // TRAITS
2529 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
2532 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
2535 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
2537
2538 // CREATORS
2539
2540 /// Create a variant object in the unset state that uses the currently
2541 /// installed default allocator to supply memory.
2542 Variant2();
2543
2544 /// Create a variant object with the specified `valueOrAllocator` that
2545 /// can be either a value of a type that the variant can hold or an
2546 /// allocator to supply memory. If `valueOrAllocator` is not a
2547 /// `bslma::Allocator *`, then the variant will hold the value and type
2548 /// of `valueOrAllocator`, and use the currently installed default
2549 /// allocator to supply memory. Otherwise, the variant will be unset
2550 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
2551 /// must be the same as one of the types that this variant can hold or
2552 /// be convertible to `bslma::Allocator *`. Note that this
2553 /// parameterized constructor is defined instead of two constructors
2554 /// (one taking a `bslma::Allocator *` and the other not) because
2555 /// template parameter arguments are always a better match than
2556 /// derived-to-base conversion (a concrete allocator pointer converted
2557 /// to `bslma::Allocator *`).
2558 template <class TYPE_OR_ALLOCATOR>
2559 explicit
2560 Variant2(const TYPE_OR_ALLOCATOR& valueOrAllocator);
2561
2562 /// Create a variant object having the specified `value` of template
2563 /// parameter `TYPE` and that uses the specified `basicAllocator` to
2564 /// supply memory. If `basicAllocator` is 0, the currently installed
2565 /// default allocator is used. `TYPE` must be the same as one of the
2566 /// types that this variant can hold.
2567 template <class TYPE>
2568 Variant2(const TYPE& value, bslma::Allocator *basicAllocator);
2569
2570 template <class TYPE>
2571 explicit
2572#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2573 Variant2(TYPE&& value,
2574 typename bsl::enable_if<
2575 !bsl::is_same<
2576 SelfType,
2577 typename bsl::remove_const<
2578 typename bsl::remove_reference<TYPE>::type>::type>::value
2579 &&
2581 void>::type * = 0);
2582#else
2584#endif
2585 // Create a variant object having the specified 'value' of template
2586 // parameter 'TYPE' by moving the contents of 'value' to the
2587 // newly-created object. Use the currently installed default allocator
2588 // to supply memory. 'value' is left in a valid but unspecified state.
2589 // 'TYPE' must be the same as one of the types that this variant can
2590 // hold. Note that in C++11 mode, this method does not participate in
2591 // overload resolution if it would lead to ambiguity with the move
2592 // constructor that does not take an allocator (below) or with the
2593 // constructor taking a 'valueOrAllocator' (above).
2594
2595 template <class TYPE>
2596#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2597 Variant2(TYPE&& value,
2598 typename bsl::enable_if<
2599 !bsl::is_same<
2600 SelfType,
2601 typename bsl::remove_const<
2602 typename bsl::remove_reference<TYPE>::type>::type>::value,
2603 bslma::Allocator>::type *basicAllocator);
2604#else
2606 bslma::Allocator *basicAllocator);
2607#endif
2608 // Create a variant object having the specified 'value' of template
2609 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
2610 // memory. If 'basicAllocator' is 0, the currently installed default
2611 // allocator is used. The contents of 'value' are moved to the
2612 // newly-created object with 'value' left in a valid but unspecified
2613 // state. 'TYPE' must be the same as one of the types that this
2614 // variant can hold. Note that in C++11 mode, this method does not
2615 // participate in overload resolution if it would lead to ambiguity
2616 // with the move constructor that takes an allocator (below).
2617
2618 /// Create a variant object having the type and value of the specified
2619 /// `original` variant. Optionally specify a `basicAllocator` used to
2620 /// supply memory. If `basicAllocator` is 0, the currently installed
2621 /// default allocator is used.
2622 Variant2(const Variant2& original, bslma::Allocator *basicAllocator = 0);
2623
2624 /// Create a variant object having the type and value of the specified
2625 /// `original` object by moving the contents of `original` to the
2626 /// newly-created object. The allocator associated with `original` (if
2627 /// any) is propagated for use in the newly-created object. `original`
2628 /// is left in a valid but unspecified state.
2630
2631 /// Create a variant object having the type and value of the specified
2632 /// `original` object that uses the specified `basicAllocator` to supply
2633 /// memory. If `basicAllocator` is 0, the currently installed default
2634 /// allocator is used. The contents of `original` are moved to the
2635 /// newly-created object with `original` left in a valid but unspecified
2636 /// state.
2638 bslma::Allocator *basicAllocator);
2639
2640 // MANIPULATORS
2641
2642 /// Assign to this object the specified `value` of template parameter
2643 /// `TYPE`, and return a reference providing modifiable access to this
2644 /// object. The value currently held by this variant (if any) is
2645 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
2646 /// must be the same as one of the types that this variant can hold.
2647 template <class TYPE>
2648 Variant2& operator=(const TYPE& value);
2649
2650 template <class TYPE>
2651#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2652 typename bsl::enable_if<
2654 typename bsl::remove_cvref<TYPE>::type>::value,
2655 SelfType>::type&
2656 operator=(TYPE&& value);
2657#else
2658 Variant2&
2660#endif
2661 // Assign to this object the specified 'value' of template parameter
2662 // 'TYPE', and return a reference providing modifiable access to this
2663 // object. The contents of 'value' are moved to this object with
2664 // 'value' left in a valid but unspecified state. The value currently
2665 // held by this variant (if any) is destroyed if that value's type is
2666 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
2667 // that this variant can hold. Note that in C++11 mode, this method
2668 // does not participate in overload resolution if it would lead to
2669 // ambiguity with the move-assignment operator (below).
2670
2671 /// Assign to this object the type and value currently held by the
2672 /// specified `rhs` object, and return a reference providing modifiable
2673 /// access to this object. The value currently held by this variant
2674 /// (if any) is destroyed if that value's type is not the same as the
2675 /// type held by the `rhs` object.
2676 Variant2& operator=(const Variant2& rhs);
2677
2678 /// Assign to this object the type and value currently held by the
2679 /// specified `rhs` object, and return a reference providing modifiable
2680 /// access to this object. The value currently held by this variant
2681 /// (if any) is destroyed if that value's type is not the same as the
2682 /// type held by the `rhs` object. The contents of `rhs` are either
2683 /// move-inserted into or move-assigned to this object with `rhs` left
2684 /// in a valid but unspecified state.
2685 Variant2& operator=(bslmf::MovableRef<Variant2> rhs);
2686};
2687
2688 // ===================
2689 // class Variant3<...>
2690 // ===================
2691
2692/// This class is a "specialization" of `Variant` for a fixed number (3) of
2693/// types. Its 3 template arguments *must* all be specified (none are
2694/// defaulted to `bslmf::Nil`). It provides the same functionality as
2695/// `Variant<A1, A2, A3>`.
2696template <class A1, class A2, class A3>
2697class Variant3 : public VariantImp<typename bslmf::TypeList3<
2698 A1, A2, A3>::ListType> {
2699
2700 // PRIVATE TYPES
2701 typedef VariantImp<typename bslmf::TypeList3<A1, A2,
2702 A3>::ListType> Imp;
2703
2704 /// `SelfType` is an alias to this class.
2706
2709
2710 public:
2711 // TRAITS
2714 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
2717 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
2720 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
2722
2723 // CREATORS
2724
2725 /// Create a variant object in the unset state that uses the currently
2726 /// installed default allocator to supply memory.
2727 Variant3();
2728
2729 /// Create a variant object with the specified `valueOrAllocator` that
2730 /// can be either a value of a type that the variant can hold or an
2731 /// allocator to supply memory. If `valueOrAllocator` is not a
2732 /// `bslma::Allocator *`, then the variant will hold the value and type
2733 /// of `valueOrAllocator`, and use the currently installed default
2734 /// allocator to supply memory. Otherwise, the variant will be unset
2735 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
2736 /// must be the same as one of the types that this variant can hold or
2737 /// be convertible to `bslma::Allocator *`. Note that this
2738 /// parameterized constructor is defined instead of two constructors
2739 /// (one taking a `bslma::Allocator *` and the other not) because
2740 /// template parameter arguments are always a better match than
2741 /// derived-to-base conversion (a concrete allocator pointer converted
2742 /// to `bslma::Allocator *`).
2743 template <class TYPE_OR_ALLOCATOR>
2744 explicit
2745 Variant3(const TYPE_OR_ALLOCATOR& valueOrAllocator);
2746
2747 /// Create a variant object having the specified `value` of template
2748 /// parameter `TYPE` and that uses the specified `basicAllocator` to
2749 /// supply memory. If `basicAllocator` is 0, the currently installed
2750 /// default allocator is used. `TYPE` must be the same as one of the
2751 /// types that this variant can hold.
2752 template <class TYPE>
2753 Variant3(const TYPE& value, bslma::Allocator *basicAllocator);
2754
2755 template <class TYPE>
2756 explicit
2757#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2758 Variant3(TYPE&& value,
2759 typename bsl::enable_if<
2760 !bsl::is_same<
2761 SelfType,
2762 typename bsl::remove_const<
2763 typename bsl::remove_reference<TYPE>::type>::type>::value
2764 &&
2766 void>::type * = 0);
2767#else
2769#endif
2770 // Create a variant object having the specified 'value' of template
2771 // parameter 'TYPE' by moving the contents of 'value' to the
2772 // newly-created object. Use the currently installed default allocator
2773 // to supply memory. 'value' is left in a valid but unspecified state.
2774 // 'TYPE' must be the same as one of the types that this variant can
2775 // hold. Note that in C++11 mode, this method does not participate in
2776 // overload resolution if it would lead to ambiguity with the move
2777 // constructor that does not take an allocator (below) or with the
2778 // constructor taking a 'valueOrAllocator' (above).
2779
2780 template <class TYPE>
2781#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2782 Variant3(TYPE&& value,
2783 typename bsl::enable_if<
2784 !bsl::is_same<
2785 SelfType,
2786 typename bsl::remove_const<
2787 typename bsl::remove_reference<TYPE>::type>::type>::value,
2788 bslma::Allocator>::type *basicAllocator);
2789#else
2791 bslma::Allocator *basicAllocator);
2792#endif
2793 // Create a variant object having the specified 'value' of template
2794 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
2795 // memory. If 'basicAllocator' is 0, the currently installed default
2796 // allocator is used. The contents of 'value' are moved to the
2797 // newly-created object with 'value' left in a valid but unspecified
2798 // state. 'TYPE' must be the same as one of the types that this
2799 // variant can hold. Note that in C++11 mode, this method does not
2800 // participate in overload resolution if it would lead to ambiguity
2801 // with the move constructor that takes an allocator (below).
2802
2803 /// Create a variant object having the type and value of the specified
2804 /// `original` variant. Optionally specify a `basicAllocator` used to
2805 /// supply memory. If `basicAllocator` is 0, the currently installed
2806 /// default allocator is used.
2807 Variant3(const Variant3& original, bslma::Allocator *basicAllocator = 0);
2808
2809 /// Create a variant object having the type and value of the specified
2810 /// `original` object by moving the contents of `original` to the
2811 /// newly-created object. The allocator associated with `original` (if
2812 /// any) is propagated for use in the newly-created object. `original`
2813 /// is left in a valid but unspecified state.
2815
2816 /// Create a variant object having the type and value of the specified
2817 /// `original` object that uses the specified `basicAllocator` to supply
2818 /// memory. If `basicAllocator` is 0, the currently installed default
2819 /// allocator is used. The contents of `original` are moved to the
2820 /// newly-created object with `original` left in a valid but unspecified
2821 /// state.
2823 bslma::Allocator *basicAllocator);
2824
2825 // MANIPULATORS
2826
2827 /// Assign to this object the specified `value` of template parameter
2828 /// `TYPE`, and return a reference providing modifiable access to this
2829 /// object. The value currently held by this variant (if any) is
2830 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
2831 /// must be the same as one of the types that this variant can hold.
2832 template <class TYPE>
2833 Variant3& operator=(const TYPE& value);
2834
2835 template <class TYPE>
2836#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2837 typename bsl::enable_if<
2839 typename bsl::remove_cvref<TYPE>::type>::value,
2840 SelfType>::type&
2841 operator=(TYPE&& value);
2842#else
2843 Variant3&
2845#endif
2846 // Assign to this object the specified 'value' of template parameter
2847 // 'TYPE', and return a reference providing modifiable access to this
2848 // object. The contents of 'value' are moved to this object with
2849 // 'value' left in a valid but unspecified state. The value currently
2850 // held by this variant (if any) is destroyed if that value's type is
2851 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
2852 // that this variant can hold. Note that in C++11 mode, this method
2853 // does not participate in overload resolution if it would lead to
2854 // ambiguity with the move-assignment operator (below).
2855
2856 /// Assign to this object the type and value currently held by the
2857 /// specified `rhs` object, and return a reference providing modifiable
2858 /// access to this object. The value currently held by this variant
2859 /// (if any) is destroyed if that value's type is not the same as the
2860 /// type held by the `rhs` object.
2861 Variant3& operator=(const Variant3& rhs);
2862
2863 /// Assign to this object the type and value currently held by the
2864 /// specified `rhs` object, and return a reference providing modifiable
2865 /// access to this object. The value currently held by this variant
2866 /// (if any) is destroyed if that value's type is not the same as the
2867 /// type held by the `rhs` object. The contents of `rhs` are either
2868 /// move-inserted into or move-assigned to this object with `rhs` left
2869 /// in a valid but unspecified state.
2870 Variant3& operator=(bslmf::MovableRef<Variant3> rhs);
2871};
2872
2873 // ===================
2874 // class Variant4<...>
2875 // ===================
2876
2877/// This class is a "specialization" of `Variant` for a fixed number (4) of
2878/// types. Its 4 template arguments *must* all be specified (none are
2879/// defaulted to `bslmf::Nil`). It provides the same functionality as
2880/// `Variant<A1, A2, ..., A4>`.
2881template <class A1, class A2, class A3, class A4>
2882class Variant4 : public VariantImp<typename bslmf::TypeList4<
2883 A1, A2, A3, A4>::ListType> {
2884
2885 // PRIVATE TYPES
2886 typedef VariantImp<typename bslmf::TypeList4<A1, A2, A3,
2887 A4>::ListType> Imp;
2888
2889 /// `SelfType` is an alias to this class.
2891
2894
2895 public:
2896 // TRAITS
2899 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
2902 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
2905 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
2907
2908 // CREATORS
2909
2910 /// Create a variant object in the unset state that uses the currently
2911 /// installed default allocator to supply memory.
2912 Variant4();
2913
2914 /// Create a variant object with the specified `valueOrAllocator` that
2915 /// can be either a value of a type that the variant can hold or an
2916 /// allocator to supply memory. If `valueOrAllocator` is not a
2917 /// `bslma::Allocator *`, then the variant will hold the value and type
2918 /// of `valueOrAllocator`, and use the currently installed default
2919 /// allocator to supply memory. Otherwise, the variant will be unset
2920 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
2921 /// must be the same as one of the types that this variant can hold or
2922 /// be convertible to `bslma::Allocator *`. Note that this
2923 /// parameterized constructor is defined instead of two constructors
2924 /// (one taking a `bslma::Allocator *` and the other not) because
2925 /// template parameter arguments are always a better match than
2926 /// derived-to-base conversion (a concrete allocator pointer converted
2927 /// to `bslma::Allocator *`).
2928 template <class TYPE_OR_ALLOCATOR>
2929 explicit
2930 Variant4(const TYPE_OR_ALLOCATOR& valueOrAllocator);
2931
2932 /// Create a variant object having the specified `value` of template
2933 /// parameter `TYPE` and that uses the specified `basicAllocator` to
2934 /// supply memory. If `basicAllocator` is 0, the currently installed
2935 /// default allocator is used. `TYPE` must be the same as one of the
2936 /// types that this variant can hold.
2937 template <class TYPE>
2938 Variant4(const TYPE& value, bslma::Allocator *basicAllocator);
2939
2940 template <class TYPE>
2941 explicit
2942#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2943 Variant4(TYPE&& value,
2944 typename bsl::enable_if<
2945 !bsl::is_same<
2946 SelfType,
2947 typename bsl::remove_const<
2948 typename bsl::remove_reference<TYPE>::type>::type>::value
2949 &&
2951 void>::type * = 0);
2952#else
2954#endif
2955 // Create a variant object having the specified 'value' of template
2956 // parameter 'TYPE' by moving the contents of 'value' to the
2957 // newly-created object. Use the currently installed default allocator
2958 // to supply memory. 'value' is left in a valid but unspecified state.
2959 // 'TYPE' must be the same as one of the types that this variant can
2960 // hold. Note that in C++11 mode, this method does not participate in
2961 // overload resolution if it would lead to ambiguity with the move
2962 // constructor that does not take an allocator (below) or with the
2963 // constructor taking a 'valueOrAllocator' (above).
2964
2965 template <class TYPE>
2966#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
2967 Variant4(TYPE&& value,
2968 typename bsl::enable_if<
2969 !bsl::is_same<
2970 SelfType,
2971 typename bsl::remove_const<
2972 typename bsl::remove_reference<TYPE>::type>::type>::value,
2973 bslma::Allocator>::type *basicAllocator);
2974#else
2976 bslma::Allocator *basicAllocator);
2977#endif
2978 // Create a variant object having the specified 'value' of template
2979 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
2980 // memory. If 'basicAllocator' is 0, the currently installed default
2981 // allocator is used. The contents of 'value' are moved to the
2982 // newly-created object with 'value' left in a valid but unspecified
2983 // state. 'TYPE' must be the same as one of the types that this
2984 // variant can hold. Note that in C++11 mode, this method does not
2985 // participate in overload resolution if it would lead to ambiguity
2986 // with the move constructor that takes an allocator (below).
2987
2988 /// Create a variant object having the type and value of the specified
2989 /// `original` variant. Optionally specify a `basicAllocator` used to
2990 /// supply memory. If `basicAllocator` is 0, the currently installed
2991 /// default allocator is used.
2992 Variant4(const Variant4& original, bslma::Allocator *basicAllocator = 0);
2993
2994 /// Create a variant object having the type and value of the specified
2995 /// `original` object by moving the contents of `original` to the
2996 /// newly-created object. The allocator associated with `original` (if
2997 /// any) is propagated for use in the newly-created object. `original`
2998 /// is left in a valid but unspecified state.
3000
3001 /// Create a variant object having the type and value of the specified
3002 /// `original` object that uses the specified `basicAllocator` to supply
3003 /// memory. If `basicAllocator` is 0, the currently installed default
3004 /// allocator is used. The contents of `original` are moved to the
3005 /// newly-created object with `original` left in a valid but unspecified
3006 /// state.
3008 bslma::Allocator *basicAllocator);
3009
3010 // MANIPULATORS
3011
3012 /// Assign to this object the specified `value` of template parameter
3013 /// `TYPE`, and return a reference providing modifiable access to this
3014 /// object. The value currently held by this variant (if any) is
3015 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3016 /// must be the same as one of the types that this variant can hold.
3017 template <class TYPE>
3018 Variant4& operator=(const TYPE& value);
3019
3020 template <class TYPE>
3021#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3022 typename bsl::enable_if<
3024 typename bsl::remove_cvref<TYPE>::type>::value,
3025 SelfType>::type&
3026 operator=(TYPE&& value);
3027#else
3028 Variant4&
3030#endif
3031 // Assign to this object the specified 'value' of template parameter
3032 // 'TYPE', and return a reference providing modifiable access to this
3033 // object. The contents of 'value' are moved to this object with
3034 // 'value' left in a valid but unspecified state. The value currently
3035 // held by this variant (if any) is destroyed if that value's type is
3036 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3037 // that this variant can hold. Note that in C++11 mode, this method
3038 // does not participate in overload resolution if it would lead to
3039 // ambiguity with the move-assignment operator (below).
3040
3041 /// Assign to this object the type and value currently held by the
3042 /// specified `rhs` object, and return a reference providing modifiable
3043 /// access to this object. The value currently held by this variant
3044 /// (if any) is destroyed if that value's type is not the same as the
3045 /// type held by the `rhs` object.
3046 Variant4& operator=(const Variant4& rhs);
3047
3048 /// Assign to this object the type and value currently held by the
3049 /// specified `rhs` object, and return a reference providing modifiable
3050 /// access to this object. The value currently held by this variant
3051 /// (if any) is destroyed if that value's type is not the same as the
3052 /// type held by the `rhs` object. The contents of `rhs` are either
3053 /// move-inserted into or move-assigned to this object with `rhs` left
3054 /// in a valid but unspecified state.
3055 Variant4& operator=(bslmf::MovableRef<Variant4> rhs);
3056};
3057
3058 // ===================
3059 // class Variant5<...>
3060 // ===================
3061
3062/// This class is a "specialization" of `Variant` for a fixed number (5) of
3063/// types. Its 5 template arguments *must* all be specified (none are
3064/// defaulted to `bslmf::Nil`). It provides the same functionality as
3065/// `Variant<A1, A2, ..., A5>`.
3066template <class A1, class A2, class A3, class A4, class A5>
3067class Variant5 : public VariantImp<typename bslmf::TypeList5<
3068 A1, A2, A3, A4, A5>::ListType> {
3069
3070 // PRIVATE TYPES
3071 typedef VariantImp<typename bslmf::TypeList5<A1, A2, A3, A4,
3072 A5>::ListType> Imp;
3073
3074 /// `SelfType` is an alias to this class.
3076
3079
3080 public:
3081 // TRAITS
3084 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
3087 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
3090 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
3092
3093 // CREATORS
3094
3095 /// Create a variant object in the unset state that uses the currently
3096 /// installed default allocator to supply memory.
3097 Variant5();
3098
3099 /// Create a variant object with the specified `valueOrAllocator` that
3100 /// can be either a value of a type that the variant can hold or an
3101 /// allocator to supply memory. If `valueOrAllocator` is not a
3102 /// `bslma::Allocator *`, then the variant will hold the value and type
3103 /// of `valueOrAllocator`, and use the currently installed default
3104 /// allocator to supply memory. Otherwise, the variant will be unset
3105 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
3106 /// must be the same as one of the types that this variant can hold or
3107 /// be convertible to `bslma::Allocator *`. Note that this
3108 /// parameterized constructor is defined instead of two constructors
3109 /// (one taking a `bslma::Allocator *` and the other not) because
3110 /// template parameter arguments are always a better match than
3111 /// derived-to-base conversion (a concrete allocator pointer converted
3112 /// to `bslma::Allocator *`).
3113 template <class TYPE_OR_ALLOCATOR>
3114 explicit
3115 Variant5(const TYPE_OR_ALLOCATOR& valueOrAllocator);
3116
3117 /// Create a variant object having the specified `value` of template
3118 /// parameter `TYPE` and that uses the specified `basicAllocator` to
3119 /// supply memory. If `basicAllocator` is 0, the currently installed
3120 /// default allocator is used. `TYPE` must be the same as one of the
3121 /// types that this variant can hold.
3122 template <class TYPE>
3123 Variant5(const TYPE& value, bslma::Allocator *basicAllocator);
3124
3125 template <class TYPE>
3126 explicit
3127#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3128 Variant5(TYPE&& value,
3129 typename bsl::enable_if<
3130 !bsl::is_same<
3131 SelfType,
3132 typename bsl::remove_const<
3133 typename bsl::remove_reference<TYPE>::type>::type>::value
3134 &&
3136 void>::type * = 0);
3137#else
3139#endif
3140 // Create a variant object having the specified 'value' of template
3141 // parameter 'TYPE' by moving the contents of 'value' to the
3142 // newly-created object. Use the currently installed default allocator
3143 // to supply memory. 'value' is left in a valid but unspecified state.
3144 // 'TYPE' must be the same as one of the types that this variant can
3145 // hold. Note that in C++11 mode, this method does not participate in
3146 // overload resolution if it would lead to ambiguity with the move
3147 // constructor that does not take an allocator (below) or with the
3148 // constructor taking a 'valueOrAllocator' (above).
3149
3150 template <class TYPE>
3151#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3152 Variant5(TYPE&& value,
3153 typename bsl::enable_if<
3154 !bsl::is_same<
3155 SelfType,
3156 typename bsl::remove_const<
3157 typename bsl::remove_reference<TYPE>::type>::type>::value,
3158 bslma::Allocator>::type *basicAllocator);
3159#else
3161 bslma::Allocator *basicAllocator);
3162#endif
3163 // Create a variant object having the specified 'value' of template
3164 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
3165 // memory. If 'basicAllocator' is 0, the currently installed default
3166 // allocator is used. The contents of 'value' are moved to the
3167 // newly-created object with 'value' left in a valid but unspecified
3168 // state. 'TYPE' must be the same as one of the types that this
3169 // variant can hold. Note that in C++11 mode, this method does not
3170 // participate in overload resolution if it would lead to ambiguity
3171 // with the move constructor that takes an allocator (below).
3172
3173 /// Create a variant object having the type and value of the specified
3174 /// `original` variant. Optionally specify a `basicAllocator` used to
3175 /// supply memory. If `basicAllocator` is 0, the currently installed
3176 /// default allocator is used.
3177 Variant5(const Variant5& original, bslma::Allocator *basicAllocator = 0);
3178
3179 /// Create a variant object having the type and value of the specified
3180 /// `original` object by moving the contents of `original` to the
3181 /// newly-created object. The allocator associated with `original` (if
3182 /// any) is propagated for use in the newly-created object. `original`
3183 /// is left in a valid but unspecified state.
3185
3186 /// Create a variant object having the type and value of the specified
3187 /// `original` object that uses the specified `basicAllocator` to supply
3188 /// memory. If `basicAllocator` is 0, the currently installed default
3189 /// allocator is used. The contents of `original` are moved to the
3190 /// newly-created object with `original` left in a valid but unspecified
3191 /// state.
3193 bslma::Allocator *basicAllocator);
3194
3195 // MANIPULATORS
3196
3197 /// Assign to this object the specified `value` of template parameter
3198 /// `TYPE`, and return a reference providing modifiable access to this
3199 /// object. The value currently held by this variant (if any) is
3200 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3201 /// must be the same as one of the types that this variant can hold.
3202 template <class TYPE>
3203 Variant5& operator=(const TYPE& value);
3204
3205 template <class TYPE>
3206#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3207 typename bsl::enable_if<
3209 typename bsl::remove_cvref<TYPE>::type>::value,
3210 SelfType>::type&
3211 operator=(TYPE&& value);
3212#else
3213 Variant5&
3215#endif
3216 // Assign to this object the specified 'value' of template parameter
3217 // 'TYPE', and return a reference providing modifiable access to this
3218 // object. The contents of 'value' are moved to this object with
3219 // 'value' left in a valid but unspecified state. The value currently
3220 // held by this variant (if any) is destroyed if that value's type is
3221 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3222 // that this variant can hold. Note that in C++11 mode, this method
3223 // does not participate in overload resolution if it would lead to
3224 // ambiguity with the move-assignment operator (below).
3225
3226 /// Assign to this object the type and value currently held by the
3227 /// specified `rhs` object, and return a reference providing modifiable
3228 /// access to this object. The value currently held by this variant
3229 /// (if any) is destroyed if that value's type is not the same as the
3230 /// type held by the `rhs` object.
3231 Variant5& operator=(const Variant5& rhs);
3232
3233 /// Assign to this object the type and value currently held by the
3234 /// specified `rhs` object, and return a reference providing modifiable
3235 /// access to this object. The value currently held by this variant
3236 /// (if any) is destroyed if that value's type is not the same as the
3237 /// type held by the `rhs` object. The contents of `rhs` are either
3238 /// move-inserted into or move-assigned to this object with `rhs` left
3239 /// in a valid but unspecified state.
3240 Variant5& operator=(bslmf::MovableRef<Variant5> rhs);
3241};
3242
3243 // ===================
3244 // class Variant6<...>
3245 // ===================
3246
3247/// This class is a "specialization" of `Variant` for a fixed number (6) of
3248/// types. Its 6 template arguments *must* all be specified (none are
3249/// defaulted to `bslmf::Nil`). It provides the same functionality as
3250/// `Variant<A1, A2, ..., A6>`.
3251template <class A1, class A2, class A3, class A4, class A5, class A6>
3252class Variant6 : public VariantImp<typename bslmf::TypeList6<
3253 A1, A2, A3, A4, A5, A6>::ListType> {
3254
3255 // PRIVATE TYPES
3256 typedef VariantImp<typename bslmf::TypeList6<A1, A2, A3, A4, A5,
3257 A6>::ListType> Imp;
3258
3259 /// `SelfType` is an alias to this class.
3261
3264
3265 public:
3266 // TRAITS
3269 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
3272 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
3275 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
3277
3278 // CREATORS
3279
3280 /// Create a variant object in the unset state that uses the currently
3281 /// installed default allocator to supply memory.
3282 Variant6();
3283
3284 /// Create a variant object with the specified `valueOrAllocator` that
3285 /// can be either a value of a type that the variant can hold or an
3286 /// allocator to supply memory. If `valueOrAllocator` is not a
3287 /// `bslma::Allocator *`, then the variant will hold the value and type
3288 /// of `valueOrAllocator`, and use the currently installed default
3289 /// allocator to supply memory. Otherwise, the variant will be unset
3290 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
3291 /// must be the same as one of the types that this variant can hold or
3292 /// be convertible to `bslma::Allocator *`. Note that this
3293 /// parameterized constructor is defined instead of two constructors
3294 /// (one taking a `bslma::Allocator *` and the other not) because
3295 /// template parameter arguments are always a better match than
3296 /// derived-to-base conversion (a concrete allocator pointer converted
3297 /// to `bslma::Allocator *`).
3298 template <class TYPE_OR_ALLOCATOR>
3299 explicit
3300 Variant6(const TYPE_OR_ALLOCATOR& valueOrAllocator);
3301
3302 /// Create a variant object having the specified `value` of template
3303 /// parameter `TYPE` and that uses the specified `basicAllocator` to
3304 /// supply memory. If `basicAllocator` is 0, the currently installed
3305 /// default allocator is used. `TYPE` must be the same as one of the
3306 /// types that this variant can hold.
3307 template <class TYPE>
3308 Variant6(const TYPE& value, bslma::Allocator *basicAllocator);
3309
3310 template <class TYPE>
3311 explicit
3312#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3313 Variant6(TYPE&& value,
3314 typename bsl::enable_if<
3315 !bsl::is_same<
3316 SelfType,
3317 typename bsl::remove_const<
3318 typename bsl::remove_reference<TYPE>::type>::type>::value
3319 &&
3321 void>::type * = 0);
3322#else
3324#endif
3325 // Create a variant object having the specified 'value' of template
3326 // parameter 'TYPE' by moving the contents of 'value' to the
3327 // newly-created object. Use the currently installed default allocator
3328 // to supply memory. 'value' is left in a valid but unspecified state.
3329 // 'TYPE' must be the same as one of the types that this variant can
3330 // hold. Note that in C++11 mode, this method does not participate in
3331 // overload resolution if it would lead to ambiguity with the move
3332 // constructor that does not take an allocator (below) or with the
3333 // constructor taking a 'valueOrAllocator' (above).
3334
3335 template <class TYPE>
3336#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3337 Variant6(TYPE&& value,
3338 typename bsl::enable_if<
3339 !bsl::is_same<
3340 SelfType,
3341 typename bsl::remove_const<
3342 typename bsl::remove_reference<TYPE>::type>::type>::value,
3343 bslma::Allocator>::type *basicAllocator);
3344#else
3346 bslma::Allocator *basicAllocator);
3347#endif
3348 // Create a variant object having the specified 'value' of template
3349 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
3350 // memory. If 'basicAllocator' is 0, the currently installed default
3351 // allocator is used. The contents of 'value' are moved to the
3352 // newly-created object with 'value' left in a valid but unspecified
3353 // state. 'TYPE' must be the same as one of the types that this
3354 // variant can hold. Note that in C++11 mode, this method does not
3355 // participate in overload resolution if it would lead to ambiguity
3356 // with the move constructor that takes an allocator (below).
3357
3358 /// Create a variant object having the type and value of the specified
3359 /// `original` variant. Optionally specify a `basicAllocator` used to
3360 /// supply memory. If `basicAllocator` is 0, the currently installed
3361 /// default allocator is used.
3362 Variant6(const Variant6& original, bslma::Allocator *basicAllocator = 0);
3363
3364 /// Create a variant object having the type and value of the specified
3365 /// `original` object by moving the contents of `original` to the
3366 /// newly-created object. The allocator associated with `original` (if
3367 /// any) is propagated for use in the newly-created object. `original`
3368 /// is left in a valid but unspecified state.
3370
3371 /// Create a variant object having the type and value of the specified
3372 /// `original` object that uses the specified `basicAllocator` to supply
3373 /// memory. If `basicAllocator` is 0, the currently installed default
3374 /// allocator is used. The contents of `original` are moved to the
3375 /// newly-created object with `original` left in a valid but unspecified
3376 /// state.
3378 bslma::Allocator *basicAllocator);
3379
3380 // MANIPULATORS
3381
3382 /// Assign to this object the specified `value` of template parameter
3383 /// `TYPE`, and return a reference providing modifiable access to this
3384 /// object. The value currently held by this variant (if any) is
3385 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3386 /// must be the same as one of the types that this variant can hold.
3387 template <class TYPE>
3388 Variant6& operator=(const TYPE& value);
3389
3390 template <class TYPE>
3391#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3392 typename bsl::enable_if<
3394 typename bsl::remove_cvref<TYPE>::type>::value,
3395 SelfType>::type&
3396 operator=(TYPE&& value);
3397#else
3398 Variant6&
3400#endif
3401 // Assign to this object the specified 'value' of template parameter
3402 // 'TYPE', and return a reference providing modifiable access to this
3403 // object. The contents of 'value' are moved to this object with
3404 // 'value' left in a valid but unspecified state. The value currently
3405 // held by this variant (if any) is destroyed if that value's type is
3406 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3407 // that this variant can hold. Note that in C++11 mode, this method
3408 // does not participate in overload resolution if it would lead to
3409 // ambiguity with the move-assignment operator (below).
3410
3411 /// Assign to this object the type and value currently held by the
3412 /// specified `rhs` object, and return a reference providing modifiable
3413 /// access to this object. The value currently held by this variant
3414 /// (if any) is destroyed if that value's type is not the same as the
3415 /// type held by the `rhs` object.
3416 Variant6& operator=(const Variant6& rhs);
3417
3418 /// Assign to this object the type and value currently held by the
3419 /// specified `rhs` object, and return a reference providing modifiable
3420 /// access to this object. The value currently held by this variant
3421 /// (if any) is destroyed if that value's type is not the same as the
3422 /// type held by the `rhs` object. The contents of `rhs` are either
3423 /// move-inserted into or move-assigned to this object with `rhs` left
3424 /// in a valid but unspecified state.
3425 Variant6& operator=(bslmf::MovableRef<Variant6> rhs);
3426};
3427
3428 // ===================
3429 // class Variant7<...>
3430 // ===================
3431
3432/// This class is a "specialization" of `Variant` for a fixed number (7) of
3433/// types. Its 7 template arguments *must* all be specified (none are
3434/// defaulted to `bslmf::Nil`). It provides the same functionality as
3435/// `Variant<A1, A2, ..., A7>`.
3436template <class A1, class A2, class A3, class A4, class A5, class A6,
3437 class A7>
3438class Variant7 : public VariantImp<typename bslmf::TypeList7<
3439 A1, A2, A3, A4, A5, A6, A7>::ListType> {
3440
3441 // PRIVATE TYPES
3442 typedef VariantImp<typename bslmf::TypeList7<A1, A2, A3, A4, A5, A6,
3443 A7>::ListType> Imp;
3444
3445 /// `SelfType` is an alias to this class.
3447
3450
3451 public:
3452 // TRAITS
3455 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
3458 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
3461 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
3463
3464 // CREATORS
3465
3466 /// Create a variant object in the unset state that uses the currently
3467 /// installed default allocator to supply memory.
3468 Variant7();
3469
3470 /// Create a variant object with the specified `valueOrAllocator` that
3471 /// can be either a value of a type that the variant can hold or an
3472 /// allocator to supply memory. If `valueOrAllocator` is not a
3473 /// `bslma::Allocator *`, then the variant will hold the value and type
3474 /// of `valueOrAllocator`, and use the currently installed default
3475 /// allocator to supply memory. Otherwise, the variant will be unset
3476 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
3477 /// must be the same as one of the types that this variant can hold or
3478 /// be convertible to `bslma::Allocator *`. Note that this
3479 /// parameterized constructor is defined instead of two constructors
3480 /// (one taking a `bslma::Allocator *` and the other not) because
3481 /// template parameter arguments are always a better match than
3482 /// derived-to-base conversion (a concrete allocator pointer converted
3483 /// to `bslma::Allocator *`).
3484 template <class TYPE_OR_ALLOCATOR>
3485 explicit
3486 Variant7(const TYPE_OR_ALLOCATOR& valueOrAllocator);
3487
3488 /// Create a variant object having the specified `value` of template
3489 /// parameter `TYPE` and that uses the specified `basicAllocator` to
3490 /// supply memory. If `basicAllocator` is 0, the currently installed
3491 /// default allocator is used. `TYPE` must be the same as one of the
3492 /// types that this variant can hold.
3493 template <class TYPE>
3494 Variant7(const TYPE& value, bslma::Allocator *basicAllocator);
3495
3496 template <class TYPE>
3497 explicit
3498#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3499 Variant7(TYPE&& value,
3500 typename bsl::enable_if<
3501 !bsl::is_same<
3502 SelfType,
3503 typename bsl::remove_const<
3504 typename bsl::remove_reference<TYPE>::type>::type>::value
3505 &&
3507 void>::type * = 0);
3508#else
3510#endif
3511 // Create a variant object having the specified 'value' of template
3512 // parameter 'TYPE' by moving the contents of 'value' to the
3513 // newly-created object. Use the currently installed default allocator
3514 // to supply memory. 'value' is left in a valid but unspecified state.
3515 // 'TYPE' must be the same as one of the types that this variant can
3516 // hold. Note that in C++11 mode, this method does not participate in
3517 // overload resolution if it would lead to ambiguity with the move
3518 // constructor that does not take an allocator (below) or with the
3519 // constructor taking a 'valueOrAllocator' (above).
3520
3521 template <class TYPE>
3522#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3523 Variant7(TYPE&& value,
3524 typename bsl::enable_if<
3525 !bsl::is_same<
3526 SelfType,
3527 typename bsl::remove_const<
3528 typename bsl::remove_reference<TYPE>::type>::type>::value,
3529 bslma::Allocator>::type *basicAllocator);
3530#else
3532 bslma::Allocator *basicAllocator);
3533#endif
3534 // Create a variant object having the specified 'value' of template
3535 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
3536 // memory. If 'basicAllocator' is 0, the currently installed default
3537 // allocator is used. The contents of 'value' are moved to the
3538 // newly-created object with 'value' left in a valid but unspecified
3539 // state. 'TYPE' must be the same as one of the types that this
3540 // variant can hold. Note that in C++11 mode, this method does not
3541 // participate in overload resolution if it would lead to ambiguity
3542 // with the move constructor that takes an allocator (below).
3543
3544 /// Create a variant object having the type and value of the specified
3545 /// `original` variant. Optionally specify a `basicAllocator` used to
3546 /// supply memory. If `basicAllocator` is 0, the currently installed
3547 /// default allocator is used.
3548 Variant7(const Variant7& original, bslma::Allocator *basicAllocator = 0);
3549
3550 /// Create a variant object having the type and value of the specified
3551 /// `original` object by moving the contents of `original` to the
3552 /// newly-created object. The allocator associated with `original` (if
3553 /// any) is propagated for use in the newly-created object. `original`
3554 /// is left in a valid but unspecified state.
3556
3557 /// Create a variant object having the type and value of the specified
3558 /// `original` object that uses the specified `basicAllocator` to supply
3559 /// memory. If `basicAllocator` is 0, the currently installed default
3560 /// allocator is used. The contents of `original` are moved to the
3561 /// newly-created object with `original` left in a valid but unspecified
3562 /// state.
3564 bslma::Allocator *basicAllocator);
3565
3566 // MANIPULATORS
3567
3568 /// Assign to this object the specified `value` of template parameter
3569 /// `TYPE`, and return a reference providing modifiable access to this
3570 /// object. The value currently held by this variant (if any) is
3571 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3572 /// must be the same as one of the types that this variant can hold.
3573 template <class TYPE>
3574 Variant7& operator=(const TYPE& value);
3575
3576 template <class TYPE>
3577#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3578 typename bsl::enable_if<
3580 typename bsl::remove_cvref<TYPE>::type>::value,
3581 SelfType>::type&
3582 operator=(TYPE&& value);
3583#else
3584 Variant7&
3586#endif
3587 // Assign to this object the specified 'value' of template parameter
3588 // 'TYPE', and return a reference providing modifiable access to this
3589 // object. The contents of 'value' are moved to this object with
3590 // 'value' left in a valid but unspecified state. The value currently
3591 // held by this variant (if any) is destroyed if that value's type is
3592 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3593 // that this variant can hold. Note that in C++11 mode, this method
3594 // does not participate in overload resolution if it would lead to
3595 // ambiguity with the move-assignment operator (below).
3596
3597 /// Assign to this object the type and value currently held by the
3598 /// specified `rhs` object, and return a reference providing modifiable
3599 /// access to this object. The value currently held by this variant
3600 /// (if any) is destroyed if that value's type is not the same as the
3601 /// type held by the `rhs` object.
3602 Variant7& operator=(const Variant7& rhs);
3603
3604 /// Assign to this object the type and value currently held by the
3605 /// specified `rhs` object, and return a reference providing modifiable
3606 /// access to this object. The value currently held by this variant
3607 /// (if any) is destroyed if that value's type is not the same as the
3608 /// type held by the `rhs` object. The contents of `rhs` are either
3609 /// move-inserted into or move-assigned to this object with `rhs` left
3610 /// in a valid but unspecified state.
3611 Variant7& operator=(bslmf::MovableRef<Variant7> rhs);
3612};
3613
3614 // ===================
3615 // class Variant8<...>
3616 // ===================
3617
3618/// This class is a "specialization" of `Variant` for a fixed number (8) of
3619/// types. Its 8 template arguments *must* all be specified (none are
3620/// defaulted to `bslmf::Nil`). It provides the same functionality as
3621/// `Variant<A1, A2, ..., A8>`.
3622template <class A1, class A2, class A3, class A4, class A5, class A6,
3623 class A7, class A8>
3624class Variant8 : public VariantImp<typename bslmf::TypeList8<
3625 A1, A2, A3, A4, A5, A6, A7, A8>::ListType> {
3626
3627 // PRIVATE TYPES
3628 typedef VariantImp<typename bslmf::TypeList8<A1, A2, A3, A4, A5, A6, A7,
3629 A8>::ListType> Imp;
3630
3631 /// `SelfType` is an alias to this class.
3633
3636
3637 public:
3638 // TRAITS
3641 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
3644 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
3647 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
3649
3650 // CREATORS
3651
3652 /// Create a variant object in the unset state that uses the currently
3653 /// installed default allocator to supply memory.
3654 Variant8();
3655
3656 /// Create a variant object with the specified `valueOrAllocator` that
3657 /// can be either a value of a type that the variant can hold or an
3658 /// allocator to supply memory. If `valueOrAllocator` is not a
3659 /// `bslma::Allocator *`, then the variant will hold the value and type
3660 /// of `valueOrAllocator`, and use the currently installed default
3661 /// allocator to supply memory. Otherwise, the variant will be unset
3662 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
3663 /// must be the same as one of the types that this variant can hold or
3664 /// be convertible to `bslma::Allocator *`. Note that this
3665 /// parameterized constructor is defined instead of two constructors
3666 /// (one taking a `bslma::Allocator *` and the other not) because
3667 /// template parameter arguments are always a better match than
3668 /// derived-to-base conversion (a concrete allocator pointer converted
3669 /// to `bslma::Allocator *`).
3670 template <class TYPE_OR_ALLOCATOR>
3671 explicit
3672 Variant8(const TYPE_OR_ALLOCATOR& valueOrAllocator);
3673
3674 /// Create a variant object having the specified `value` of template
3675 /// parameter `TYPE` and that uses the specified `basicAllocator` to
3676 /// supply memory. If `basicAllocator` is 0, the currently installed
3677 /// default allocator is used. `TYPE` must be the same as one of the
3678 /// types that this variant can hold.
3679 template <class TYPE>
3680 Variant8(const TYPE& value, bslma::Allocator *basicAllocator);
3681
3682 template <class TYPE>
3683 explicit
3684#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3685 Variant8(TYPE&& value,
3686 typename bsl::enable_if<
3687 !bsl::is_same<
3688 SelfType,
3689 typename bsl::remove_const<
3690 typename bsl::remove_reference<TYPE>::type>::type>::value
3691 &&
3693 void>::type * = 0);
3694#else
3696#endif
3697 // Create a variant object having the specified 'value' of template
3698 // parameter 'TYPE' by moving the contents of 'value' to the
3699 // newly-created object. Use the currently installed default allocator
3700 // to supply memory. 'value' is left in a valid but unspecified state.
3701 // 'TYPE' must be the same as one of the types that this variant can
3702 // hold. Note that in C++11 mode, this method does not participate in
3703 // overload resolution if it would lead to ambiguity with the move
3704 // constructor that does not take an allocator (below) or with the
3705 // constructor taking a 'valueOrAllocator' (above).
3706
3707 template <class TYPE>
3708#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3709 Variant8(TYPE&& value,
3710 typename bsl::enable_if<
3711 !bsl::is_same<
3712 SelfType,
3713 typename bsl::remove_const<
3714 typename bsl::remove_reference<TYPE>::type>::type>::value,
3715 bslma::Allocator>::type *basicAllocator);
3716#else
3718 bslma::Allocator *basicAllocator);
3719#endif
3720 // Create a variant object having the specified 'value' of template
3721 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
3722 // memory. If 'basicAllocator' is 0, the currently installed default
3723 // allocator is used. The contents of 'value' are moved to the
3724 // newly-created object with 'value' left in a valid but unspecified
3725 // state. 'TYPE' must be the same as one of the types that this
3726 // variant can hold. Note that in C++11 mode, this method does not
3727 // participate in overload resolution if it would lead to ambiguity
3728 // with the move constructor that takes an allocator (below).
3729
3730 /// Create a variant object having the type and value of the specified
3731 /// `original` variant. Optionally specify a `basicAllocator` used to
3732 /// supply memory. If `basicAllocator` is 0, the currently installed
3733 /// default allocator is used.
3734 Variant8(const Variant8& original, bslma::Allocator *basicAllocator = 0);
3735
3736 /// Create a variant object having the type and value of the specified
3737 /// `original` object by moving the contents of `original` to the
3738 /// newly-created object. The allocator associated with `original` (if
3739 /// any) is propagated for use in the newly-created object. `original`
3740 /// is left in a valid but unspecified state.
3742
3743 /// Create a variant object having the type and value of the specified
3744 /// `original` object that uses the specified `basicAllocator` to supply
3745 /// memory. If `basicAllocator` is 0, the currently installed default
3746 /// allocator is used. The contents of `original` are moved to the
3747 /// newly-created object with `original` left in a valid but unspecified
3748 /// state.
3750 bslma::Allocator *basicAllocator);
3751
3752 // MANIPULATORS
3753
3754 /// Assign to this object the specified `value` of template parameter
3755 /// `TYPE`, and return a reference providing modifiable access to this
3756 /// object. The value currently held by this variant (if any) is
3757 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3758 /// must be the same as one of the types that this variant can hold.
3759 template <class TYPE>
3760 Variant8& operator=(const TYPE& value);
3761
3762 template <class TYPE>
3763#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3764 typename bsl::enable_if<
3766 typename bsl::remove_cvref<TYPE>::type>::value,
3767 SelfType>::type&
3768 operator=(TYPE&& value);
3769#else
3770 Variant8&
3772#endif
3773 // Assign to this object the specified 'value' of template parameter
3774 // 'TYPE', and return a reference providing modifiable access to this
3775 // object. The contents of 'value' are moved to this object with
3776 // 'value' left in a valid but unspecified state. The value currently
3777 // held by this variant (if any) is destroyed if that value's type is
3778 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3779 // that this variant can hold. Note that in C++11 mode, this method
3780 // does not participate in overload resolution if it would lead to
3781 // ambiguity with the move-assignment operator (below).
3782
3783 /// Assign to this object the type and value currently held by the
3784 /// specified `rhs` object, and return a reference providing modifiable
3785 /// access to this object. The value currently held by this variant
3786 /// (if any) is destroyed if that value's type is not the same as the
3787 /// type held by the `rhs` object.
3788 Variant8& operator=(const Variant8& rhs);
3789
3790 /// Assign to this object the type and value currently held by the
3791 /// specified `rhs` object, and return a reference providing modifiable
3792 /// access to this object. The value currently held by this variant
3793 /// (if any) is destroyed if that value's type is not the same as the
3794 /// type held by the `rhs` object. The contents of `rhs` are either
3795 /// move-inserted into or move-assigned to this object with `rhs` left
3796 /// in a valid but unspecified state.
3797 Variant8& operator=(bslmf::MovableRef<Variant8> rhs);
3798};
3799
3800 // ===================
3801 // class Variant9<...>
3802 // ===================
3803
3804/// This class is a "specialization" of `Variant` for a fixed number (9) of
3805/// types. Its 9 template arguments *must* all be specified (none are
3806/// defaulted to `bslmf::Nil`). It provides the same functionality as
3807/// `Variant<A1, A2, ..., A9>`.
3808template <class A1, class A2, class A3, class A4, class A5, class A6,
3809 class A7, class A8, class A9>
3810class Variant9 : public VariantImp<typename bslmf::TypeList9<
3811 A1, A2, A3, A4, A5, A6, A7, A8, A9>::ListType> {
3812
3813 // PRIVATE TYPES
3814 typedef VariantImp<typename bslmf::TypeList9<A1, A2, A3, A4, A5, A6, A7,
3815 A8, A9>::ListType> Imp;
3816
3817 /// `SelfType` is an alias to this class.
3819
3822
3823 public:
3824 // TRAITS
3827 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
3830 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
3833 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
3835
3836 // CREATORS
3837
3838 /// Create a variant object in the unset state that uses the currently
3839 /// installed default allocator to supply memory.
3840 Variant9();
3841
3842 /// Create a variant object with the specified `valueOrAllocator` that
3843 /// can be either a value of a type that the variant can hold or an
3844 /// allocator to supply memory. If `valueOrAllocator` is not a
3845 /// `bslma::Allocator *`, then the variant will hold the value and type
3846 /// of `valueOrAllocator`, and use the currently installed default
3847 /// allocator to supply memory. Otherwise, the variant will be unset
3848 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
3849 /// must be the same as one of the types that this variant can hold or
3850 /// be convertible to `bslma::Allocator *`. Note that this
3851 /// parameterized constructor is defined instead of two constructors
3852 /// (one taking a `bslma::Allocator *` and the other not) because
3853 /// template parameter arguments are always a better match than
3854 /// derived-to-base conversion (a concrete allocator pointer converted
3855 /// to `bslma::Allocator *`).
3856 template <class TYPE_OR_ALLOCATOR>
3857 explicit
3858 Variant9(const TYPE_OR_ALLOCATOR& valueOrAllocator);
3859
3860 /// Create a variant object having the specified `value` of template
3861 /// parameter `TYPE` and that uses the specified `basicAllocator` to
3862 /// supply memory. If `basicAllocator` is 0, the currently installed
3863 /// default allocator is used. `TYPE` must be the same as one of the
3864 /// types that this variant can hold.
3865 template <class TYPE>
3866 Variant9(const TYPE& value, bslma::Allocator *basicAllocator);
3867
3868 template <class TYPE>
3869 explicit
3870#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3871 Variant9(TYPE&& value,
3872 typename bsl::enable_if<
3873 !bsl::is_same<
3874 SelfType,
3875 typename bsl::remove_const<
3876 typename bsl::remove_reference<TYPE>::type>::type>::value
3877 &&
3879 void>::type * = 0);
3880#else
3882#endif
3883 // Create a variant object having the specified 'value' of template
3884 // parameter 'TYPE' by moving the contents of 'value' to the
3885 // newly-created object. Use the currently installed default allocator
3886 // to supply memory. 'value' is left in a valid but unspecified state.
3887 // 'TYPE' must be the same as one of the types that this variant can
3888 // hold. Note that in C++11 mode, this method does not participate in
3889 // overload resolution if it would lead to ambiguity with the move
3890 // constructor that does not take an allocator (below) or with the
3891 // constructor taking a 'valueOrAllocator' (above).
3892
3893 template <class TYPE>
3894#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3895 Variant9(TYPE&& value,
3896 typename bsl::enable_if<
3897 !bsl::is_same<
3898 SelfType,
3899 typename bsl::remove_const<
3900 typename bsl::remove_reference<TYPE>::type>::type>::value,
3901 bslma::Allocator>::type *basicAllocator);
3902#else
3904 bslma::Allocator *basicAllocator);
3905#endif
3906 // Create a variant object having the specified 'value' of template
3907 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
3908 // memory. If 'basicAllocator' is 0, the currently installed default
3909 // allocator is used. The contents of 'value' are moved to the
3910 // newly-created object with 'value' left in a valid but unspecified
3911 // state. 'TYPE' must be the same as one of the types that this
3912 // variant can hold. Note that in C++11 mode, this method does not
3913 // participate in overload resolution if it would lead to ambiguity
3914 // with the move constructor that takes an allocator (below).
3915
3916 /// Create a variant object having the type and value of the specified
3917 /// `original` variant. Optionally specify a `basicAllocator` used to
3918 /// supply memory. If `basicAllocator` is 0, the currently installed
3919 /// default allocator is used.
3920 Variant9(const Variant9& original, bslma::Allocator *basicAllocator = 0);
3921
3922 /// Create a variant object having the type and value of the specified
3923 /// `original` object by moving the contents of `original` to the
3924 /// newly-created object. The allocator associated with `original` (if
3925 /// any) is propagated for use in the newly-created object. `original`
3926 /// is left in a valid but unspecified state.
3928
3929 /// Create a variant object having the type and value of the specified
3930 /// `original` object that uses the specified `basicAllocator` to supply
3931 /// memory. If `basicAllocator` is 0, the currently installed default
3932 /// allocator is used. The contents of `original` are moved to the
3933 /// newly-created object with `original` left in a valid but unspecified
3934 /// state.
3936 bslma::Allocator *basicAllocator);
3937
3938 // MANIPULATORS
3939
3940 /// Assign to this object the specified `value` of template parameter
3941 /// `TYPE`, and return a reference providing modifiable access to this
3942 /// object. The value currently held by this variant (if any) is
3943 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
3944 /// must be the same as one of the types that this variant can hold.
3945 template <class TYPE>
3946 Variant9& operator=(const TYPE& value);
3947
3948 template <class TYPE>
3949#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
3950 typename bsl::enable_if<
3952 typename bsl::remove_cvref<TYPE>::type>::value,
3953 SelfType>::type&
3954 operator=(TYPE&& value);
3955#else
3956 Variant9&
3958#endif
3959 // Assign to this object the specified 'value' of template parameter
3960 // 'TYPE', and return a reference providing modifiable access to this
3961 // object. The contents of 'value' are moved to this object with
3962 // 'value' left in a valid but unspecified state. The value currently
3963 // held by this variant (if any) is destroyed if that value's type is
3964 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
3965 // that this variant can hold. Note that in C++11 mode, this method
3966 // does not participate in overload resolution if it would lead to
3967 // ambiguity with the move-assignment operator (below).
3968
3969 /// Assign to this object the type and value currently held by the
3970 /// specified `rhs` object, and return a reference providing modifiable
3971 /// access to this object. The value currently held by this variant
3972 /// (if any) is destroyed if that value's type is not the same as the
3973 /// type held by the `rhs` object.
3974 Variant9& operator=(const Variant9& rhs);
3975
3976 /// Assign to this object the type and value currently held by the
3977 /// specified `rhs` object, and return a reference providing modifiable
3978 /// access to this object. The value currently held by this variant
3979 /// (if any) is destroyed if that value's type is not the same as the
3980 /// type held by the `rhs` object. The contents of `rhs` are either
3981 /// move-inserted into or move-assigned to this object with `rhs` left
3982 /// in a valid but unspecified state.
3983 Variant9& operator=(bslmf::MovableRef<Variant9> rhs);
3984};
3985
3986 // ====================
3987 // class Variant10<...>
3988 // ====================
3989
3990/// This class is a "specialization" of `Variant` for a fixed number (10) of
3991/// types. Its 10 template arguments *must* all be specified (none are
3992/// defaulted to `bslmf::Nil`). It provides the same functionality as
3993/// `Variant<A1, A2, ..., A10>`.
3994template <class A1, class A2, class A3, class A4, class A5, class A6,
3995 class A7, class A8, class A9, class A10>
3996class Variant10 : public VariantImp<typename bslmf::TypeList10<
3997 A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::ListType> {
3998
3999 // PRIVATE TYPES
4000 typedef VariantImp<typename bslmf::TypeList10<A1, A2, A3, A4, A5, A6, A7,
4001 A8, A9,
4002 A10>::ListType> Imp;
4003
4004 /// `SelfType` is an alias to this class.
4006
4009
4010 public:
4011 // TRAITS
4014 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4017 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4020 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4022
4023 // CREATORS
4024
4025 /// Create a variant object in the unset state that uses the currently
4026 /// installed default allocator to supply memory.
4027 Variant10();
4028
4029 /// Create a variant object with the specified `valueOrAllocator` that
4030 /// can be either a value of a type that the variant can hold or an
4031 /// allocator to supply memory. If `valueOrAllocator` is not a
4032 /// `bslma::Allocator *`, then the variant will hold the value and type
4033 /// of `valueOrAllocator`, and use the currently installed default
4034 /// allocator to supply memory. Otherwise, the variant will be unset
4035 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4036 /// must be the same as one of the types that this variant can hold or
4037 /// be convertible to `bslma::Allocator *`. Note that this
4038 /// parameterized constructor is defined instead of two constructors
4039 /// (one taking a `bslma::Allocator *` and the other not) because
4040 /// template parameter arguments are always a better match than
4041 /// derived-to-base conversion (a concrete allocator pointer converted
4042 /// to `bslma::Allocator *`).
4043 template <class TYPE_OR_ALLOCATOR>
4044 explicit
4045 Variant10(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4046
4047 /// Create a variant object having the specified `value` of template
4048 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4049 /// supply memory. If `basicAllocator` is 0, the currently installed
4050 /// default allocator is used. `TYPE` must be the same as one of the
4051 /// types that this variant can hold.
4052 template <class TYPE>
4053 Variant10(const TYPE& value, bslma::Allocator *basicAllocator);
4054
4055 template <class TYPE>
4056 explicit
4057#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4058 Variant10(TYPE&& value,
4059 typename bsl::enable_if<
4060 !bsl::is_same<
4061 SelfType,
4062 typename bsl::remove_const<
4063 typename bsl::remove_reference<TYPE>::type>::type>::value
4064 &&
4066 void>::type * = 0);
4067#else
4069#endif
4070 // Create a variant object having the specified 'value' of template
4071 // parameter 'TYPE' by moving the contents of 'value' to the
4072 // newly-created object. Use the currently installed default allocator
4073 // to supply memory. 'value' is left in a valid but unspecified state.
4074 // 'TYPE' must be the same as one of the types that this variant can
4075 // hold. Note that in C++11 mode, this method does not participate in
4076 // overload resolution if it would lead to ambiguity with the move
4077 // constructor that does not take an allocator (below) or with the
4078 // constructor taking a 'valueOrAllocator' (above).
4079
4080 template <class TYPE>
4081#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4082 Variant10(TYPE&& value,
4083 typename bsl::enable_if<
4084 !bsl::is_same<
4085 SelfType,
4086 typename bsl::remove_const<
4087 typename bsl::remove_reference<TYPE>::type>::type>::value,
4088 bslma::Allocator>::type *basicAllocator);
4089#else
4091 bslma::Allocator *basicAllocator);
4092#endif
4093 // Create a variant object having the specified 'value' of template
4094 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
4095 // memory. If 'basicAllocator' is 0, the currently installed default
4096 // allocator is used. The contents of 'value' are moved to the
4097 // newly-created object with 'value' left in a valid but unspecified
4098 // state. 'TYPE' must be the same as one of the types that this
4099 // variant can hold. Note that in C++11 mode, this method does not
4100 // participate in overload resolution if it would lead to ambiguity
4101 // with the move constructor that takes an allocator (below).
4102
4103 /// Create a variant object having the type and value of the specified
4104 /// `original` variant. Optionally specify a `basicAllocator` used to
4105 /// supply memory. If `basicAllocator` is 0, the currently installed
4106 /// default allocator is used.
4107 Variant10(const Variant10& original, bslma::Allocator *basicAllocator = 0);
4108
4109 /// Create a variant object having the type and value of the specified
4110 /// `original` object by moving the contents of `original` to the
4111 /// newly-created object. The allocator associated with `original` (if
4112 /// any) is propagated for use in the newly-created object. `original`
4113 /// is left in a valid but unspecified state.
4115
4116 /// Create a variant object having the type and value of the specified
4117 /// `original` object that uses the specified `basicAllocator` to supply
4118 /// memory. If `basicAllocator` is 0, the currently installed default
4119 /// allocator is used. The contents of `original` are moved to the
4120 /// newly-created object with `original` left in a valid but unspecified
4121 /// state.
4123 bslma::Allocator *basicAllocator);
4124
4125 // MANIPULATORS
4126
4127 /// Assign to this object the specified `value` of template parameter
4128 /// `TYPE`, and return a reference providing modifiable access to this
4129 /// object. The value currently held by this variant (if any) is
4130 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
4131 /// must be the same as one of the types that this variant can hold.
4132 template <class TYPE>
4133 Variant10& operator=(const TYPE& value);
4134
4135 template <class TYPE>
4136#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4137 typename bsl::enable_if<
4139 typename bsl::remove_cvref<TYPE>::type>::value,
4140 SelfType>::type&
4141 operator=(TYPE&& value);
4142#else
4143 Variant10&
4145#endif
4146 // Assign to this object the specified 'value' of template parameter
4147 // 'TYPE', and return a reference providing modifiable access to this
4148 // object. The contents of 'value' are moved to this object with
4149 // 'value' left in a valid but unspecified state. The value currently
4150 // held by this variant (if any) is destroyed if that value's type is
4151 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
4152 // that this variant can hold. Note that in C++11 mode, this method
4153 // does not participate in overload resolution if it would lead to
4154 // ambiguity with the move-assignment operator (below).
4155
4156 /// Assign to this object the type and value currently held by the
4157 /// specified `rhs` object, and return a reference providing modifiable
4158 /// access to this object. The value currently held by this variant
4159 /// (if any) is destroyed if that value's type is not the same as the
4160 /// type held by the `rhs` object.
4161 Variant10& operator=(const Variant10& rhs);
4162
4163 /// Assign to this object the type and value currently held by the
4164 /// specified `rhs` object, and return a reference providing modifiable
4165 /// access to this object. The value currently held by this variant
4166 /// (if any) is destroyed if that value's type is not the same as the
4167 /// type held by the `rhs` object. The contents of `rhs` are either
4168 /// move-inserted into or move-assigned to this object with `rhs` left
4169 /// in a valid but unspecified state.
4171};
4172
4173 // ====================
4174 // class Variant11<...>
4175 // ====================
4176
4177/// This class is a "specialization" of `Variant` for a fixed number (11) of
4178/// types. Its 11 template arguments *must* all be specified (none are
4179/// defaulted to `bslmf::Nil`). It provides the same functionality as
4180/// `Variant<A1, A2, ..., A11>`.
4181template <class A1, class A2, class A3, class A4, class A5, class A6,
4182 class A7, class A8, class A9, class A10, class A11>
4183class Variant11 : public VariantImp<typename bslmf::TypeList11<
4184 A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::ListType> {
4185
4186 // PRIVATE TYPES
4187 typedef VariantImp<typename bslmf::TypeList11<A1, A2, A3, A4, A5, A6, A7,
4188 A8, A9, A10,
4189 A11>::ListType> Imp;
4190
4191 /// `SelfType` is an alias to this class.
4192 typedef Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
4193 A11> SelfType;
4194
4197
4198 public:
4199 // TRAITS
4202 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4205 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4208 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4210
4211 // CREATORS
4212
4213 /// Create a variant object in the unset state that uses the currently
4214 /// installed default allocator to supply memory.
4215 Variant11();
4216
4217 /// Create a variant object with the specified `valueOrAllocator` that
4218 /// can be either a value of a type that the variant can hold or an
4219 /// allocator to supply memory. If `valueOrAllocator` is not a
4220 /// `bslma::Allocator *`, then the variant will hold the value and type
4221 /// of `valueOrAllocator`, and use the currently installed default
4222 /// allocator to supply memory. Otherwise, the variant will be unset
4223 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4224 /// must be the same as one of the types that this variant can hold or
4225 /// be convertible to `bslma::Allocator *`. Note that this
4226 /// parameterized constructor is defined instead of two constructors
4227 /// (one taking a `bslma::Allocator *` and the other not) because
4228 /// template parameter arguments are always a better match than
4229 /// derived-to-base conversion (a concrete allocator pointer converted
4230 /// to `bslma::Allocator *`).
4231 template <class TYPE_OR_ALLOCATOR>
4232 explicit
4233 Variant11(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4234
4235 /// Create a variant object having the specified `value` of template
4236 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4237 /// supply memory. If `basicAllocator` is 0, the currently installed
4238 /// default allocator is used. `TYPE` must be the same as one of the
4239 /// types that this variant can hold.
4240 template <class TYPE>
4241 Variant11(const TYPE& value, bslma::Allocator *basicAllocator);
4242
4243 template <class TYPE>
4244 explicit
4245#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4246 Variant11(TYPE&& value,
4247 typename bsl::enable_if<
4248 !bsl::is_same<
4249 SelfType,
4250 typename bsl::remove_const<
4251 typename bsl::remove_reference<TYPE>::type>::type>::value
4252 &&
4254 void>::type * = 0);
4255#else
4257#endif
4258 // Create a variant object having the specified 'value' of template
4259 // parameter 'TYPE' by moving the contents of 'value' to the
4260 // newly-created object. Use the currently installed default allocator
4261 // to supply memory. 'value' is left in a valid but unspecified state.
4262 // 'TYPE' must be the same as one of the types that this variant can
4263 // hold. Note that in C++11 mode, this method does not participate in
4264 // overload resolution if it would lead to ambiguity with the move
4265 // constructor that does not take an allocator (below) or with the
4266 // constructor taking a 'valueOrAllocator' (above).
4267
4268 template <class TYPE>
4269#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4270 Variant11(TYPE&& value,
4271 typename bsl::enable_if<
4272 !bsl::is_same<
4273 SelfType,
4274 typename bsl::remove_const<
4275 typename bsl::remove_reference<TYPE>::type>::type>::value,
4276 bslma::Allocator>::type *basicAllocator);
4277#else
4279 bslma::Allocator *basicAllocator);
4280#endif
4281 // Create a variant object having the specified 'value' of template
4282 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
4283 // memory. If 'basicAllocator' is 0, the currently installed default
4284 // allocator is used. The contents of 'value' are moved to the
4285 // newly-created object with 'value' left in a valid but unspecified
4286 // state. 'TYPE' must be the same as one of the types that this
4287 // variant can hold. Note that in C++11 mode, this method does not
4288 // participate in overload resolution if it would lead to ambiguity
4289 // with the move constructor that takes an allocator (below).
4290
4291 /// Create a variant object having the type and value of the specified
4292 /// `original` variant. Optionally specify a `basicAllocator` used to
4293 /// supply memory. If `basicAllocator` is 0, the currently installed
4294 /// default allocator is used.
4295 Variant11(const Variant11& original, bslma::Allocator *basicAllocator = 0);
4296
4297 /// Create a variant object having the type and value of the specified
4298 /// `original` object by moving the contents of `original` to the
4299 /// newly-created object. The allocator associated with `original` (if
4300 /// any) is propagated for use in the newly-created object. `original`
4301 /// is left in a valid but unspecified state.
4303
4304 /// Create a variant object having the type and value of the specified
4305 /// `original` object that uses the specified `basicAllocator` to supply
4306 /// memory. If `basicAllocator` is 0, the currently installed default
4307 /// allocator is used. The contents of `original` are moved to the
4308 /// newly-created object with `original` left in a valid but unspecified
4309 /// state.
4311 bslma::Allocator *basicAllocator);
4312
4313 // MANIPULATORS
4314
4315 /// Assign to this object the specified `value` of template parameter
4316 /// `TYPE`, and return a reference providing modifiable access to this
4317 /// object. The value currently held by this variant (if any) is
4318 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
4319 /// must be the same as one of the types that this variant can hold.
4320 template <class TYPE>
4321 Variant11& operator=(const TYPE& value);
4322
4323 template <class TYPE>
4324#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4325 typename bsl::enable_if<
4327 typename bsl::remove_cvref<TYPE>::type>::value,
4328 SelfType>::type&
4329 operator=(TYPE&& value);
4330#else
4331 Variant11&
4333#endif
4334 // Assign to this object the specified 'value' of template parameter
4335 // 'TYPE', and return a reference providing modifiable access to this
4336 // object. The contents of 'value' are moved to this object with
4337 // 'value' left in a valid but unspecified state. The value currently
4338 // held by this variant (if any) is destroyed if that value's type is
4339 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
4340 // that this variant can hold. Note that in C++11 mode, this method
4341 // does not participate in overload resolution if it would lead to
4342 // ambiguity with the move-assignment operator (below).
4343
4344 /// Assign to this object the type and value currently held by the
4345 /// specified `rhs` object, and return a reference providing modifiable
4346 /// access to this object. The value currently held by this variant
4347 /// (if any) is destroyed if that value's type is not the same as the
4348 /// type held by the `rhs` object.
4349 Variant11& operator=(const Variant11& rhs);
4350
4351 /// Assign to this object the type and value currently held by the
4352 /// specified `rhs` object, and return a reference providing modifiable
4353 /// access to this object. The value currently held by this variant
4354 /// (if any) is destroyed if that value's type is not the same as the
4355 /// type held by the `rhs` object. The contents of `rhs` are either
4356 /// move-inserted into or move-assigned to this object with `rhs` left
4357 /// in a valid but unspecified state.
4359};
4360
4361 // ====================
4362 // class Variant12<...>
4363 // ====================
4364
4365/// This class is a "specialization" of `Variant` for a fixed number (12) of
4366/// types. Its 12 template arguments *must* all be specified (none are
4367/// defaulted to `bslmf::Nil`). It provides the same functionality as
4368/// `Variant<A1, A2, ..., A12>`.
4369template <class A1, class A2, class A3, class A4, class A5, class A6,
4370 class A7, class A8, class A9, class A10, class A11, class A12>
4371class Variant12 : public VariantImp<typename bslmf::TypeList12<
4372 A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>::ListType> {
4373
4374 // PRIVATE TYPES
4375 typedef VariantImp<typename bslmf::TypeList12<A1, A2, A3, A4, A5, A6,
4376 A7, A8, A9, A10, A11,
4377 A12>::ListType> Imp;
4378
4379 /// `SelfType` is an alias to this class.
4380 typedef Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
4381 A11, A12> SelfType;
4382
4385
4386 public:
4387 // TRAITS
4390 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4393 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4396 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4398
4399 // CREATORS
4400
4401 /// Create a variant object in the unset state that uses the currently
4402 /// installed default allocator to supply memory.
4403 Variant12();
4404
4405 /// Create a variant object with the specified `valueOrAllocator` that
4406 /// can be either a value of a type that the variant can hold or an
4407 /// allocator to supply memory. If `valueOrAllocator` is not a
4408 /// `bslma::Allocator *`, then the variant will hold the value and type
4409 /// of `valueOrAllocator`, and use the currently installed default
4410 /// allocator to supply memory. Otherwise, the variant will be unset
4411 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4412 /// must be the same as one of the types that this variant can hold or
4413 /// be convertible to `bslma::Allocator *`. Note that this
4414 /// parameterized constructor is defined instead of two constructors
4415 /// (one taking a `bslma::Allocator *` and the other not) because
4416 /// template parameter arguments are always a better match than
4417 /// derived-to-base conversion (a concrete allocator pointer converted
4418 /// to `bslma::Allocator *`).
4419 template <class TYPE_OR_ALLOCATOR>
4420 explicit
4421 Variant12(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4422
4423 /// Create a variant object having the specified `value` of template
4424 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4425 /// supply memory. If `basicAllocator` is 0, the currently installed
4426 /// default allocator is used. `TYPE` must be the same as one of the
4427 /// types that this variant can hold.
4428 template <class TYPE>
4429 Variant12(const TYPE& value, bslma::Allocator *basicAllocator);
4430
4431 template <class TYPE>
4432 explicit
4433#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4434 Variant12(TYPE&& value,
4435 typename bsl::enable_if<
4436 !bsl::is_same<
4437 SelfType,
4438 typename bsl::remove_const<
4439 typename bsl::remove_reference<TYPE>::type>::type>::value
4440 &&
4442 void>::type * = 0);
4443#else
4445#endif
4446 // Create a variant object having the specified 'value' of template
4447 // parameter 'TYPE' by moving the contents of 'value' to the
4448 // newly-created object. Use the currently installed default allocator
4449 // to supply memory. 'value' is left in a valid but unspecified state.
4450 // 'TYPE' must be the same as one of the types that this variant can
4451 // hold. Note that in C++11 mode, this method does not participate in
4452 // overload resolution if it would lead to ambiguity with the move
4453 // constructor that does not take an allocator (below) or with the
4454 // constructor taking a 'valueOrAllocator' (above).
4455
4456 template <class TYPE>
4457#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4458 Variant12(TYPE&& value,
4459 typename bsl::enable_if<
4460 !bsl::is_same<
4461 SelfType,
4462 typename bsl::remove_const<
4463 typename bsl::remove_reference<TYPE>::type>::type>::value,
4464 bslma::Allocator>::type *basicAllocator);
4465#else
4467 bslma::Allocator *basicAllocator);
4468#endif
4469 // Create a variant object having the specified 'value' of template
4470 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
4471 // memory. If 'basicAllocator' is 0, the currently installed default
4472 // allocator is used. The contents of 'value' are moved to the
4473 // newly-created object with 'value' left in a valid but unspecified
4474 // state. 'TYPE' must be the same as one of the types that this
4475 // variant can hold. Note that in C++11 mode, this method does not
4476 // participate in overload resolution if it would lead to ambiguity
4477 // with the move constructor that takes an allocator (below).
4478
4479 /// Create a variant object having the type and value of the specified
4480 /// `original` variant. Optionally specify a `basicAllocator` used to
4481 /// supply memory. If `basicAllocator` is 0, the currently installed
4482 /// default allocator is used.
4483 Variant12(const Variant12& original, bslma::Allocator *basicAllocator = 0);
4484
4485 /// Create a variant object having the type and value of the specified
4486 /// `original` object by moving the contents of `original` to the
4487 /// newly-created object. The allocator associated with `original` (if
4488 /// any) is propagated for use in the newly-created object. `original`
4489 /// is left in a valid but unspecified state.
4491
4492 /// Create a variant object having the type and value of the specified
4493 /// `original` object that uses the specified `basicAllocator` to supply
4494 /// memory. If `basicAllocator` is 0, the currently installed default
4495 /// allocator is used. The contents of `original` are moved to the
4496 /// newly-created object with `original` left in a valid but unspecified
4497 /// state.
4499 bslma::Allocator *basicAllocator);
4500
4501 // MANIPULATORS
4502
4503 /// Assign to this object the specified `value` of template parameter
4504 /// `TYPE`, and return a reference providing modifiable access to this
4505 /// object. The value currently held by this variant (if any) is
4506 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
4507 /// must be the same as one of the types that this variant can hold.
4508 template <class TYPE>
4509 Variant12& operator=(const TYPE& value);
4510
4511 template <class TYPE>
4512#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4513 typename bsl::enable_if<
4515 typename bsl::remove_cvref<TYPE>::type>::value,
4516 SelfType>::type&
4517 operator=(TYPE&& value);
4518#else
4519 Variant12&
4521#endif
4522 // Assign to this object the specified 'value' of template parameter
4523 // 'TYPE', and return a reference providing modifiable access to this
4524 // object. The contents of 'value' are moved to this object with
4525 // 'value' left in a valid but unspecified state. The value currently
4526 // held by this variant (if any) is destroyed if that value's type is
4527 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
4528 // that this variant can hold. Note that in C++11 mode, this method
4529 // does not participate in overload resolution if it would lead to
4530 // ambiguity with the move-assignment operator (below).
4531
4532 /// Assign to this object the type and value currently held by the
4533 /// specified `rhs` object, and return a reference providing modifiable
4534 /// access to this object. The value currently held by this variant
4535 /// (if any) is destroyed if that value's type is not the same as the
4536 /// type held by the `rhs` object.
4537 Variant12& operator=(const Variant12& rhs);
4538
4539 /// Assign to this object the type and value currently held by the
4540 /// specified `rhs` object, and return a reference providing modifiable
4541 /// access to this object. The value currently held by this variant
4542 /// (if any) is destroyed if that value's type is not the same as the
4543 /// type held by the `rhs` object. The contents of `rhs` are either
4544 /// move-inserted into or move-assigned to this object with `rhs` left
4545 /// in a valid but unspecified state.
4547};
4548
4549 // ====================
4550 // class Variant13<...>
4551 // ====================
4552
4553/// This class is a "specialization" of `Variant` for a fixed number (13) of
4554/// types. Its 13 template arguments *must* all be specified (none are
4555/// defaulted to `bslmf::Nil`). It provides the same functionality as
4556/// `Variant<A1, A2, ..., A13>`.
4557template <class A1, class A2, class A3, class A4, class A5, class A6,
4558 class A7, class A8, class A9, class A10, class A11, class A12,
4559 class A13>
4560class Variant13 : public VariantImp<typename bslmf::TypeList13<
4561 A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>::ListType> {
4562
4563 // PRIVATE TYPES
4564 typedef VariantImp<typename bslmf::TypeList13<A1, A2, A3, A4, A5, A6,
4565 A7, A8, A9, A10, A11, A12,
4566 A13>::ListType> Imp;
4567
4568 /// `SelfType` is an alias to this class.
4569 typedef Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9,
4570 A10, A11, A12, A13> SelfType;
4571
4574
4575 public:
4576 // TRAITS
4579 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4582 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4585 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4587
4588 // CREATORS
4589
4590 /// Create a variant object in the unset state that uses the currently
4591 /// installed default allocator to supply memory.
4592 Variant13();
4593
4594 /// Create a variant object with the specified `valueOrAllocator` that
4595 /// can be either a value of a type that the variant can hold or an
4596 /// allocator to supply memory. If `valueOrAllocator` is not a
4597 /// `bslma::Allocator *`, then the variant will hold the value and type
4598 /// of `valueOrAllocator`, and use the currently installed default
4599 /// allocator to supply memory. Otherwise, the variant will be unset
4600 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4601 /// must be the same as one of the types that this variant can hold or
4602 /// be convertible to `bslma::Allocator *`. Note that this
4603 /// parameterized constructor is defined instead of two constructors
4604 /// (one taking a `bslma::Allocator *` and the other not) because
4605 /// template parameter arguments are always a better match than
4606 /// derived-to-base conversion (a concrete allocator pointer converted
4607 /// to `bslma::Allocator *`).
4608 template <class TYPE_OR_ALLOCATOR>
4609 explicit
4610 Variant13(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4611
4612 /// Create a variant object having the specified `value` of template
4613 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4614 /// supply memory. If `basicAllocator` is 0, the currently installed
4615 /// default allocator is used. `TYPE` must be the same as one of the
4616 /// types that this variant can hold.
4617 template <class TYPE>
4618 Variant13(const TYPE& value, bslma::Allocator *basicAllocator);
4619
4620 template <class TYPE>
4621 explicit
4622#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4623 Variant13(TYPE&& value,
4624 typename bsl::enable_if<
4625 !bsl::is_same<
4626 SelfType,
4627 typename bsl::remove_const<
4628 typename bsl::remove_reference<TYPE>::type>::type>::value
4629 &&
4631 void>::type * = 0);
4632#else
4634#endif
4635 // Create a variant object having the specified 'value' of template
4636 // parameter 'TYPE' by moving the contents of 'value' to the
4637 // newly-created object. Use the currently installed default allocator
4638 // to supply memory. 'value' is left in a valid but unspecified state.
4639 // 'TYPE' must be the same as one of the types that this variant can
4640 // hold. Note that in C++11 mode, this method does not participate in
4641 // overload resolution if it would lead to ambiguity with the move
4642 // constructor that does not take an allocator (below) or with the
4643 // constructor taking a 'valueOrAllocator' (above).
4644
4645 template <class TYPE>
4646#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4647 Variant13(TYPE&& value,
4648 typename bsl::enable_if<
4649 !bsl::is_same<
4650 SelfType,
4651 typename bsl::remove_const<
4652 typename bsl::remove_reference<TYPE>::type>::type>::value,
4653 bslma::Allocator>::type *basicAllocator);
4654#else
4656 bslma::Allocator *basicAllocator);
4657#endif
4658 // Create a variant object having the specified 'value' of template
4659 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
4660 // memory. If 'basicAllocator' is 0, the currently installed default
4661 // allocator is used. The contents of 'value' are moved to the
4662 // newly-created object with 'value' left in a valid but unspecified
4663 // state. 'TYPE' must be the same as one of the types that this
4664 // variant can hold. Note that in C++11 mode, this method does not
4665 // participate in overload resolution if it would lead to ambiguity
4666 // with the move constructor that takes an allocator (below).
4667
4668 /// Create a variant object having the type and value of the specified
4669 /// `original` variant. Optionally specify a `basicAllocator` used to
4670 /// supply memory. If `basicAllocator` is 0, the currently installed
4671 /// default allocator is used.
4672 Variant13(const Variant13& original, bslma::Allocator *basicAllocator = 0);
4673
4674 /// Create a variant object having the type and value of the specified
4675 /// `original` object by moving the contents of `original` to the
4676 /// newly-created object. The allocator associated with `original` (if
4677 /// any) is propagated for use in the newly-created object. `original`
4678 /// is left in a valid but unspecified state.
4680
4681 /// Create a variant object having the type and value of the specified
4682 /// `original` object that uses the specified `basicAllocator` to supply
4683 /// memory. If `basicAllocator` is 0, the currently installed default
4684 /// allocator is used. The contents of `original` are moved to the
4685 /// newly-created object with `original` left in a valid but unspecified
4686 /// state.
4688 bslma::Allocator *basicAllocator);
4689
4690 // MANIPULATORS
4691
4692 /// Assign to this object the specified `value` of template parameter
4693 /// `TYPE`, and return a reference providing modifiable access to this
4694 /// object. The value currently held by this variant (if any) is
4695 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
4696 /// must be the same as one of the types that this variant can hold.
4697 template <class TYPE>
4698 Variant13& operator=(const TYPE& value);
4699
4700 template <class TYPE>
4701#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4702 typename bsl::enable_if<
4704 typename bsl::remove_cvref<TYPE>::type>::value,
4705 SelfType>::type&
4706 operator=(TYPE&& value);
4707#else
4708 Variant13&
4710#endif
4711 // Assign to this object the specified 'value' of template parameter
4712 // 'TYPE', and return a reference providing modifiable access to this
4713 // object. The contents of 'value' are moved to this object with
4714 // 'value' left in a valid but unspecified state. The value currently
4715 // held by this variant (if any) is destroyed if that value's type is
4716 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
4717 // that this variant can hold. Note that in C++11 mode, this method
4718 // does not participate in overload resolution if it would lead to
4719 // ambiguity with the move-assignment operator (below).
4720
4721 /// Assign to this object the type and value currently held by the
4722 /// specified `rhs` object, and return a reference providing modifiable
4723 /// access to this object. The value currently held by this variant
4724 /// (if any) is destroyed if that value's type is not the same as the
4725 /// type held by the `rhs` object.
4726 Variant13& operator=(const Variant13& rhs);
4727
4728 /// Assign to this object the type and value currently held by the
4729 /// specified `rhs` object, and return a reference providing modifiable
4730 /// access to this object. The value currently held by this variant
4731 /// (if any) is destroyed if that value's type is not the same as the
4732 /// type held by the `rhs` object. The contents of `rhs` are either
4733 /// move-inserted into or move-assigned to this object with `rhs` left
4734 /// in a valid but unspecified state.
4736};
4737
4738 // ====================
4739 // class Variant14<...>
4740 // ====================
4741
4742/// This class is a "specialization" of `Variant` for a fixed number (14) of
4743/// types. Its 14 template arguments *must* all be specified (none are
4744/// defaulted to `bslmf::Nil`). It provides the same functionality as
4745/// `Variant<A1, A2, ..., A14>`.
4746template <class A1, class A2, class A3, class A4, class A5, class A6,
4747 class A7, class A8, class A9, class A10, class A11, class A12,
4748 class A13, class A14>
4749class Variant14 : public VariantImp<typename bslmf::TypeList14<
4750 A1, A2, A3, A4, A5,
4751 A6, A7, A8, A9, A10,
4752 A11, A12, A13, A14>::ListType> {
4753
4754 // PRIVATE TYPES
4755 typedef VariantImp<typename bslmf::TypeList14<A1, A2, A3, A4, A5, A6,
4756 A7, A8, A9, A10, A11, A12,
4757 A13,
4758 A14>::ListType> Imp;
4759
4760 /// `SelfType` is an alias to this class.
4761 typedef Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9,
4762 A10, A11, A12, A13, A14> SelfType;
4763
4766
4767 public:
4768 // TRAITS
4771 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4774 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4777 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4779
4780 // CREATORS
4781
4782 /// Create a variant object in the unset state that uses the currently
4783 /// installed default allocator to supply memory.
4784 Variant14();
4785
4786 /// Create a variant object with the specified `valueOrAllocator` that
4787 /// can be either a value of a type that the variant can hold or an
4788 /// allocator to supply memory. If `valueOrAllocator` is not a
4789 /// `bslma::Allocator *`, then the variant will hold the value and type
4790 /// of `valueOrAllocator`, and use the currently installed default
4791 /// allocator to supply memory. Otherwise, the variant will be unset
4792 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4793 /// must be the same as one of the types that this variant can hold or
4794 /// be convertible to `bslma::Allocator *`. Note that this
4795 /// parameterized constructor is defined instead of two constructors
4796 /// (one taking a `bslma::Allocator *` and the other not) because
4797 /// template parameter arguments are always a better match than
4798 /// derived-to-base conversion (a concrete allocator pointer converted
4799 /// to `bslma::Allocator *`).
4800 template <class TYPE_OR_ALLOCATOR>
4801 explicit
4802 Variant14(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4803
4804 /// Create a variant object having the specified `value` of template
4805 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4806 /// supply memory. If `basicAllocator` is 0, the currently installed
4807 /// default allocator is used. `TYPE` must be the same as one of the
4808 /// types that this variant can hold.
4809 template <class TYPE>
4810 Variant14(const TYPE& value, bslma::Allocator *basicAllocator);
4811
4812 template <class TYPE>
4813 explicit
4814#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4815 Variant14(TYPE&& value,
4816 typename bsl::enable_if<
4817 !bsl::is_same<
4818 SelfType,
4819 typename bsl::remove_const<
4820 typename bsl::remove_reference<TYPE>::type>::type>::value
4821 &&
4823 void>::type * = 0);
4824#else
4826#endif
4827 // Create a variant object having the specified 'value' of template
4828 // parameter 'TYPE' by moving the contents of 'value' to the
4829 // newly-created object. Use the currently installed default allocator
4830 // to supply memory. 'value' is left in a valid but unspecified state.
4831 // 'TYPE' must be the same as one of the types that this variant can
4832 // hold. Note that in C++11 mode, this method does not participate in
4833 // overload resolution if it would lead to ambiguity with the move
4834 // constructor that does not take an allocator (below) or with the
4835 // constructor taking a 'valueOrAllocator' (above).
4836
4837 template <class TYPE>
4838#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4839 Variant14(TYPE&& value,
4840 typename bsl::enable_if<
4841 !bsl::is_same<
4842 SelfType,
4843 typename bsl::remove_const<
4844 typename bsl::remove_reference<TYPE>::type>::type>::value,
4845 bslma::Allocator>::type *basicAllocator);
4846#else
4848 bslma::Allocator *basicAllocator);
4849#endif
4850 // Create a variant object having the specified 'value' of template
4851 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
4852 // memory. If 'basicAllocator' is 0, the currently installed default
4853 // allocator is used. The contents of 'value' are moved to the
4854 // newly-created object with 'value' left in a valid but unspecified
4855 // state. 'TYPE' must be the same as one of the types that this
4856 // variant can hold. Note that in C++11 mode, this method does not
4857 // participate in overload resolution if it would lead to ambiguity
4858 // with the move constructor that takes an allocator (below).
4859
4860 /// Create a variant object having the type and value of the specified
4861 /// `original` variant. Optionally specify a `basicAllocator` used to
4862 /// supply memory. If `basicAllocator` is 0, the currently installed
4863 /// default allocator is used.
4864 Variant14(const Variant14& original, bslma::Allocator *basicAllocator = 0);
4865
4866 /// Create a variant object having the type and value of the specified
4867 /// `original` object by moving the contents of `original` to the
4868 /// newly-created object. The allocator associated with `original` (if
4869 /// any) is propagated for use in the newly-created object. `original`
4870 /// is left in a valid but unspecified state.
4872
4873 /// Create a variant object having the type and value of the specified
4874 /// `original` object that uses the specified `basicAllocator` to supply
4875 /// memory. If `basicAllocator` is 0, the currently installed default
4876 /// allocator is used. The contents of `original` are moved to the
4877 /// newly-created object with `original` left in a valid but unspecified
4878 /// state.
4880 bslma::Allocator *basicAllocator);
4881
4882 // MANIPULATORS
4883
4884 /// Assign to this object the specified `value` of template parameter
4885 /// `TYPE`, and return a reference providing modifiable access to this
4886 /// object. The value currently held by this variant (if any) is
4887 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
4888 /// must be the same as one of the types that this variant can hold.
4889 template <class TYPE>
4890 Variant14& operator=(const TYPE& value);
4891
4892 template <class TYPE>
4893#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
4894 typename bsl::enable_if<
4896 typename bsl::remove_cvref<TYPE>::type>::value,
4897 SelfType>::type&
4898 operator=(TYPE&& value);
4899#else
4900 Variant14&
4902#endif
4903 // Assign to this object the specified 'value' of template parameter
4904 // 'TYPE', and return a reference providing modifiable access to this
4905 // object. The contents of 'value' are moved to this object with
4906 // 'value' left in a valid but unspecified state. The value currently
4907 // held by this variant (if any) is destroyed if that value's type is
4908 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
4909 // that this variant can hold. Note that in C++11 mode, this method
4910 // does not participate in overload resolution if it would lead to
4911 // ambiguity with the move-assignment operator (below).
4912
4913 /// Assign to this object the type and value currently held by the
4914 /// specified `rhs` object, and return a reference providing modifiable
4915 /// access to this object. The value currently held by this variant
4916 /// (if any) is destroyed if that value's type is not the same as the
4917 /// type held by the `rhs` object.
4918 Variant14& operator=(const Variant14& rhs);
4919
4920 /// Assign to this object the type and value currently held by the
4921 /// specified `rhs` object, and return a reference providing modifiable
4922 /// access to this object. The value currently held by this variant
4923 /// (if any) is destroyed if that value's type is not the same as the
4924 /// type held by the `rhs` object. The contents of `rhs` are either
4925 /// move-inserted into or move-assigned to this object with `rhs` left
4926 /// in a valid but unspecified state.
4928};
4929
4930 // ====================
4931 // class Variant15<...>
4932 // ====================
4933
4934/// This class is a "specialization" of `Variant` for a fixed number (15) of
4935/// types. Its 15 template arguments *must* all be specified (none are
4936/// defaulted to `bslmf::Nil`). It provides the same functionality as
4937/// `Variant<A1, A2, ..., A15>`.
4938template <class A1, class A2, class A3, class A4, class A5, class A6,
4939 class A7, class A8, class A9, class A10, class A11, class A12,
4940 class A13, class A14, class A15>
4941class Variant15 : public VariantImp<typename bslmf::TypeList15<
4942 A1, A2, A3, A4, A5,
4943 A6, A7, A8, A9, A10,
4944 A11, A12, A13, A14, A15>::ListType> {
4945
4946 // PRIVATE TYPES
4947 typedef VariantImp<typename bslmf::TypeList15<A1, A2, A3, A4, A5, A6,
4948 A7, A8, A9, A10, A11, A12,
4949 A13, A14,
4950 A15>::ListType> Imp;
4951
4952 /// `SelfType` is an alias to this class.
4953 typedef Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9,
4954 A10, A11, A12, A13, A14, A15> SelfType;
4955
4958
4959 public:
4960 // TRAITS
4963 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
4966 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
4969 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
4971
4972 // CREATORS
4973
4974 /// Create a variant object in the unset state that uses the currently
4975 /// installed default allocator to supply memory.
4976 Variant15();
4977
4978 /// Create a variant object with the specified `valueOrAllocator` that
4979 /// can be either a value of a type that the variant can hold or an
4980 /// allocator to supply memory. If `valueOrAllocator` is not a
4981 /// `bslma::Allocator *`, then the variant will hold the value and type
4982 /// of `valueOrAllocator`, and use the currently installed default
4983 /// allocator to supply memory. Otherwise, the variant will be unset
4984 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
4985 /// must be the same as one of the types that this variant can hold or
4986 /// be convertible to `bslma::Allocator *`. Note that this
4987 /// parameterized constructor is defined instead of two constructors
4988 /// (one taking a `bslma::Allocator *` and the other not) because
4989 /// template parameter arguments are always a better match than
4990 /// derived-to-base conversion (a concrete allocator pointer converted
4991 /// to `bslma::Allocator *`).
4992 template <class TYPE_OR_ALLOCATOR>
4993 explicit
4994 Variant15(const TYPE_OR_ALLOCATOR& valueOrAllocator);
4995
4996 /// Create a variant object having the specified `value` of template
4997 /// parameter `TYPE` and that uses the specified `basicAllocator` to
4998 /// supply memory. If `basicAllocator` is 0, the currently installed
4999 /// default allocator is used. `TYPE` must be the same as one of the
5000 /// types that this variant can hold.
5001 template <class TYPE>
5002 Variant15(const TYPE& value, bslma::Allocator *basicAllocator);
5003
5004 template <class TYPE>
5005 explicit
5006#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5007 Variant15(TYPE&& value,
5008 typename bsl::enable_if<
5009 !bsl::is_same<
5010 SelfType,
5011 typename bsl::remove_const<
5012 typename bsl::remove_reference<TYPE>::type>::type>::value
5013 &&
5015 void>::type * = 0);
5016#else
5018#endif
5019 // Create a variant object having the specified 'value' of template
5020 // parameter 'TYPE' by moving the contents of 'value' to the
5021 // newly-created object. Use the currently installed default allocator
5022 // to supply memory. 'value' is left in a valid but unspecified state.
5023 // 'TYPE' must be the same as one of the types that this variant can
5024 // hold. Note that in C++11 mode, this method does not participate in
5025 // overload resolution if it would lead to ambiguity with the move
5026 // constructor that does not take an allocator (below) or with the
5027 // constructor taking a 'valueOrAllocator' (above).
5028
5029 template <class TYPE>
5030#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5031 Variant15(TYPE&& value,
5032 typename bsl::enable_if<
5033 !bsl::is_same<
5034 SelfType,
5035 typename bsl::remove_const<
5036 typename bsl::remove_reference<TYPE>::type>::type>::value,
5037 bslma::Allocator>::type *basicAllocator);
5038#else
5040 bslma::Allocator *basicAllocator);
5041#endif
5042 // Create a variant object having the specified 'value' of template
5043 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
5044 // memory. If 'basicAllocator' is 0, the currently installed default
5045 // allocator is used. The contents of 'value' are moved to the
5046 // newly-created object with 'value' left in a valid but unspecified
5047 // state. 'TYPE' must be the same as one of the types that this
5048 // variant can hold. Note that in C++11 mode, this method does not
5049 // participate in overload resolution if it would lead to ambiguity
5050 // with the move constructor that takes an allocator (below).
5051
5052 /// Create a variant object having the type and value of the specified
5053 /// `original` variant. Optionally specify a `basicAllocator` used to
5054 /// supply memory. If `basicAllocator` is 0, the currently installed
5055 /// default allocator is used.
5056 Variant15(const Variant15& original, bslma::Allocator *basicAllocator = 0);
5057
5058 /// Create a variant object having the type and value of the specified
5059 /// `original` object by moving the contents of `original` to the
5060 /// newly-created object. The allocator associated with `original` (if
5061 /// any) is propagated for use in the newly-created object. `original`
5062 /// is left in a valid but unspecified state.
5064
5065 /// Create a variant object having the type and value of the specified
5066 /// `original` object that uses the specified `basicAllocator` to supply
5067 /// memory. If `basicAllocator` is 0, the currently installed default
5068 /// allocator is used. The contents of `original` are moved to the
5069 /// newly-created object with `original` left in a valid but unspecified
5070 /// state.
5072 bslma::Allocator *basicAllocator);
5073
5074 // MANIPULATORS
5075
5076 /// Assign to this object the specified `value` of template parameter
5077 /// `TYPE`, and return a reference providing modifiable access to this
5078 /// object. The value currently held by this variant (if any) is
5079 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
5080 /// must be the same as one of the types that this variant can hold.
5081 template <class TYPE>
5082 Variant15& operator=(const TYPE& value);
5083
5084 template <class TYPE>
5085#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5086 typename bsl::enable_if<
5088 typename bsl::remove_cvref<TYPE>::type>::value,
5089 SelfType>::type&
5090 operator=(TYPE&& value);
5091#else
5092 Variant15&
5094#endif
5095 // Assign to this object the specified 'value' of template parameter
5096 // 'TYPE', and return a reference providing modifiable access to this
5097 // object. The contents of 'value' are moved to this object with
5098 // 'value' left in a valid but unspecified state. The value currently
5099 // held by this variant (if any) is destroyed if that value's type is
5100 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
5101 // that this variant can hold. Note that in C++11 mode, this method
5102 // does not participate in overload resolution if it would lead to
5103 // ambiguity with the move-assignment operator (below).
5104
5105 /// Assign to this object the type and value currently held by the
5106 /// specified `rhs` object, and return a reference providing modifiable
5107 /// access to this object. The value currently held by this variant
5108 /// (if any) is destroyed if that value's type is not the same as the
5109 /// type held by the `rhs` object.
5110 Variant15& operator=(const Variant15& rhs);
5111
5112 /// Assign to this object the type and value currently held by the
5113 /// specified `rhs` object, and return a reference providing modifiable
5114 /// access to this object. The value currently held by this variant
5115 /// (if any) is destroyed if that value's type is not the same as the
5116 /// type held by the `rhs` object. The contents of `rhs` are either
5117 /// move-inserted into or move-assigned to this object with `rhs` left
5118 /// in a valid but unspecified state.
5120};
5121
5122 // ====================
5123 // class Variant16<...>
5124 // ====================
5125
5126/// This class is a "specialization" of `Variant` for a fixed number (16) of
5127/// types. Its 16 template arguments *must* all be specified (none are
5128/// defaulted to `bslmf::Nil`). It provides the same functionality as
5129/// `Variant<A1, A2, ..., A16>`.
5130template <class A1, class A2, class A3, class A4, class A5, class A6,
5131 class A7, class A8, class A9, class A10, class A11, class A12,
5132 class A13, class A14, class A15, class A16>
5133class Variant16 : public VariantImp<typename bslmf::TypeList16<
5134 A1, A2, A3, A4, A5,
5135 A6, A7, A8, A9, A10,
5136 A11, A12, A13, A14, A15,
5137 A16>::ListType> {
5138
5139 // PRIVATE TYPES
5140 typedef VariantImp<typename bslmf::TypeList16<A1, A2, A3, A4, A5, A6,
5141 A7, A8, A9, A10, A11, A12,
5142 A13, A14, A15,
5143 A16>::ListType> Imp;
5144
5145 /// `SelfType` is an alias to this class.
5146 typedef Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9,
5147 A10, A11, A12, A13, A14, A15, A16> SelfType;
5148
5151
5152 public:
5153 // TRAITS
5156 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
5159 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
5162 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
5164
5165 // CREATORS
5166
5167 /// Create a variant object in the unset state that uses the currently
5168 /// installed default allocator to supply memory.
5169 Variant16();
5170
5171 /// Create a variant object with the specified `valueOrAllocator` that
5172 /// can be either a value of a type that the variant can hold or an
5173 /// allocator to supply memory. If `valueOrAllocator` is not a
5174 /// `bslma::Allocator *`, then the variant will hold the value and type
5175 /// of `valueOrAllocator`, and use the currently installed default
5176 /// allocator to supply memory. Otherwise, the variant will be unset
5177 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
5178 /// must be the same as one of the types that this variant can hold or
5179 /// be convertible to `bslma::Allocator *`. Note that this
5180 /// parameterized constructor is defined instead of two constructors
5181 /// (one taking a `bslma::Allocator *` and the other not) because
5182 /// template parameter arguments are always a better match than
5183 /// derived-to-base conversion (a concrete allocator pointer converted
5184 /// to `bslma::Allocator *`).
5185 template <class TYPE_OR_ALLOCATOR>
5186 explicit
5187 Variant16(const TYPE_OR_ALLOCATOR& valueOrAllocator);
5188
5189 /// Create a variant object having the specified `value` of template
5190 /// parameter `TYPE` and that uses the specified `basicAllocator` to
5191 /// supply memory. If `basicAllocator` is 0, the currently installed
5192 /// default allocator is used. `TYPE` must be the same as one of the
5193 /// types that this variant can hold.
5194 template <class TYPE>
5195 Variant16(const TYPE& value, bslma::Allocator *basicAllocator);
5196
5197 template <class TYPE>
5198 explicit
5199#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5200 Variant16(TYPE&& value,
5201 typename bsl::enable_if<
5202 !bsl::is_same<
5203 SelfType,
5204 typename bsl::remove_const<
5205 typename bsl::remove_reference<TYPE>::type>::type>::value
5206 &&
5208 void>::type * = 0);
5209#else
5211#endif
5212 // Create a variant object having the specified 'value' of template
5213 // parameter 'TYPE' by moving the contents of 'value' to the
5214 // newly-created object. Use the currently installed default allocator
5215 // to supply memory. 'value' is left in a valid but unspecified state.
5216 // 'TYPE' must be the same as one of the types that this variant can
5217 // hold. Note that in C++11 mode, this method does not participate in
5218 // overload resolution if it would lead to ambiguity with the move
5219 // constructor that does not take an allocator (below) or with the
5220 // constructor taking a 'valueOrAllocator' (above).
5221
5222 template <class TYPE>
5223#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5224 Variant16(TYPE&& value,
5225 typename bsl::enable_if<
5226 !bsl::is_same<
5227 SelfType,
5228 typename bsl::remove_const<
5229 typename bsl::remove_reference<TYPE>::type>::type>::value,
5230 bslma::Allocator>::type *basicAllocator);
5231#else
5233 bslma::Allocator *basicAllocator);
5234#endif
5235 // Create a variant object having the specified 'value' of template
5236 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
5237 // memory. If 'basicAllocator' is 0, the currently installed default
5238 // allocator is used. The contents of 'value' are moved to the
5239 // newly-created object with 'value' left in a valid but unspecified
5240 // state. 'TYPE' must be the same as one of the types that this
5241 // variant can hold. Note that in C++11 mode, this method does not
5242 // participate in overload resolution if it would lead to ambiguity
5243 // with the move constructor that takes an allocator (below).
5244
5245 /// Create a variant object having the type and value of the specified
5246 /// `original` variant. Optionally specify a `basicAllocator` used to
5247 /// supply memory. If `basicAllocator` is 0, the currently installed
5248 /// default allocator is used.
5249 Variant16(const Variant16& original, bslma::Allocator *basicAllocator = 0);
5250
5251 /// Create a variant object having the type and value of the specified
5252 /// `original` object by moving the contents of `original` to the
5253 /// newly-created object. The allocator associated with `original` (if
5254 /// any) is propagated for use in the newly-created object. `original`
5255 /// is left in a valid but unspecified state.
5257
5258 /// Create a variant object having the type and value of the specified
5259 /// `original` object that uses the specified `basicAllocator` to supply
5260 /// memory. If `basicAllocator` is 0, the currently installed default
5261 /// allocator is used. The contents of `original` are moved to the
5262 /// newly-created object with `original` left in a valid but unspecified
5263 /// state.
5265 bslma::Allocator *basicAllocator);
5266
5267 // MANIPULATORS
5268
5269 /// Assign to this object the specified `value` of template parameter
5270 /// `TYPE`, and return a reference providing modifiable access to this
5271 /// object. The value currently held by this variant (if any) is
5272 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
5273 /// must be the same as one of the types that this variant can hold.
5274 template <class TYPE>
5275 Variant16& operator=(const TYPE& value);
5276
5277 template <class TYPE>
5278#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5279 typename bsl::enable_if<
5281 typename bsl::remove_cvref<TYPE>::type>::value,
5282 SelfType>::type&
5283 operator=(TYPE&& value);
5284#else
5285 Variant16&
5287#endif
5288 // Assign to this object the specified 'value' of template parameter
5289 // 'TYPE', and return a reference providing modifiable access to this
5290 // object. The contents of 'value' are moved to this object with
5291 // 'value' left in a valid but unspecified state. The value currently
5292 // held by this variant (if any) is destroyed if that value's type is
5293 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
5294 // that this variant can hold. Note that in C++11 mode, this method
5295 // does not participate in overload resolution if it would lead to
5296 // ambiguity with the move-assignment operator (below).
5297
5298 /// Assign to this object the type and value currently held by the
5299 /// specified `rhs` object, and return a reference providing modifiable
5300 /// access to this object. The value currently held by this variant
5301 /// (if any) is destroyed if that value's type is not the same as the
5302 /// type held by the `rhs` object.
5303 Variant16& operator=(const Variant16& rhs);
5304
5305 /// Assign to this object the type and value currently held by the
5306 /// specified `rhs` object, and return a reference providing modifiable
5307 /// access to this object. The value currently held by this variant
5308 /// (if any) is destroyed if that value's type is not the same as the
5309 /// type held by the `rhs` object. The contents of `rhs` are either
5310 /// move-inserted into or move-assigned to this object with `rhs` left
5311 /// in a valid but unspecified state.
5313};
5314
5315 // ====================
5316 // class Variant17<...>
5317 // ====================
5318
5319/// This class is a "specialization" of `Variant` for a fixed number (17) of
5320/// types. Its 17 template arguments *must* all be specified (none are
5321/// defaulted to `bslmf::Nil`). It provides the same functionality as
5322/// `Variant<A1, A2, ..., A17>`.
5323template <class A1, class A2, class A3, class A4, class A5, class A6,
5324 class A7, class A8, class A9, class A10, class A11, class A12,
5325 class A13, class A14, class A15, class A16, class A17>
5326class Variant17 : public VariantImp<typename bslmf::TypeList17<
5327 A1, A2, A3, A4, A5,
5328 A6, A7, A8, A9, A10,
5329 A11, A12, A13, A14, A15,
5330 A16, A17>::ListType> {
5331
5332 // PRIVATE TYPES
5333 typedef VariantImp<typename bslmf::TypeList17<A1, A2, A3, A4, A5, A6,
5334 A7, A8, A9, A10, A11, A12,
5335 A13, A14, A15, A16,
5336 A17>::ListType> Imp;
5337
5338 /// `SelfType` is an alias to this class.
5339 typedef Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9,
5340 A10, A11, A12, A13, A14, A15, A16, A17> SelfType;
5341
5344
5345 public:
5346 // TRAITS
5349 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
5352 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
5355 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
5357
5358 // CREATORS
5359
5360 /// Create a variant object in the unset state that uses the currently
5361 /// installed default allocator to supply memory.
5362 Variant17();
5363
5364 /// Create a variant object with the specified `valueOrAllocator` that
5365 /// can be either a value of a type that the variant can hold or an
5366 /// allocator to supply memory. If `valueOrAllocator` is not a
5367 /// `bslma::Allocator *`, then the variant will hold the value and type
5368 /// of `valueOrAllocator`, and use the currently installed default
5369 /// allocator to supply memory. Otherwise, the variant will be unset
5370 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
5371 /// must be the same as one of the types that this variant can hold or
5372 /// be convertible to `bslma::Allocator *`. Note that this
5373 /// parameterized constructor is defined instead of two constructors
5374 /// (one taking a `bslma::Allocator *` and the other not) because
5375 /// template parameter arguments are always a better match than
5376 /// derived-to-base conversion (a concrete allocator pointer converted
5377 /// to `bslma::Allocator *`).
5378 template <class TYPE_OR_ALLOCATOR>
5379 explicit
5380 Variant17(const TYPE_OR_ALLOCATOR& valueOrAllocator);
5381
5382 /// Create a variant object having the specified `value` of template
5383 /// parameter `TYPE` and that uses the specified `basicAllocator` to
5384 /// supply memory. If `basicAllocator` is 0, the currently installed
5385 /// default allocator is used. `TYPE` must be the same as one of the
5386 /// types that this variant can hold.
5387 template <class TYPE>
5388 Variant17(const TYPE& value, bslma::Allocator *basicAllocator);
5389
5390 template <class TYPE>
5391 explicit
5392#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5393 Variant17(TYPE&& value,
5394 typename bsl::enable_if<
5395 !bsl::is_same<
5396 SelfType,
5397 typename bsl::remove_const<
5398 typename bsl::remove_reference<TYPE>::type>::type>::value
5399 &&
5401 void>::type * = 0);
5402#else
5404#endif
5405 // Create a variant object having the specified 'value' of template
5406 // parameter 'TYPE' by moving the contents of 'value' to the
5407 // newly-created object. Use the currently installed default allocator
5408 // to supply memory. 'value' is left in a valid but unspecified state.
5409 // 'TYPE' must be the same as one of the types that this variant can
5410 // hold. Note that in C++11 mode, this method does not participate in
5411 // overload resolution if it would lead to ambiguity with the move
5412 // constructor that does not take an allocator (below) or with the
5413 // constructor taking a 'valueOrAllocator' (above).
5414
5415 template <class TYPE>
5416#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5417 Variant17(TYPE&& value,
5418 typename bsl::enable_if<
5419 !bsl::is_same<
5420 SelfType,
5421 typename bsl::remove_const<
5422 typename bsl::remove_reference<TYPE>::type>::type>::value,
5423 bslma::Allocator>::type *basicAllocator);
5424#else
5426 bslma::Allocator *basicAllocator);
5427#endif
5428 // Create a variant object having the specified 'value' of template
5429 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
5430 // memory. If 'basicAllocator' is 0, the currently installed default
5431 // allocator is used. The contents of 'value' are moved to the
5432 // newly-created object with 'value' left in a valid but unspecified
5433 // state. 'TYPE' must be the same as one of the types that this
5434 // variant can hold. Note that in C++11 mode, this method does not
5435 // participate in overload resolution if it would lead to ambiguity
5436 // with the move constructor that takes an allocator (below).
5437
5438 /// Create a variant object having the type and value of the specified
5439 /// `original` variant. Optionally specify a `basicAllocator` used to
5440 /// supply memory. If `basicAllocator` is 0, the currently installed
5441 /// default allocator is used.
5442 Variant17(const Variant17& original, bslma::Allocator *basicAllocator = 0);
5443
5444 /// Create a variant object having the type and value of the specified
5445 /// `original` object by moving the contents of `original` to the
5446 /// newly-created object. The allocator associated with `original` (if
5447 /// any) is propagated for use in the newly-created object. `original`
5448 /// is left in a valid but unspecified state.
5450
5451 /// Create a variant object having the type and value of the specified
5452 /// `original` object that uses the specified `basicAllocator` to supply
5453 /// memory. If `basicAllocator` is 0, the currently installed default
5454 /// allocator is used. The contents of `original` are moved to the
5455 /// newly-created object with `original` left in a valid but unspecified
5456 /// state.
5458 bslma::Allocator *basicAllocator);
5459
5460 // MANIPULATORS
5461
5462 /// Assign to this object the specified `value` of template parameter
5463 /// `TYPE`, and return a reference providing modifiable access to this
5464 /// object. The value currently held by this variant (if any) is
5465 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
5466 /// must be the same as one of the types that this variant can hold.
5467 template <class TYPE>
5468 Variant17& operator=(const TYPE& value);
5469
5470 template <class TYPE>
5471#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5472 typename bsl::enable_if<
5474 typename bsl::remove_cvref<TYPE>::type>::value,
5475 SelfType>::type&
5476 operator=(TYPE&& value);
5477#else
5478 Variant17&
5480#endif
5481 // Assign to this object the specified 'value' of template parameter
5482 // 'TYPE', and return a reference providing modifiable access to this
5483 // object. The contents of 'value' are moved to this object with
5484 // 'value' left in a valid but unspecified state. The value currently
5485 // held by this variant (if any) is destroyed if that value's type is
5486 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
5487 // that this variant can hold. Note that in C++11 mode, this method
5488 // does not participate in overload resolution if it would lead to
5489 // ambiguity with the move-assignment operator (below).
5490
5491 /// Assign to this object the type and value currently held by the
5492 /// specified `rhs` object, and return a reference providing modifiable
5493 /// access to this object. The value currently held by this variant
5494 /// (if any) is destroyed if that value's type is not the same as the
5495 /// type held by the `rhs` object.
5496 Variant17& operator=(const Variant17& rhs);
5497
5498 /// Assign to this object the type and value currently held by the
5499 /// specified `rhs` object, and return a reference providing modifiable
5500 /// access to this object. The value currently held by this variant
5501 /// (if any) is destroyed if that value's type is not the same as the
5502 /// type held by the `rhs` object. The contents of `rhs` are either
5503 /// move-inserted into or move-assigned to this object with `rhs` left
5504 /// in a valid but unspecified state.
5506};
5507
5508 // ====================
5509 // class Variant18<...>
5510 // ====================
5511
5512/// This class is a "specialization" of `Variant` for a fixed number (18) of
5513/// types. Its 18 template arguments *must* all be specified (none are
5514/// defaulted to `bslmf::Nil`). It provides the same functionality as
5515/// `Variant<A1, A2, ..., A18>`.
5516template <class A1, class A2, class A3, class A4, class A5, class A6,
5517 class A7, class A8, class A9, class A10, class A11, class A12,
5518 class A13, class A14, class A15, class A16, class A17, class A18>
5519class Variant18 : public VariantImp<typename bslmf::TypeList18<
5520 A1, A2, A3, A4, A5,
5521 A6, A7, A8, A9, A10,
5522 A11, A12, A13, A14, A15,
5523 A16, A17, A18>::ListType> {
5524
5525 // PRIVATE TYPES
5526 typedef VariantImp<typename bslmf::TypeList18<A1, A2, A3, A4, A5, A6,
5527 A7, A8, A9, A10, A11, A12,
5528 A13, A14, A15, A16, A17,
5529 A18>::ListType> Imp;
5530
5531 /// `SelfType` is an alias to this class.
5532 typedef Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9,
5533 A10, A11, A12, A13, A14, A15, A16, A17, A18> SelfType;
5534
5537
5538 public:
5539 // TRAITS
5542 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
5545 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
5548 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
5550
5551 // CREATORS
5552
5553 /// Create a variant object in the unset state that uses the currently
5554 /// installed default allocator to supply memory.
5555 Variant18();
5556
5557 /// Create a variant object with the specified `valueOrAllocator` that
5558 /// can be either a value of a type that the variant can hold or an
5559 /// allocator to supply memory. If `valueOrAllocator` is not a
5560 /// `bslma::Allocator *`, then the variant will hold the value and type
5561 /// of `valueOrAllocator`, and use the currently installed default
5562 /// allocator to supply memory. Otherwise, the variant will be unset
5563 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
5564 /// must be the same as one of the types that this variant can hold or
5565 /// be convertible to `bslma::Allocator *`. Note that this
5566 /// parameterized constructor is defined instead of two constructors
5567 /// (one taking a `bslma::Allocator *` and the other not) because
5568 /// template parameter arguments are always a better match than
5569 /// derived-to-base conversion (a concrete allocator pointer converted
5570 /// to `bslma::Allocator *`).
5571 template <class TYPE_OR_ALLOCATOR>
5572 explicit
5573 Variant18(const TYPE_OR_ALLOCATOR& valueOrAllocator);
5574
5575 /// Create a variant object having the specified `value` of template
5576 /// parameter `TYPE` and that uses the specified `basicAllocator` to
5577 /// supply memory. If `basicAllocator` is 0, the currently installed
5578 /// default allocator is used. `TYPE` must be the same as one of the
5579 /// types that this variant can hold.
5580 template <class TYPE>
5581 Variant18(const TYPE& value, bslma::Allocator *basicAllocator);
5582
5583 template <class TYPE>
5584 explicit
5585#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5586 Variant18(TYPE&& value,
5587 typename bsl::enable_if<
5588 !bsl::is_same<
5589 SelfType,
5590 typename bsl::remove_const<
5591 typename bsl::remove_reference<TYPE>::type>::type>::value
5592 &&
5594 void>::type * = 0);
5595#else
5597#endif
5598 // Create a variant object having the specified 'value' of template
5599 // parameter 'TYPE' by moving the contents of 'value' to the
5600 // newly-created object. Use the currently installed default allocator
5601 // to supply memory. 'value' is left in a valid but unspecified state.
5602 // 'TYPE' must be the same as one of the types that this variant can
5603 // hold. Note that in C++11 mode, this method does not participate in
5604 // overload resolution if it would lead to ambiguity with the move
5605 // constructor that does not take an allocator (below) or with the
5606 // constructor taking a 'valueOrAllocator' (above).
5607
5608 template <class TYPE>
5609#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5610 Variant18(TYPE&& value,
5611 typename bsl::enable_if<
5612 !bsl::is_same<
5613 SelfType,
5614 typename bsl::remove_const<
5615 typename bsl::remove_reference<TYPE>::type>::type>::value,
5616 bslma::Allocator>::type *basicAllocator);
5617#else
5619 bslma::Allocator *basicAllocator);
5620#endif
5621 // Create a variant object having the specified 'value' of template
5622 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
5623 // memory. If 'basicAllocator' is 0, the currently installed default
5624 // allocator is used. The contents of 'value' are moved to the
5625 // newly-created object with 'value' left in a valid but unspecified
5626 // state. 'TYPE' must be the same as one of the types that this
5627 // variant can hold. Note that in C++11 mode, this method does not
5628 // participate in overload resolution if it would lead to ambiguity
5629 // with the move constructor that takes an allocator (below).
5630
5631 /// Create a variant object having the type and value of the specified
5632 /// `original` variant. Optionally specify a `basicAllocator` used to
5633 /// supply memory. If `basicAllocator` is 0, the currently installed
5634 /// default allocator is used.
5635 Variant18(const Variant18& original, bslma::Allocator *basicAllocator = 0);
5636
5637 /// Create a variant object having the type and value of the specified
5638 /// `original` object by moving the contents of `original` to the
5639 /// newly-created object. The allocator associated with `original` (if
5640 /// any) is propagated for use in the newly-created object. `original`
5641 /// is left in a valid but unspecified state.
5643
5644 /// Create a variant object having the type and value of the specified
5645 /// `original` object that uses the specified `basicAllocator` to supply
5646 /// memory. If `basicAllocator` is 0, the currently installed default
5647 /// allocator is used. The contents of `original` are moved to the
5648 /// newly-created object with `original` left in a valid but unspecified
5649 /// state.
5651 bslma::Allocator *basicAllocator);
5652
5653 // MANIPULATORS
5654
5655 /// Assign to this object the specified `value` of template parameter
5656 /// `TYPE`, and return a reference providing modifiable access to this
5657 /// object. The value currently held by this variant (if any) is
5658 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
5659 /// must be the same as one of the types that this variant can hold.
5660 template <class TYPE>
5661 Variant18& operator=(const TYPE& value);
5662
5663 template <class TYPE>
5664#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5665 typename bsl::enable_if<
5667 typename bsl::remove_cvref<TYPE>::type>::value,
5668 SelfType>::type&
5669 operator=(TYPE&& value);
5670#else
5671 Variant18&
5673#endif
5674 // Assign to this object the specified 'value' of template parameter
5675 // 'TYPE', and return a reference providing modifiable access to this
5676 // object. The contents of 'value' are moved to this object with
5677 // 'value' left in a valid but unspecified state. The value currently
5678 // held by this variant (if any) is destroyed if that value's type is
5679 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
5680 // that this variant can hold. Note that in C++11 mode, this method
5681 // does not participate in overload resolution if it would lead to
5682 // ambiguity with the move-assignment operator (below).
5683
5684 /// Assign to this object the type and value currently held by the
5685 /// specified `rhs` object, and return a reference providing modifiable
5686 /// access to this object. The value currently held by this variant
5687 /// (if any) is destroyed if that value's type is not the same as the
5688 /// type held by the `rhs` object.
5689 Variant18& operator=(const Variant18& rhs);
5690
5691 /// Assign to this object the type and value currently held by the
5692 /// specified `rhs` object, and return a reference providing modifiable
5693 /// access to this object. The value currently held by this variant
5694 /// (if any) is destroyed if that value's type is not the same as the
5695 /// type held by the `rhs` object. The contents of `rhs` are either
5696 /// move-inserted into or move-assigned to this object with `rhs` left
5697 /// in a valid but unspecified state.
5699};
5700
5701 // ====================
5702 // class Variant19<...>
5703 // ====================
5704
5705/// This class is a "specialization" of `Variant` for a fixed number (19) of
5706/// types. Its 19 template arguments *must* all be specified (none are
5707/// defaulted to `bslmf::Nil`). It provides the same functionality as
5708/// `Variant<A1, A2, ..., A19>`.
5709template <class A1, class A2, class A3, class A4, class A5, class A6,
5710 class A7, class A8, class A9, class A10, class A11, class A12,
5711 class A13, class A14, class A15, class A16, class A17, class A18,
5712 class A19>
5713class Variant19 : public VariantImp<typename bslmf::TypeList19<
5714 A1, A2, A3, A4, A5,
5715 A6, A7, A8, A9, A10,
5716 A11, A12, A13, A14, A15,
5717 A16, A17, A18, A19>::ListType> {
5718
5719 // PRIVATE TYPES
5720 typedef VariantImp<typename bslmf::TypeList19<A1, A2, A3, A4, A5, A6,
5721 A7, A8, A9, A10, A11, A12,
5722 A13, A14, A15, A16, A17, A18,
5723 A19>::ListType> Imp;
5724
5725 /// `SelfType` is an alias to this class.
5726 typedef Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9,
5727 A10, A11, A12, A13, A14, A15, A16, A17, A18,
5728 A19> SelfType;
5729
5732
5733 public:
5734 // TRAITS
5737 Traits::k_VARIANT_USES_BSLMA_ALLOCATOR);
5740 Traits::k_VARIANT_IS_BITWISE_COPYABLE);
5743 Traits::k_VARIANT_IS_BITWISE_MOVEABLE);
5745
5746 // CREATORS
5747
5748 /// Create a variant object in the unset state that uses the currently
5749 /// installed default allocator to supply memory.
5750 Variant19();
5751
5752 /// Create a variant object with the specified `valueOrAllocator` that
5753 /// can be either a value of a type that the variant can hold or an
5754 /// allocator to supply memory. If `valueOrAllocator` is not a
5755 /// `bslma::Allocator *`, then the variant will hold the value and type
5756 /// of `valueOrAllocator`, and use the currently installed default
5757 /// allocator to supply memory. Otherwise, the variant will be unset
5758 /// and use `valueOrAllocator` to supply memory. `TYPE_OR_ALLOCATOR`
5759 /// must be the same as one of the types that this variant can hold or
5760 /// be convertible to `bslma::Allocator *`. Note that this
5761 /// parameterized constructor is defined instead of two constructors
5762 /// (one taking a `bslma::Allocator *` and the other not) because
5763 /// template parameter arguments are always a better match than
5764 /// derived-to-base conversion (a concrete allocator pointer converted
5765 /// to `bslma::Allocator *`).
5766 template <class TYPE_OR_ALLOCATOR>
5767 explicit
5768 Variant19(const TYPE_OR_ALLOCATOR& valueOrAllocator);
5769
5770 /// Create a variant object having the specified `value` of template
5771 /// parameter `TYPE` and that uses the specified `basicAllocator` to
5772 /// supply memory. If `basicAllocator` is 0, the currently installed
5773 /// default allocator is used. `TYPE` must be the same as one of the
5774 /// types that this variant can hold.
5775 template <class TYPE>
5776 Variant19(const TYPE& value, bslma::Allocator *basicAllocator);
5777
5778 template <class TYPE>
5779 explicit
5780#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5781 Variant19(TYPE&& value,
5782 typename bsl::enable_if<
5783 !bsl::is_same<
5784 SelfType,
5785 typename bsl::remove_const<
5786 typename bsl::remove_reference<TYPE>::type>::type>::value
5787 &&
5789 void>::type * = 0);
5790#else
5792#endif
5793 // Create a variant object having the specified 'value' of template
5794 // parameter 'TYPE' by moving the contents of 'value' to the
5795 // newly-created object. Use the currently installed default allocator
5796 // to supply memory. 'value' is left in a valid but unspecified state.
5797 // 'TYPE' must be the same as one of the types that this variant can
5798 // hold. Note that in C++11 mode, this method does not participate in
5799 // overload resolution if it would lead to ambiguity with the move
5800 // constructor that does not take an allocator (below) or with the
5801 // constructor taking a 'valueOrAllocator' (above).
5802
5803 template <class TYPE>
5804#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5805 Variant19(TYPE&& value,
5806 typename bsl::enable_if<
5807 !bsl::is_same<
5808 SelfType,
5809 typename bsl::remove_const<
5810 typename bsl::remove_reference<TYPE>::type>::type>::value,
5811 bslma::Allocator>::type *basicAllocator);
5812#else
5814 bslma::Allocator *basicAllocator);
5815#endif
5816 // Create a variant object having the specified 'value' of template
5817 // parameter 'TYPE' that uses the specified 'basicAllocator' to supply
5818 // memory. If 'basicAllocator' is 0, the currently installed default
5819 // allocator is used. The contents of 'value' are moved to the
5820 // newly-created object with 'value' left in a valid but unspecified
5821 // state. 'TYPE' must be the same as one of the types that this
5822 // variant can hold. Note that in C++11 mode, this method does not
5823 // participate in overload resolution if it would lead to ambiguity
5824 // with the move constructor that takes an allocator (below).
5825
5826 /// Create a variant object having the type and value of the specified
5827 /// `original` variant. Optionally specify a `basicAllocator` used to
5828 /// supply memory. If `basicAllocator` is 0, the currently installed
5829 /// default allocator is used.
5830 Variant19(const Variant19& original, bslma::Allocator *basicAllocator = 0);
5831
5832 /// Create a variant object having the type and value of the specified
5833 /// `original` object by moving the contents of `original` to the
5834 /// newly-created object. The allocator associated with `original` (if
5835 /// any) is propagated for use in the newly-created object. `original`
5836 /// is left in a valid but unspecified state.
5838
5839 /// Create a variant object having the type and value of the specified
5840 /// `original` object that uses the specified `basicAllocator` to supply
5841 /// memory. If `basicAllocator` is 0, the currently installed default
5842 /// allocator is used. The contents of `original` are moved to the
5843 /// newly-created object with `original` left in a valid but unspecified
5844 /// state.
5846 bslma::Allocator *basicAllocator);
5847
5848 // MANIPULATORS
5849
5850 /// Assign to this object the specified `value` of template parameter
5851 /// `TYPE`, and return a reference providing modifiable access to this
5852 /// object. The value currently held by this variant (if any) is
5853 /// destroyed if that value's type is not the same as `TYPE`. `TYPE`
5854 /// must be the same as one of the types that this variant can hold.
5855 template <class TYPE>
5856 Variant19& operator=(const TYPE& value);
5857
5858 template <class TYPE>
5859#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
5860 typename bsl::enable_if<
5862 typename bsl::remove_cvref<TYPE>::type>::value,
5863 SelfType>::type&
5864 operator=(TYPE&& value);
5865#else
5866 Variant19&
5868#endif
5869 // Assign to this object the specified 'value' of template parameter
5870 // 'TYPE', and return a reference providing modifiable access to this
5871 // object. The contents of 'value' are moved to this object with
5872 // 'value' left in a valid but unspecified state. The value currently
5873 // held by this variant (if any) is destroyed if that value's type is
5874 // not the same as 'TYPE'. 'TYPE' must be the same as one of the types
5875 // that this variant can hold. Note that in C++11 mode, this method
5876 // does not participate in overload resolution if it would lead to
5877 // ambiguity with the move-assignment operator (below).
5878
5879 /// Assign to this object the type and value currently held by the
5880 /// specified `rhs` object, and return a reference providing modifiable
5881 /// access to this object. The value currently held by this variant
5882 /// (if any) is destroyed if that value's type is not the same as the
5883 /// type held by the `rhs` object.
5884 Variant19& operator=(const Variant19& rhs);
5885
5886 /// Assign to this object the type and value currently held by the
5887 /// specified `rhs` object, and return a reference providing modifiable
5888 /// access to this object. The value currently held by this variant
5889 /// (if any) is destroyed if that value's type is not the same as the
5890 /// type held by the `rhs` object. The contents of `rhs` are either
5891 /// move-inserted into or move-assigned to this object with `rhs` left
5892 /// in a valid but unspecified state.
5894};
5895
5896// ---- Anything below this line is implementation specific. Do not use. ----
5897
5898 // =====================================
5899 // struct Variant_TypeIndex<TYPES, TYPE>
5900 // =====================================
5901
5902/// Component-private meta-function. Do not use. This meta-function
5903/// computes the index of the template parameter `TYPE` in the template
5904/// parameter list of `TYPES`.
5905template <class TYPES, class TYPE>
5907
5908 enum {
5909 value = bsl::is_same<
5911 TYPE>::value ? 1
5912 : bsl::is_same<
5914 TYPE>::value ? 2
5915 : bsl::is_same<
5917 TYPE>::value ? 3
5918 : bsl::is_same<
5920 TYPE>::value ? 4
5921 : bsl::is_same<
5923 TYPE>::value ? 5
5924 : bsl::is_same<
5926 TYPE>::value ? 6
5927 : bsl::is_same<
5929 TYPE>::value ? 7
5930 : bsl::is_same<
5932 TYPE>::value ? 8
5933 : bsl::is_same<
5935 TYPE>::value ? 9
5936 : bsl::is_same<
5938 TYPE>::value ? 10
5939 : bsl::is_same<
5941 TYPE>::value ? 11
5942 : bsl::is_same<
5944 TYPE>::value ? 12
5945 : bsl::is_same<
5947 TYPE>::value ? 13
5948 : bsl::is_same<
5950 TYPE>::value ? 14
5951 : bsl::is_same<
5953 TYPE>::value ? 15
5954 : bsl::is_same<
5956 TYPE>::value ? 16
5957 : bsl::is_same<
5959 TYPE>::value ? 17
5960 : bsl::is_same<
5962 TYPE>::value ? 18
5963 : bsl::is_same<
5965 TYPE>::value ? 19
5966 : bsl::is_same<
5968 TYPE>::value ? 20
5970 ? 21
5971 : 0
5973
5974 BSLMF_ASSERT(0 != value);
5975
5976#if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES)
5977 // See 'testCase17' in the test driver for code snippets that motivate this
5978 // compile-time assertion (see the "out of bounds" comments). In C++03,
5979 // 'TYPES::LENGTH' yields an incorrect value if 'TYPES' has a trailing
5980 // 'bslmf::Nil' (unless the variant is declared using 'VariantN'). It is
5981 // arguably dubious to allow 'bslmf::Nil' as one of the types that a
5982 // variant may hold, but there is such use in production code that needs to
5983 // be considered if that "feature" is to be suppressed. This would do it:
5984 //..
5985 // BSLMF_ASSERT((!bsl::is_same<TYPE, bslmf::Nil>::value));
5986 //..
5987
5988 // TBD The following breaks compilation of some client code in C++11 mode
5989 // that is most likely misusing 'bslmf::Nil'.
5990 // BSLMF_ASSERT(((int)value <= (int)TYPES::LENGTH || 21 == value));
5991#endif
5992};
5993
5994 // ======================================
5995 // struct Variant_DefaultConstructVisitor
5996 // ======================================
5997
5998/// This visitor, when invoked as a non-modifiable function object on an
5999/// instance of some template parameter `TYPE`, will create a default
6000/// instance of `TYPE`.
6002
6003 // PUBLIC DATA
6005
6006 // CREATORS
6007 explicit
6009 : d_allocator_p(allocator)
6010 {
6011 }
6012
6013 // ACCESSORS
6014 template <class TYPE>
6015 void operator()(TYPE& value) const
6016 {
6017 bslma::ConstructionUtil::construct(&value, d_allocator_p);
6018 }
6019};
6020
6021 // ===================================
6022 // struct Variant_CopyConstructVisitor
6023 // ===================================
6024
6025/// This visitor, when invoked as a non-modifiable function object on an
6026/// instance of some template parameter `TYPE`, will copy-insert that
6027/// instance to create an instance of the same `TYPE` in an uninitialized
6028/// buffer specified at construction of this visitor.
6030
6031 // PUBLIC DATA
6034
6035 // CREATORS
6037 : d_buffer_p(buffer)
6038 , d_allocator_p(allocator)
6039 {
6040 BSLS_ASSERT_SAFE(d_buffer_p);
6041 }
6042
6043 // ACCESSORS
6044 template <class TYPE>
6045 void operator()(const TYPE& value) const
6046 {
6048 reinterpret_cast<TYPE *>(d_buffer_p),
6049 d_allocator_p,
6050 value);
6051 }
6052};
6053
6054 // ===================================
6055 // struct Variant_MoveConstructVisitor
6056 // ===================================
6057
6058/// This visitor, when invoked as a non-modifiable function object on an
6059/// instance of some template parameter `TYPE`, will move-insert that
6060/// instance to create an instance of the same `TYPE` in an uninitialized
6061/// buffer specified at construction of this visitor.
6063
6064 // PUBLIC DATA
6067
6068 // CREATORS
6070 : d_buffer_p(buffer)
6071 , d_allocator_p(allocator)
6072 {
6073 BSLS_ASSERT_SAFE(d_buffer_p);
6074 }
6075
6076 // ACCESSORS
6077 template <class TYPE>
6078 void operator()(TYPE& value) const
6079 {
6081 reinterpret_cast<TYPE *>(d_buffer_p),
6082 d_allocator_p,
6084 }
6085};
6086
6087 // ================================
6088 // struct Variant_DestructorVisitor
6089 // ================================
6090
6091/// This visitor, when invoked as a function object on an instance of some
6092/// template parameter `TYPE`, will destroy that instance.
6094
6095 // ACCESSORS
6096 template <class TYPE>
6097 void operator()(TYPE& object) const
6098 {
6099 bslma::DestructionUtil::destroy(&object);
6100 }
6101};
6102
6103 // ================================
6104 // struct Variant_CopyAssignVisitor
6105 // ================================
6106
6107/// This visitor, when invoked as a non-modifiable function object on an
6108/// instance of some template parameter `TYPE`, will copy-assign that
6109/// instance to the instance of the same `TYPE` held in a buffer specified
6110/// at construction of this visitor.
6112
6113 // PUBLIC DATA
6115
6116 // CREATORS
6117 explicit
6119 : d_buffer_p(buffer)
6120 {
6121 BSLS_ASSERT_SAFE(d_buffer_p);
6122 }
6123
6124 // ACCESSORS
6125 template <class TYPE>
6126 void operator()(const TYPE& value)
6127 {
6128 *reinterpret_cast<TYPE *>(d_buffer_p) = value;
6129 }
6130};
6131
6132 // ================================
6133 // struct Variant_MoveAssignVisitor
6134 // ================================
6135
6136/// This visitor, when invoked as a non-modifiable function object on an
6137/// instance of some template parameter `TYPE`, will move-assign that
6138/// instance to the instance of the same `TYPE` held in a buffer specified
6139/// at construction of this visitor.
6141
6142 // PUBLIC DATA
6144
6145 // CREATORS
6146 explicit
6148 : d_buffer_p(buffer)
6149 {
6150 BSLS_ASSERT_SAFE(d_buffer_p);
6151 }
6152
6153 // ACCESSORS
6154 template <class TYPE>
6155 void operator()(TYPE& value)
6156 {
6157 *reinterpret_cast<TYPE *>(d_buffer_p) =
6159 }
6160};
6161
6162 // ==========================
6163 // struct Variant_SwapVisitor
6164 // ==========================
6165
6166/// This visitor swaps the variant object data that it holds with another
6167/// variant object data of parameterize `TYPE`. It requires that the two
6168/// variant objects being swapped contain data of the same type, and use the
6169/// same allocator.
6171
6172 // PUBLIC DATA
6174
6175 // CREATORS
6176 explicit
6178 : d_buffer_p(buffer)
6179 {
6180 BSLS_ASSERT_SAFE(d_buffer_p);
6181 }
6182
6183 // MANIPULATORS
6184 template <class TYPE>
6185 void operator()(TYPE& value)
6186 {
6187 bslalg::SwapUtil::swap(reinterpret_cast<TYPE *>(d_buffer_p), &value);
6188 }
6189};
6190
6191#ifndef BDE_OMIT_INTERNAL_DEPRECATED
6192
6193 // ==================================
6194 // struct Variant_BdexStreamInVisitor
6195 // ==================================
6196
6197/// This visitor, when invoked as a non-modifiable function object on an
6198/// initialized instance of some parameterized `TYPE`, will stream in
6199/// a value of the same `TYPE` into that instance from a stream specified at
6200/// construction of this visitor, using a version also specified at
6201/// construction of this visitor.
6202template <class STREAM>
6204
6205 // PUBLIC DATA
6206 STREAM& d_stream; // held, not owned
6207 int d_version; // BDEX version
6208
6209 // CREATORS
6210 Variant_BdexStreamInVisitor(STREAM& stream, int version)
6211 : d_stream(stream)
6212 , d_version(version)
6213 {
6214 }
6215
6216 // ACCESSORS
6217 template <class VALUETYPE>
6218 inline
6219 void operator()(VALUETYPE& object) const
6220 {
6221 bslx::InStreamFunctions::bdexStreamIn(d_stream, object, d_version);
6222 }
6223
6224 inline
6226 {
6227 // no op
6228 }
6229};
6230
6231 // ===================================
6232 // struct Variant_BdexStreamOutVisitor
6233 // ===================================
6234
6235/// This visitor, when invoked as a non-modifiable function object on an
6236/// initialized instance of some parameterized `TYPE`, will stream out the
6237/// value of that instance into a stream specified at construction of this
6238/// visitor, using a version also specified at construction of this
6239/// visitor.
6240template <class STREAM>
6242
6243 // PUBLIC DATA
6244 STREAM& d_stream; // held, not owned
6245 int d_version; // BDEX version
6246
6247 // CREATORS
6248 Variant_BdexStreamOutVisitor(STREAM& stream, int version)
6249 : d_stream(stream)
6250 , d_version(version)
6251 {
6252 }
6253
6254 // ACCESSORS
6255 template <class VALUETYPE>
6256 inline
6257 void operator()(const VALUETYPE& object) const
6258 {
6259 bslx::OutStreamFunctions::bdexStreamOut(d_stream, object, d_version);
6260 }
6261
6262 inline
6264 {
6265 // no op
6266 }
6267};
6268#endif
6269
6270 // ===========================
6271 // struct Variant_PrintVisitor
6272 // ===========================
6273
6274/// This visitor, when invoked as a non-modifiable function object on an
6275/// instance of some template parameter `TYPE`, writes the value of that
6276/// instance to a stream specified at construction of this visitor, using
6277/// spacing information also specified at construction.
6279
6280 // PUBLIC DATA
6281 bsl::ostream *d_stream_p; // held, not owned
6284
6285 // CREATORS
6286 Variant_PrintVisitor(bsl::ostream *stream,
6287 int level,
6288 int spacesPerLevel)
6289 : d_stream_p(stream)
6290 , d_level(level)
6291 , d_spacesPerLevel(spacesPerLevel)
6292 {
6293 BSLS_ASSERT_SAFE(d_stream_p);
6294 }
6295
6296 // ACCESSORS
6297 template <class TYPE>
6298 void operator()(const TYPE& value) const
6299 {
6300 PrintMethods::print(*d_stream_p, value, d_level, d_spacesPerLevel);
6301 }
6302
6304 {
6305 // no op
6306 }
6307};
6308
6309 // ==================================
6310 // struct Variant_EqualityTestVisitor
6311 // ==================================
6312
6313/// This visitor, when invoked as a non-modifiable function object on an
6314/// instance of some template parameter `TYPE`, tests the equality of the
6315/// value of that instance and of another instance held in a buffer
6316/// specified at construction of this visitor, and stores the result into
6317/// its publicly accessible `d_result` member.
6319
6320 // PUBLIC DATA
6321 mutable bool d_result;
6322 const void *d_buffer_p; // held, not owned
6323
6324 // CREATORS
6325 explicit
6327 : d_result(true)
6328 , d_buffer_p(buffer)
6329 {
6330 BSLS_ASSERT_SAFE(d_buffer_p);
6331 }
6332
6333 // ACCESSORS
6334 template <class TYPE>
6335 void operator()(const TYPE& value) const
6336 {
6337 d_result = *reinterpret_cast<const TYPE *>(d_buffer_p) == value;
6338 }
6339
6341 {
6342 d_result = true;
6343 }
6344};
6345
6346// ============================================================================
6347// INLINE DEFINITIONS
6348// ============================================================================
6349
6350 // -------------------------------------
6351 // class VariantImp_AllocatorBase<TYPES>
6352 // -------------------------------------
6353
6354// CREATORS
6355template <class TYPES>
6356inline
6358VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator)
6359: d_type(type)
6360, d_allocator_p(bslma::Default::allocator(basicAllocator))
6361{
6362}
6363
6364template <class TYPES>
6365inline
6368: d_type(0)
6369, d_allocator_p(bslma::Default::allocator(basicAllocator))
6370{
6371}
6372
6373template <class TYPES>
6374template <class TYPE>
6375inline
6377VariantImp_AllocatorBase(int type, const TYPE&, bsl::false_type)
6378: d_type(type)
6379, d_allocator_p(bslma::Default::allocator(0))
6380{
6381}
6382
6383// ACCESSORS
6384template <class TYPES>
6385inline
6388{
6389 return d_allocator_p;
6390}
6391
6392 // ---------------------------------------
6393 // class VariantImp_NoAllocatorBase<TYPES>
6394 // ---------------------------------------
6395
6396// CREATORS
6397template <class TYPES>
6398inline
6404
6405template <class TYPES>
6406inline
6412
6413template <class TYPES>
6414template <class TYPE>
6415inline
6417VariantImp_NoAllocatorBase(int type, const TYPE&, bsl::false_type)
6418: d_type(type)
6419{
6420}
6421
6422// ACCESSORS
6423template <class TYPES>
6424inline
6427{
6428 return 0;
6429}
6430
6431 // ------------------------------
6432 // class Variant_RawVisitorHelper
6433 // ------------------------------
6434
6435// CREATORS
6436template <class RESULT_TYPE, class VISITOR>
6437inline
6439Variant_RawVisitorHelper(VISITOR *visitor)
6440: d_visitor(visitor)
6441{
6442 BSLS_ASSERT_SAFE(0 != visitor);
6443}
6444
6445// MANIPULATORS
6446template <class RESULT_TYPE, class VISITOR>
6447template <class ARGUMENT_TYPE>
6448inline
6449RESULT_TYPE
6451 ARGUMENT_TYPE& argument)
6452{
6453 return static_cast<RESULT_TYPE>((*d_visitor)(argument));
6454}
6455
6456template <class RESULT_TYPE, class VISITOR>
6457template <class ARGUMENT_TYPE>
6458inline
6459RESULT_TYPE
6461 const ARGUMENT_TYPE& argument)
6462{
6463 return static_cast<RESULT_TYPE>((*d_visitor)(argument));
6464}
6465
6466// ACCESSORS
6467template <class RESULT_TYPE, class VISITOR>
6468template <class ARGUMENT_TYPE>
6469inline
6470RESULT_TYPE
6472 ARGUMENT_TYPE& argument) const
6473{
6474 return static_cast<RESULT_TYPE>((*d_visitor)(argument));
6475}
6476
6477template <class RESULT_TYPE, class VISITOR>
6478template <class ARGUMENT_TYPE>
6479inline
6480RESULT_TYPE
6482 const ARGUMENT_TYPE& argument) const
6483{
6484 return static_cast<RESULT_TYPE>((*d_visitor)(argument));
6485}
6486
6487template <class RESULT_TYPE, class VISITOR>
6488RESULT_TYPE
6493
6494 // -----------------------
6495 // class VariantImp<TYPES>
6496 // -----------------------
6497
6498// PRIVATE MANIPULATORS
6499template <class TYPES>
6500template <class TYPE, class VISITOR_REF>
6501inline
6502void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::false_type)
6503{
6504 typedef bsls::ObjectBuffer<TYPE> BufferType;
6505
6506 visitor(reinterpret_cast<BufferType *>(&this->d_value)->object());
6507}
6508
6509template <class TYPES>
6510template <class TYPE, class VISITOR_REF>
6511inline
6512void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::true_type)
6513{
6514 bslmf::Nil nil = bslmf::Nil();
6515 visitor(nil);
6516}
6517
6518template <class TYPES>
6519template <class TYPE, class VISITOR_REF>
6520inline
6521void VariantImp<TYPES>::applyImp(VISITOR_REF visitor)
6522{
6523 typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset;
6524 applyImp<TYPE, VISITOR_REF>(visitor, IsUnset());
6525}
6526
6527template <class TYPES>
6528template <class TYPE, class VISITOR_REF, class RET_TYPE>
6529inline
6530RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::false_type)
6531{
6532 typedef bsls::ObjectBuffer<TYPE> BufferType;
6533
6534 return visitor(reinterpret_cast<BufferType *>(&this->d_value)->object());
6535}
6536
6537template <class TYPES>
6538template <class TYPE, class VISITOR_REF, class RET_TYPE>
6539inline
6540RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::true_type)
6541{
6542 bslmf::Nil nil = bslmf::Nil();
6543 return visitor(nil);
6544}
6545
6546template <class TYPES>
6547template <class TYPE, class VISITOR_REF, class RET_TYPE>
6548inline
6549RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor)
6550{
6551 typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset;
6552 return applyImpR<TYPE, VISITOR_REF, RET_TYPE>(visitor, IsUnset());
6553}
6554
6555template <class TYPES>
6556template <class TYPE, class SOURCE_TYPE>
6557void VariantImp<TYPES>::assignImp(const SOURCE_TYPE& value)
6558{
6559 typedef bsls::ObjectBuffer<TYPE> BufferType;
6560
6561 reset();
6563 reinterpret_cast<BufferType *>(&this->d_value)->address(),
6564 this->getAllocator(),
6565 value);
6567}
6568
6569template <class TYPES>
6570template <class TYPE>
6571#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
6572void VariantImp<TYPES>::assignImp(TYPE&& value)
6573#else
6574void VariantImp<TYPES>::assignImp(bslmf::MovableRef<TYPE> value)
6575#endif
6576{
6578 BufferType;
6579
6580 reset();
6581
6582#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
6584 reinterpret_cast<BufferType *>(&this->d_value)->address(),
6585 this->getAllocator(),
6586 BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
6587#else
6588 TYPE& lvalue = value;
6590 reinterpret_cast<BufferType *>(&this->d_value)->address(),
6591 this->getAllocator(),
6593#endif
6594
6595 this->d_type =
6596 Variant_TypeIndex<TYPES,
6597 typename bsl::remove_reference<TYPE>::type>::value;
6598}
6599
6600template <class TYPES>
6601template <class VISITOR_REF>
6602void VariantImp<TYPES>::doApply(VISITOR_REF visitor, int type)
6603{
6604 switch (type) {
6605 case 0: {
6606 BSLS_ASSERT(0 == "'doApply' invoked on an unset variant");
6607 } break;
6608 case 1: {
6609 applyImp<typename Base::Type1, VISITOR_REF>(visitor);
6610 } break;
6611 case 2: {
6612 applyImp<typename Base::Type2, VISITOR_REF>(visitor);
6613 } break;
6614 case 3: {
6615 applyImp<typename Base::Type3, VISITOR_REF>(visitor);
6616 } break;
6617 case 4: {
6618 applyImp<typename Base::Type4, VISITOR_REF>(visitor);
6619 } break;
6620 case 5: {
6621 applyImp<typename Base::Type5, VISITOR_REF>(visitor);
6622 } break;
6623 case 6: {
6624 applyImp<typename Base::Type6, VISITOR_REF>(visitor);
6625 } break;
6626 case 7: {
6627 applyImp<typename Base::Type7, VISITOR_REF>(visitor);
6628 } break;
6629 case 8: {
6630 applyImp<typename Base::Type8, VISITOR_REF>(visitor);
6631 } break;
6632 case 9: {
6633 applyImp<typename Base::Type9, VISITOR_REF>(visitor);
6634 } break;
6635 case 10: {
6636 applyImp<typename Base::Type10, VISITOR_REF>(visitor);
6637 } break;
6638 case 11: {
6639 applyImp<typename Base::Type11, VISITOR_REF>(visitor);
6640 } break;
6641 case 12: {
6642 applyImp<typename Base::Type12, VISITOR_REF>(visitor);
6643 } break;
6644 case 13: {
6645 applyImp<typename Base::Type13, VISITOR_REF>(visitor);
6646 } break;
6647 case 14: {
6648 applyImp<typename Base::Type14, VISITOR_REF>(visitor);
6649 } break;
6650 case 15: {
6651 applyImp<typename Base::Type15, VISITOR_REF>(visitor);
6652 } break;
6653 case 16: {
6654 applyImp<typename Base::Type16, VISITOR_REF>(visitor);
6655 } break;
6656 case 17: {
6657 applyImp<typename Base::Type17, VISITOR_REF>(visitor);
6658 } break;
6659 case 18: {
6660 applyImp<typename Base::Type18, VISITOR_REF>(visitor);
6661 } break;
6662 case 19: {
6663 applyImp<typename Base::Type19, VISITOR_REF>(visitor);
6664 } break;
6665 case 20: {
6666 applyImp<typename Base::Type20, VISITOR_REF>(visitor);
6667 } break;
6668 default: {
6669 BSLS_ASSERT(0 == "Unreachable by design!");
6670 } break;
6671 }
6672}
6673
6674template <class TYPES>
6675template <class TYPE>
6676inline
6677void VariantImp<TYPES>::create(const TYPE& value, bsl::false_type)
6678{
6679 typedef bsls::ObjectBuffer<TYPE> BufferType;
6680
6682 reinterpret_cast<BufferType *>(&this->d_value)->address(),
6683 this->getAllocator(),
6684 value);
6685}
6686
6687template <class TYPES>
6688inline
6689void VariantImp<TYPES>::create(bslma::Allocator *, bsl::true_type)
6690{
6691}
6692
6693template <class TYPES>
6694template <class VISITOR_REF, class RET_TYPE>
6695RET_TYPE VariantImp<TYPES>::doApplyR(VISITOR_REF visitor, int type)
6696{
6697 switch (type) {
6698 case 0: {
6699 BSLS_ASSERT_INVOKE_NORETURN("'doApplyR' invoked on an unset variant");
6700 } break;
6701 case 1: {
6702 return applyImpR<typename Base::Type1,
6703 VISITOR_REF,
6704 RET_TYPE>(visitor); // RETURN
6705 } break;
6706 case 2: {
6707 return applyImpR<typename Base::Type2,
6708 VISITOR_REF,
6709 RET_TYPE>(visitor); // RETURN
6710 } break;
6711 case 3: {
6712 return applyImpR<typename Base::Type3,
6713 VISITOR_REF,
6714 RET_TYPE>(visitor); // RETURN
6715 } break;
6716 case 4: {
6717 return applyImpR<typename Base::Type4,
6718 VISITOR_REF,
6719 RET_TYPE>(visitor); // RETURN
6720 } break;
6721 case 5: {
6722 return applyImpR<typename Base::Type5,
6723 VISITOR_REF,
6724 RET_TYPE>(visitor); // RETURN
6725 } break;
6726 case 6: {
6727 return applyImpR<typename Base::Type6,
6728 VISITOR_REF,
6729 RET_TYPE>(visitor); // RETURN
6730 } break;
6731 case 7: {
6732 return applyImpR<typename Base::Type7,
6733 VISITOR_REF,
6734 RET_TYPE>(visitor); // RETURN
6735 } break;
6736 case 8: {
6737 return applyImpR<typename Base::Type8,
6738 VISITOR_REF,
6739 RET_TYPE>(visitor); // RETURN
6740 } break;
6741 case 9: {
6742 return applyImpR<typename Base::Type9,
6743 VISITOR_REF,
6744 RET_TYPE>(visitor); // RETURN
6745 } break;
6746 case 10: {
6747 return applyImpR<typename Base::Type10,
6748 VISITOR_REF,
6749 RET_TYPE>(visitor); // RETURN
6750 } break;
6751 case 11: {
6752 return applyImpR<typename Base::Type11,
6753 VISITOR_REF,
6754 RET_TYPE>(visitor); // RETURN
6755 } break;
6756 case 12: {
6757 return applyImpR<typename Base::Type12,
6758 VISITOR_REF,
6759 RET_TYPE>(visitor); // RETURN
6760 } break;
6761 case 13: {
6762 return applyImpR<typename Base::Type13,
6763 VISITOR_REF,
6764 RET_TYPE>(visitor); // RETURN
6765 } break;
6766 case 14: {
6767 return applyImpR<typename Base::Type14,
6768 VISITOR_REF,
6769 RET_TYPE>(visitor); // RETURN
6770 } break;
6771 case 15: {
6772 return applyImpR<typename Base::Type15,
6773 VISITOR_REF,
6774 RET_TYPE>(visitor); // RETURN
6775 } break;
6776 case 16: {
6777 return applyImpR<typename Base::Type16,
6778 VISITOR_REF,
6779 RET_TYPE>(visitor); // RETURN
6780 } break;
6781 case 17: {
6782 return applyImpR<typename Base::Type17,
6783 VISITOR_REF,
6784 RET_TYPE>(visitor); // RETURN
6785 } break;
6786 case 18: {
6787 return applyImpR<typename Base::Type18,
6788 VISITOR_REF,
6789 RET_TYPE>(visitor); // RETURN
6790 } break;
6791 case 19: {
6792 return applyImpR<typename Base::Type19,
6793 VISITOR_REF,
6794 RET_TYPE>(visitor); // RETURN
6795 } break;
6796 case 20: {
6797 return applyImpR<typename Base::Type20,
6798 VISITOR_REF,
6799 RET_TYPE>(visitor); // RETURN
6800 } break;
6801 default: {
6802 BSLS_ASSERT_INVOKE_NORETURN("Unreachable by design!");
6803 } break;
6804 }
6805}
6806
6807// PRIVATE ACCESSORS
6808template <class TYPES>
6809template <class TYPE, class VISITOR_REF>
6810inline
6811void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::false_type) const
6812{
6813 typedef bsls::ObjectBuffer<TYPE> BufferType;
6814
6815 visitor(reinterpret_cast<const BufferType *>(&this->d_value)->object());
6816}
6817
6818template <class TYPES>
6819template <class TYPE, class VISITOR_REF>
6820inline
6821void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::true_type) const
6822{
6823 bslmf::Nil nil = bslmf::Nil();
6824 visitor(nil);
6825}
6826
6827template <class TYPES>
6828template <class TYPE, class VISITOR_REF>
6829inline
6830void VariantImp<TYPES>::applyImp(VISITOR_REF visitor) const
6831{
6832 typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset;
6833 applyImp<TYPE, VISITOR_REF>(visitor, IsUnset());
6834}
6835
6836template <class TYPES>
6837template <class TYPE, class VISITOR_REF, class RET_TYPE>
6838inline
6839RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor,
6840 bsl::false_type) const
6841{
6842 typedef bsls::ObjectBuffer<TYPE> BufferType;
6843
6844 return visitor(reinterpret_cast<const BufferType *>(
6845 &this->d_value)->object());
6846}
6847
6848template <class TYPES>
6849template <class TYPE, class VISITOR_REF, class RET_TYPE>
6850inline
6851RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor,
6852 bsl::true_type) const
6853{
6854 bslmf::Nil nil = bslmf::Nil();
6855 return visitor(nil);
6856}
6857
6858template <class TYPES>
6859template <class TYPE, class VISITOR_REF, class RET_TYPE>
6860inline
6861RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor) const
6862{
6863 typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset;
6864 return applyImpR<TYPE, VISITOR_REF, RET_TYPE>(visitor, IsUnset());
6865}
6866
6867template <class TYPES>
6868template <class VISITOR_REF>
6869void VariantImp<TYPES>::doApply(VISITOR_REF visitor, int type) const
6870{
6871 switch (type) {
6872 case 0: {
6873 BSLS_ASSERT_INVOKE_NORETURN("'doApply' invoked on an unset variant");
6874 } break;
6875 case 1: {
6876 applyImp<typename Base::Type1, VISITOR_REF>(visitor);
6877 } break;
6878 case 2: {
6879 applyImp<typename Base::Type2, VISITOR_REF>(visitor);
6880 } break;
6881 case 3: {
6882 applyImp<typename Base::Type3, VISITOR_REF>(visitor);
6883 } break;
6884 case 4: {
6885 applyImp<typename Base::Type4, VISITOR_REF>(visitor);
6886 } break;
6887 case 5: {
6888 applyImp<typename Base::Type5, VISITOR_REF>(visitor);
6889 } break;
6890 case 6: {
6891 applyImp<typename Base::Type6, VISITOR_REF>(visitor);
6892 } break;
6893 case 7: {
6894 applyImp<typename Base::Type7, VISITOR_REF>(visitor);
6895 } break;
6896 case 8: {
6897 applyImp<typename Base::Type8, VISITOR_REF>(visitor);
6898 } break;
6899 case 9: {
6900 applyImp<typename Base::Type9, VISITOR_REF>(visitor);
6901 } break;
6902 case 10: {
6903 applyImp<typename Base::Type10, VISITOR_REF>(visitor);
6904 } break;
6905 case 11: {
6906 applyImp<typename Base::Type11, VISITOR_REF>(visitor);
6907 } break;
6908 case 12: {
6909 applyImp<typename Base::Type12, VISITOR_REF>(visitor);
6910 } break;
6911 case 13: {
6912 applyImp<typename Base::Type13, VISITOR_REF>(visitor);
6913 } break;
6914 case 14: {
6915 applyImp<typename Base::Type14, VISITOR_REF>(visitor);
6916 } break;
6917 case 15: {
6918 applyImp<typename Base::Type15, VISITOR_REF>(visitor);
6919 } break;
6920 case 16: {
6921 applyImp<typename Base::Type16, VISITOR_REF>(visitor);
6922 } break;
6923 case 17: {
6924 applyImp<typename Base::Type17, VISITOR_REF>(visitor);
6925 } break;
6926 case 18: {
6927 applyImp<typename Base::Type18, VISITOR_REF>(visitor);
6928 } break;
6929 case 19: {
6930 applyImp<typename Base::Type19, VISITOR_REF>(visitor);
6931 } break;
6932 case 20: {
6933 applyImp<typename Base::Type20, VISITOR_REF>(visitor);
6934 } break;
6935 default: {
6936 BSLS_ASSERT_INVOKE_NORETURN("Unreachable by design!");
6937 } break;
6938 }
6939}
6940
6941template <class TYPES>
6942template <class VISITOR_REF, class RET_TYPE>
6943RET_TYPE VariantImp<TYPES>::doApplyR(VISITOR_REF visitor, int type) const
6944{
6945 switch (type) {
6946 case 0: {
6947 BSLS_ASSERT_INVOKE_NORETURN("'doApplyR' invoked on an unset variant");
6948 } break;
6949 case 1: {
6950 return applyImpR<typename Base::Type1,
6951 VISITOR_REF,
6952 RET_TYPE>(visitor); // RETURN
6953 } break;
6954 case 2: {
6955 return applyImpR<typename Base::Type2,
6956 VISITOR_REF,
6957 RET_TYPE>(visitor); // RETURN
6958 } break;
6959 case 3: {
6960 return applyImpR<typename Base::Type3,
6961 VISITOR_REF,
6962 RET_TYPE>(visitor); // RETURN
6963 } break;
6964 case 4: {
6965 return applyImpR<typename Base::Type4,
6966 VISITOR_REF,
6967 RET_TYPE>(visitor); // RETURN
6968 } break;
6969 case 5: {
6970 return applyImpR<typename Base::Type5,
6971 VISITOR_REF,
6972 RET_TYPE>(visitor); // RETURN
6973 } break;
6974 case 6: {
6975 return applyImpR<typename Base::Type6,
6976 VISITOR_REF,
6977 RET_TYPE>(visitor); // RETURN
6978 } break;
6979 case 7: {
6980 return applyImpR<typename Base::Type7,
6981 VISITOR_REF,
6982 RET_TYPE>(visitor); // RETURN
6983 } break;
6984 case 8: {
6985 return applyImpR<typename Base::Type8,
6986 VISITOR_REF,
6987 RET_TYPE>(visitor); // RETURN
6988 } break;
6989 case 9: {
6990 return applyImpR<typename Base::Type9,
6991 VISITOR_REF,
6992 RET_TYPE>(visitor); // RETURN
6993 } break;
6994 case 10: {
6995 return applyImpR<typename Base::Type10,
6996 VISITOR_REF,
6997 RET_TYPE>(visitor); // RETURN
6998 } break;
6999 case 11: {
7000 return applyImpR<typename Base::Type11,
7001 VISITOR_REF,
7002 RET_TYPE>(visitor); // RETURN
7003 } break;
7004 case 12: {
7005 return applyImpR<typename Base::Type12,
7006 VISITOR_REF,
7007 RET_TYPE>(visitor); // RETURN
7008 } break;
7009 case 13: {
7010 return applyImpR<typename Base::Type13,
7011 VISITOR_REF,
7012 RET_TYPE>(visitor); // RETURN
7013 } break;
7014 case 14: {
7015 return applyImpR<typename Base::Type14,
7016 VISITOR_REF,
7017 RET_TYPE>(visitor); // RETURN
7018 } break;
7019 case 15: {
7020 return applyImpR<typename Base::Type15,
7021 VISITOR_REF,
7022 RET_TYPE>(visitor); // RETURN
7023 } break;
7024 case 16: {
7025 return applyImpR<typename Base::Type16,
7026 VISITOR_REF,
7027 RET_TYPE>(visitor); // RETURN
7028 } break;
7029 case 17: {
7030 return applyImpR<typename Base::Type17,
7031 VISITOR_REF,
7032 RET_TYPE>(visitor); // RETURN
7033 } break;
7034 case 18: {
7035 return applyImpR<typename Base::Type18,
7036 VISITOR_REF,
7037 RET_TYPE>(visitor); // RETURN
7038 } break;
7039 case 19: {
7040 return applyImpR<typename Base::Type19,
7041 VISITOR_REF,
7042 RET_TYPE>(visitor); // RETURN
7043 } break;
7044 case 20: {
7045 return applyImpR<typename Base::Type20,
7046 VISITOR_REF,
7047 RET_TYPE>(visitor); // RETURN
7048 } break;
7049 default: {
7050 BSLS_ASSERT_INVOKE_NORETURN("Unreachable by design!");
7051 } break;
7052 }
7053}
7054
7055// CREATORS
7056template <class TYPES>
7057inline
7059: Base(0, 0)
7060{
7061}
7062
7063template <class TYPES>
7064template <class TYPE_OR_ALLOCATOR>
7065inline
7066VariantImp<TYPES>::VariantImp(const TYPE_OR_ALLOCATOR& valueOrAllocator)
7067: Base(Variant_TypeIndex<TYPES, TYPE_OR_ALLOCATOR>::value,
7068 valueOrAllocator,
7069 bsl::integral_constant<bool, bsl::is_convertible<TYPE_OR_ALLOCATOR,
7070 bslma::Allocator *>::value>())
7071{
7072 enum {
7073 k_IS_ALLOCATOR = bsl::is_convertible<TYPE_OR_ALLOCATOR,
7074 bslma::Allocator *>::value
7075 };
7076
7077 create(valueOrAllocator, bsl::integral_constant<bool, k_IS_ALLOCATOR>());
7078}
7079
7080template <class TYPES>
7081template <class TYPE>
7082inline
7084 bslma::Allocator *basicAllocator)
7085: Base(Variant_TypeIndex<TYPES, TYPE>::value, basicAllocator)
7086{
7087 typedef bsls::ObjectBuffer<TYPE> BufferType;
7088
7090 reinterpret_cast<BufferType *>(&this->d_value)->address(),
7091 this->getAllocator(),
7092 value);
7093}
7094
7095template <class TYPES>
7096template <class TYPE>
7098#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7099VariantImp(TYPE&& value,
7100 typename bsl::enable_if<
7101 !bsl::is_same<
7102 SelfType,
7103 typename bsl::remove_const<
7104 typename bsl::remove_reference<TYPE>::type>::type>::value
7105 &&
7107 void>::type *)
7108#else
7110#endif
7112 TYPES,
7113 typename bsl::remove_const<
7114 typename bsl::remove_reference<TYPE>::type>::type>::value,
7115 0)
7116{
7117 typedef bsls::ObjectBuffer<
7118 typename bsl::remove_const<
7119 typename bsl::remove_reference<TYPE>::type>::type> BufferType;
7120
7121#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7123 reinterpret_cast<BufferType *>(&this->d_value)->address(),
7124 this->getAllocator(),
7125 BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
7126#else
7127 TYPE& lvalue = value;
7129 reinterpret_cast<BufferType *>(&this->d_value)->address(),
7130 this->getAllocator(),
7132#endif
7133}
7134
7135template <class TYPES>
7136template <class TYPE>
7138#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7139VariantImp(TYPE&& value,
7140 typename bsl::enable_if<
7141 !bsl::is_same<
7142 SelfType,
7143 typename bsl::remove_const<
7144 typename bsl::remove_reference<TYPE>::type>::type>::value,
7145 bslma::Allocator>::type *basicAllocator)
7146#else
7148 bslma::Allocator *basicAllocator)
7149#endif
7151 TYPES,
7152 typename bsl::remove_const<
7153 typename bsl::remove_reference<TYPE>::type>::type>::value,
7154 basicAllocator)
7155{
7156 typedef bsls::ObjectBuffer<
7157 typename bsl::remove_const<
7158 typename bsl::remove_reference<TYPE>::type>::type> BufferType;
7159
7160#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7162 reinterpret_cast<BufferType *>(&this->d_value)->address(),
7163 this->getAllocator(),
7164 BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
7165#else
7166 TYPE& lvalue = value;
7168 reinterpret_cast<BufferType *>(&this->d_value)->address(),
7169 this->getAllocator(),
7171#endif
7172}
7173
7174template <class TYPES>
7176 bslma::Allocator *basicAllocator)
7177: Base(original.d_type, basicAllocator)
7178{
7179 if (this->d_type) {
7180 Variant_CopyConstructVisitor copyConstructor(&this->d_value,
7181 this->getAllocator());
7182 original.apply(copyConstructor);
7183 }
7184}
7185
7186template <class TYPES>
7188: Base(MoveUtil::access(original).d_type,
7189 MoveUtil::access(original).getAllocator())
7190{
7191 if (this->d_type) {
7192 Variant_MoveConstructVisitor moveConstructor(&this->d_value,
7193 this->getAllocator());
7194 VariantImp& lvalue = original;
7195
7196 lvalue.apply(moveConstructor);
7197 }
7198}
7199
7200template <class TYPES>
7202 bslma::Allocator *basicAllocator)
7203: Base(MoveUtil::access(original).d_type, basicAllocator)
7204{
7205 if (this->d_type) {
7206 Variant_MoveConstructVisitor moveConstructor(&this->d_value,
7207 this->getAllocator());
7208 VariantImp& lvalue = original;
7209
7210 lvalue.apply(moveConstructor);
7211 }
7212}
7213
7214template <class TYPES>
7215inline
7217{
7218 reset();
7219}
7220
7221// MANIPULATORS
7222template <class TYPES>
7223template <class TYPE>
7224inline
7227{
7228 return assign(value);
7229}
7230
7231template <class TYPES>
7232template <class TYPE>
7233inline
7234#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7235typename bsl::enable_if<
7237 typename bsl::remove_cvref<TYPE>::type>::value,
7238VariantImp<TYPES> >::type&
7239VariantImp<TYPES>::operator=(TYPE&& value)
7240#else
7243#endif
7244{
7245#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7246 return assign(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
7247#else
7248 TYPE& lvalue = value;
7249 return assign(MoveUtil::move(lvalue));
7250#endif
7251}
7252
7253template <class TYPES>
7256{
7257 if (&rhs != this) {
7258 if (this->d_type == rhs.d_type) {
7259 if (this->d_type) {
7260 Variant_CopyAssignVisitor assigner(&this->d_value);
7261 rhs.apply(assigner);
7262 }
7263 }
7264 else {
7265 reset();
7266 if (rhs.d_type) {
7267 Variant_CopyConstructVisitor copyConstructor(
7268 &this->d_value,
7269 this->getAllocator());
7270 rhs.apply(copyConstructor);
7271 this->d_type = rhs.d_type;
7272 }
7273 }
7274 }
7275
7276 return *this;
7277}
7278
7279template <class TYPES>
7282{
7283 VariantImp& lvalue = rhs;
7284
7285 if (&lvalue != this) {
7286 if (this->d_type == lvalue.d_type) {
7287 if (this->d_type) {
7288 Variant_MoveAssignVisitor assigner(&this->d_value);
7289 lvalue.apply(assigner);
7290 }
7291 }
7292 else {
7293 reset();
7294 if (lvalue.d_type) {
7295 Variant_MoveConstructVisitor moveConstructor(
7296 &this->d_value,
7297 this->getAllocator());
7298 lvalue.apply(moveConstructor);
7299 this->d_type = lvalue.d_type;
7300 }
7301 }
7302 }
7303
7304 return *this;
7305}
7306
7307template <class TYPES>
7308template <class RET_TYPE, class VISITOR>
7309inline
7310RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor)
7311{
7312 if (this->d_type) {
7313 return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN
7314 }
7315
7316 bslmf::Nil nil = bslmf::Nil();
7317 return visitor(nil);
7318}
7319
7320template <class TYPES>
7321template <class RET_TYPE, class VISITOR>
7322inline
7323RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor)
7324{
7325 if (this->d_type) {
7326 return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type);
7327 // RETURN
7328 }
7329
7330 bslmf::Nil nil = bslmf::Nil();
7331 return visitor(nil);
7332}
7333
7334template <class TYPES>
7335template <class RET_TYPE, class VISITOR, class TYPE>
7336inline
7337RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor, const TYPE& defaultValue)
7338{
7339 if (this->d_type) {
7340 return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN
7341 }
7342
7343 return visitor(defaultValue);
7344}
7345
7346template <class TYPES>
7347template <class RET_TYPE, class VISITOR, class TYPE>
7348inline
7349RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor,
7350 const TYPE& defaultValue)
7351{
7352 if (this->d_type) {
7353 return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type);
7354 // RETURN
7355 }
7356
7357 return visitor(defaultValue);
7358}
7359
7360template <class TYPES>
7361template <class RET_TYPE, class VISITOR>
7362inline
7363RET_TYPE VariantImp<TYPES>::applyRaw(VISITOR& visitor)
7364{
7366
7367 return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type);
7368}
7369
7370template <class TYPES>
7371template <class RET_TYPE, class VISITOR>
7372inline
7373RET_TYPE VariantImp<TYPES>::applyRaw(const VISITOR& visitor)
7374{
7376
7377 return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type);
7378}
7379
7380template <class TYPES>
7381template <class TYPE>
7383{
7384 typedef bsls::ObjectBuffer<TYPE> BufferType;
7385
7386 if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type) {
7387 reinterpret_cast<BufferType *>(&this->d_value)->object() = value;
7388 }
7389 else {
7390 assignImp<TYPE, TYPE>(value);
7391 }
7392
7393 return *this;
7394}
7395
7396template <class TYPES>
7397template <class TYPE>
7398#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7400#else
7402#endif
7403{
7405 BufferType;
7406
7407#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7408 if (Variant_TypeIndex<TYPES,
7409 typename bsl::remove_reference<TYPE>::type>::value
7410 == this->d_type) {
7411 reinterpret_cast<BufferType *>(&this->d_value)->object() =
7412 BSLS_COMPILERFEATURES_FORWARD(TYPE, value);
7413 }
7414 else {
7415 assignImp<TYPE>(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
7416 }
7417#else
7418 TYPE& lvalue = value;
7419
7420 if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type) {
7421 reinterpret_cast<BufferType *>(&this->d_value)->object() =
7422 MoveUtil::move(lvalue);
7423 }
7424 else {
7425 assignImp<TYPE>(MoveUtil::move(lvalue));
7426 }
7427#endif
7428
7429 return *this;
7430}
7431
7432template <class TYPES>
7433template <class TYPE, class SOURCE_TYPE>
7435{
7436 typedef bsls::ObjectBuffer<TYPE> BufferType;
7437
7438 if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type
7440 reinterpret_cast<BufferType *>(&this->d_value)->object() = value;
7441 }
7442 else {
7443 assignImp<TYPE, SOURCE_TYPE>(value);
7444 }
7445
7446 return *this;
7447}
7448
7449#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=14
7450
7451template <class TYPES>
7452template <class TYPE, class... ARGS>
7453inline
7454TYPE& VariantImp<TYPES>::createInPlace(ARGS&&... arguments)
7455{
7456 typedef bsls::ObjectBuffer<TYPE> BufferType;
7457 BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value);
7458
7459 reset();
7461 bufR.address(),
7462 this->getAllocator(),
7463 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
7465
7466 return bufR.object();
7467}
7468
7469#endif
7470
7471template <class TYPES>
7473{
7474 if (this->d_type) {
7475 Variant_DestructorVisitor destructor;
7476 apply(destructor);
7477 this->d_type = 0;
7478 }
7479}
7480
7481template <class TYPES>
7483{
7484 if (!this->d_type) {
7485 if (!other.d_type) {
7486 return; // RETURN
7487 }
7488 *this = other;
7489 other.reset();
7490 }
7491 else if (!other.d_type) {
7492 other = *this;
7493 this->reset();
7494 }
7495 else {
7496 if (this->d_type == other.d_type
7497 && this->getAllocator() == other.getAllocator()) {
7498 // Same types and same allocators, so use a visitor that calls
7499 // 'swap'.
7500
7501 Variant_SwapVisitor swapper(&this->d_value);
7502 other.apply(swapper);
7503 }
7504 else {
7505 // Different types and/or allocators, so swap via assignment. Note
7506 // that this doesn't fit the usual pattern for calling 'swap'
7507 // because infinite recursion would result.
7508
7509 bsl::swap(*this, other);
7510 }
7511 }
7512}
7513
7514template <class TYPES>
7515template <class TYPE>
7516inline
7518{
7521
7522 typedef bsls::ObjectBuffer<TYPE> BufferType;
7523
7524 return reinterpret_cast<BufferType *>(&this->d_value)->object();
7525}
7526
7527// ACCESSORS
7528template <class TYPES>
7529template <class RET_TYPE, class VISITOR>
7530inline
7531RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor) const
7532{
7533 if (this->d_type) {
7534 return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN
7535 }
7536
7537 bslmf::Nil nil = bslmf::Nil();
7538 return visitor(nil);
7539}
7540
7541template <class TYPES>
7542template <class RET_TYPE, class VISITOR>
7543inline
7544RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor) const
7545{
7546 if (this->d_type) {
7547 return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type);
7548 // RETURN
7549 }
7550
7551 bslmf::Nil nil = bslmf::Nil();
7552 return visitor(nil);
7553}
7554
7555template <class TYPES>
7556template <class RET_TYPE, class VISITOR, class TYPE>
7557inline
7558RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor,
7559 const TYPE& defaultValue) const
7560{
7561 if (this->d_type) {
7562 return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN
7563 }
7564
7565 return visitor(defaultValue);
7566}
7567
7568template <class TYPES>
7569template <class RET_TYPE, class VISITOR, class TYPE>
7570inline
7571RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor,
7572 const TYPE& defaultValue) const
7573{
7574 if (this->d_type) {
7575 return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type);
7576 // RETURN
7577 }
7578
7579 return visitor(defaultValue);
7580}
7581
7582template <class TYPES>
7583template <class RET_TYPE, class VISITOR>
7584inline
7585RET_TYPE VariantImp<TYPES>::applyRaw(VISITOR& visitor) const
7586{
7588
7589 return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type);
7590}
7591
7592template <class TYPES>
7593template <class RET_TYPE, class VISITOR>
7594inline
7595RET_TYPE VariantImp<TYPES>::applyRaw(const VISITOR& visitor) const
7596{
7598
7599 return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type);
7600}
7601
7602template <class TYPES>
7603template <class TYPE>
7604inline
7606{
7607 return Variant_TypeIndex<TYPES, TYPE>::value == this->d_type;
7608}
7609
7610template <class TYPES>
7611inline
7613{
7614 return !this->d_type;
7615}
7616
7617template <class TYPES>
7618bsl::ostream&
7619VariantImp<TYPES>::print(bsl::ostream& stream,
7620 int level,
7621 int spacesPerLevel) const
7622{
7623 if (this->d_type) {
7624 Variant_PrintVisitor visitor(&stream, level, spacesPerLevel);
7625
7626 doApply<const Variant_PrintVisitor&>(visitor, this->d_type);
7627 }
7628 return stream;
7629}
7630
7631template <class TYPES>
7632template <class TYPE>
7633inline
7634const TYPE& VariantImp<TYPES>::the() const
7635{
7638
7639 typedef bsls::ObjectBuffer<TYPE> BufferType;
7640
7641 return reinterpret_cast<const BufferType *>(&this->d_value)->object();
7642}
7643
7644template <class TYPES>
7645inline
7647{
7648 return this->d_type;
7649}
7650
7651#ifndef BDE_OMIT_INTERNAL_DEPRECATED
7652template <class TYPES>
7653inline
7654const bsl::type_info& VariantImp<TYPES>::typeInfo() const
7655{
7656 return typeid(void);
7657}
7658
7659template <class TYPES>
7660template <class STREAM>
7661STREAM& VariantImp<TYPES>::bdexStreamIn(STREAM& stream, int version)
7662{
7663 int type;
7665
7666 if (!stream || type < 0 || 20 < type) {
7667 stream.invalidate();
7668 return stream;
7669 }
7670
7671 if (type != this->d_type) {
7672 reset();
7673
7674 if (type) {
7675 Variant_DefaultConstructVisitor defaultConstructor(
7676 this->getAllocator());
7677 doApply(defaultConstructor, type);
7678 }
7679
7680 this->d_type = type;
7681 }
7682
7683 if (type) {
7684 Variant_BdexStreamInVisitor<STREAM> streamer(stream, version);
7685 doApply(streamer, type);
7686 }
7687 return stream;
7688}
7689
7690template <class TYPES>
7691inline
7693{
7694 return 1;
7695}
7696
7697template <class TYPES>
7698template <class STREAM>
7699STREAM& VariantImp<TYPES>::bdexStreamOut(STREAM& stream, int version) const
7700{
7701 bslx::OutStreamFunctions::bdexStreamOut(stream, this->d_type, 0);
7702
7703 if (this->d_type) {
7704 typedef Variant_BdexStreamOutVisitor<STREAM> Streamer;
7705
7706 Streamer streamer(stream, version);
7707 doApply<Streamer&>(streamer, this->d_type);
7708 }
7709 return stream;
7710}
7711
7712#endif // BDE_OMIT_INTERNAL_DEPRECATED
7713
7714} // close package namespace
7715
7716// FREE OPERATORS
7717template <class TYPES>
7718bool bdlb::operator==(const VariantImp<TYPES>& lhs,
7719 const VariantImp<TYPES>& rhs)
7720{
7721 if (lhs.typeIndex() != rhs.typeIndex()) {
7722 return false; // RETURN
7723 }
7724
7725 if (0 == lhs.typeIndex()) {
7726 return true; // RETURN
7727 }
7728
7729 Variant_EqualityTestVisitor visitor(&rhs.d_value);
7730 lhs.apply(visitor);
7731
7732 return visitor.d_result;
7733}
7734
7735template <class TYPES>
7736inline
7737bool bdlb::operator!=(const VariantImp<TYPES>& lhs,
7738 const VariantImp<TYPES>& rhs)
7739{
7740 return !(lhs == rhs);
7741}
7742
7743template <class TYPES>
7744inline
7745bsl::ostream& bdlb::operator<<(bsl::ostream& stream,
7746 const VariantImp<TYPES>& object)
7747{
7748 return object.print(stream, 0, -1);
7749}
7750
7751// FREE FUNCTIONS
7752template <class TYPES>
7753inline
7754void bdlb::swap(VariantImp<TYPES>& a, VariantImp<TYPES>& b)
7755{
7756 a.swap(b);
7757}
7758
7759namespace bdlb {
7760
7761 // ------------------
7762 // class Variant<...>
7763 // ------------------
7764
7765// CREATORS
7766#if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES)
7767template <class ...TYPES>
7768inline
7770{
7771}
7772
7773template <class ...TYPES>
7774template <class TYPE_OR_ALLOCATOR>
7775inline
7776Variant<TYPES...>::Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator)
7777: Imp(valueOrAllocator)
7778{
7779}
7780
7781template <class ...TYPES>
7782template <class TYPE>
7783inline
7784Variant<TYPES...>::Variant(const TYPE& value, bslma::Allocator *basicAllocator)
7785: Imp(value, basicAllocator)
7786{
7787}
7788
7789template <class ...TYPES>
7790template <class TYPE>
7791inline
7792Variant<TYPES...>::
7793#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7794Variant(TYPE&& value,
7795 typename bsl::enable_if<
7796 !bsl::is_same<
7797 SelfType,
7798 typename bsl::remove_const<
7799 typename bsl::remove_reference<TYPE>::type>::type>::value
7800 &&
7802 void>::type *)
7803: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
7804#else
7805Variant(bslmf::MovableRef<TYPE> value)
7806: Imp(MoveUtil::move(value))
7807#endif
7808{
7809}
7810
7811template <class ...TYPES>
7812template <class TYPE>
7813inline
7814Variant<TYPES...>::
7815#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7816Variant(TYPE&& value,
7817 typename bsl::enable_if<
7818 !bsl::is_same<
7819 SelfType,
7820 typename bsl::remove_const<
7821 typename bsl::remove_reference<TYPE>::type>::type>::value,
7822 bslma::Allocator>::type *basicAllocator)
7823: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
7824#else
7825Variant(bslmf::MovableRef<TYPE> value,
7826 bslma::Allocator *basicAllocator)
7827: Imp(MoveUtil::move(value), basicAllocator)
7828#endif
7829{
7830}
7831
7832/// Up-cast needed since template matching has higher overloading precedence
7833/// than derived-to-base matching.
7834template <class ...TYPES>
7835inline
7836Variant<TYPES...>::Variant(const Variant& original,
7837 bslma::Allocator *basicAllocator)
7838: Imp(static_cast<const Imp&>(original), basicAllocator)
7839{
7840}
7841
7842template <class ...TYPES>
7843inline
7845: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
7846{
7847}
7848
7849template <class ...TYPES>
7850inline
7852 bslma::Allocator *basicAllocator)
7853: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
7854 basicAllocator)
7855{
7856}
7857
7858// MANIPULATORS
7859template <class ...TYPES>
7860template <class TYPE>
7861inline
7862Variant<TYPES...>& Variant<TYPES...>::operator=(const TYPE& value)
7863{
7864 Imp::operator=(value);
7865 return *this;
7866}
7867
7868template <class ...TYPES>
7869template <class TYPE>
7870inline
7871#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7872typename bsl::enable_if<
7873 !bsl::is_same<Variant<TYPES...>,
7874 typename bsl::remove_cvref<TYPE>::type>::value,
7875Variant<TYPES...> >::type&
7876Variant<TYPES...>::operator=(TYPE&& value)
7877#else
7878Variant<TYPES...>&
7880#endif
7881{
7882#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7883 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
7884#else
7885 TYPE& lvalue = value;
7886 Imp::operator=(MoveUtil::move(lvalue));
7887#endif
7888
7889 return *this;
7890}
7891
7892template <class ...TYPES>
7893inline
7894Variant<TYPES...>& Variant<TYPES...>::operator=(const Variant& rhs)
7895{
7896 // Up-cast needed since template matching has higher overloading precedence
7897 // than derived-to-base matching.
7898
7899 Imp::operator=(static_cast<const Imp&>(rhs));
7900 return *this;
7901}
7902
7903template <class ...TYPES>
7904inline
7906{
7907 // Up-cast needed since template matching has higher overloading precedence
7908 // than derived-to-base matching.
7909
7910 Variant& lvalue = rhs;
7911
7912 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
7913 return *this;
7914}
7915
7916#else // BDLB_VARIANT_USING_VARIADIC_TEMPLATES
7917template <class A1, class A2, class A3, class A4, class A5, class A6,
7918 class A7, class A8, class A9, class A10, class A11, class A12,
7919 class A13, class A14, class A15, class A16, class A17, class A18,
7920 class A19, class A20>
7921inline
7922Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
7923 A13, A14, A15, A16, A17, A18, A19, A20>::Variant()
7924{
7925}
7926
7927template <class A1, class A2, class A3, class A4, class A5, class A6,
7928 class A7, class A8, class A9, class A10, class A11, class A12,
7929 class A13, class A14, class A15, class A16, class A17, class A18,
7930 class A19, class A20>
7931template <class TYPE_OR_ALLOCATOR>
7932inline
7933Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
7934 A13, A14, A15, A16, A17, A18, A19, A20>::Variant(
7935 const TYPE_OR_ALLOCATOR& valueOrAllocator)
7936: Imp(valueOrAllocator)
7937{
7938}
7939
7940template <class A1, class A2, class A3, class A4, class A5, class A6,
7941 class A7, class A8, class A9, class A10, class A11, class A12,
7942 class A13, class A14, class A15, class A16, class A17, class A18,
7943 class A19, class A20>
7944template <class TYPE>
7945inline
7946Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
7947 A13, A14, A15, A16, A17, A18, A19, A20>::Variant(
7948 const TYPE& value,
7949 bslma::Allocator *basicAllocator)
7950: Imp(value, basicAllocator)
7951{
7952}
7953
7954template <class A1, class A2, class A3, class A4, class A5, class A6,
7955 class A7, class A8, class A9, class A10, class A11, class A12,
7956 class A13, class A14, class A15, class A16, class A17, class A18,
7957 class A19, class A20>
7958template <class TYPE>
7959inline
7960Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
7961 A13, A14, A15, A16, A17, A18, A19, A20>::
7962#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7963Variant(TYPE&& value,
7964 typename bsl::enable_if<
7965 !bsl::is_same<
7966 SelfType,
7967 typename bsl::remove_const<
7968 typename bsl::remove_reference<TYPE>::type>::type>::value
7969 &&
7971 void>::type *)
7972: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
7973#else
7974Variant(bslmf::MovableRef<TYPE> value)
7975: Imp(MoveUtil::move(value))
7976#endif
7977{
7978}
7979
7980template <class A1, class A2, class A3, class A4, class A5, class A6,
7981 class A7, class A8, class A9, class A10, class A11, class A12,
7982 class A13, class A14, class A15, class A16, class A17, class A18,
7983 class A19, class A20>
7984template <class TYPE>
7985inline
7986Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
7987 A13, A14, A15, A16, A17, A18, A19, A20>::
7988#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
7989Variant(TYPE&& value,
7990 typename bsl::enable_if<
7991 !bsl::is_same<
7992 SelfType,
7993 typename bsl::remove_const<
7994 typename bsl::remove_reference<TYPE>::type>::type>::value,
7995 bslma::Allocator>::type *basicAllocator)
7996: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
7997#else
7998Variant(bslmf::MovableRef<TYPE> value,
7999 bslma::Allocator *basicAllocator)
8000: Imp(MoveUtil::move(value), basicAllocator)
8001#endif
8002{
8003}
8004
8005template <class A1, class A2, class A3, class A4, class A5, class A6,
8006 class A7, class A8, class A9, class A10, class A11, class A12,
8007 class A13, class A14, class A15, class A16, class A17, class A18,
8008 class A19, class A20>
8009inline
8010Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8011 A13, A14, A15, A16, A17, A18, A19, A20>::Variant(
8012 const Variant& original,
8013 bslma::Allocator *basicAllocator)
8014: Imp(static_cast<const Imp&>(original), basicAllocator)
8015 // Up-cast needed since template matching has higher overloading precedence
8016 // than derived-to-base matching.
8017{
8018}
8019
8020template <class A1, class A2, class A3, class A4, class A5, class A6,
8021 class A7, class A8, class A9, class A10, class A11, class A12,
8022 class A13, class A14, class A15, class A16, class A17, class A18,
8023 class A19, class A20>
8024inline
8025Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8026 A13, A14, A15, A16, A17, A18, A19, A20>::Variant(
8028: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8029{
8030}
8031
8032template <class A1, class A2, class A3, class A4, class A5, class A6,
8033 class A7, class A8, class A9, class A10, class A11, class A12,
8034 class A13, class A14, class A15, class A16, class A17, class A18,
8035 class A19, class A20>
8036inline
8037Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8038 A13, A14, A15, A16, A17, A18, A19, A20>::Variant(
8040 bslma::Allocator *basicAllocator)
8041: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8042 basicAllocator)
8043{
8044}
8045
8046// MANIPULATORS
8047template <class A1, class A2, class A3, class A4, class A5, class A6,
8048 class A7, class A8, class A9, class A10, class A11, class A12,
8049 class A13, class A14, class A15, class A16, class A17, class A18,
8050 class A19, class A20>
8051template <class TYPE>
8052inline
8053Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8054 A13, A14, A15, A16, A17, A18, A19, A20>&
8055Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8056 A13, A14, A15, A16, A17, A18, A19, A20>::operator=(const TYPE& value)
8057{
8058 Imp::operator=(value);
8059 return *this;
8060}
8061
8062template <class A1, class A2, class A3, class A4, class A5, class A6,
8063 class A7, class A8, class A9, class A10, class A11, class A12,
8064 class A13, class A14, class A15, class A16, class A17, class A18,
8065 class A19, class A20>
8066template <class TYPE>
8067inline
8068#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8069typename bsl::enable_if<
8070 !bsl::is_same<Variant<A1, A2, A3, A4, A5, A6, A7,
8071 A8, A9, A10, A11, A12, A13, A14,
8072 A15, A16, A17, A18, A19, A20>,
8073 typename bsl::remove_cvref<TYPE>::type>::value,
8074Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
8075 A16, A17, A18, A19, A20> >::type&
8076Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
8077 A16, A17, A18, A19, A20>::operator=(TYPE&& value)
8078#else
8079Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
8080 A16, A17, A18, A19, A20>&
8081Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
8082 A16, A17, A18, A19, A20>::operator=(bslmf::MovableRef<TYPE> value)
8083#endif
8084{
8085#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8086 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8087#else
8088 TYPE& lvalue = value;
8089 Imp::operator=(MoveUtil::move(lvalue));
8090#endif
8091
8092 return *this;
8093}
8094
8095template <class A1, class A2, class A3, class A4, class A5, class A6,
8096 class A7, class A8, class A9, class A10, class A11, class A12,
8097 class A13, class A14, class A15, class A16, class A17, class A18,
8098 class A19, class A20>
8099inline
8100Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8101 A13, A14, A15, A16, A17, A18, A19, A20>&
8102Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8103 A13, A14, A15, A16, A17, A18, A19, A20>::operator=(const Variant& rhs)
8104{
8105 // Up-cast needed since template matching has higher overloading precedence
8106 // than derived-to-base matching.
8107
8108 Imp::operator=(static_cast<const Imp&>(rhs));
8109 return *this;
8110}
8111
8112template <class A1, class A2, class A3, class A4, class A5, class A6,
8113 class A7, class A8, class A9, class A10, class A11, class A12,
8114 class A13, class A14, class A15, class A16, class A17, class A18,
8115 class A19, class A20>
8116inline
8117Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8118 A13, A14, A15, A16, A17, A18, A19, A20>&
8119Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
8120 A13, A14, A15, A16, A17, A18, A19, A20>::
8121operator=(bslmf::MovableRef<Variant> rhs)
8122{
8123 // Up-cast needed since template matching has higher overloading precedence
8124 // than derived-to-base matching.
8125
8126 Variant& lvalue = rhs;
8127
8128 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8129 return *this;
8130}
8131
8132#endif // BDLB_VARIANT_USING_VARIADIC_TEMPLATES
8133
8134#ifdef BDLB_VARIANT_USING_VARIADIC_TEMPLATES
8135#undef BDLB_VARIANT_USING_VARIADIC_TEMPLATES
8136#endif
8137
8138 // -------------------
8139 // class Variant2<...>
8140 // -------------------
8141
8142// CREATORS
8143template <class A1, class A2>
8144inline
8148
8149template <class A1, class A2>
8150template <class TYPE_OR_ALLOCATOR>
8151inline
8152Variant2<A1, A2>::Variant2(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8153: Imp(valueOrAllocator)
8154{
8155}
8156
8157template <class A1, class A2>
8158template <class TYPE>
8159inline
8161 bslma::Allocator *basicAllocator)
8162: Imp(value, basicAllocator)
8163{
8164}
8165
8166template <class A1, class A2>
8167template <class TYPE>
8168inline
8170#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8171Variant2(TYPE&& value,
8172 typename bsl::enable_if<
8173 !bsl::is_same<
8174 SelfType,
8175 typename bsl::remove_const<
8176 typename bsl::remove_reference<TYPE>::type>::type>::value
8177 &&
8179 void>::type *)
8180: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8181#else
8182Variant2(bslmf::MovableRef<TYPE> value)
8183: Imp(MoveUtil::move(value))
8184#endif
8185{
8186}
8187
8188template <class A1, class A2>
8189template <class TYPE>
8190inline
8192#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8193Variant2(TYPE&& value,
8194 typename bsl::enable_if<
8195 !bsl::is_same<
8196 SelfType,
8197 typename bsl::remove_const<
8198 typename bsl::remove_reference<TYPE>::type>::type>::value,
8199 bslma::Allocator>::type *basicAllocator)
8200: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8201#else
8202Variant2(bslmf::MovableRef<TYPE> value,
8203 bslma::Allocator *basicAllocator)
8204: Imp(MoveUtil::move(value), basicAllocator)
8205#endif
8206{
8207}
8208
8209template <class A1, class A2>
8210inline
8212 bslma::Allocator *basicAllocator)
8213: Imp(static_cast<const Imp&>(original), basicAllocator)
8214{
8215}
8216
8217template <class A1, class A2>
8218inline
8220: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8221{
8222}
8223
8224template <class A1, class A2>
8225inline
8227 bslma::Allocator *basicAllocator)
8228: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8229 basicAllocator)
8230{
8231}
8232
8233// MANIPULATORS
8234template <class A1, class A2>
8235template <class TYPE>
8236inline
8239{
8240 Imp::operator=(value);
8241 return *this;
8242}
8243
8244template <class A1, class A2>
8245template <class TYPE>
8246inline
8247#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8248typename bsl::enable_if<
8250 typename bsl::remove_cvref<TYPE>::type>::value,
8251Variant2<A1, A2> >::type&
8252Variant2<A1, A2>::operator=(TYPE&& value)
8253#else
8256#endif
8257{
8258#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8259 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8260#else
8261 TYPE& lvalue = value;
8262 Imp::operator=(MoveUtil::move(lvalue));
8263#endif
8264
8265 return *this;
8266}
8267
8268template <class A1, class A2>
8269inline
8272{
8273 Imp::operator=(static_cast<const Imp&>(rhs));
8274 return *this;
8275}
8276
8277template <class A1, class A2>
8278inline
8281{
8282 Variant2& lvalue = rhs;
8283
8284 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8285 return *this;
8286}
8287
8288 // -------------------
8289 // class Variant3<...>
8290 // -------------------
8291
8292// CREATORS
8293template <class A1, class A2, class A3>
8294inline
8298
8299template <class A1, class A2, class A3>
8300template <class TYPE_OR_ALLOCATOR>
8301inline
8303Variant3(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8304: Imp(valueOrAllocator)
8305{
8306}
8307
8308template <class A1, class A2, class A3>
8309template <class TYPE>
8310inline
8312Variant3(const TYPE& value, bslma::Allocator *basicAllocator)
8313: Imp(value, basicAllocator)
8314{
8315}
8316
8317template <class A1, class A2, class A3>
8318template <class TYPE>
8319inline
8321#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8322Variant3(TYPE&& value,
8323 typename bsl::enable_if<
8324 !bsl::is_same<
8325 SelfType,
8326 typename bsl::remove_const<
8327 typename bsl::remove_reference<TYPE>::type>::type>::value
8328 &&
8330 void>::type *)
8331: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8332#else
8333Variant3(bslmf::MovableRef<TYPE> value)
8334: Imp(MoveUtil::move(value))
8335#endif
8336{
8337}
8338
8339template <class A1, class A2, class A3>
8340template <class TYPE>
8341inline
8343#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8344Variant3(TYPE&& value,
8345 typename bsl::enable_if<
8346 !bsl::is_same<
8347 SelfType,
8348 typename bsl::remove_const<
8349 typename bsl::remove_reference<TYPE>::type>::type>::value,
8350 bslma::Allocator>::type *basicAllocator)
8351: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8352#else
8353Variant3(bslmf::MovableRef<TYPE> value,
8354 bslma::Allocator *basicAllocator)
8355: Imp(MoveUtil::move(value), basicAllocator)
8356#endif
8357{
8358}
8359
8360template <class A1, class A2, class A3>
8361inline
8363Variant3(const Variant3& original, bslma::Allocator *basicAllocator)
8364: Imp(static_cast<const Imp&>(original), basicAllocator)
8365{
8366}
8367
8368template <class A1, class A2, class A3>
8369inline
8372: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8373{
8374}
8375
8376template <class A1, class A2, class A3>
8377inline
8380 bslma::Allocator *basicAllocator)
8381: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8382 basicAllocator)
8383{
8384}
8385
8386// MANIPULATORS
8387template <class A1, class A2, class A3>
8388template <class TYPE>
8389inline
8392{
8393 Imp::operator=(value);
8394 return *this;
8395}
8396
8397template <class A1, class A2, class A3>
8398template <class TYPE>
8399inline
8400#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8401typename bsl::enable_if<
8403 typename bsl::remove_cvref<TYPE>::type>::value,
8404Variant3<A1, A2, A3> >::type&
8406#else
8409#endif
8410{
8411#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8412 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8413#else
8414 TYPE& lvalue = value;
8415 Imp::operator=(MoveUtil::move(lvalue));
8416#endif
8417
8418 return *this;
8419}
8420
8421template <class A1, class A2, class A3>
8422inline
8425{
8426 Imp::operator=(static_cast<const Imp&>(rhs));
8427 return *this;
8428}
8429
8430template <class A1, class A2, class A3>
8431inline
8434{
8435 Variant3& lvalue = rhs;
8436
8437 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8438 return *this;
8439}
8440
8441 // -------------------
8442 // class Variant4<...>
8443 // -------------------
8444
8445// CREATORS
8446template <class A1, class A2, class A3, class A4>
8447inline
8451
8452template <class A1, class A2, class A3, class A4>
8453template <class TYPE_OR_ALLOCATOR>
8454inline
8456Variant4(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8457: Imp(valueOrAllocator)
8458{
8459}
8460
8461template <class A1, class A2, class A3, class A4>
8462template <class TYPE>
8463inline
8465Variant4(const TYPE& value, bslma::Allocator *basicAllocator)
8466: Imp(value, basicAllocator)
8467{
8468}
8469
8470template <class A1, class A2, class A3, class A4>
8471template <class TYPE>
8472inline
8474#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8475Variant4(TYPE&& value,
8476 typename bsl::enable_if<
8477 !bsl::is_same<
8478 SelfType,
8479 typename bsl::remove_const<
8480 typename bsl::remove_reference<TYPE>::type>::type>::value
8481 &&
8483 void>::type *)
8484: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8485#else
8486Variant4(bslmf::MovableRef<TYPE> value)
8487: Imp(MoveUtil::move(value))
8488#endif
8489{
8490}
8491
8492template <class A1, class A2, class A3, class A4>
8493template <class TYPE>
8494inline
8496#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8497Variant4(TYPE&& value,
8498 typename bsl::enable_if<
8499 !bsl::is_same<
8500 SelfType,
8501 typename bsl::remove_const<
8502 typename bsl::remove_reference<TYPE>::type>::type>::value,
8503 bslma::Allocator>::type *basicAllocator)
8504: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8505#else
8506Variant4(bslmf::MovableRef<TYPE> value,
8507 bslma::Allocator *basicAllocator)
8508: Imp(MoveUtil::move(value), basicAllocator)
8509#endif
8510{
8511}
8512
8513template <class A1, class A2, class A3, class A4>
8514inline
8516Variant4(const Variant4& original, bslma::Allocator *basicAllocator)
8517: Imp(static_cast<const Imp&>(original), basicAllocator)
8518{
8519}
8520
8521template <class A1, class A2, class A3, class A4>
8522inline
8525: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8526{
8527}
8528
8529template <class A1, class A2, class A3, class A4>
8530inline
8533 bslma::Allocator *basicAllocator)
8534: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8535 basicAllocator)
8536{
8537}
8538
8539// MANIPULATORS
8540template <class A1, class A2, class A3, class A4>
8541template <class TYPE>
8542inline
8545{
8546 Imp::operator=(value);
8547 return *this;
8548}
8549
8550template <class A1, class A2, class A3, class A4>
8551template <class TYPE>
8552inline
8553#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8554typename bsl::enable_if<
8556 typename bsl::remove_cvref<TYPE>::type>::value,
8559#else
8562#endif
8563{
8564#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8565 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8566#else
8567 TYPE& lvalue = value;
8568 Imp::operator=(MoveUtil::move(lvalue));
8569#endif
8570
8571 return *this;
8572}
8573
8574template <class A1, class A2, class A3, class A4>
8575inline
8578{
8579 Imp::operator=(static_cast<const Imp&>(rhs));
8580 return *this;
8581}
8582
8583template <class A1, class A2, class A3, class A4>
8584inline
8587{
8588 Variant4& lvalue = rhs;
8589
8590 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8591 return *this;
8592}
8593
8594 // -------------------
8595 // class Variant5<...>
8596 // -------------------
8597
8598// CREATORS
8599template <class A1, class A2, class A3, class A4, class A5>
8600inline
8604
8605template <class A1, class A2, class A3, class A4, class A5>
8606template <class TYPE_OR_ALLOCATOR>
8607inline
8609Variant5(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8610: Imp(valueOrAllocator)
8611{
8612}
8613
8614template <class A1, class A2, class A3, class A4, class A5>
8615template <class TYPE>
8616inline
8618Variant5(const TYPE& value, bslma::Allocator *basicAllocator)
8619: Imp(value, basicAllocator)
8620{
8621}
8622
8623template <class A1, class A2, class A3, class A4, class A5>
8624template <class TYPE>
8625inline
8627#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8628Variant5(TYPE&& value,
8629 typename bsl::enable_if<
8630 !bsl::is_same<
8631 SelfType,
8632 typename bsl::remove_const<
8633 typename bsl::remove_reference<TYPE>::type>::type>::value
8634 &&
8636 void>::type *)
8637: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8638#else
8639Variant5(bslmf::MovableRef<TYPE> value)
8640: Imp(MoveUtil::move(value))
8641#endif
8642{
8643}
8644
8645template <class A1, class A2, class A3, class A4, class A5>
8646template <class TYPE>
8647inline
8649#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8650Variant5(TYPE&& value,
8651 typename bsl::enable_if<
8652 !bsl::is_same<
8653 SelfType,
8654 typename bsl::remove_const<
8655 typename bsl::remove_reference<TYPE>::type>::type>::value,
8656 bslma::Allocator>::type *basicAllocator)
8657: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8658#else
8659Variant5(bslmf::MovableRef<TYPE> value,
8660 bslma::Allocator *basicAllocator)
8661: Imp(MoveUtil::move(value), basicAllocator)
8662#endif
8663{
8664}
8665
8666template <class A1, class A2, class A3, class A4, class A5>
8667inline
8669Variant5(const Variant5& original, bslma::Allocator *basicAllocator)
8670: Imp(static_cast<const Imp&>(original), basicAllocator)
8671{
8672}
8673
8674template <class A1, class A2, class A3, class A4, class A5>
8675inline
8678: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8679{
8680}
8681
8682template <class A1, class A2, class A3, class A4, class A5>
8683inline
8686 bslma::Allocator *basicAllocator)
8687: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8688 basicAllocator)
8689{
8690}
8691
8692// MANIPULATORS
8693template <class A1, class A2, class A3, class A4, class A5>
8694template <class TYPE>
8695inline
8698{
8699 Imp::operator=(value);
8700 return *this;
8701}
8702
8703template <class A1, class A2, class A3, class A4, class A5>
8704template <class TYPE>
8705inline
8706#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8707typename bsl::enable_if<
8709 typename bsl::remove_cvref<TYPE>::type>::value,
8712#else
8715#endif
8716{
8717#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8718 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8719#else
8720 TYPE& lvalue = value;
8721 Imp::operator=(MoveUtil::move(lvalue));
8722#endif
8723
8724 return *this;
8725}
8726
8727template <class A1, class A2, class A3, class A4, class A5>
8728inline
8731{
8732 Imp::operator=(static_cast<const Imp&>(rhs));
8733 return *this;
8734}
8735
8736template <class A1, class A2, class A3, class A4, class A5>
8737inline
8740{
8741 Variant5& lvalue = rhs;
8742
8743 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8744 return *this;
8745}
8746
8747 // -------------------
8748 // class Variant6<...>
8749 // -------------------
8750
8751// CREATORS
8752template <class A1, class A2, class A3, class A4, class A5, class A6>
8753inline
8757
8758template <class A1, class A2, class A3, class A4, class A5, class A6>
8759template <class TYPE_OR_ALLOCATOR>
8760inline
8762Variant6(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8763: Imp(valueOrAllocator)
8764{
8765}
8766
8767template <class A1, class A2, class A3, class A4, class A5, class A6>
8768template <class TYPE>
8769inline
8771Variant6(const TYPE& value, bslma::Allocator *basicAllocator)
8772: Imp(value, basicAllocator)
8773{
8774}
8775
8776template <class A1, class A2, class A3, class A4, class A5, class A6>
8777template <class TYPE>
8778inline
8780#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8781Variant6(TYPE&& value,
8782 typename bsl::enable_if<
8783 !bsl::is_same<
8784 SelfType,
8785 typename bsl::remove_const<
8786 typename bsl::remove_reference<TYPE>::type>::type>::value
8787 &&
8789 void>::type *)
8790: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8791#else
8792Variant6(bslmf::MovableRef<TYPE> value)
8793: Imp(MoveUtil::move(value))
8794#endif
8795{
8796}
8797
8798template <class A1, class A2, class A3, class A4, class A5, class A6>
8799template <class TYPE>
8800inline
8802#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8803Variant6(TYPE&& value,
8804 typename bsl::enable_if<
8805 !bsl::is_same<
8806 SelfType,
8807 typename bsl::remove_const<
8808 typename bsl::remove_reference<TYPE>::type>::type>::value,
8809 bslma::Allocator>::type *basicAllocator)
8810: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8811#else
8812Variant6(bslmf::MovableRef<TYPE> value,
8813 bslma::Allocator *basicAllocator)
8814: Imp(MoveUtil::move(value), basicAllocator)
8815#endif
8816{
8817}
8818
8819template <class A1, class A2, class A3, class A4, class A5, class A6>
8820inline
8822Variant6(const Variant6& original, bslma::Allocator *basicAllocator)
8823: Imp(static_cast<const Imp&>(original), basicAllocator)
8824{
8825}
8826
8827template <class A1, class A2, class A3, class A4, class A5, class A6>
8828inline
8831: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8832{
8833}
8834
8835template <class A1, class A2, class A3, class A4, class A5, class A6>
8836inline
8839 bslma::Allocator *basicAllocator)
8840: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8841 basicAllocator)
8842{
8843}
8844
8845// MANIPULATORS
8846template <class A1, class A2, class A3, class A4, class A5, class A6>
8847template <class TYPE>
8848inline
8851{
8852 Imp::operator=(value);
8853 return *this;
8854}
8855
8856template <class A1, class A2, class A3, class A4, class A5, class A6>
8857template <class TYPE>
8858inline
8859#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8860typename bsl::enable_if<
8862 typename bsl::remove_cvref<TYPE>::type>::value,
8865#else
8868#endif
8869{
8870#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8871 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
8872#else
8873 TYPE& lvalue = value;
8874 Imp::operator=(MoveUtil::move(lvalue));
8875#endif
8876
8877 return *this;
8878}
8879
8880template <class A1, class A2, class A3, class A4, class A5, class A6>
8881inline
8884{
8885 Imp::operator=(static_cast<const Imp&>(rhs));
8886 return *this;
8887}
8888
8889template <class A1, class A2, class A3, class A4, class A5, class A6>
8890inline
8893{
8894 Variant6& lvalue = rhs;
8895
8896 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
8897 return *this;
8898}
8899
8900 // -------------------
8901 // class Variant7<...>
8902 // -------------------
8903
8904// CREATORS
8905template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8906inline
8910
8911template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8912template <class TYPE_OR_ALLOCATOR>
8913inline
8915Variant7(const TYPE_OR_ALLOCATOR& valueOrAllocator)
8916: Imp(valueOrAllocator)
8917{
8918}
8919
8920template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8921template <class TYPE>
8922inline
8924Variant7(const TYPE& value, bslma::Allocator *basicAllocator)
8925: Imp(value, basicAllocator)
8926{
8927}
8928
8929template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8930template <class TYPE>
8931inline
8933#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8934Variant7(TYPE&& value,
8935 typename bsl::enable_if<
8936 !bsl::is_same<
8937 SelfType,
8938 typename bsl::remove_const<
8939 typename bsl::remove_reference<TYPE>::type>::type>::value
8940 &&
8942 void>::type *)
8943: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
8944#else
8945Variant7(bslmf::MovableRef<TYPE> value)
8946: Imp(MoveUtil::move(value))
8947#endif
8948{
8949}
8950
8951template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8952template <class TYPE>
8953inline
8955#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
8956Variant7(TYPE&& value,
8957 typename bsl::enable_if<
8958 !bsl::is_same<
8959 SelfType,
8960 typename bsl::remove_const<
8961 typename bsl::remove_reference<TYPE>::type>::type>::value,
8962 bslma::Allocator>::type *basicAllocator)
8963: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
8964#else
8965Variant7(bslmf::MovableRef<TYPE> value,
8966 bslma::Allocator *basicAllocator)
8967: Imp(MoveUtil::move(value), basicAllocator)
8968#endif
8969{
8970}
8971
8972template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8973inline
8975Variant7(const Variant7& original, bslma::Allocator *basicAllocator)
8976: Imp(static_cast<const Imp&>(original), basicAllocator)
8977{
8978}
8979
8980template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8981inline
8984: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
8985{
8986}
8987
8988template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8989inline
8992 bslma::Allocator *basicAllocator)
8993: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
8994 basicAllocator)
8995{
8996}
8997
8998// MANIPULATORS
8999template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9000template <class TYPE>
9001inline
9004{
9005 Imp::operator=(value);
9006 return *this;
9007}
9008
9009template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9010template <class TYPE>
9011inline
9012#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9013typename bsl::enable_if<
9015 typename bsl::remove_cvref<TYPE>::type>::value,
9018#else
9021#endif
9022{
9023#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9024 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9025#else
9026 TYPE& lvalue = value;
9027 Imp::operator=(MoveUtil::move(lvalue));
9028#endif
9029
9030 return *this;
9031}
9032
9033template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9034inline
9037operator=(const Variant7& rhs)
9038{
9039 Imp::operator=(static_cast<const Imp&>(rhs));
9040 return *this;
9041}
9042
9043template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9044inline
9048{
9049 Variant7& lvalue = rhs;
9050
9051 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9052 return *this;
9053}
9054
9055 // -------------------
9056 // class Variant8<...>
9057 // -------------------
9058
9059// CREATORS
9060template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9061 class A8>
9062inline
9066
9067template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9068 class A8>
9069template <class TYPE_OR_ALLOCATOR>
9070inline
9072Variant8(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9073: Imp(valueOrAllocator)
9074{
9075}
9076
9077template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9078 class A8>
9079template <class TYPE>
9080inline
9082Variant8(const TYPE& value, bslma::Allocator *basicAllocator)
9083: Imp(value, basicAllocator)
9084{
9085}
9086
9087template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9088 class A8>
9089template <class TYPE>
9090inline
9092#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9093Variant8(TYPE&& value,
9094 typename bsl::enable_if<
9095 !bsl::is_same<
9096 SelfType,
9097 typename bsl::remove_const<
9098 typename bsl::remove_reference<TYPE>::type>::type>::value
9099 &&
9101 void>::type *)
9102: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9103#else
9104Variant8(bslmf::MovableRef<TYPE> value)
9105: Imp(MoveUtil::move(value))
9106#endif
9107{
9108}
9109
9110template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9111 class A8>
9112template <class TYPE>
9113inline
9115#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9116Variant8(TYPE&& value,
9117 typename bsl::enable_if<
9118 !bsl::is_same<
9119 SelfType,
9120 typename bsl::remove_const<
9121 typename bsl::remove_reference<TYPE>::type>::type>::value,
9122 bslma::Allocator>::type *basicAllocator)
9123: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9124#else
9125Variant8(bslmf::MovableRef<TYPE> value,
9126 bslma::Allocator *basicAllocator)
9127: Imp(MoveUtil::move(value), basicAllocator)
9128#endif
9129{
9130}
9131
9132template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9133 class A8>
9134inline
9136Variant8(const Variant8& original, bslma::Allocator *basicAllocator)
9137: Imp(static_cast<const Imp&>(original), basicAllocator)
9138{
9139}
9140
9141template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9142 class A8>
9143inline
9146: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
9147{
9148}
9149
9150template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9151 class A8>
9152inline
9155 bslma::Allocator *basicAllocator)
9156: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
9157 basicAllocator)
9158{
9159}
9160
9161// MANIPULATORS
9162template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9163 class A8>
9164template <class TYPE>
9165inline
9168{
9169 Imp::operator=(value);
9170 return *this;
9171}
9172
9173template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9174 class A8>
9175template <class TYPE>
9176inline
9177#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9178typename bsl::enable_if<
9180 typename bsl::remove_cvref<TYPE>::type>::value,
9183operator=(TYPE&& value)
9184#else
9188#endif
9189{
9190#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9191 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9192#else
9193 TYPE& lvalue = value;
9194 Imp::operator=(MoveUtil::move(lvalue));
9195#endif
9196
9197 return *this;
9198}
9199
9200template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9201 class A8>
9202inline
9205operator=(const Variant8& rhs)
9206{
9207 Imp::operator=(static_cast<const Imp&>(rhs));
9208 return *this;
9209}
9210
9211template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9212 class A8>
9213inline
9217{
9218 Variant8& lvalue = rhs;
9219
9220 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9221 return *this;
9222}
9223
9224 // -------------------
9225 // class Variant9<...>
9226 // -------------------
9227
9228// CREATORS
9229template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9230 class A8, class A9>
9231inline
9235
9236template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9237 class A8, class A9>
9238template <class TYPE_OR_ALLOCATOR>
9239inline
9241Variant9(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9242: Imp(valueOrAllocator)
9243{
9244}
9245
9246template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9247 class A8, class A9>
9248template <class TYPE>
9249inline
9251Variant9(const TYPE& value, bslma::Allocator *basicAllocator)
9252: Imp(value, basicAllocator)
9253{
9254}
9255
9256template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9257 class A8, class A9>
9258template <class TYPE>
9259inline
9261#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9262Variant9(TYPE&& value,
9263 typename bsl::enable_if<
9264 !bsl::is_same<
9265 SelfType,
9266 typename bsl::remove_const<
9267 typename bsl::remove_reference<TYPE>::type>::type>::value
9268 &&
9270 void>::type *)
9271: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9272#else
9273Variant9(bslmf::MovableRef<TYPE> value)
9274: Imp(MoveUtil::move(value))
9275#endif
9276{
9277}
9278
9279template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9280 class A8, class A9>
9281template <class TYPE>
9282inline
9284#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9285Variant9(TYPE&& value,
9286 typename bsl::enable_if<
9287 !bsl::is_same<
9288 SelfType,
9289 typename bsl::remove_const<
9290 typename bsl::remove_reference<TYPE>::type>::type>::value,
9291 bslma::Allocator>::type *basicAllocator)
9292: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9293#else
9294Variant9(bslmf::MovableRef<TYPE> value,
9295 bslma::Allocator *basicAllocator)
9296: Imp(MoveUtil::move(value), basicAllocator)
9297#endif
9298{
9299}
9300
9301template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9302 class A8, class A9>
9303inline
9305Variant9(const Variant9& original, bslma::Allocator *basicAllocator)
9306: Imp(static_cast<const Imp&>(original), basicAllocator)
9307{
9308}
9309
9310template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9311 class A8, class A9>
9312inline
9315: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
9316{
9317}
9318
9319template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9320 class A8, class A9>
9321inline
9324 bslma::Allocator *basicAllocator)
9325: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
9326 basicAllocator)
9327{
9328}
9329
9330// MANIPULATORS
9331template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9332 class A8, class A9>
9333template <class TYPE>
9334inline
9337operator=(const TYPE& value)
9338{
9339 Imp::operator=(value);
9340 return *this;
9341}
9342
9343template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9344 class A8, class A9>
9345template <class TYPE>
9346inline
9347#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9348typename bsl::enable_if<
9350 typename bsl::remove_cvref<TYPE>::type>::value,
9353operator=(TYPE&& value)
9354#else
9358#endif
9359{
9360#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9361 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9362#else
9363 TYPE& lvalue = value;
9364 Imp::operator=(MoveUtil::move(lvalue));
9365#endif
9366
9367 return *this;
9368}
9369
9370template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9371 class A8, class A9>
9372inline
9375operator=(const Variant9& rhs)
9376{
9377 Imp::operator=(static_cast<const Imp&>(rhs));
9378 return *this;
9379}
9380
9381template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9382 class A8, class A9>
9383inline
9387{
9388 Variant9& lvalue = rhs;
9389
9390 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9391 return *this;
9392}
9393
9394 // --------------------
9395 // class Variant10<...>
9396 // --------------------
9397
9398// CREATORS
9399template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9400 class A8, class A9, class A10>
9401inline
9405
9406template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9407 class A8, class A9, class A10>
9408template <class TYPE_OR_ALLOCATOR>
9409inline
9411Variant10(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9412: Imp(valueOrAllocator)
9413{
9414}
9415
9416template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9417 class A8, class A9, class A10>
9418template <class TYPE>
9419inline
9421Variant10(const TYPE& value, bslma::Allocator *basicAllocator)
9422: Imp(value, basicAllocator)
9423{
9424}
9425
9426template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9427 class A8, class A9, class A10>
9428template <class TYPE>
9429inline
9431#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9432Variant10(TYPE&& value,
9433 typename bsl::enable_if<
9434 !bsl::is_same<
9435 SelfType,
9436 typename bsl::remove_const<
9437 typename bsl::remove_reference<TYPE>::type>::type>::value
9438 &&
9440 void>::type *)
9441: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9442#else
9443Variant10(bslmf::MovableRef<TYPE> value)
9444: Imp(MoveUtil::move(value))
9445#endif
9446{
9447}
9448
9449template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9450 class A8, class A9, class A10>
9451template <class TYPE>
9452inline
9454#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9455Variant10(TYPE&& value,
9456 typename bsl::enable_if<
9457 !bsl::is_same<
9458 SelfType,
9459 typename bsl::remove_const<
9460 typename bsl::remove_reference<TYPE>::type>::type>::value,
9461 bslma::Allocator>::type *basicAllocator)
9462: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9463#else
9464Variant10(bslmf::MovableRef<TYPE> value,
9465 bslma::Allocator *basicAllocator)
9466: Imp(MoveUtil::move(value), basicAllocator)
9467#endif
9468{
9469}
9470
9471template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9472 class A8, class A9, class A10>
9473inline
9475Variant10(const Variant10& original, bslma::Allocator *basicAllocator)
9476: Imp(static_cast<const Imp&>(original), basicAllocator)
9477{
9478}
9479
9480template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9481 class A8, class A9, class A10>
9482inline
9485: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
9486{
9487}
9488
9489template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9490 class A8, class A9, class A10>
9491inline
9494 bslma::Allocator *basicAllocator)
9495: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
9496 basicAllocator)
9497{
9498}
9499
9500// MANIPULATORS
9501template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9502 class A8, class A9, class A10>
9503template <class TYPE>
9504inline
9507operator=(const TYPE& value)
9508{
9509 Imp::operator=(value);
9510 return *this;
9511}
9512
9513template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9514 class A8, class A9, class A10>
9515template <class TYPE>
9516inline
9517#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9518typename bsl::enable_if<
9520 typename bsl::remove_cvref<TYPE>::type>::value,
9523operator=(TYPE&& value)
9524#else
9528#endif
9529{
9530#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9531 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9532#else
9533 TYPE& lvalue = value;
9534 Imp::operator=(MoveUtil::move(lvalue));
9535#endif
9536
9537 return *this;
9538}
9539
9540template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9541 class A8, class A9, class A10>
9542inline
9545operator=(const Variant10& rhs)
9546{
9547 Imp::operator=(static_cast<const Imp&>(rhs));
9548 return *this;
9549}
9550
9551template <class A1, class A2, class A3, class A4, class A5, class A6, class A7,
9552 class A8, class A9, class A10>
9553inline
9557{
9558 Variant10& lvalue = rhs;
9559
9560 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9561 return *this;
9562}
9563
9564 // --------------------
9565 // class Variant11<...>
9566 // --------------------
9567
9568// CREATORS
9569template <class A1, class A2, class A3, class A4, class A5, class A6,
9570 class A7, class A8, class A9, class A10, class A11>
9571inline
9576
9577template <class A1, class A2, class A3, class A4, class A5, class A6,
9578 class A7, class A8, class A9, class A10, class A11>
9579template <class TYPE_OR_ALLOCATOR>
9580inline
9582Variant11(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9583: Imp(valueOrAllocator)
9584{
9585}
9586
9587template <class A1, class A2, class A3, class A4, class A5, class A6,
9588 class A7, class A8, class A9, class A10, class A11>
9589template <class TYPE>
9590inline
9592Variant11(const TYPE& value, bslma::Allocator *basicAllocator)
9593: Imp(value, basicAllocator)
9594{
9595}
9596
9597template <class A1, class A2, class A3, class A4, class A5, class A6,
9598 class A7, class A8, class A9, class A10, class A11>
9599template <class TYPE>
9600inline
9602#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9603Variant11(TYPE&& value,
9604 typename bsl::enable_if<
9605 !bsl::is_same<
9606 SelfType,
9607 typename bsl::remove_const<
9608 typename bsl::remove_reference<TYPE>::type>::type>::value
9609 &&
9611 void>::type *)
9612: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9613#else
9614Variant11(bslmf::MovableRef<TYPE> value)
9615: Imp(MoveUtil::move(value))
9616#endif
9617{
9618}
9619
9620template <class A1, class A2, class A3, class A4, class A5, class A6,
9621 class A7, class A8, class A9, class A10, class A11>
9622template <class TYPE>
9623inline
9625#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9626Variant11(TYPE&& value,
9627 typename bsl::enable_if<
9628 !bsl::is_same<
9629 SelfType,
9630 typename bsl::remove_const<
9631 typename bsl::remove_reference<TYPE>::type>::type>::value,
9632 bslma::Allocator>::type *basicAllocator)
9633: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9634#else
9635Variant11(bslmf::MovableRef<TYPE> value,
9636 bslma::Allocator *basicAllocator)
9637: Imp(MoveUtil::move(value), basicAllocator)
9638#endif
9639{
9640}
9641
9642template <class A1, class A2, class A3, class A4, class A5, class A6,
9643 class A7, class A8, class A9, class A10, class A11>
9644inline
9646Variant11(const Variant11& original, bslma::Allocator *basicAllocator)
9647: Imp(static_cast<const Imp&>(original), basicAllocator)
9648{
9649}
9650
9651template <class A1, class A2, class A3, class A4, class A5, class A6,
9652 class A7, class A8, class A9, class A10, class A11>
9653inline
9659
9660template <class A1, class A2, class A3, class A4, class A5, class A6,
9661 class A7, class A8, class A9, class A10, class A11>
9662inline
9665 bslma::Allocator *basicAllocator)
9666: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
9667 basicAllocator)
9668{
9669}
9670
9671// MANIPULATORS
9672template <class A1, class A2, class A3, class A4, class A5, class A6,
9673 class A7, class A8, class A9, class A10, class A11>
9674template <class TYPE>
9675inline
9678operator=(const TYPE& value)
9679{
9680 Imp::operator=(value);
9681 return *this;
9682}
9683
9684template <class A1, class A2, class A3, class A4, class A5, class A6,
9685 class A7, class A8, class A9, class A10, class A11>
9686template <class TYPE>
9687inline
9688#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9689typename bsl::enable_if<
9691 typename bsl::remove_cvref<TYPE>::type>::value,
9694operator=(TYPE&& value)
9695#else
9699#endif
9700{
9701#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9702 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9703#else
9704 TYPE& lvalue = value;
9705 Imp::operator=(MoveUtil::move(lvalue));
9706#endif
9707
9708 return *this;
9709}
9710
9711template <class A1, class A2, class A3, class A4, class A5, class A6,
9712 class A7, class A8, class A9, class A10, class A11>
9713inline
9716operator=(const Variant11& rhs)
9717{
9718 Imp::operator=(static_cast<const Imp&>(rhs));
9719 return *this;
9720}
9721
9722template <class A1, class A2, class A3, class A4, class A5, class A6,
9723 class A7, class A8, class A9, class A10, class A11>
9724inline
9728{
9729 Variant11& lvalue = rhs;
9730
9731 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9732 return *this;
9733}
9734
9735 // --------------------
9736 // class Variant12<...>
9737 // --------------------
9738
9739// CREATORS
9740template <class A1, class A2, class A3, class A4, class A5, class A6,
9741 class A7, class A8, class A9, class A10, class A11, class A12>
9742inline
9747
9748template <class A1, class A2, class A3, class A4, class A5, class A6,
9749 class A7, class A8, class A9, class A10, class A11, class A12>
9750template <class TYPE_OR_ALLOCATOR>
9751inline
9753Variant12(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9754: Imp(valueOrAllocator)
9755{
9756}
9757
9758template <class A1, class A2, class A3, class A4, class A5, class A6,
9759 class A7, class A8, class A9, class A10, class A11, class A12>
9760template <class TYPE>
9761inline
9763Variant12(const TYPE& value, bslma::Allocator *basicAllocator)
9764: Imp(value, basicAllocator)
9765{
9766}
9767
9768template <class A1, class A2, class A3, class A4, class A5, class A6,
9769 class A7, class A8, class A9, class A10, class A11, class A12>
9770template <class TYPE>
9771inline
9773#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9774Variant12(TYPE&& value,
9775 typename bsl::enable_if<
9776 !bsl::is_same<
9777 SelfType,
9778 typename bsl::remove_const<
9779 typename bsl::remove_reference<TYPE>::type>::type>::value
9780 &&
9782 void>::type *)
9783: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9784#else
9785Variant12(bslmf::MovableRef<TYPE> value)
9786: Imp(MoveUtil::move(value))
9787#endif
9788{
9789}
9790
9791template <class A1, class A2, class A3, class A4, class A5, class A6,
9792 class A7, class A8, class A9, class A10, class A11, class A12>
9793template <class TYPE>
9794inline
9796#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9797Variant12(TYPE&& value,
9798 typename bsl::enable_if<
9799 !bsl::is_same<
9800 SelfType,
9801 typename bsl::remove_const<
9802 typename bsl::remove_reference<TYPE>::type>::type>::value,
9803 bslma::Allocator>::type *basicAllocator)
9804: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9805#else
9806Variant12(bslmf::MovableRef<TYPE> value,
9807 bslma::Allocator *basicAllocator)
9808: Imp(MoveUtil::move(value), basicAllocator)
9809#endif
9810{
9811}
9812
9813template <class A1, class A2, class A3, class A4, class A5, class A6,
9814 class A7, class A8, class A9, class A10, class A11, class A12>
9815inline
9817Variant12(const Variant12& original, bslma::Allocator *basicAllocator)
9818: Imp(static_cast<const Imp&>(original), basicAllocator)
9819{
9820}
9821
9822template <class A1, class A2, class A3, class A4, class A5, class A6,
9823 class A7, class A8, class A9, class A10, class A11, class A12>
9824inline
9830
9831template <class A1, class A2, class A3, class A4, class A5, class A6,
9832 class A7, class A8, class A9, class A10, class A11, class A12>
9833inline
9836 bslma::Allocator *basicAllocator)
9837: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
9838 basicAllocator)
9839{
9840}
9841
9842// MANIPULATORS
9843template <class A1, class A2, class A3, class A4, class A5, class A6,
9844 class A7, class A8, class A9, class A10, class A11, class A12>
9845template <class TYPE>
9846inline
9849operator=(const TYPE& value)
9850{
9851 Imp::operator=(value);
9852 return *this;
9853}
9854
9855template <class A1, class A2, class A3, class A4, class A5, class A6,
9856 class A7, class A8, class A9, class A10, class A11, class A12>
9857template <class TYPE>
9858inline
9859#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9860typename bsl::enable_if<
9862 typename bsl::remove_cvref<TYPE>::type>::value,
9865operator=(TYPE&& value)
9866#else
9870#endif
9871{
9872#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9873 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
9874#else
9875 TYPE& lvalue = value;
9876 Imp::operator=(MoveUtil::move(lvalue));
9877#endif
9878
9879 return *this;
9880}
9881
9882template <class A1, class A2, class A3, class A4, class A5, class A6,
9883 class A7, class A8, class A9, class A10, class A11, class A12>
9884inline
9887operator=(const Variant12& rhs)
9888{
9889 Imp::operator=(static_cast<const Imp&>(rhs));
9890 return *this;
9891}
9892
9893template <class A1, class A2, class A3, class A4, class A5, class A6,
9894 class A7, class A8, class A9, class A10, class A11, class A12>
9895inline
9899{
9900 Variant12& lvalue = rhs;
9901
9902 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
9903 return *this;
9904}
9905
9906 // --------------------
9907 // class Variant13<...>
9908 // --------------------
9909
9910// CREATORS
9911template <class A1, class A2, class A3, class A4, class A5, class A6,
9912 class A7, class A8, class A9, class A10, class A11, class A12,
9913 class A13>
9914inline
9919
9920template <class A1, class A2, class A3, class A4, class A5, class A6,
9921 class A7, class A8, class A9, class A10, class A11, class A12,
9922 class A13>
9923template <class TYPE_OR_ALLOCATOR>
9924inline
9926Variant13(const TYPE_OR_ALLOCATOR& valueOrAllocator)
9927: Imp(valueOrAllocator)
9928{
9929}
9930
9931template <class A1, class A2, class A3, class A4, class A5, class A6,
9932 class A7, class A8, class A9, class A10, class A11, class A12,
9933 class A13>
9934template <class TYPE>
9935inline
9937Variant13(const TYPE& value, bslma::Allocator *basicAllocator)
9938: Imp(value, basicAllocator)
9939{
9940}
9941
9942template <class A1, class A2, class A3, class A4, class A5, class A6,
9943 class A7, class A8, class A9, class A10, class A11, class A12,
9944 class A13>
9945template <class TYPE>
9946inline
9948#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9949Variant13(TYPE&& value,
9950 typename bsl::enable_if<
9951 !bsl::is_same<
9952 SelfType,
9953 typename bsl::remove_const<
9954 typename bsl::remove_reference<TYPE>::type>::type>::value
9955 &&
9957 void>::type *)
9958: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
9959#else
9960Variant13(bslmf::MovableRef<TYPE> value)
9961: Imp(MoveUtil::move(value))
9962#endif
9963{
9964}
9965
9966template <class A1, class A2, class A3, class A4, class A5, class A6,
9967 class A7, class A8, class A9, class A10, class A11, class A12,
9968 class A13>
9969template <class TYPE>
9970inline
9972#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
9973Variant13(TYPE&& value,
9974 typename bsl::enable_if<
9975 !bsl::is_same<
9976 SelfType,
9977 typename bsl::remove_const<
9978 typename bsl::remove_reference<TYPE>::type>::type>::value,
9979 bslma::Allocator>::type *basicAllocator)
9980: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
9981#else
9982Variant13(bslmf::MovableRef<TYPE> value,
9983 bslma::Allocator *basicAllocator)
9984: Imp(MoveUtil::move(value), basicAllocator)
9985#endif
9986{
9987}
9988
9989template <class A1, class A2, class A3, class A4, class A5, class A6,
9990 class A7, class A8, class A9, class A10, class A11, class A12,
9991 class A13>
9992inline
9994Variant13(const Variant13& original, bslma::Allocator *basicAllocator)
9995: Imp(static_cast<const Imp&>(original), basicAllocator)
9996{
9997}
9998
9999template <class A1, class A2, class A3, class A4, class A5, class A6,
10000 class A7, class A8, class A9, class A10, class A11, class A12,
10001 class A13>
10002inline
10008
10009template <class A1, class A2, class A3, class A4, class A5, class A6,
10010 class A7, class A8, class A9, class A10, class A11, class A12,
10011 class A13>
10012inline
10015 bslma::Allocator *basicAllocator)
10016: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10017 basicAllocator)
10018{
10019}
10020
10021// MANIPULATORS
10022template <class A1, class A2, class A3, class A4, class A5, class A6,
10023 class A7, class A8, class A9, class A10, class A11, class A12,
10024 class A13>
10025template <class TYPE>
10026inline
10029operator=(const TYPE& value)
10030{
10031 Imp::operator=(value);
10032 return *this;
10033}
10034
10035template <class A1, class A2, class A3, class A4, class A5, class A6,
10036 class A7, class A8, class A9, class A10, class A11, class A12,
10037 class A13>
10038template <class TYPE>
10039inline
10040#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10041typename bsl::enable_if<
10042 !bsl::is_same<Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
10043 A13>,
10044 typename bsl::remove_cvref<TYPE>::type>::value,
10047operator=(TYPE&& value)
10048#else
10052#endif
10053{
10054#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10055 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
10056#else
10057 TYPE& lvalue = value;
10058 Imp::operator=(MoveUtil::move(lvalue));
10059#endif
10060
10061 return *this;
10062}
10063
10064template <class A1, class A2, class A3, class A4, class A5, class A6,
10065 class A7, class A8, class A9, class A10, class A11, class A12,
10066 class A13>
10067inline
10070operator=(const Variant13& rhs)
10071{
10072 Imp::operator=(static_cast<const Imp&>(rhs));
10073 return *this;
10074}
10075
10076template <class A1, class A2, class A3, class A4, class A5, class A6,
10077 class A7, class A8, class A9, class A10, class A11, class A12,
10078 class A13>
10079inline
10083{
10084 Variant13& lvalue = rhs;
10085
10086 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
10087 return *this;
10088}
10089
10090 // --------------------
10091 // class Variant14<...>
10092 // --------------------
10093
10094// CREATORS
10095template <class A1, class A2, class A3, class A4, class A5, class A6,
10096 class A7, class A8, class A9, class A10, class A11, class A12,
10097 class A13, class A14>
10098inline
10103
10104template <class A1, class A2, class A3, class A4, class A5, class A6,
10105 class A7, class A8, class A9, class A10, class A11, class A12,
10106 class A13, class A14>
10107template <class TYPE_OR_ALLOCATOR>
10108inline
10110Variant14(const TYPE_OR_ALLOCATOR& valueOrAllocator)
10111: Imp(valueOrAllocator)
10112{
10113}
10114
10115template <class A1, class A2, class A3, class A4, class A5, class A6,
10116 class A7, class A8, class A9, class A10, class A11, class A12,
10117 class A13, class A14>
10118template <class TYPE>
10119inline
10121Variant14(const TYPE& value, bslma::Allocator *basicAllocator)
10122: Imp(value, basicAllocator)
10123{
10124}
10125
10126template <class A1, class A2, class A3, class A4, class A5, class A6,
10127 class A7, class A8, class A9, class A10, class A11, class A12,
10128 class A13, class A14>
10129template <class TYPE>
10130inline
10132#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10133Variant14(TYPE&& value,
10134 typename bsl::enable_if<
10135 !bsl::is_same<
10136 SelfType,
10137 typename bsl::remove_const<
10138 typename bsl::remove_reference<TYPE>::type>::type>::value
10139 &&
10141 void>::type *)
10142: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
10143#else
10144Variant14(bslmf::MovableRef<TYPE> value)
10145: Imp(MoveUtil::move(value))
10146#endif
10147{
10148}
10149
10150template <class A1, class A2, class A3, class A4, class A5, class A6,
10151 class A7, class A8, class A9, class A10, class A11, class A12,
10152 class A13, class A14>
10153template <class TYPE>
10154inline
10156#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10157Variant14(TYPE&& value,
10158 typename bsl::enable_if<
10159 !bsl::is_same<
10160 SelfType,
10161 typename bsl::remove_const<
10162 typename bsl::remove_reference<TYPE>::type>::type>::value,
10163 bslma::Allocator>::type *basicAllocator)
10164: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
10165#else
10166Variant14(bslmf::MovableRef<TYPE> value,
10167 bslma::Allocator *basicAllocator)
10168: Imp(MoveUtil::move(value), basicAllocator)
10169#endif
10170{
10171}
10172
10173template <class A1, class A2, class A3, class A4, class A5, class A6,
10174 class A7, class A8, class A9, class A10, class A11, class A12,
10175 class A13, class A14>
10176inline
10178Variant14(const Variant14& original, bslma::Allocator *basicAllocator)
10179: Imp(static_cast<const Imp&>(original), basicAllocator)
10180{
10181}
10182
10183template <class A1, class A2, class A3, class A4, class A5, class A6,
10184 class A7, class A8, class A9, class A10, class A11, class A12,
10185 class A13, class A14>
10186inline
10192
10193template <class A1, class A2, class A3, class A4, class A5, class A6,
10194 class A7, class A8, class A9, class A10, class A11, class A12,
10195 class A13, class A14>
10196inline
10199 bslma::Allocator *basicAllocator)
10200: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10201 basicAllocator)
10202{
10203}
10204
10205// MANIPULATORS
10206template <class A1, class A2, class A3, class A4, class A5, class A6,
10207 class A7, class A8, class A9, class A10, class A11, class A12,
10208 class A13, class A14>
10209template <class TYPE>
10210inline
10213operator=(const TYPE& value)
10214{
10215 Imp::operator=(value);
10216 return *this;
10217}
10218
10219template <class A1, class A2, class A3, class A4, class A5, class A6,
10220 class A7, class A8, class A9, class A10, class A11, class A12,
10221 class A13, class A14>
10222template <class TYPE>
10223inline
10224#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10225typename bsl::enable_if<
10226 !bsl::is_same<Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
10227 A13, A14>,
10228 typename bsl::remove_cvref<TYPE>::type>::value,
10231operator=(TYPE&& value)
10232#else
10236#endif
10237{
10238#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10239 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
10240#else
10241 TYPE& lvalue = value;
10242 Imp::operator=(MoveUtil::move(lvalue));
10243#endif
10244
10245 return *this;
10246}
10247
10248template <class A1, class A2, class A3, class A4, class A5, class A6,
10249 class A7, class A8, class A9, class A10, class A11, class A12,
10250 class A13, class A14>
10251inline
10254operator=(const Variant14& rhs)
10255{
10256 Imp::operator=(static_cast<const Imp&>(rhs));
10257 return *this;
10258}
10259
10260template <class A1, class A2, class A3, class A4, class A5, class A6,
10261 class A7, class A8, class A9, class A10, class A11, class A12,
10262 class A13, class A14>
10263inline
10267{
10268 Variant14& lvalue = rhs;
10269
10270 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
10271 return *this;
10272}
10273
10274 // --------------------
10275 // class Variant15<...>
10276 // --------------------
10277
10278// CREATORS
10279template <class A1, class A2, class A3, class A4, class A5, class A6,
10280 class A7, class A8, class A9, class A10, class A11, class A12,
10281 class A13, class A14, class A15>
10282inline
10287
10288template <class A1, class A2, class A3, class A4, class A5, class A6,
10289 class A7, class A8, class A9, class A10, class A11, class A12,
10290 class A13, class A14, class A15>
10291template <class TYPE_OR_ALLOCATOR>
10292inline
10294Variant15(const TYPE_OR_ALLOCATOR& valueOrAllocator)
10295: Imp(valueOrAllocator)
10296{
10297}
10298
10299template <class A1, class A2, class A3, class A4, class A5, class A6,
10300 class A7, class A8, class A9, class A10, class A11, class A12,
10301 class A13, class A14, class A15>
10302template <class TYPE>
10303inline
10305Variant15(const TYPE& value, bslma::Allocator *basicAllocator)
10306: Imp(value, basicAllocator)
10307{
10308}
10309
10310template <class A1, class A2, class A3, class A4, class A5, class A6,
10311 class A7, class A8, class A9, class A10, class A11, class A12,
10312 class A13, class A14, class A15>
10313template <class TYPE>
10314inline
10316#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10317Variant15(TYPE&& value,
10318 typename bsl::enable_if<
10319 !bsl::is_same<
10320 SelfType,
10321 typename bsl::remove_const<
10322 typename bsl::remove_reference<TYPE>::type>::type>::value
10323 &&
10325 void>::type *)
10326: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
10327#else
10328Variant15(bslmf::MovableRef<TYPE> value)
10329: Imp(MoveUtil::move(value))
10330#endif
10331{
10332}
10333
10334template <class A1, class A2, class A3, class A4, class A5, class A6,
10335 class A7, class A8, class A9, class A10, class A11, class A12,
10336 class A13, class A14, class A15>
10337template <class TYPE>
10338inline
10340#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10341Variant15(TYPE&& value,
10342 typename bsl::enable_if<
10343 !bsl::is_same<
10344 SelfType,
10345 typename bsl::remove_const<
10346 typename bsl::remove_reference<TYPE>::type>::type>::value,
10347 bslma::Allocator>::type *basicAllocator)
10348: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
10349#else
10350Variant15(bslmf::MovableRef<TYPE> value,
10351 bslma::Allocator *basicAllocator)
10352: Imp(MoveUtil::move(value), basicAllocator)
10353#endif
10354{
10355}
10356
10357template <class A1, class A2, class A3, class A4, class A5, class A6,
10358 class A7, class A8, class A9, class A10, class A11, class A12,
10359 class A13, class A14, class A15>
10360inline
10362Variant15(const Variant15& original, bslma::Allocator *basicAllocator)
10363: Imp(static_cast<const Imp&>(original), basicAllocator)
10364{
10365}
10366
10367template <class A1, class A2, class A3, class A4, class A5, class A6,
10368 class A7, class A8, class A9, class A10, class A11, class A12,
10369 class A13, class A14, class A15>
10370inline
10376
10377template <class A1, class A2, class A3, class A4, class A5, class A6,
10378 class A7, class A8, class A9, class A10, class A11, class A12,
10379 class A13, class A14, class A15>
10380inline
10383 bslma::Allocator *basicAllocator)
10384: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10385 basicAllocator)
10386{
10387}
10388
10389// MANIPULATORS
10390template <class A1, class A2, class A3, class A4, class A5, class A6,
10391 class A7, class A8, class A9, class A10, class A11, class A12,
10392 class A13, class A14, class A15>
10393template <class TYPE>
10394inline
10397operator=(const TYPE& value)
10398{
10399 Imp::operator=(value);
10400 return *this;
10401}
10402
10403template <class A1, class A2, class A3, class A4, class A5, class A6,
10404 class A7, class A8, class A9, class A10, class A11, class A12,
10405 class A13, class A14, class A15>
10406template <class TYPE>
10407inline
10408#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10409typename bsl::enable_if<
10410 !bsl::is_same<Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,
10411 A12, A13, A14, A15>,
10412 typename bsl::remove_cvref<TYPE>::type>::value,
10413Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10414 A15> >::type&
10416operator=(TYPE&& value)
10417#else
10421#endif
10422{
10423#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10424 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
10425#else
10426 TYPE& lvalue = value;
10427 Imp::operator=(MoveUtil::move(lvalue));
10428#endif
10429
10430 return *this;
10431}
10432
10433template <class A1, class A2, class A3, class A4, class A5, class A6,
10434 class A7, class A8, class A9, class A10, class A11, class A12,
10435 class A13, class A14, class A15>
10436inline
10439operator=(const Variant15& rhs)
10440{
10441 Imp::operator=(static_cast<const Imp&>(rhs));
10442 return *this;
10443}
10444
10445template <class A1, class A2, class A3, class A4, class A5, class A6,
10446 class A7, class A8, class A9, class A10, class A11, class A12,
10447 class A13, class A14, class A15>
10448inline
10452{
10453 Variant15& lvalue = rhs;
10454
10455 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
10456 return *this;
10457}
10458
10459 // --------------------
10460 // class Variant16<...>
10461 // --------------------
10462
10463// CREATORS
10464template <class A1, class A2, class A3, class A4, class A5, class A6,
10465 class A7, class A8, class A9, class A10, class A11, class A12,
10466 class A13, class A14, class A15, class A16>
10467inline
10468Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10469 A15, A16>::
10470Variant16()
10471{
10472}
10473
10474template <class A1, class A2, class A3, class A4, class A5, class A6,
10475 class A7, class A8, class A9, class A10, class A11, class A12,
10476 class A13, class A14, class A15, class A16>
10477template <class TYPE_OR_ALLOCATOR>
10478inline
10479Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10480 A15, A16>::
10481Variant16(const TYPE_OR_ALLOCATOR& valueOrAllocator)
10482: Imp(valueOrAllocator)
10483{
10484}
10485
10486template <class A1, class A2, class A3, class A4, class A5, class A6,
10487 class A7, class A8, class A9, class A10, class A11, class A12,
10488 class A13, class A14, class A15, class A16>
10489template <class TYPE>
10490inline
10491Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10492 A15, A16>::
10493Variant16(const TYPE& value, bslma::Allocator *basicAllocator)
10494: Imp(value, basicAllocator)
10495{
10496}
10497
10498template <class A1, class A2, class A3, class A4, class A5, class A6,
10499 class A7, class A8, class A9, class A10, class A11, class A12,
10500 class A13, class A14, class A15, class A16>
10501template <class TYPE>
10502inline
10503Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10504 A15, A16>::
10505#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10506Variant16(TYPE&& value,
10507 typename bsl::enable_if<
10508 !bsl::is_same<
10509 SelfType,
10510 typename bsl::remove_const<
10511 typename bsl::remove_reference<TYPE>::type>::type>::value
10512 &&
10514 void>::type *)
10515: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
10516#else
10517Variant16(bslmf::MovableRef<TYPE> value)
10518: Imp(MoveUtil::move(value))
10519#endif
10520{
10521}
10522
10523template <class A1, class A2, class A3, class A4, class A5, class A6,
10524 class A7, class A8, class A9, class A10, class A11, class A12,
10525 class A13, class A14, class A15, class A16>
10526template <class TYPE>
10527inline
10528Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10529 A15, A16>::
10530#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10531Variant16(TYPE&& value,
10532 typename bsl::enable_if<
10533 !bsl::is_same<
10534 SelfType,
10535 typename bsl::remove_const<
10536 typename bsl::remove_reference<TYPE>::type>::type>::value,
10537 bslma::Allocator>::type *basicAllocator)
10538: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
10539#else
10540Variant16(bslmf::MovableRef<TYPE> value,
10541 bslma::Allocator *basicAllocator)
10542: Imp(MoveUtil::move(value), basicAllocator)
10543#endif
10544{
10545}
10546
10547template <class A1, class A2, class A3, class A4, class A5, class A6,
10548 class A7, class A8, class A9, class A10, class A11, class A12,
10549 class A13, class A14, class A15, class A16>
10550inline
10551Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10552 A15, A16>::
10553Variant16(const Variant16& original, bslma::Allocator *basicAllocator)
10554: Imp(static_cast<const Imp&>(original), basicAllocator)
10555{
10556}
10557
10558template <class A1, class A2, class A3, class A4, class A5, class A6,
10559 class A7, class A8, class A9, class A10, class A11, class A12,
10560 class A13, class A14, class A15, class A16>
10561inline
10562Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10563 A15, A16>::
10564Variant16(bslmf::MovableRef<Variant16> original)
10565: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
10566{
10567}
10568
10569template <class A1, class A2, class A3, class A4, class A5, class A6,
10570 class A7, class A8, class A9, class A10, class A11, class A12,
10571 class A13, class A14, class A15, class A16>
10572inline
10573Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10574 A15, A16>::
10575Variant16(bslmf::MovableRef<Variant16> original,
10576 bslma::Allocator *basicAllocator)
10577: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10578 basicAllocator)
10579{
10580}
10581
10582// MANIPULATORS
10583template <class A1, class A2, class A3, class A4, class A5, class A6,
10584 class A7, class A8, class A9, class A10, class A11, class A12,
10585 class A13, class A14, class A15, class A16>
10586template <class TYPE>
10587inline
10588Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10589 A15, A16>&
10590Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10591 A15, A16>::
10592operator=(const TYPE& value)
10593{
10594 Imp::operator=(value);
10595 return *this;
10596}
10597
10598template <class A1, class A2, class A3, class A4, class A5, class A6,
10599 class A7, class A8, class A9, class A10, class A11, class A12,
10600 class A13, class A14, class A15, class A16>
10601template <class TYPE>
10602inline
10603#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10604typename bsl::enable_if<
10605 !bsl::is_same<Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,
10606 A12, A13, A14, A15, A16>,
10607 typename bsl::remove_cvref<TYPE>::type>::value,
10608Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10609 A16> >::type&
10610Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10611 A16>::operator=(TYPE&& value)
10612#else
10613Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10614 A16>&
10615Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10616 A16>::operator=(bslmf::MovableRef<TYPE> value)
10617#endif
10618{
10619#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10620 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
10621#else
10622 TYPE& lvalue = value;
10623 Imp::operator=(MoveUtil::move(lvalue));
10624#endif
10625
10626 return *this;
10627}
10628
10629template <class A1, class A2, class A3, class A4, class A5, class A6,
10630 class A7, class A8, class A9, class A10, class A11, class A12,
10631 class A13, class A14, class A15, class A16>
10632inline
10633Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10634 A15, A16>&
10635Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10636 A15, A16>::
10637operator=(const Variant16& rhs)
10638{
10639 Imp::operator=(static_cast<const Imp&>(rhs));
10640 return *this;
10641}
10642
10643template <class A1, class A2, class A3, class A4, class A5, class A6,
10644 class A7, class A8, class A9, class A10, class A11, class A12,
10645 class A13, class A14, class A15, class A16>
10646inline
10647Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10648 A15, A16>&
10649Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10650 A15, A16>::
10651operator=(bslmf::MovableRef<Variant16> rhs)
10652{
10653 Variant16& lvalue = rhs;
10654
10655 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
10656 return *this;
10657}
10658
10659 // --------------------
10660 // class Variant17<...>
10661 // --------------------
10662
10663// CREATORS
10664template <class A1, class A2, class A3, class A4, class A5, class A6,
10665 class A7, class A8, class A9, class A10, class A11, class A12,
10666 class A13, class A14, class A15, class A16, class A17>
10667inline
10668Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10669 A15, A16, A17>::
10670Variant17()
10671{
10672}
10673
10674template <class A1, class A2, class A3, class A4, class A5, class A6,
10675 class A7, class A8, class A9, class A10, class A11, class A12,
10676 class A13, class A14, class A15, class A16, class A17>
10677template <class TYPE_OR_ALLOCATOR>
10678inline
10679Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10680 A15, A16, A17>::
10681Variant17(const TYPE_OR_ALLOCATOR& valueOrAllocator)
10682: Imp(valueOrAllocator)
10683{
10684}
10685
10686template <class A1, class A2, class A3, class A4, class A5, class A6,
10687 class A7, class A8, class A9, class A10, class A11, class A12,
10688 class A13, class A14, class A15, class A16, class A17>
10689template <class TYPE>
10690inline
10691Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10692 A15, A16, A17>::
10693Variant17(const TYPE& value, bslma::Allocator *basicAllocator)
10694: Imp(value, basicAllocator)
10695{
10696}
10697
10698template <class A1, class A2, class A3, class A4, class A5, class A6,
10699 class A7, class A8, class A9, class A10, class A11, class A12,
10700 class A13, class A14, class A15, class A16, class A17>
10701template <class TYPE>
10702inline
10703Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10704 A15, A16, A17>::
10705#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10706Variant17(TYPE&& value,
10707 typename bsl::enable_if<
10708 !bsl::is_same<
10709 SelfType,
10710 typename bsl::remove_const<
10711 typename bsl::remove_reference<TYPE>::type>::type>::value
10712 &&
10714 void>::type *)
10715: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
10716#else
10717Variant17(bslmf::MovableRef<TYPE> value)
10718: Imp(MoveUtil::move(value))
10719#endif
10720{
10721}
10722
10723template <class A1, class A2, class A3, class A4, class A5, class A6,
10724 class A7, class A8, class A9, class A10, class A11, class A12,
10725 class A13, class A14, class A15, class A16, class A17>
10726template <class TYPE>
10727inline
10728Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10729 A15, A16, A17>::
10730#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10731Variant17(TYPE&& value,
10732 typename bsl::enable_if<
10733 !bsl::is_same<
10734 SelfType,
10735 typename bsl::remove_const<
10736 typename bsl::remove_reference<TYPE>::type>::type>::value,
10737 bslma::Allocator>::type *basicAllocator)
10738: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
10739#else
10740Variant17(bslmf::MovableRef<TYPE> value,
10741 bslma::Allocator *basicAllocator)
10742: Imp(MoveUtil::move(value), basicAllocator)
10743#endif
10744{
10745}
10746
10747template <class A1, class A2, class A3, class A4, class A5, class A6,
10748 class A7, class A8, class A9, class A10, class A11, class A12,
10749 class A13, class A14, class A15, class A16, class A17>
10750inline
10751Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10752 A15, A16, A17>::
10753Variant17(const Variant17& original, bslma::Allocator *basicAllocator)
10754: Imp(static_cast<const Imp&>(original), basicAllocator)
10755{
10756}
10757
10758template <class A1, class A2, class A3, class A4, class A5, class A6,
10759 class A7, class A8, class A9, class A10, class A11, class A12,
10760 class A13, class A14, class A15, class A16, class A17>
10761inline
10762Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10763 A15, A16, A17>::
10764Variant17(bslmf::MovableRef<Variant17> original)
10765: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
10766{
10767}
10768
10769template <class A1, class A2, class A3, class A4, class A5, class A6,
10770 class A7, class A8, class A9, class A10, class A11, class A12,
10771 class A13, class A14, class A15, class A16, class A17>
10772inline
10773Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10774 A15, A16, A17>::
10775Variant17(bslmf::MovableRef<Variant17> original,
10776 bslma::Allocator *basicAllocator)
10777: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10778 basicAllocator)
10779{
10780}
10781
10782// MANIPULATORS
10783template <class A1, class A2, class A3, class A4, class A5, class A6,
10784 class A7, class A8, class A9, class A10, class A11, class A12,
10785 class A13, class A14, class A15, class A16, class A17>
10786template <class TYPE>
10787inline
10788Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10789 A15, A16, A17>&
10790Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10791 A15, A16, A17>::
10792operator=(const TYPE& value)
10793{
10794 Imp::operator=(value);
10795 return *this;
10796}
10797
10798template <class A1, class A2, class A3, class A4, class A5, class A6,
10799 class A7, class A8, class A9, class A10, class A11, class A12,
10800 class A13, class A14, class A15, class A16, class A17>
10801template <class TYPE>
10802inline
10803#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10804typename bsl::enable_if<
10805 !bsl::is_same<Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,
10806 A12, A13, A14, A15, A16, A17>,
10807 typename bsl::remove_cvref<TYPE>::type>::value,
10808Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10809 A16, A17> >::type&
10810Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10811 A16, A17>::operator=(TYPE&& value)
10812#else
10813Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10814 A16, A17>&
10815Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
10816 A16, A17>::operator=(bslmf::MovableRef<TYPE> value)
10817#endif
10818{
10819#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10820 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
10821#else
10822 TYPE& lvalue = value;
10823 Imp::operator=(MoveUtil::move(lvalue));
10824#endif
10825
10826 return *this;
10827}
10828
10829template <class A1, class A2, class A3, class A4, class A5, class A6,
10830 class A7, class A8, class A9, class A10, class A11, class A12,
10831 class A13, class A14, class A15, class A16, class A17>
10832inline
10833Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10834 A15, A16, A17>&
10835Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10836 A15, A16, A17>::
10837operator=(const Variant17& rhs)
10838{
10839 Imp::operator=(static_cast<const Imp&>(rhs));
10840 return *this;
10841}
10842
10843template <class A1, class A2, class A3, class A4, class A5, class A6,
10844 class A7, class A8, class A9, class A10, class A11, class A12,
10845 class A13, class A14, class A15, class A16, class A17>
10846inline
10847Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10848 A15, A16, A17>&
10849Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10850 A15, A16, A17>::
10851operator=(bslmf::MovableRef<Variant17> rhs)
10852{
10853 Variant17& lvalue = rhs;
10854
10855 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
10856 return *this;
10857}
10858
10859 // --------------------
10860 // class Variant18<...>
10861 // --------------------
10862
10863// CREATORS
10864template <class A1, class A2, class A3, class A4, class A5, class A6,
10865 class A7, class A8, class A9, class A10, class A11, class A12,
10866 class A13, class A14, class A15, class A16, class A17, class A18>
10867inline
10868Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10869 A15, A16, A17, A18>::
10870Variant18()
10871{
10872}
10873
10874template <class A1, class A2, class A3, class A4, class A5, class A6,
10875 class A7, class A8, class A9, class A10, class A11, class A12,
10876 class A13, class A14, class A15, class A16, class A17, class A18>
10877template <class TYPE_OR_ALLOCATOR>
10878inline
10879Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10880 A15, A16, A17, A18>::
10881Variant18(const TYPE_OR_ALLOCATOR& valueOrAllocator)
10882: Imp(valueOrAllocator)
10883{
10884}
10885
10886template <class A1, class A2, class A3, class A4, class A5, class A6,
10887 class A7, class A8, class A9, class A10, class A11, class A12,
10888 class A13, class A14, class A15, class A16, class A17, class A18>
10889template <class TYPE>
10890inline
10891Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10892 A15, A16, A17, A18>::
10893Variant18(const TYPE& value, bslma::Allocator *basicAllocator)
10894: Imp(value, basicAllocator)
10895{
10896}
10897
10898template <class A1, class A2, class A3, class A4, class A5, class A6,
10899 class A7, class A8, class A9, class A10, class A11, class A12,
10900 class A13, class A14, class A15, class A16, class A17, class A18>
10901template <class TYPE>
10902inline
10903Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10904 A15, A16, A17, A18>::
10905#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10906Variant18(TYPE&& value,
10907 typename bsl::enable_if<
10908 !bsl::is_same<
10909 SelfType,
10910 typename bsl::remove_const<
10911 typename bsl::remove_reference<TYPE>::type>::type>::value
10912 &&
10914 void>::type *)
10915: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
10916#else
10917Variant18(bslmf::MovableRef<TYPE> value)
10918: Imp(MoveUtil::move(value))
10919#endif
10920{
10921}
10922
10923template <class A1, class A2, class A3, class A4, class A5, class A6,
10924 class A7, class A8, class A9, class A10, class A11, class A12,
10925 class A13, class A14, class A15, class A16, class A17, class A18>
10926template <class TYPE>
10927inline
10928Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10929 A15, A16, A17, A18>::
10930#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
10931Variant18(TYPE&& value,
10932 typename bsl::enable_if<
10933 !bsl::is_same<
10934 SelfType,
10935 typename bsl::remove_const<
10936 typename bsl::remove_reference<TYPE>::type>::type>::value,
10937 bslma::Allocator>::type *basicAllocator)
10938: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
10939#else
10940Variant18(bslmf::MovableRef<TYPE> value,
10941 bslma::Allocator *basicAllocator)
10942: Imp(MoveUtil::move(value), basicAllocator)
10943#endif
10944{
10945}
10946
10947template <class A1, class A2, class A3, class A4, class A5, class A6,
10948 class A7, class A8, class A9, class A10, class A11, class A12,
10949 class A13, class A14, class A15, class A16, class A17, class A18>
10950inline
10951Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10952 A15, A16, A17, A18>::
10953Variant18(const Variant18& original, bslma::Allocator *basicAllocator)
10954: Imp(static_cast<const Imp&>(original), basicAllocator)
10955{
10956}
10957
10958template <class A1, class A2, class A3, class A4, class A5, class A6,
10959 class A7, class A8, class A9, class A10, class A11, class A12,
10960 class A13, class A14, class A15, class A16, class A17, class A18>
10961inline
10962Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10963 A15, A16, A17, A18>::
10964Variant18(bslmf::MovableRef<Variant18> original)
10965: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
10966{
10967}
10968
10969template <class A1, class A2, class A3, class A4, class A5, class A6,
10970 class A7, class A8, class A9, class A10, class A11, class A12,
10971 class A13, class A14, class A15, class A16, class A17, class A18>
10972inline
10973Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10974 A15, A16, A17, A18>::
10975Variant18(bslmf::MovableRef<Variant18> original,
10976 bslma::Allocator *basicAllocator)
10977: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
10978 basicAllocator)
10979{
10980}
10981
10982// MANIPULATORS
10983template <class A1, class A2, class A3, class A4, class A5, class A6,
10984 class A7, class A8, class A9, class A10, class A11, class A12,
10985 class A13, class A14, class A15, class A16, class A17, class A18>
10986template <class TYPE>
10987inline
10988Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10989 A15, A16, A17, A18>&
10990Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
10991 A15, A16, A17, A18>::
10992operator=(const TYPE& value)
10993{
10994 Imp::operator=(value);
10995 return *this;
10996}
10997
10998template <class A1, class A2, class A3, class A4, class A5, class A6,
10999 class A7, class A8, class A9, class A10, class A11, class A12,
11000 class A13, class A14, class A15, class A16, class A17, class A18>
11001template <class TYPE>
11002inline
11003#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11004typename bsl::enable_if<
11005 !bsl::is_same<Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
11006 A11, A12, A13, A14, A15, A16, A17, A18>,
11007 typename bsl::remove_cvref<TYPE>::type>::value,
11008Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11009 A16, A17, A18> >::type&
11010Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11011 A16, A17, A18>::operator=(TYPE&& value)
11012#else
11013Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11014 A16, A17, A18>&
11015Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11016 A16, A17, A18>::operator=(bslmf::MovableRef<TYPE> value)
11017#endif
11018{
11019#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11020 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
11021#else
11022 TYPE& lvalue = value;
11023 Imp::operator=(MoveUtil::move(lvalue));
11024#endif
11025
11026 return *this;
11027}
11028
11029template <class A1, class A2, class A3, class A4, class A5, class A6,
11030 class A7, class A8, class A9, class A10, class A11, class A12,
11031 class A13, class A14, class A15, class A16, class A17, class A18>
11032inline
11033Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11034 A15, A16, A17, A18>&
11035Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11036 A15, A16, A17, A18>::
11037operator=(const Variant18& rhs)
11038{
11039 Imp::operator=(static_cast<const Imp&>(rhs));
11040 return *this;
11041}
11042
11043template <class A1, class A2, class A3, class A4, class A5, class A6,
11044 class A7, class A8, class A9, class A10, class A11, class A12,
11045 class A13, class A14, class A15, class A16, class A17, class A18>
11046inline
11047Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11048 A15, A16, A17, A18>&
11049Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11050 A15, A16, A17, A18>::
11051operator=(bslmf::MovableRef<Variant18> rhs)
11052{
11053 Variant18& lvalue = rhs;
11054
11055 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
11056 return *this;
11057}
11058
11059 // --------------------
11060 // class Variant19<...>
11061 // --------------------
11062
11063// CREATORS
11064template <class A1, class A2, class A3, class A4, class A5, class A6,
11065 class A7, class A8, class A9, class A10, class A11, class A12,
11066 class A13, class A14, class A15, class A16, class A17, class A18,
11067 class A19>
11068inline
11069Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11070 A15, A16, A17, A18, A19>::
11071Variant19()
11072{
11073}
11074
11075template <class A1, class A2, class A3, class A4, class A5, class A6,
11076 class A7, class A8, class A9, class A10, class A11, class A12,
11077 class A13, class A14, class A15, class A16, class A17, class A18,
11078 class A19>
11079template <class TYPE_OR_ALLOCATOR>
11080inline
11081Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11082 A15, A16, A17, A18, A19>::
11083Variant19(const TYPE_OR_ALLOCATOR& valueOrAllocator)
11084: Imp(valueOrAllocator)
11085{
11086}
11087
11088template <class A1, class A2, class A3, class A4, class A5, class A6,
11089 class A7, class A8, class A9, class A10, class A11, class A12,
11090 class A13, class A14, class A15, class A16, class A17, class A18,
11091 class A19>
11092template <class TYPE>
11093inline
11094Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11095 A15, A16, A17, A18, A19>::
11096Variant19(const TYPE& value, bslma::Allocator *basicAllocator)
11097: Imp(value, basicAllocator)
11098{
11099}
11100
11101template <class A1, class A2, class A3, class A4, class A5, class A6,
11102 class A7, class A8, class A9, class A10, class A11, class A12,
11103 class A13, class A14, class A15, class A16, class A17, class A18,
11104 class A19>
11105template <class TYPE>
11106inline
11107Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11108 A15, A16, A17, A18, A19>::
11109#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11110Variant19(TYPE&& value,
11111 typename bsl::enable_if<
11112 !bsl::is_same<
11113 SelfType,
11114 typename bsl::remove_const<
11115 typename bsl::remove_reference<TYPE>::type>::type>::value
11116 &&
11118 void>::type *)
11119: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value))
11120#else
11121Variant19(bslmf::MovableRef<TYPE> value)
11122: Imp(MoveUtil::move(value))
11123#endif
11124{
11125}
11126
11127template <class A1, class A2, class A3, class A4, class A5, class A6,
11128 class A7, class A8, class A9, class A10, class A11, class A12,
11129 class A13, class A14, class A15, class A16, class A17, class A18,
11130 class A19>
11131template <class TYPE>
11132inline
11133Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11134 A15, A16, A17, A18, A19>::
11135#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11136Variant19(TYPE&& value,
11137 typename bsl::enable_if<
11138 !bsl::is_same<
11139 SelfType,
11140 typename bsl::remove_const<
11141 typename bsl::remove_reference<TYPE>::type>::type>::value,
11142 bslma::Allocator>::type *basicAllocator)
11143: Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator)
11144#else
11145Variant19(bslmf::MovableRef<TYPE> value,
11146 bslma::Allocator *basicAllocator)
11147: Imp(MoveUtil::move(value), basicAllocator)
11148#endif
11149{
11150}
11151
11152template <class A1, class A2, class A3, class A4, class A5, class A6,
11153 class A7, class A8, class A9, class A10, class A11, class A12,
11154 class A13, class A14, class A15, class A16, class A17, class A18,
11155 class A19>
11156inline
11157Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11158 A15, A16, A17, A18, A19>::
11159Variant19(const Variant19& original, bslma::Allocator *basicAllocator)
11160: Imp(static_cast<const Imp&>(original), basicAllocator)
11161{
11162}
11163
11164template <class A1, class A2, class A3, class A4, class A5, class A6,
11165 class A7, class A8, class A9, class A10, class A11, class A12,
11166 class A13, class A14, class A15, class A16, class A17, class A18,
11167 class A19>
11168inline
11169Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11170 A15, A16, A17, A18, A19>::
11171Variant19(bslmf::MovableRef<Variant19> original)
11172: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))))
11173{
11174}
11175
11176template <class A1, class A2, class A3, class A4, class A5, class A6,
11177 class A7, class A8, class A9, class A10, class A11, class A12,
11178 class A13, class A14, class A15, class A16, class A17, class A18,
11179 class A19>
11180inline
11181Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11182 A15, A16, A17, A18, A19>::
11183Variant19(bslmf::MovableRef<Variant19> original,
11184 bslma::Allocator *basicAllocator)
11185: Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))),
11186 basicAllocator)
11187{
11188}
11189
11190// MANIPULATORS
11191template <class A1, class A2, class A3, class A4, class A5, class A6,
11192 class A7, class A8, class A9, class A10, class A11, class A12,
11193 class A13, class A14, class A15, class A16, class A17, class A18,
11194 class A19>
11195template <class TYPE>
11196inline
11197Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11198 A15, A16, A17, A18, A19>&
11199Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11200 A15, A16, A17, A18, A19>::
11201operator=(const TYPE& value)
11202{
11203 Imp::operator=(value);
11204 return *this;
11205}
11206
11207template <class A1, class A2, class A3, class A4, class A5, class A6,
11208 class A7, class A8, class A9, class A10, class A11, class A12,
11209 class A13, class A14, class A15, class A16, class A17, class A18,
11210 class A19>
11211template <class TYPE>
11212inline
11213#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11214typename bsl::enable_if<
11215 !bsl::is_same<Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
11216 A11, A12, A13, A14, A15, A16, A17, A18, A19>,
11217 typename bsl::remove_cvref<TYPE>::type>::value,
11218Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11219 A16, A17, A18, A19> >::type&
11220Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11221 A16, A17, A18, A19>::operator=(TYPE&& value)
11222#else
11223Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11224 A16, A17, A18, A19>&
11225Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
11226 A16, A17, A18, A19>::operator=(bslmf::MovableRef<TYPE> value)
11227#endif
11228{
11229#if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES)
11230 Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value));
11231#else
11232 TYPE& lvalue = value;
11233 Imp::operator=(MoveUtil::move(lvalue));
11234#endif
11235
11236 return *this;
11237}
11238
11239template <class A1, class A2, class A3, class A4, class A5, class A6,
11240 class A7, class A8, class A9, class A10, class A11, class A12,
11241 class A13, class A14, class A15, class A16, class A17, class A18,
11242 class A19>
11243inline
11244Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11245 A15, A16, A17, A18, A19>&
11246Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11247 A15, A16, A17, A18, A19>::
11248operator=(const Variant19& rhs)
11249{
11250 Imp::operator=(static_cast<const Imp&>(rhs));
11251 return *this;
11252}
11253
11254template <class A1, class A2, class A3, class A4, class A5, class A6,
11255 class A7, class A8, class A9, class A10, class A11, class A12,
11256 class A13, class A14, class A15, class A16, class A17, class A18,
11257 class A19>
11258inline
11259Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11260 A15, A16, A17, A18, A19>&
11261Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,
11262 A15, A16, A17, A18, A19>::
11263operator=(bslmf::MovableRef<Variant19> rhs)
11264{
11265 Variant19& lvalue = rhs;
11266
11267 Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue)));
11268 return *this;
11269}
11270
11271} // close package namespace
11272
11273
11274#endif // End C++11 code
11275
11276#endif
11277
11278// ----------------------------------------------------------------------------
11279// Copyright 2015 Bloomberg Finance L.P.
11280//
11281// Licensed under the Apache License, Version 2.0 (the "License");
11282// you may not use this file except in compliance with the License.
11283// You may obtain a copy of the License at
11284//
11285// http://www.apache.org/licenses/LICENSE-2.0
11286//
11287// Unless required by applicable law or agreed to in writing, software
11288// distributed under the License is distributed on an "AS IS" BASIS,
11289// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11290// See the License for the specific language governing permissions and
11291// limitations under the License.
11292// ----------------------------- END-OF-FILE ----------------------------------
11293
11294/** @} */
11295/** @} */
11296/** @} */
Definition bdlb_variant.h:3997
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant10 & operator=(const TYPE &value)
Variant10 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant10, HasPrintMethod)
Variant10()
Definition bdlb_variant.h:9402
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Definition bdlb_variant.h:4184
Variant11 & operator=(const TYPE &value)
Variant11()
Definition bdlb_variant.h:9573
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant11 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant11, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Definition bdlb_variant.h:4372
BSLMF_NESTED_TRAIT_DECLARATION(Variant12, HasPrintMethod)
Variant12 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant12()
Definition bdlb_variant.h:9744
Variant12 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Definition bdlb_variant.h:4561
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant13()
Definition bdlb_variant.h:9916
Variant13 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION(Variant13, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant13 & operator=(bslmf::MovableRef< TYPE > value)
Definition bdlb_variant.h:4752
Variant14 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant14 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant14, HasPrintMethod)
Variant14()
Definition bdlb_variant.h:10100
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Definition bdlb_variant.h:4944
BSLMF_NESTED_TRAIT_DECLARATION(Variant15, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant15 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant15()
Definition bdlb_variant.h:10284
Variant15 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Definition bdlb_variant.h:5137
BSLMF_NESTED_TRAIT_DECLARATION(Variant16, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant16 & operator=(const TYPE &value)
Variant16 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Definition bdlb_variant.h:5330
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant17 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION(Variant17, HasPrintMethod)
Variant17 & operator=(bslmf::MovableRef< TYPE > value)
Definition bdlb_variant.h:5523
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION(Variant18, HasPrintMethod)
Variant18 & operator=(bslmf::MovableRef< TYPE > value)
Variant18 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Definition bdlb_variant.h:5717
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant19 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant19 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION(Variant19, HasPrintMethod)
Definition bdlb_variant.h:2514
BSLMF_NESTED_TRAIT_DECLARATION(Variant2, HasPrintMethod)
Variant2()
Definition bdlb_variant.h:8145
Variant2 & operator=(const TYPE &value)
Variant2 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Definition bdlb_variant.h:2698
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant3 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant3 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant3, HasPrintMethod)
Variant3()
Definition bdlb_variant.h:8295
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Definition bdlb_variant.h:2883
Variant4 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant4, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant4()
Definition bdlb_variant.h:8448
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant4 & operator=(bslmf::MovableRef< TYPE > value)
Definition bdlb_variant.h:3068
Variant5()
Definition bdlb_variant.h:8601
Variant5 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION(Variant5, HasPrintMethod)
Variant5 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Definition bdlb_variant.h:3253
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant6 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant6()
Definition bdlb_variant.h:8754
Variant6 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION(Variant6, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Definition bdlb_variant.h:3439
BSLMF_NESTED_TRAIT_DECLARATION(Variant7, HasPrintMethod)
Variant7 & operator=(const TYPE &value)
Variant7 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant7()
Definition bdlb_variant.h:8907
Definition bdlb_variant.h:3625
Variant8()
Definition bdlb_variant.h:9063
Variant8 & operator=(bslmf::MovableRef< TYPE > value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
BSLMF_NESTED_TRAIT_DECLARATION(Variant8, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant8 & operator=(const TYPE &value)
Definition bdlb_variant.h:3811
Variant9 & operator=(bslmf::MovableRef< TYPE > value)
Variant9()
Definition bdlb_variant.h:9232
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant9 & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
BSLMF_NESTED_TRAIT_DECLARATION(Variant9, HasPrintMethod)
Definition bdlb_variant.h:816
TYPES TypeList
Definition bdlb_variant.h:823
bslmf::TypeListTypeOf< 20, TYPES >::TypeOrDefault Type20
Definition bdlb_variant.h:848
bslmf::TypeListTypeOf< 10, TYPES >::TypeOrDefault Type10
Definition bdlb_variant.h:834
bslmf::TypeListTypeOf< 2, TYPES >::TypeOrDefault Type2
Definition bdlb_variant.h:826
bslmf::TypeListTypeOf< 8, TYPES >::TypeOrDefault Type8
Definition bdlb_variant.h:832
bslmf::TypeListTypeOf< 15, TYPES >::TypeOrDefault Type15
Definition bdlb_variant.h:839
bslmf::TypeListTypeOf< 14, TYPES >::TypeOrDefault Type14
Definition bdlb_variant.h:838
bslmf::TypeListTypeOf< 9, TYPES >::TypeOrDefault Type9
Definition bdlb_variant.h:833
BSLMF_NESTED_TRAIT_DECLARATION(VariantImp_AllocatorBase, bslma::UsesBslmaAllocator)
bslmf::TypeListTypeOf< 4, TYPES >::TypeOrDefault Type4
Definition bdlb_variant.h:828
bslmf::TypeListTypeOf< 7, TYPES >::TypeOrDefault Type7
Definition bdlb_variant.h:831
friend bool operator==(const VariantImp< VARIANT_TYPES > &, const VariantImp< VARIANT_TYPES > &)
bslmf::TypeListTypeOf< 6, TYPES >::TypeOrDefault Type6
Definition bdlb_variant.h:830
bslmf::TypeListTypeOf< 12, TYPES >::TypeOrDefault Type12
Definition bdlb_variant.h:836
bslmf::TypeListTypeOf< 11, TYPES >::TypeOrDefault Type11
Definition bdlb_variant.h:835
bslmf::TypeListTypeOf< 5, TYPES >::TypeOrDefault Type5
Definition bdlb_variant.h:829
bslmf::TypeListTypeOf< 16, TYPES >::TypeOrDefault Type16
Definition bdlb_variant.h:840
bslmf::TypeListTypeOf< 13, TYPES >::TypeOrDefault Type13
Definition bdlb_variant.h:837
bslma::Allocator * getAllocator() const
Return the allocator used by this object to supply memory.
Definition bdlb_variant.h:6387
bslmf::TypeListTypeOf< 18, TYPES >::TypeOrDefault Type18
Definition bdlb_variant.h:842
bslmf::TypeListTypeOf< 3, TYPES >::TypeOrDefault Type3
Definition bdlb_variant.h:827
bslmf::TypeListTypeOf< 19, TYPES >::TypeOrDefault Type19
Definition bdlb_variant.h:843
bslmf::TypeListTypeOf< 1, TYPES >::TypeOrDefault Type1
Definition bdlb_variant.h:825
VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:6358
bslmf::TypeListTypeOf< 17, TYPES >::TypeOrDefault Type17
Definition bdlb_variant.h:841
Definition bdlb_variant.h:931
bslma::Allocator * getAllocator() const
Return 0. Note that this object does not hold an allocator pointer.
Definition bdlb_variant.h:6426
bslmf::TypeListTypeOf< 17, TYPES >::TypeOrDefault Type17
Definition bdlb_variant.h:956
bslmf::TypeListTypeOf< 6, TYPES >::TypeOrDefault Type6
Definition bdlb_variant.h:945
bslmf::TypeListTypeOf< 4, TYPES >::TypeOrDefault Type4
Definition bdlb_variant.h:943
friend bool operator==(const VariantImp< VARIANT_TYPES > &, const VariantImp< VARIANT_TYPES > &)
bslmf::TypeListTypeOf< 8, TYPES >::TypeOrDefault Type8
Definition bdlb_variant.h:947
bslmf::TypeListTypeOf< 14, TYPES >::TypeOrDefault Type14
Definition bdlb_variant.h:953
bslmf::TypeListTypeOf< 1, TYPES >::TypeOrDefault Type1
Definition bdlb_variant.h:940
bslmf::TypeListTypeOf< 18, TYPES >::TypeOrDefault Type18
Definition bdlb_variant.h:957
bslmf::TypeListTypeOf< 10, TYPES >::TypeOrDefault Type10
Definition bdlb_variant.h:949
bslmf::TypeListTypeOf< 15, TYPES >::TypeOrDefault Type15
Definition bdlb_variant.h:954
bslmf::TypeListTypeOf< 2, TYPES >::TypeOrDefault Type2
Definition bdlb_variant.h:941
bslmf::TypeListTypeOf< 20, TYPES >::TypeOrDefault Type20
Definition bdlb_variant.h:963
bslmf::TypeListTypeOf< 7, TYPES >::TypeOrDefault Type7
Definition bdlb_variant.h:946
bslmf::TypeListTypeOf< 16, TYPES >::TypeOrDefault Type16
Definition bdlb_variant.h:955
bslmf::TypeListTypeOf< 12, TYPES >::TypeOrDefault Type12
Definition bdlb_variant.h:951
bslmf::TypeListTypeOf< 19, TYPES >::TypeOrDefault Type19
Definition bdlb_variant.h:958
bslmf::TypeListTypeOf< 3, TYPES >::TypeOrDefault Type3
Definition bdlb_variant.h:942
bslmf::TypeListTypeOf< 9, TYPES >::TypeOrDefault Type9
Definition bdlb_variant.h:948
TYPES TypeList
Definition bdlb_variant.h:938
bslmf::TypeListTypeOf< 13, TYPES >::TypeOrDefault Type13
Definition bdlb_variant.h:952
bslmf::TypeListTypeOf< 11, TYPES >::TypeOrDefault Type11
Definition bdlb_variant.h:950
bslmf::TypeListTypeOf< 5, TYPES >::TypeOrDefault Type5
Definition bdlb_variant.h:944
VariantImp_NoAllocatorBase(int type, bslma::Allocator *)
Definition bdlb_variant.h:6400
Definition bdlb_variant.h:1213
void reset()
Definition bdlb_variant.h:7472
STREAM & bdexStreamIn(STREAM &stream, int version)
DEPRECATED: Do not use.
Definition bdlb_variant.h:7661
VariantImp(const VariantImp &original, bslma::Allocator *basicAllocator=0)
Definition bdlb_variant.h:7175
VariantImp & operator=(bslmf::MovableRef< TYPE > value)
RET_TYPE apply(VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:7337
BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type applyRaw(const VISITOR &visitor) const
Definition bdlb_variant.h:2169
RET_TYPE applyRaw(VISITOR &visitor) const
Definition bdlb_variant.h:7585
VariantImp(const TYPE &value, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:7083
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(const VISITOR &visitor) const
Definition bdlb_variant.h:1917
bool is() const
Definition bdlb_variant.h:7605
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type applyRaw(const VISITOR &visitor) const
Definition bdlb_variant.h:2130
VariantImp & operator=(const VariantImp &rhs)
Definition bdlb_variant.h:7255
~VariantImp()
Definition bdlb_variant.h:7216
int typeIndex() const
Definition bdlb_variant.h:7646
RET_TYPE apply(VISITOR &visitor) const
Definition bdlb_variant.h:7531
RET_TYPE applyRaw(VISITOR &visitor)
Definition bdlb_variant.h:7363
VariantImp()
Definition bdlb_variant.h:7058
const bsl::type_info & typeInfo() const
Definition bdlb_variant.h:7654
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(VISITOR &visitor) const
Definition bdlb_variant.h:1894
RET_TYPE applyRaw(const VISITOR &visitor)
Definition bdlb_variant.h:7373
RET_TYPE apply(VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:7558
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(VISITOR &visitor)
Definition bdlb_variant.h:1517
VariantImp(bslmf::MovableRef< TYPE > value)
Definition bdlb_variant.h:7109
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:1568
TYPE & createInPlace(ARGS &&... arguments)
Definition bdlb_variant.h:7454
VariantImp & assign(bslmf::MovableRef< TYPE > value)
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:1944
RET_TYPE applyRaw(const VISITOR &visitor) const
Definition bdlb_variant.h:7595
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(const VISITOR &visitor)
Definition bdlb_variant.h:1638
VariantImp(bslmf::MovableRef< VariantImp > original, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:7201
RET_TYPE apply(const VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:7571
VariantImp & operator=(const TYPE &value)
STREAM & bdexStreamOut(STREAM &stream, int version) const
DEPRECATED: Do not use.
Definition bdlb_variant.h:7699
RET_TYPE apply(VISITOR &visitor)
Definition bdlb_variant.h:7310
VariantImp(const TYPE_OR_ALLOCATOR &valueOrAllocator)
Definition bdlb_variant.h:7066
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:1664
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type applyRaw(const VISITOR &visitor)
Definition bdlb_variant.h:1758
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type applyRaw(VISITOR &visitor)
Definition bdlb_variant.h:1736
int maxSupportedBdexVersion() const
DEPRECATED: Do not use.
Definition bdlb_variant.h:7692
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type applyRaw(VISITOR &visitor) const
Definition bdlb_variant.h:2151
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(const VISITOR &visitor) const
Definition bdlb_variant.h:2014
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(const VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:1594
BSLMF_NESTED_TRAIT_DECLARATION(VariantImp, HasPrintMethod)
BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
bool isUnset() const
Definition bdlb_variant.h:7612
TYPE & the()
Definition bdlb_variant.h:7517
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(VISITOR &visitor)
Definition bdlb_variant.h:1616
RET_TYPE apply(const VISITOR &visitor)
Definition bdlb_variant.h:7323
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:2040
const TYPE & the() const
Definition bdlb_variant.h:7634
VariantImp & assign(const TYPE &value)
void swap(VariantImp &other)
Definition bdlb_variant.h:7482
VariantImp(bslmf::MovableRef< TYPE > value, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:7147
VariantImp(bslmf::MovableRef< VariantImp > original)
Definition bdlb_variant.h:7187
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(const VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:1970
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type applyRaw(VISITOR &visitor) const
Definition bdlb_variant.h:2109
VariantImp & assignTo(const SOURCE_TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
RET_TYPE apply(const VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:7349
RET_TYPE apply(const VISITOR &visitor) const
Definition bdlb_variant.h:7544
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type applyRaw(VISITOR &visitor)
Definition bdlb_variant.h:1779
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type applyRaw(const VISITOR &visitor)
Definition bdlb_variant.h:1797
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==1, typenameVISITOR::ResultType >::type apply(const VISITOR &visitor)
Definition bdlb_variant.h:1541
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(VISITOR &visitor) const
Definition bdlb_variant.h:1992
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlb_variant.h:7619
VariantImp & operator=(bslmf::MovableRef< VariantImp > rhs)
Definition bdlb_variant.h:7281
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(const VISITOR &visitor, const TYPE &defaultValue)
Definition bdlb_variant.h:1689
bsl::enable_if< Variant_ReturnValueHelper< VISITOR >::value==0, void >::type apply(const VISITOR &visitor, const TYPE &defaultValue) const
Definition bdlb_variant.h:2065
Definition bdlb_variant.h:1152
RESULT_TYPE operator()(ARGUMENT_TYPE &argument)
Definition bdlb_variant.h:6450
Variant_RawVisitorHelper(VISITOR *visitor)
Definition bdlb_variant.h:6439
Definition bdlb_variant.h:2312
Variant(bslmf::MovableRef< Variant > original, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:8038
Variant & operator=(const Variant &rhs)
Definition bdlb_variant.h:8103
BSLMF_NESTED_TRAIT_DECLARATION(Variant, HasPrintMethod)
Variant(const TYPE &value, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:7947
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR)
Variant(bslmf::MovableRef< TYPE > value, bslma::Allocator *basicAllocator)
Definition bdlb_variant.h:7998
Variant & operator=(bslmf::MovableRef< Variant > rhs)
Definition bdlb_variant.h:8121
Variant & operator=(const TYPE &value)
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE)
Variant()
Definition bdlb_variant.h:7923
Variant(const TYPE_OR_ALLOCATOR &valueOrAllocator)
Definition bdlb_variant.h:7934
Variant(bslmf::MovableRef< TYPE > value)
Definition bdlb_variant.h:7974
Variant(const Variant &original, bslma::Allocator *basicAllocator=0)
Definition bdlb_variant.h:8011
BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bslmf::IsBitwiseCopyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE)
Variant(bslmf::MovableRef< Variant > original)
Definition bdlb_variant.h:8026
Variant & operator=(bslmf::MovableRef< TYPE > value)
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
Definition bslmf_movableref.h:751
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:1895
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
void reset(TYPE *object)
Reset the value of the specified object to its default value.
Definition bdlb_algorithmworkaroundutil.h:74
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
char Variant_ReturnValueHelper_YesType
Definition bdlb_variant.h:770
bsl::ostream & operator<<(bsl::ostream &stream, const BigEndianInt16 &integer)
void swap(NullableAllocatedValue< TYPE > &a, NullableAllocatedValue< TYPE > &b)
bool operator==(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
STREAM & bdexStreamIn(STREAM &stream, VALUE_TYPE &variable)
Definition bslx_instreamfunctions.h:1247
STREAM & bdexStreamOut(STREAM &stream, const TYPE &value)
Definition bslx_outstreamfunctions.h:992
Definition bdlb_printmethods.h:306
Definition bdlb_variant.h:1031
bslmf::TypeListTypeOf< 14, TYPES >::TypeOrDefault Type14
Definition bdlb_variant.h:1047
bsl::conditional< k_VARIANT_USES_BSLMA_ALLOCATOR, VariantImp_AllocatorBase< TYPES >, VariantImp_NoAllocatorBase< TYPES > >::type BaseType
Determines what the base type is.
Definition bdlb_variant.h:1132
bslmf::TypeListTypeOf< 7, TYPES >::TypeOrDefault Type7
Definition bdlb_variant.h:1040
bslmf::TypeListTypeOf< 12, TYPES >::TypeOrDefault Type12
Definition bdlb_variant.h:1045
bslmf::TypeListTypeOf< 18, TYPES >::TypeOrDefault Type18
Definition bdlb_variant.h:1051
bslmf::TypeListTypeOf< 6, TYPES >::TypeOrDefault Type6
Definition bdlb_variant.h:1039
bslmf::TypeListTypeOf< 13, TYPES >::TypeOrDefault Type13
Definition bdlb_variant.h:1046
bslmf::TypeListTypeOf< 19, TYPES >::TypeOrDefault Type19
Definition bdlb_variant.h:1052
bslmf::TypeListTypeOf< 17, TYPES >::TypeOrDefault Type17
Definition bdlb_variant.h:1050
bslmf::TypeListTypeOf< 3, TYPES >::TypeOrDefault Type3
Definition bdlb_variant.h:1036
bslmf::TypeListTypeOf< 11, TYPES >::TypeOrDefault Type11
Definition bdlb_variant.h:1044
@ VARIANT_USES_BSLMA_ALLOCATOR
Definition bdlb_variant.h:1122
@ VARIANT_IS_BITWISE_COPYABLE
Definition bdlb_variant.h:1123
@ k_VARIANT_IS_BITWISE_MOVEABLE
Definition bdlb_variant.h:1100
@ VARIANT_IS_BITWISE_MOVEABLE
Definition bdlb_variant.h:1124
@ k_VARIANT_USES_BSLMA_ALLOCATOR
Definition bdlb_variant.h:1056
@ k_VARIANT_IS_BITWISE_COPYABLE
Definition bdlb_variant.h:1078
bslmf::TypeListTypeOf< 1, TYPES >::TypeOrDefault Type1
Definition bdlb_variant.h:1034
bslmf::TypeListTypeOf< 8, TYPES >::TypeOrDefault Type8
Definition bdlb_variant.h:1041
bslmf::TypeListTypeOf< 2, TYPES >::TypeOrDefault Type2
Definition bdlb_variant.h:1035
bslmf::TypeListTypeOf< 16, TYPES >::TypeOrDefault Type16
Definition bdlb_variant.h:1049
bslmf::TypeListTypeOf< 5, TYPES >::TypeOrDefault Type5
Definition bdlb_variant.h:1038
bslmf::TypeListTypeOf< 20, TYPES >::TypeOrDefault Type20
Definition bdlb_variant.h:1053
bslmf::TypeListTypeOf< 15, TYPES >::TypeOrDefault Type15
Definition bdlb_variant.h:1048
bslmf::TypeListTypeOf< 4, TYPES >::TypeOrDefault Type4
Definition bdlb_variant.h:1037
bslmf::TypeListTypeOf< 9, TYPES >::TypeOrDefault Type9
Definition bdlb_variant.h:1042
bslmf::TypeListTypeOf< 10, TYPES >::TypeOrDefault Type10
Definition bdlb_variant.h:1043
Definition bdlb_variant.h:6203
Variant_BdexStreamInVisitor(STREAM &stream, int version)
Definition bdlb_variant.h:6210
int d_version
Definition bdlb_variant.h:6207
STREAM & d_stream
Definition bdlb_variant.h:6206
void operator()(VALUETYPE &object) const
Definition bdlb_variant.h:6219
void operator()(bslmf::Nil) const
Definition bdlb_variant.h:6225
Definition bdlb_variant.h:6241
void operator()(bslmf::Nil) const
Definition bdlb_variant.h:6263
void operator()(const VALUETYPE &object) const
Definition bdlb_variant.h:6257
STREAM & d_stream
Definition bdlb_variant.h:6244
Variant_BdexStreamOutVisitor(STREAM &stream, int version)
Definition bdlb_variant.h:6248
int d_version
Definition bdlb_variant.h:6245
Definition bdlb_variant.h:6111
void operator()(const TYPE &value)
Definition bdlb_variant.h:6126
Variant_CopyAssignVisitor(void *buffer)
Definition bdlb_variant.h:6118
void * d_buffer_p
Definition bdlb_variant.h:6114
Definition bdlb_variant.h:6029
void * d_buffer_p
Definition bdlb_variant.h:6032
void operator()(const TYPE &value) const
Definition bdlb_variant.h:6045
Variant_CopyConstructVisitor(void *buffer, bslma::Allocator *allocator)
Definition bdlb_variant.h:6036
bslma::Allocator * d_allocator_p
Definition bdlb_variant.h:6033
Definition bdlb_variant.h:6001
Variant_DefaultConstructVisitor(bslma::Allocator *allocator)
Definition bdlb_variant.h:6008
void operator()(TYPE &value) const
Definition bdlb_variant.h:6015
bslma::Allocator * d_allocator_p
Definition bdlb_variant.h:6004
Definition bdlb_variant.h:6093
void operator()(TYPE &object) const
Definition bdlb_variant.h:6097
Definition bdlb_variant.h:6318
const void * d_buffer_p
Definition bdlb_variant.h:6322
void operator()(bslmf::Nil) const
Definition bdlb_variant.h:6340
void operator()(const TYPE &value) const
Definition bdlb_variant.h:6335
bool d_result
Definition bdlb_variant.h:6321
Variant_EqualityTestVisitor(const void *buffer)
Definition bdlb_variant.h:6326
Definition bdlb_variant.h:6140
void operator()(TYPE &value)
Definition bdlb_variant.h:6155
void * d_buffer_p
Definition bdlb_variant.h:6143
Variant_MoveAssignVisitor(void *buffer)
Definition bdlb_variant.h:6147
Definition bdlb_variant.h:6062
void operator()(TYPE &value) const
Definition bdlb_variant.h:6078
void * d_buffer_p
Definition bdlb_variant.h:6065
bslma::Allocator * d_allocator_p
Definition bdlb_variant.h:6066
Variant_MoveConstructVisitor(void *buffer, bslma::Allocator *allocator)
Definition bdlb_variant.h:6069
Definition bdlb_variant.h:6278
void operator()(bslmf::Nil) const
Definition bdlb_variant.h:6303
Variant_PrintVisitor(bsl::ostream *stream, int level, int spacesPerLevel)
Definition bdlb_variant.h:6286
bsl::ostream * d_stream_p
Definition bdlb_variant.h:6281
void operator()(const TYPE &value) const
Definition bdlb_variant.h:6298
int d_level
Definition bdlb_variant.h:6282
int d_spacesPerLevel
Definition bdlb_variant.h:6283
Definition bdlb_variant.h:780
static Variant_ReturnValueHelper_YesType match(typename bsl::remove_reference< typename T::ResultType >::type *)
static Variant_ReturnValueHelper_NoType match(...)
Definition bdlb_variant.h:771
Definition bdlb_variant.h:802
Definition bdlb_variant.h:6170
void * d_buffer_p
Definition bdlb_variant.h:6173
Variant_SwapVisitor(void *buffer)
Definition bdlb_variant.h:6177
void operator()(TYPE &value)
Definition bdlb_variant.h:6185
Definition bdlb_variant.h:5906
@ value
Definition bdlb_variant.h:5909
Definition bslmf_conditional.h:120
Definition bslmf_enableif.h:525
Definition bslmf_integralconstant.h:244
Definition bslmf_isconvertible.h:867
Definition bslmf_issame.h:146
Definition bslmf_removeconst.h:156
bsl::remove_cv< typenamebsl::remove_reference< t_TYPE >::type >::type type
Definition bslmf_removecvref.h:136
static void construct(TARGET_TYPE *address, const ALLOCATOR &allocator)
Definition bslma_constructionutil.h:1243
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisecopyable.h:298
Definition bslmf_isbitwisemoveable.h:718
Definition bslmf_movableref.h:791
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1060
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131
Definition bslmf_typelist.h:1856
Definition bslmf_typelist.h:1899
Definition bslmf_typelist.h:1945
Definition bslmf_typelist.h:1994
Definition bslmf_typelist.h:2046
Definition bslmf_typelist.h:2101
Definition bslmf_typelist.h:2159
Definition bslmf_typelist.h:2220
Definition bslmf_typelist.h:2284
Definition bslmf_typelist.h:2351
List of a three types t_A1, t_A2, t_A3 types.
Definition bslmf_typelist.h:1685
Definition bslmf_typelist.h:1703
Definition bslmf_typelist.h:1720
Definition bslmf_typelist.h:1743
Definition bslmf_typelist.h:1768
Definition bslmf_typelist.h:1795
Definition bslmf_typelist.h:1824
Definition bslmf_typelist.h:1609
Definition bsls_objectbuffer.h:276