// bdlb_variant.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BDLB_VARIANT #define INCLUDED_BDLB_VARIANT #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a variant (discriminated 'union'-like) type. // //@CLASSES: // bdlb::Variant: variant of up to 20 types // bdlb::Variant2: variant of exactly 2 types // bdlb::Variant3: variant of exactly 3 types // bdlb::Variant4: variant of exactly 4 types // bdlb::Variant5: variant of exactly 5 types // bdlb::Variant6: variant of exactly 6 types // bdlb::Variant7: variant of exactly 7 types // bdlb::Variant8: variant of exactly 8 types // bdlb::Variant9: variant of exactly 9 types // bdlb::Variant10: variant of exactly 10 types // bdlb::Variant11: variant of exactly 11 types // bdlb::Variant12: variant of exactly 12 types // bdlb::Variant13: variant of exactly 13 types // bdlb::Variant14: variant of exactly 14 types // bdlb::Variant15: variant of exactly 15 types // bdlb::Variant16: variant of exactly 16 types // bdlb::Variant17: variant of exactly 17 types // bdlb::Variant18: variant of exactly 18 types // bdlb::Variant19: variant of exactly 19 types // bdlb::VariantImp: variant from a type list // //@SEE_ALSO: // //@DESCRIPTION: This component provides: (1) a variant class template, // 'bdlb::Variant', that can store an instance of one of up to some // (implementation-defined) number of parameter types (currently 20), (2) // several variant class templates that accommodate a *fixed* number (from 2 // to 19) of types, 'bdlb::Variant2', 'bdlb::Variant3', 'bdlb::Variant4', // 'bdlb::Variant5', 'bdlb::Variant6', 'bdlb::Variant7', 'bdlb::Variant8', // 'bdlb::Variant9', 'bdlb::Variant10', 'bdlb::Variant11', 'bdlb::Variant12', // 'bdlb::Variant13', 'bdlb::Variant14', 'bdlb::Variant15', 'bdlb::Variant16', // 'bdlb::Variant17', 'bdlb::Variant18', and 'bdlb::Variant19', and (3) a final // variant class template, 'bdlb::VariantImp', whose supported types are // specified via a 'bslmf::TypeList'. A variant (of any of the aforementioned // classes) can hold any one of the types defined in its signature at any point // in time. Clients can retrieve the value and type that a variant currently // holds, assign a new value to the variant, or apply a visitor to the variant. // A visitor's action is based on the value and type the variant currently // holds. Assigning a value of a new type destroys the object of the old type // and constructs the new value by copy constructing the supplied value. // // When the number ('N') of types that needs to be supported is known, it is // better to use the 'bdlb::VariantN' templates that use an identical // implementation, but generate shorter symbols and debugging information due // to the lack of defaulted template argument types. Note that // 'bdlb::VariantN<T1, ..., TN>' and 'bdlb::Variant<T1, ..., TN>' are, // nevertheless, distinct types. // // When the variant types are (directly) supplied as a type list (of type // 'bslmf::TypeList'), the type 'bdlb::VariantImp<TYPELIST>' can be used in // place of: //.. // bdlb::Variant<typename TYPELIST::Type1, typename TYPELIST::Type2, ...> //.. // // Lastly, move constructors (taking an optional allocator) and move-assignment // operators are also provided. Note that move semantics are emulated with // C++03 compilers. // ///Default Construction ///-------------------- // The 'bdlb::Variant' class, when default constructed, does not hold a value // and 'isUnset' returns 'true'. This state is the same as that of a // 'bdlb::Variant' that is reset by the 'reset' method. // ///Visitors ///-------- // 'bdlb::Variant' provides an 'apply' method that implements the visitor // design pattern. 'apply' accepts a visitor (functor) that provides an // 'operator()' that is invoked with the value that the variant currently // holds. // // Note, that visitor must satisfy the following requirements: //: o The visitor's 'operator()' must be callable with any of the types that //: might be contained in the variant. //: o For the 'apply' methods (but not 'applyRaw') the visitor's 'operator()' //: must be callable with an argument of type 'bslmf::Nil'. //: o For the 'apply' and 'applyRaw' methods returning non-void type the return //: value of all callable overloads of 'operator()' must be convertible to //: this type. // // The 'apply' method should be preferred over a 'switch' statement based on // the type index of a variant. If the order or types contained by the variant // is changed in the future, every place where the type index is hard-coded // needs to be updated. Whereas if 'apply' were used, no change would be // needed because function overloading will automatically resolve to the proper // 'operator()' to invoke. // // There are several variations of the 'apply' method, varying based on the // return type and the handling of unset variants. Firstly, // the method varies based on whether 'apply' returns a value or not. // There can either be: //: o No return value. //: o A return type specified in the visitor interface. //: o A return type specified explicitly when invoking 'apply'. // // The default is no return value. Even if visitor's 'operator()' returns any // non-void value, it will not be passed to the user. If users would like to // return a value from the visitor's 'operator()', they can specify a public // alias 'ResultType' to the desired return type in the functor class. For // example, if 'operator()' were to return an 'int', the functor class should // specify: //.. // typedef int ResultType; //.. // If 'ResultType' cannot be determined, users also have the option of // explicitly specifying the return type when invoking apply: //.. // apply<int>(visitor); //.. // Secondly, the 'apply' method varies based on how the method handles an unset // variant. A user can choose to: //: o Pass a default-constructed 'bslmf::Nil' to the visitor. //: o Pass a user-specified "default" value to the visitor. // // Furthermore, if the user is sure that the variant cannot be unset, the user // can invoke 'applyRaw', which is slightly more efficient. However, if the // variant is, in fact, unset, the behavior of 'applyRaw' is undefined. // ///BDEX Streamability ///------------------ // BDEX streaming is not implemented for any of the variant classes. // ///Class Synopsis ///-------------- // Due to the complexity of the implementation, the following synopsis is // provided to aid users in locating documentation for functions. Note that // this is not a complete summary of all available methods; only the key // methods are shown. For more information, refer to the function-level // documentation. // ///Creators /// - - - - //.. // bdlb::Variant() // bdlb::Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator); // bdlb::Variant(const TYPE& value, bslma::Allocator *basicAllocator); //.. // Create a variant. Users can choose to initialize a variant with a specified // value, or leave the variant in the unset state (via default construction). // Users can also supply a 'bslma::Allocator *' for memory allocation. // ///Manipulators /// - - - - - - //.. // bdlb::Variant& operator=(const TYPE& value); //.. // Assign a different value of template parameter 'TYPE' to the variant. //.. // bdlb::Variant& operator=(const bdlb::Variant& rhs); //.. // Assign another variant to a variant. //.. // void apply(VISITOR& visitor); // VISITOR::ResultType apply(VISITOR& visitor); // RET_TYPE apply(VISITOR& visitor); //.. // Access a variant's value using a specified visitor functor whereby // 'bslmf::Nil' is passed to the visitor's 'operator()' if the variant is // unset. //.. // void apply(VISITOR& visitor, const TYPE& defaultValue); // VISITOR::ResultType apply(VISITOR& visitor, const TYPE& defaultValue); // RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue); //.. // Access a variant's value using a specified visitor functor whereby a // user-specified default value is passed to the visitor's 'operator()' if the // variant is unset. //.. // void applyRaw(VISITOR& visitor); // VISITOR::ResultType applyRaw(VISITOR& visitor); // RET_TYPE applyRaw(VISITOR& visitor); //.. // Access a variant's value using a specified visitor functor whereby the // behavior is undefined if the variant is unset. //.. // template <class TYPE> // TYPE& createInPlace(); // TYPE& createInPlace(const A1& a1); // // ... // TYPE& createInPlace(const A1& a1, const A2& a2, ..., const A14& a14); //.. // Create a new value of template parameter 'TYPE' in-place, with up to 14 // constructor arguments. //.. // void reset(); //.. // Reset a variant to the unset state. //.. // template <class TYPE> // TYPE& the(); //.. // Access the value of template parameter 'TYPE' currently held by a variant. // This method should be invoked using the syntax 'the<TYPE>()', e.g., // 'the<int>()'. // ///Accessors ///- - - - - //.. // template <class TYPE> // bool is() const; //.. // Check whether a variant is currently holding a particular type. This // method should be invoked using the syntax 'is<TYPE>()', e.g., 'is<int>()'. //.. // bool isUnset() const; //.. // Return 'true' if a variant is currently unset, and 'false' otherwise. //.. // bsl::ostream& print(bsl::ostream& stream, // int level = 0, // int spacesPerLevel = 4) const; //.. // Write a description of a variant to a specified 'stream'. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Variant Construction ///- - - - - - - - - - - - - - - - // The following example illustrates the different ways of constructing a // 'bdlb::Variant': //.. // typedef bdlb::Variant <int, double, bsl::string> List; // typedef bdlb::Variant3<int, double, bsl::string> List3; // equivalent //.. // The contained types can be retrieved as a 'bslmf::TypeList' (using the // 'TypeList' nested type), or individually (using 'TypeN', for 'N' varying // from 1 to the length of the 'TypeList'). In the example below, we use the // 'List' variant, but this could be substituted with 'List3' with no change // to the code: //.. // assert(3 == List::TypeList::LENGTH); // assert(3 == List3::TypeList::LENGTH); //.. // We can check that the variant defaults to the unset state by using the // 'is<TYPE>' and 'typeIndex' methods: //.. // List x; // // assert(!x.is<int>()); // assert(!x.is<double>()); // assert(!x.is<bsl::string>()); // assert(0 == x.typeIndex()); //.. // Single-argument construction from a type in the 'TypeList' of a variant is // also supported. This is more efficient than creating an unset variant and // assigning a value to it: //.. // List3 y(bsl::string("Hello")); // // assert(!y.is<int>()); // assert(!y.is<double>()); // assert( y.is<bsl::string>()); // // assert("Hello" == y.the<bsl::string>()); //.. // Furthermore, 'createInPlace' is provided to support direct in-place // construction. This method allows users to directly construct the target // type inside the variant, instead of first creating a temporary object, then // copy constructing the object to initialize the variant: //.. // List z; // z.createInPlace<bsl::string>("Hello", 5); // // assert(!z.is<int>()); // assert(!z.is<double>()); // assert( z.is<bsl::string>()); // // assert("Hello" == z.the<bsl::string>()); //.. // Up to 14 constructor arguments are supported for in-place construction of // an object. Users can also safely create another object of the same or // different type in a variant that already holds a value using the // 'createInPlace' method. No memory is leaked in all cases and the destructor // for the currently held object is invoked: //.. // z.createInPlace<bsl::string>("Hello", 5); // assert(z.is<bsl::string>()); // assert("Hello" == z.the<bsl::string>()); // // z.createInPlace<double>(10.0); // assert(z.is<double>()); // assert(10.0 == z.the<double>()); // // z.createInPlace<int>(10); // assert(z.is<int>()); // assert(10 == z.the<int>()); //.. // 'createInPlace' returns a reference providing modifiable access to the // created object: //.. // bsl::string& ref = z.createInPlace<bsl::string>("Goodbye"); // assert("Goodbye" == z.the<bsl::string>()); // assert("Goodbye" == ref); // assert(&ref == &z.the<bsl::string>()); // // ref = "Hello again!"; // assert("Hello again!" == z.the<bsl::string>()); //.. // ///Example 2: Variant Assignment ///- - - - - - - - - - - - - - - // A value of a given type can be stored in a variant in three different ways: // //: o 'operator=' //: o 'assignTo<TYPE>' //: o 'assign' // // 'operator=' automatically deduces the type that the user is trying to assign // to the variant. This should be used most of the time. The 'assignTo<TYPE>' // method should be used when conversion to the type that the user is assigning // to is necessary (see the first two examples below for more details). // Finally, 'assign' is equivalent to 'operator=' and exists simply for // backwards compatibility. // ///'operator=' /// - - - - // The following example illustrates how to use 'operator=': //.. // typedef bdlb::Variant<int, double, bsl::string> List; // // List x; // // List::Type1 v1 = 1; // 'int' // List::Type2 v2 = 2.0; // 'double' // List::Type3 v3("hello"); // 'bsl::string' // // x = v1; // assert( x.is<int>()); // assert(!x.is<double>()); // assert(!x.is<bsl::string>()); // assert(v1 == x.the<int>()); // // x = v2; // assert(!x.is<int>()); // assert( x.is<double>()); // assert(!x.is<bsl::string>()); // assert(v2 == x.the<double>()); // // x = v3; // assert(!x.is<int>()); // assert(!x.is<double>()); // assert( x.is<bsl::string>()); // assert(v3 == x.the<bsl::string>()); //.. // Note that the type of the object is deduced automatically during assignment, // as in: //.. // x = v1; //.. // This automatic deduction, however, cannot be extended to conversion // constructors, such as: //.. // x = static_cast<const char *>("Bye"); // ERROR //.. // The compiler will diagnose that 'const char *' is not a variant type // specified in the list of parameter types used in the definition of 'List', // and will trigger a compile-time assertion. To overcome this problem, see // the next usage example of 'assignTo<TYPE>'. // ///'assignTo<TYPE>' ///- - - - - - // In the previous example, 'const char *' was not part of the variant's type // list, which resulted in a compilation diagnostic. The use of // 'assignTo<TYPE>' explicitly informs the compiler of the intended type to // assign to the variant: //.. // x.assignTo<bsl::string>(static_cast<const char *>("Bye")); // // assert(!x.is<int>()); // assert(!x.is<double>()); // assert( x.is<bsl::string>()); // // assert("Bye" == x.the<bsl::string>()); //.. // ///'assign' /// - - - // Finally, for backwards compatibility, 'assign' can also be used in place of // 'operator=' (but not 'assignTo'): //.. // x.assign<int>(v1); // assert( x.is<int>()); // assert(!x.is<double>()); // assert(!x.is<bsl::string>()); // assert(v1 == x.the<int>()); // // x.assign<double>(v2); // assert(!x.is<int>()); // assert( x.is<double>()); // assert(!x.is<bsl::string>()); // assert(v2 == x.the<double>()); // // x.assign<bsl::string>(v3); // assert(!x.is<int>()); // assert(!x.is<double>()); // assert( x.is<bsl::string>()); // assert(v3 == x.the<bsl::string>()); //.. // ///Example 3: Visiting a Variant via 'apply' ///- - - - - - - - - - - - - - - - - - - - - // As described in {Visitors} (above), there are different ways to invoke the // 'apply' method. The first two examples below illustrate the different ways // to invoke 'apply' (with no return value) to control the behavior of visiting // an unset variant: //: o 'bslmf::Nil' is passed to the visitor. //: o A user-specified default value is passed to the visitor. // // A third example illustrates use of 'applyRaw', the behavior of which is // undefined if the variant is unset. Two final examples illustrate different // ways to specify the return value from 'apply': //: o The return value is specified in the visitor. //: o The return value is specified with the function call. // ///'bslmf::Nil' Passed to Visitor ///- - - - - - - - - - - // A simple visitor that does not require any return value might be one that // prints the value of the variant to 'stdout': //.. // class my_PrintVisitor { // public: // template <class TYPE> // void operator()(const TYPE& value) const // { // bsl::cout << value << bsl::endl; // } // // void operator()(bslmf::Nil value) const // { // bsl::cout << "null" << bsl::endl; // } // }; // // typedef bdlb::Variant<int, double, bsl::string> List; // // List x[4]; // // // Note that 'x[3]' is uninitialized. // // x[0].assign(1); // x[1].assign(1.1); // x[2].assignTo<bsl::string>(static_cast<const char *>("Hello")); // // my_PrintVisitor printVisitor; // // for (int i = 0; i < 4; ++i) { // x[i].apply(printVisitor); // } //.. // The above prints the following on 'stdout': //.. // 1 // 1.1 // Hello // null //.. // Note that 'operator()' is overloaded with 'bslmf::Nil'. A direct match has // higher precedence than a template parameter match. When the variant is // unset (such as 'x[3]'), a 'bslmf::Nil' is passed to the visitor. // ///User-Specified Default Value Passed to Visitor ///- - - - - - - - - - - - - - - - // Instead of using 'bslmf::Nil', users can also specify a default value to // pass to the visitor when the variant is currently unset. Using the same // 'my_PrintVisitor' class from the previous example: //.. // for (int i = 0; i < 4; ++i) { // x[i].apply(printVisitor, "Print this when unset"); // } //.. // Now, the above code prints the following on 'stdout': //.. // 1 // 1.1 // Hello // Print this when unset //.. // This variation of 'apply' is useful since the user can provide a default // value to the visitor without incurring the cost of initializing the variant // itself. // ///'applyRaw' Undefined If Variant Is Unset ///- - - - - - - - - - - - - - // If it is certain that a variant is not unset, then the 'applyRaw' method can // be used instead of 'apply'. 'applyRaw' is slightly more efficient than // 'apply', but the behavior of 'applyRaw' is undefined if the variant is // unset. In the following application of 'applyRaw', we purposely circumvent // 'x[3]' from being visited because we know that it is unset: //.. // for (int i = 0; i < 3; ++i) { // NOT 'i < 4' as above. // assert(!x[i].isUnset()); // x[i].applyRaw(printVisitor); // undefined behavior for 'x[3]' // } // assert(x[3].isUnset()); //.. // ///Return Value Specified in Visitor /// - - - - - - - - - - - // Users can also specify a return type that 'operator()' will return by // specifying a 'typedef' with the name 'ResultType' in their functor class. // This is necessary in order for the 'apply' method to know what type to // return at compile time: //.. // class my_AddVisitor { // public: // typedef bool ResultType; // // // Note that the return type of 'operator()' is 'ResultType'. // // template <class TYPE> // ResultType operator()(TYPE& value) const // // Return 'true' when addition is performed successfully, and // // 'false' otherwise. // { // if (bsl::is_convertible<TYPE, double>::value) { // // // Add certain values to the variant. The details are elided // // as it is the return value that is the focus of this example. // // return true; // RETURN // } // return false; // } // }; // // typedef bdlb::Variant<int, double, bsl::string> List; // // List x[3]; // // x[0].assign(1); // x[1].assign(1.1); // x[2].assignTo<bsl::string>(static_cast<const char *>("Hello")); // // my_AddVisitor addVisitor; // // bool ret[3]; // // for (int i = 0; i < 3; ++i) { // ret[i] = x[i].apply(addVisitor); // if (!ret[i]) { // bsl::cout << "Cannot add to types not convertible to 'double'." // << bsl::endl; // } // } // assert(true == ret[0]); // assert(true == ret[1]); // assert(false == ret[2]); //.. // The above prints the following on 'stdout': //.. // Cannot add to types not convertible to 'double'. //.. // Note that if no 'typedef' is provided (as in the 'my_PrintVisitor' class), // then the default return value is 'void'. // ///Return Value Specified with Function Call /// - - - - - - - - - - - - - - // There may be some cases when a visitor interface is not owned by a client // (hence the client cannot add a 'typedef' to the visitor), or the visitor // could not determine the return type at design time. In these scenarios, // users can explicitly specify the return type when invoking 'apply': //.. // class ThirdPartyVisitor { // public: // template <class TYPE> // bsl::string operator()(const TYPE& value) const; // // Return the name of the specified 'value' as a 'bsl::string'. // // Note that the implementation of this class is deliberately not // // shown since this class belongs to a third-party library. // }; // // typedef bdlb::Variant<int, double, bsl::string> List; // // List x[3]; // // x[0].assign(1); // x[1].assign(1.1); // x[2].assignTo<bsl::string>(static_cast<const char *>("Hello")); // // ThirdPartyVisitor visitor; // // for (int i = 0; i < 3; ++i) { // // // Note that the return type is explicitly specified. // // bsl::string ret = x[i].apply<bsl::string>(visitor); // bsl::cout << ret << bsl::endl; // } //.. #include <bdlscm_version.h> #include <bdlb_printmethods.h> #include <bslalg_swaputil.h> #include <bslma_allocator.h> #include <bslma_constructionutil.h> #include <bslma_default.h> #include <bslma_destructionutil.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_assert.h> #include <bslmf_conditional.h> #include <bslmf_enableif.h> #include <bslmf_integralconstant.h> #include <bslmf_isbitwisemoveable.h> #include <bslmf_isconvertible.h> #include <bslmf_issame.h> #include <bslmf_istriviallycopyable.h> #include <bslmf_movableref.h> #include <bslmf_nestedtraitdeclaration.h> #include <bslmf_nil.h> #include <bslmf_removeconst.h> #include <bslmf_removecvref.h> #include <bslmf_removereference.h> #include <bslmf_typelist.h> #include <bslmf_util.h> // 'forward(V)' #include <bslx_instreamfunctions.h> #include <bslx_outstreamfunctions.h> #include <bslx_versionfunctions.h> #include <bsls_assert.h> #include <bsls_compilerfeatures.h> #include <bsls_objectbuffer.h> #include <bsls_util.h> // 'forward<T>(V)' #include <bsl_algorithm.h> #include <bsl_iosfwd.h> #ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES #include <bslmf_if.h> #endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES #ifndef BDE_OMIT_INTERNAL_DEPRECATED #include <bslalg_scalardestructionprimitives.h> #include <bslalg_scalarprimitives.h> #include <bsl_typeinfo.h> #endif // BDE_OMIT_INTERNAL_DEPRECATED #if defined(BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES) \ && defined(BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES) #define BDLB_VARIANT_USING_VARIADIC_TEMPLATES // Note that this macro definition parallels that of a similar macro // defined in 'bslmf_typelist.h'. #endif namespace BloombergLP { namespace bdlb { struct Variant_CopyAssignVisitor; struct Variant_CopyConstructVisitor; struct Variant_DefaultConstructVisitor; struct Variant_DestructorVisitor; struct Variant_EqualityTestVisitor; struct Variant_MoveAssignVisitor; struct Variant_MoveConstructVisitor; struct Variant_PrintVisitor; template <class TYPES> class VariantImp; template <class TYPES, class TYPE> struct Variant_TypeIndex; // ================================ // struct Variant_ReturnValueHelper // ================================ // These definitions are provided outside of 'Variant_ReturnValueHelper' // because of a bug in the IBM xlC compiler. typedef char Variant_ReturnValueHelper_YesType; typedef struct { char a[2]; } Variant_ReturnValueHelper_NoType; BSLMF_ASSERT(sizeof(Variant_ReturnValueHelper_YesType) != sizeof(Variant_ReturnValueHelper_NoType)); template <class VISITOR> struct Variant_ReturnValueHelper { // This struct is a component-private meta-function. Do *not* use. This // meta-function checks whether the template parameter type 'VISITOR' has // the member 'ResultType' defined using "SFINAE" (Substitution Failure Is // Not An Error). template <class T> static Variant_ReturnValueHelper_YesType match( typename bsl::remove_reference<typename T::ResultType>::type *); template <class T> static Variant_ReturnValueHelper_NoType match(...); // Return 'YesType' if 'T::ResultType' exists, and 'NoType' otherwise. // Note that if 'T::ResultType' exists, then the first function is a // better match than the ellipsis version. enum { value = sizeof(match<VISITOR>(0)) == sizeof(Variant_ReturnValueHelper_YesType) #ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE3.0 , VALUE = sizeof(match<VISITOR>(0)) == sizeof(Variant_ReturnValueHelper_YesType) #endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE3.0 }; // A 'value' of 'true' indicates 'VISITOR::ResultType' exists, and // 'false' otherwise. }; // ===================================== // class VariantImp_AllocatorBase<TYPES> // ===================================== template <class TYPES> class VariantImp_AllocatorBase { // This class is component-private. Do not use. This class contains the // 'typedef's and data members of the 'Variant' class, and serves as the // base class for the variant when any one of the types held by the variant // has the 'bslma::UsesBslmaAllocator' type trait. public: // TYPES typedef TYPES TypeList; // 'TypeList' is an alias for the 'bslmf::TypeList' type serving as the // template parameter to this variant implementation. typedef typename bslmf::TypeListTypeOf< 1, TYPES>::TypeOrDefault Type1; typedef typename bslmf::TypeListTypeOf< 2, TYPES>::TypeOrDefault Type2; typedef typename bslmf::TypeListTypeOf< 3, TYPES>::TypeOrDefault Type3; typedef typename bslmf::TypeListTypeOf< 4, TYPES>::TypeOrDefault Type4; typedef typename bslmf::TypeListTypeOf< 5, TYPES>::TypeOrDefault Type5; typedef typename bslmf::TypeListTypeOf< 6, TYPES>::TypeOrDefault Type6; typedef typename bslmf::TypeListTypeOf< 7, TYPES>::TypeOrDefault Type7; typedef typename bslmf::TypeListTypeOf< 8, TYPES>::TypeOrDefault Type8; typedef typename bslmf::TypeListTypeOf< 9, TYPES>::TypeOrDefault Type9; typedef typename bslmf::TypeListTypeOf<10, TYPES>::TypeOrDefault Type10; typedef typename bslmf::TypeListTypeOf<11, TYPES>::TypeOrDefault Type11; typedef typename bslmf::TypeListTypeOf<12, TYPES>::TypeOrDefault Type12; typedef typename bslmf::TypeListTypeOf<13, TYPES>::TypeOrDefault Type13; typedef typename bslmf::TypeListTypeOf<14, TYPES>::TypeOrDefault Type14; typedef typename bslmf::TypeListTypeOf<15, TYPES>::TypeOrDefault Type15; typedef typename bslmf::TypeListTypeOf<16, TYPES>::TypeOrDefault Type16; typedef typename bslmf::TypeListTypeOf<17, TYPES>::TypeOrDefault Type17; typedef typename bslmf::TypeListTypeOf<18, TYPES>::TypeOrDefault Type18; typedef typename bslmf::TypeListTypeOf<19, TYPES>::TypeOrDefault Type19; typedef typename bslmf::TypeListTypeOf<20, TYPES>::TypeOrDefault Type20; // 'TypeN' is an alias for the 'N'th type in the 'TypeList' of this // variant implementation. If less than 'N' template arguments were // given to the 'Variant' type, then 'TypeN' is 'bslmf::Nil'. private: union Value { bsls::ObjectBuffer<Type1> d_v1; bsls::ObjectBuffer<Type2> d_v2; bsls::ObjectBuffer<Type3> d_v3; bsls::ObjectBuffer<Type4> d_v4; bsls::ObjectBuffer<Type5> d_v5; bsls::ObjectBuffer<Type6> d_v6; bsls::ObjectBuffer<Type7> d_v7; bsls::ObjectBuffer<Type8> d_v8; bsls::ObjectBuffer<Type9> d_v9; bsls::ObjectBuffer<Type10> d_v10; bsls::ObjectBuffer<Type11> d_v11; bsls::ObjectBuffer<Type12> d_v12; bsls::ObjectBuffer<Type13> d_v13; bsls::ObjectBuffer<Type14> d_v14; bsls::ObjectBuffer<Type15> d_v15; bsls::ObjectBuffer<Type16> d_v16; bsls::ObjectBuffer<Type17> d_v17; bsls::ObjectBuffer<Type18> d_v18; bsls::ObjectBuffer<Type19> d_v19; bsls::ObjectBuffer<Type20> d_v20; }; // 'Value' is a union of 'bsls::ObjectBuffer' of all types contained by // the variant. 'bsls::ObjectBuffer' is used to: 1) wrap non-POD types // within the union, and 2) ensure proper alignment of the types. // DATA Value d_value; // value of the object, initialized by // derived class int d_type; // current type the variant is holding (0 // if unset) bslma::Allocator *d_allocator_p; // pointer to allocator (held, not owned) // FRIENDS template <class VARIANT_TYPES> friend class VariantImp; template <class VARIANT_TYPES> friend bool operator==(const VariantImp<VARIANT_TYPES>&, const VariantImp<VARIANT_TYPES>&); public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(VariantImp_AllocatorBase, bslma::UsesBslmaAllocator); // CREATORS VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator); VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator, bsl::true_type); // Create a 'VariantImp_AllocatorBase' with the specified 'type' // indicating the type of the object that the variant will initially // hold, and the specified 'basicAllocator' to supply memory. template <class TYPE> VariantImp_AllocatorBase(int type, const TYPE&, bsl::false_type); // ACCESSORS bslma::Allocator *getAllocator() const; // Return the allocator used by this object to supply memory. }; // ======================================= // class VariantImp_NoAllocatorBase<TYPES> // ======================================= template <class TYPES> class VariantImp_NoAllocatorBase { // This class is component-private. Do not use. This class contains the // 'typedef's and data members of the 'Variant' class, and serves as the // base class for the variant when none of the types held by the variant // has the 'bslma::UsesBslmaAllocator' type trait. The goal is to optimize // the size of the variant to avoid holding an unnecessary allocator // pointer. public: // TYPES typedef TYPES TypeList; // 'TypeList' is an alias for the 'bslmf::TypeList' type serving as the // template parameter to this variant implementation. typedef typename bslmf::TypeListTypeOf< 1, TYPES>::TypeOrDefault Type1; typedef typename bslmf::TypeListTypeOf< 2, TYPES>::TypeOrDefault Type2; typedef typename bslmf::TypeListTypeOf< 3, TYPES>::TypeOrDefault Type3; typedef typename bslmf::TypeListTypeOf< 4, TYPES>::TypeOrDefault Type4; typedef typename bslmf::TypeListTypeOf< 5, TYPES>::TypeOrDefault Type5; typedef typename bslmf::TypeListTypeOf< 6, TYPES>::TypeOrDefault Type6; typedef typename bslmf::TypeListTypeOf< 7, TYPES>::TypeOrDefault Type7; typedef typename bslmf::TypeListTypeOf< 8, TYPES>::TypeOrDefault Type8; typedef typename bslmf::TypeListTypeOf< 9, TYPES>::TypeOrDefault Type9; typedef typename bslmf::TypeListTypeOf<10, TYPES>::TypeOrDefault Type10; typedef typename bslmf::TypeListTypeOf<11, TYPES>::TypeOrDefault Type11; typedef typename bslmf::TypeListTypeOf<12, TYPES>::TypeOrDefault Type12; typedef typename bslmf::TypeListTypeOf<13, TYPES>::TypeOrDefault Type13; typedef typename bslmf::TypeListTypeOf<14, TYPES>::TypeOrDefault Type14; typedef typename bslmf::TypeListTypeOf<15, TYPES>::TypeOrDefault Type15; typedef typename bslmf::TypeListTypeOf<16, TYPES>::TypeOrDefault Type16; typedef typename bslmf::TypeListTypeOf<17, TYPES>::TypeOrDefault Type17; typedef typename bslmf::TypeListTypeOf<18, TYPES>::TypeOrDefault Type18; typedef typename bslmf::TypeListTypeOf<19, TYPES>::TypeOrDefault Type19; typedef typename bslmf::TypeListTypeOf<20, TYPES>::TypeOrDefault Type20; // 'TypeN' is an alias for the 'N'th type in the 'TypeList' of this // variant implementation. If less than 'N' template arguments were // given to the 'Variant' type, then 'TypeN' is 'bslmf::Nil'. private: union Value { bsls::ObjectBuffer<Type1> d_v1; bsls::ObjectBuffer<Type2> d_v2; bsls::ObjectBuffer<Type3> d_v3; bsls::ObjectBuffer<Type4> d_v4; bsls::ObjectBuffer<Type5> d_v5; bsls::ObjectBuffer<Type6> d_v6; bsls::ObjectBuffer<Type7> d_v7; bsls::ObjectBuffer<Type8> d_v8; bsls::ObjectBuffer<Type9> d_v9; bsls::ObjectBuffer<Type10> d_v10; bsls::ObjectBuffer<Type11> d_v11; bsls::ObjectBuffer<Type12> d_v12; bsls::ObjectBuffer<Type13> d_v13; bsls::ObjectBuffer<Type14> d_v14; bsls::ObjectBuffer<Type15> d_v15; bsls::ObjectBuffer<Type16> d_v16; bsls::ObjectBuffer<Type17> d_v17; bsls::ObjectBuffer<Type18> d_v18; bsls::ObjectBuffer<Type19> d_v19; bsls::ObjectBuffer<Type20> d_v20; }; // 'Value' is a union of 'bsls::ObjectBuffer' of all types contained by // the variant. 'bsls::ObjectBuffer' is used to: 1) wrap non-POD types // within the union, and 2) ensure proper alignment of the types. // DATA Value d_value; // value of the object, initialized by derived class int d_type; // current type the variant is holding (0 if unset) // FRIENDS template <class VARIANT_TYPES> friend class VariantImp; template <class VARIANT_TYPES> friend bool operator==(const VariantImp<VARIANT_TYPES>&, const VariantImp<VARIANT_TYPES>&); public: // CREATORS VariantImp_NoAllocatorBase(int type, bslma::Allocator *); VariantImp_NoAllocatorBase(int type, bslma::Allocator *, bsl::true_type); // Create a 'VariantImp_NoAllocatorBase' with the specified 'type' // indicating the type of the object that the variant will initially // hold. template <class TYPE> VariantImp_NoAllocatorBase(int type, const TYPE&, bsl::false_type); // ACCESSORS bslma::Allocator *getAllocator() const; // Return 0. Note that this object does not hold an allocator pointer. }; // ======================== // struct VariantImp_Traits // ======================== template <class TYPES> struct VariantImp_Traits { // This struct is component-private. Do not use. This meta-function // selects 'VariantImp_AllocatorBase' as a base class type if any one of // the types held by a variant has the 'bslma::UsesBslmaAllocator' trait, // and 'VariantImp_NoAllocatorBase' otherwise. // TYPES typedef typename bslmf::TypeListTypeOf< 1, TYPES>::TypeOrDefault Type1; typedef typename bslmf::TypeListTypeOf< 2, TYPES>::TypeOrDefault Type2; typedef typename bslmf::TypeListTypeOf< 3, TYPES>::TypeOrDefault Type3; typedef typename bslmf::TypeListTypeOf< 4, TYPES>::TypeOrDefault Type4; typedef typename bslmf::TypeListTypeOf< 5, TYPES>::TypeOrDefault Type5; typedef typename bslmf::TypeListTypeOf< 6, TYPES>::TypeOrDefault Type6; typedef typename bslmf::TypeListTypeOf< 7, TYPES>::TypeOrDefault Type7; typedef typename bslmf::TypeListTypeOf< 8, TYPES>::TypeOrDefault Type8; typedef typename bslmf::TypeListTypeOf< 9, TYPES>::TypeOrDefault Type9; typedef typename bslmf::TypeListTypeOf<10, TYPES>::TypeOrDefault Type10; typedef typename bslmf::TypeListTypeOf<11, TYPES>::TypeOrDefault Type11; typedef typename bslmf::TypeListTypeOf<12, TYPES>::TypeOrDefault Type12; typedef typename bslmf::TypeListTypeOf<13, TYPES>::TypeOrDefault Type13; typedef typename bslmf::TypeListTypeOf<14, TYPES>::TypeOrDefault Type14; typedef typename bslmf::TypeListTypeOf<15, TYPES>::TypeOrDefault Type15; typedef typename bslmf::TypeListTypeOf<16, TYPES>::TypeOrDefault Type16; typedef typename bslmf::TypeListTypeOf<17, TYPES>::TypeOrDefault Type17; typedef typename bslmf::TypeListTypeOf<18, TYPES>::TypeOrDefault Type18; typedef typename bslmf::TypeListTypeOf<19, TYPES>::TypeOrDefault Type19; typedef typename bslmf::TypeListTypeOf<20, TYPES>::TypeOrDefault Type20; enum { k_VARIANT_USES_BSLMA_ALLOCATOR = ( bslma::UsesBslmaAllocator< Type1>::value || bslma::UsesBslmaAllocator< Type2>::value || bslma::UsesBslmaAllocator< Type3>::value || bslma::UsesBslmaAllocator< Type4>::value || bslma::UsesBslmaAllocator< Type5>::value || bslma::UsesBslmaAllocator< Type6>::value || bslma::UsesBslmaAllocator< Type7>::value || bslma::UsesBslmaAllocator< Type8>::value || bslma::UsesBslmaAllocator< Type9>::value || bslma::UsesBslmaAllocator<Type10>::value || bslma::UsesBslmaAllocator<Type11>::value || bslma::UsesBslmaAllocator<Type12>::value || bslma::UsesBslmaAllocator<Type13>::value || bslma::UsesBslmaAllocator<Type14>::value || bslma::UsesBslmaAllocator<Type15>::value || bslma::UsesBslmaAllocator<Type16>::value || bslma::UsesBslmaAllocator<Type17>::value || bslma::UsesBslmaAllocator<Type18>::value || bslma::UsesBslmaAllocator<Type19>::value || bslma::UsesBslmaAllocator<Type20>::value), k_VARIANT_IS_BITWISE_COPYABLE = ( bsl::is_trivially_copyable< Type1>::value && bsl::is_trivially_copyable< Type2>::value && bsl::is_trivially_copyable< Type3>::value && bsl::is_trivially_copyable< Type4>::value && bsl::is_trivially_copyable< Type5>::value && bsl::is_trivially_copyable< Type6>::value && bsl::is_trivially_copyable< Type7>::value && bsl::is_trivially_copyable< Type8>::value && bsl::is_trivially_copyable< Type9>::value && bsl::is_trivially_copyable<Type10>::value && bsl::is_trivially_copyable<Type11>::value && bsl::is_trivially_copyable<Type12>::value && bsl::is_trivially_copyable<Type13>::value && bsl::is_trivially_copyable<Type14>::value && bsl::is_trivially_copyable<Type15>::value && bsl::is_trivially_copyable<Type16>::value && bsl::is_trivially_copyable<Type17>::value && bsl::is_trivially_copyable<Type18>::value && bsl::is_trivially_copyable<Type19>::value && bsl::is_trivially_copyable<Type20>::value), k_VARIANT_IS_BITWISE_MOVEABLE = ( bslmf::IsBitwiseMoveable< Type1>::value && bslmf::IsBitwiseMoveable< Type2>::value && bslmf::IsBitwiseMoveable< Type3>::value && bslmf::IsBitwiseMoveable< Type4>::value && bslmf::IsBitwiseMoveable< Type5>::value && bslmf::IsBitwiseMoveable< Type6>::value && bslmf::IsBitwiseMoveable< Type7>::value && bslmf::IsBitwiseMoveable< Type8>::value && bslmf::IsBitwiseMoveable< Type9>::value && bslmf::IsBitwiseMoveable<Type10>::value && bslmf::IsBitwiseMoveable<Type11>::value && bslmf::IsBitwiseMoveable<Type12>::value && bslmf::IsBitwiseMoveable<Type13>::value && bslmf::IsBitwiseMoveable<Type14>::value && bslmf::IsBitwiseMoveable<Type15>::value && bslmf::IsBitwiseMoveable<Type16>::value && bslmf::IsBitwiseMoveable<Type17>::value && bslmf::IsBitwiseMoveable<Type18>::value && bslmf::IsBitwiseMoveable<Type19>::value && bslmf::IsBitwiseMoveable<Type20>::value) #ifndef BDE_OMIT_INTERNAL_DEPRECATED , VARIANT_USES_BSLMA_ALLOCATOR = k_VARIANT_USES_BSLMA_ALLOCATOR , VARIANT_IS_BITWISE_COPYABLE = k_VARIANT_IS_BITWISE_COPYABLE , VARIANT_IS_BITWISE_MOVEABLE = k_VARIANT_IS_BITWISE_MOVEABLE #endif // BDE_OMIT_INTERNAL_DEPRECATED }; typedef typename bsl::conditional<k_VARIANT_USES_BSLMA_ALLOCATOR, VariantImp_AllocatorBase<TYPES>, VariantImp_NoAllocatorBase<TYPES> >::type BaseType; // Determines what the base type is. }; // =============================== // class Variant_ReturnAnyTypeUtil // =============================== template <class TYPE> struct Variant_ReturnAnyTypeUtil { // This 'struct' provides a function that returns an (invalid) instance of // any type. It is meant to allow clients to express: //.. // template <RESULT_TYPE> // RESULT_TYPE foo() // { // // ... // // // The following 'return' is unreachable, but is required for // // compilation. // // return Variant_ReturnAnyTypeUtil::doNotCall(); // } //.. // where 'RESULT_TYPE' may be 'void'. Note that while such a return // statement is not required by the C++ standard, the lack of such a // return statement causes a warning (or error) with many compilers. // CLASS METHODS static TYPE doNotCall(TYPE *dummy); // Return the specified '*dummy'. static TYPE doNotCall(); // Return a 'TYPE' object. }; template <> struct Variant_ReturnAnyTypeUtil<void> { // This partial specialization of 'Variant_ReturnAnyTypeUtil' provides // functions that do not have return value. // CLASS METHODS static void doNotCall(); // Do nothing. }; template <class TYPE> struct Variant_ReturnAnyTypeUtil<TYPE&> { // This partial specialization of 'Variant_ReturnAnyTypeUtil' provides a // function that returns an lvalue reference. // CLASS METHODS static TYPE& lvalueRef(TYPE *dummy); // Return an lvalue reference providing modifiable access to the // specified '*dummy'. static TYPE& doNotCall(); // Return a 'TYPE&' object. }; #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) template <class TYPE> struct Variant_ReturnAnyTypeUtil<TYPE&&> // This partial specialization of 'Variant_ReturnAnyTypeUtil' provides a // function that returns an rvalue reference. { // CLASS METHODS static TYPE&& rvalueRef(TYPE *dummy); // Return an rvalue reference providing modifiable access to the // specified '*dummy'. static TYPE&& doNotCall(); // Return a 'TYPE&&' object. }; #endif // ============================== // class Variant_RawVisitorHelper // ============================== template <class RESULT_TYPE, class VISITOR> class Variant_RawVisitorHelper { // This 'struct' provides a helper for implementing 'Variant::applyRaw' // that enables 'applyRaw' to support visitor functors that do not provide // an overload for 'operator()(bslmf::Nil)'. Objects of this type are // constructed using a functor of (template parameter) type 'VISITOR', // whose 'operator()' returns the (template parameter) type 'RESULT_TYPE'. // A 'Variant_RawVisitorHelper' wraps a functor of type 'VISITOR' and // provides an implementation of 'operator()(bslmf::Nil)' that performs a // 'BSLS_ASSERT_OPT(false)'. Note that this overload is needed to enable // compilation (specifically, to instantiate 'doApply' and 'doApplyR'), but // is never invoked by any code path at runtime. // DATA VISITOR *d_visitor; // visitor to which this helper delegates public: // CREATORS explicit Variant_RawVisitorHelper(VISITOR *visitor); // Create a 'RawVisitorHelper' functor that delegates to the specified // 'visitor'. // MANIPULATORS template <class ARGUMENT_TYPE> RESULT_TYPE operator()(ARGUMENT_TYPE& argument); template <class ARGUMENT_TYPE> RESULT_TYPE operator()(const ARGUMENT_TYPE& argument); // Invoke the functor supplied at construction with the specified // 'argument', and return the result. // ACCESSORS template <class ARGUMENT_TYPE> RESULT_TYPE operator()(ARGUMENT_TYPE& argument) const; template <class ARGUMENT_TYPE> RESULT_TYPE operator()(const ARGUMENT_TYPE& argument) const; // Invoke the functor supplied at construction with the specified // 'argument', and return the result. RESULT_TYPE operator()(bslmf::Nil) const; // Do not call. The behavior of this method is undefined. }; // ======================= // class VariantImp<TYPES> // ======================= template <class TYPES> class VariantImp : public VariantImp_Traits<TYPES>::BaseType { // This class provides the implementation of 'Variant' (except for the // creators) given a list of template parameter 'TYPES'. // // More generally, if each of the types in the list of 'TYPES' is // value semantic, then this class also supports a complete set of *value* // *semantic* operations, including copy construction, assignment, equality // comparison, and 'ostream' printing. A precise operational definition of // when two instances have the same value can be found in the description // of 'operator==' for the class. This class is *exception* *neutral* with // no guarantee of rollback: if an exception is thrown during the // invocation of a method on a pre-existing instance, the object is left in // a valid state, but its value is undefined. In no event is memory // leaked. Finally, *aliasing* (e.g., using all or part of an object as // both source and destination) is supported in all cases. // // If any of the types in the list of 'TYPES' does not support // 'operator==', or any of the value-semantic operations mentioned above, // then this variant also does not support that operation and attempts to // invoke it will trigger a compilation diagnostic. // PRIVATE TYPES typedef VariantImp_Traits<TYPES> Traits; typedef typename Traits::BaseType Base; typedef bslmf::MovableRefUtil MoveUtil; typedef VariantImp<TYPES> SelfType; // 'SelfType' is an alias to this class. private: // PRIVATE MANIPULATORS template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor, bsl::false_type); template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor, bsl::true_type); template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor); // Invoke 'operator()' of the specified 'visitor' on the current value // (of template parameter 'TYPE') held by this variant. 'TYPE' must be // the same as one of the types that this variant can hold. The // behavior is undefined unless this variant holds a value of template // parameter 'TYPE'. Note that the second argument is for resolving // overloading ambiguity and is not used. template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor, bsl::false_type); template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor, bsl::true_type); template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor); // Invoke 'operator()' of the specified 'visitor' on the current value // (of template parameter 'TYPE') held by this variant, and return the // value (of template parameter 'RET_TYPE') returned by the 'visitor'. // 'TYPE' must be the same as one of the types that this variant can // hold. The behavior is undefined unless this variant holds a value // of template parameter 'TYPE'. Note that the second argument is for // resolving overloading ambiguity and is not used. template <class TYPE, class SOURCE_TYPE> void assignImp(const SOURCE_TYPE& value); // Assign to this variant the specified 'value' of template parameter // 'SOURCE_TYPE' converted to template parameter 'TYPE'. 'TYPE' must // be the same as one of the types that this variant can hold and // 'SOURCE_TYPE' must be convertible to 'TYPE'. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) void assignImp(TYPE&& value); #else void assignImp(bslmf::MovableRef<TYPE> value); #endif // Assign to this variant the specified 'value' of template parameter // 'TYPE'. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. 'TYPE' must be the // same as one of the types that this variant can hold. template <class TYPE> void create(const TYPE& value, bsl::false_type); // Construct this variant object to initially hold the specified // 'value' of template parameter 'TYPE'. 'TYPE' must be the same as // one of the types that this variant can hold. Note that the second // parameter is for resolving overloading ambiguity and is not used. void create(bslma::Allocator *, bsl::true_type); // Construct this variant object to be initially in the unset state. template <class VISITOR_REF> void doApply(VISITOR_REF visitor, int type); // Apply the specified 'visitor' on the current value held by this // variant by invoking 'applyImp' with the appropriate template // arguments, determined by the specified 'type'. The behavior is // undefined unless 'type != 0'. template <class VISITOR_REF, class RET_TYPE> RET_TYPE doApplyR(VISITOR_REF visitor, int type); // Apply the specified 'visitor' on the current value held by this // variant by invoking 'applyImpR' with the appropriate template // arguments, determined by the specified 'type', and return the value // (of template parameter 'RET_TYPE') returned by the 'visitor'. The // behavior is undefined unless 'type != 0'. // PRIVATE ACCESSORS template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor, bsl::false_type) const; template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor, bsl::true_type) const; template <class TYPE, class VISITOR_REF> void applyImp(VISITOR_REF visitor) const; // Invoke 'operator()' of the specified 'visitor' on the current value // (of template parameter 'TYPE') held by this variant. 'TYPE' must be // the same as one of the types that this variant can hold. The // behavior is undefined unless this variant holds a value of template // parameter 'TYPE'. Note that the second argument is for resolving // overloading ambiguity and is not used. template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor, bsl::false_type) const; template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor, bsl::true_type) const; template <class TYPE, class VISITOR_REF, class RET_TYPE> RET_TYPE applyImpR(VISITOR_REF visitor) const; // Invoke 'operator()' of the specified 'visitor' on the current value // (of template parameter 'TYPE') held by this variant, and return the // value (of template parameter 'RET_TYPE') returned by the 'visitor'. // 'TYPE' must be the same as one of the types that this variant can // hold. The behavior is undefined unless this variant holds a value // of template parameter 'TYPE'. Note that the second argument is for // resolving overloading ambiguity and is not used. template <class VISITOR_REF> void doApply(VISITOR_REF visitor, int type) const; // Apply the specified 'visitor' on the current value held by this // variant by invoking 'applyImp' with the appropriate template // arguments, determined by the specified 'type'. The behavior is // undefined unless 'type != 0'. template <class VISITOR_REF, class RET_TYPE> RET_TYPE doApplyR(VISITOR_REF visitor, int type) const; // Apply the specified 'visitor' on the current value held by this // variant by invoking 'applyImpR' with the appropriate template // arguments, determined by the specified 'type', and return the value // (of template parameter 'RET_TYPE') returned by the 'visitor'. The // behavior is undefined unless 'type != 0'. public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(VariantImp, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(VariantImp, HasPrintMethod); // CREATORS VariantImp(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit VariantImp(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> VariantImp(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else VariantImp(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else VariantImp(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). VariantImp(const VariantImp& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. VariantImp(bslmf::MovableRef<VariantImp> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. VariantImp(bslmf::MovableRef<VariantImp> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. ~VariantImp(); // Destroy this variant object, invoking the destructor of the type of // object contained (if any) on the value of that type. // MANIPULATORS template <class TYPE> VariantImp& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else VariantImp& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). VariantImp& operator=(const VariantImp& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. VariantImp& operator=(bslmf::MovableRef<VariantImp> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value this variant currently holds to the 'visitor' object's // 'operator()', and return the value returned by the 'visitor'. If // this variant is unset, a default constructed 'bslmf::Nil' is passed // to the 'visitor'. Note that this method is selected only if the // template parameter type 'VISITOR' defines a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. if (this->d_type) { return doApplyR<VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(const VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value this variant currently holds to the 'visitor' object's // 'operator()', and return the value returned by the 'visitor'. If // If this variant is unset, a default constructed 'bslmf::Nil' is // passed to the 'visitor'. Note that this method is selected only if // the template parameter type 'VISITOR' defines a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. if (this->d_type) { return doApplyR<const VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(VISITOR& visitor, const TYPE& defaultValue) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // returned by the 'visitor'. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // defines a 'typedef' of 'ResultType' in its public interface. Also // note that this method is defined inline to work around a Windows // compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(const VISITOR& visitor, const TYPE& defaultValue) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // returned by the 'visitor'. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // defines a 'typedef' of 'ResultType' in its public interface. Also // note that this method is defined inline to work around a Windows // compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<const VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value this variant currently holds to the 'visitor' object's // 'operator()'. This method does not return a value. If this variant // is unset, a default constructed 'bslmf::Nil' is passed to the // 'visitor'. Note that this method is selected only if the template // parameter type 'VISITOR' does not define a 'typedef' of 'ResultType' // in its public interface. Also note that this method is defined // inline to work around a Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<VISITOR&>(visitor, this->d_type); return; // RETURN } bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(const VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value this variant currently holds to the 'visitor' object's // 'operator()'. This method does not return a value. If this variant // is unset, a default constructed 'bslmf::Nil' is passed to the // 'visitor'. Note that this method is selected only if the template // parameter type 'VISITOR' does not define a 'typedef' of 'ResultType' // in its public interface. Also note that this method is defined // inline to work around a Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<const VISITOR&>(visitor, this->d_type); return; // RETURN } bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(VISITOR& visitor, const TYPE& defaultValue) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()'. This method does not // return a value. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // does not define a 'typedef' of 'ResultType' in its public interface. // Also note that this method is defined inline to work around a // Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<VISITOR&>(visitor, this->d_type); return; // RETURN } visitor(defaultValue); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(const VISITOR& visitor, const TYPE& defaultValue) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()'. This method does not // return a value. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // does not define a 'typedef' of 'ResultType' in its public interface. // Also note that this method is defined inline to work around a // Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<const VISITOR&>(visitor, this->d_type); return; // RETURN } visitor(defaultValue); } template <class RET_TYPE, class VISITOR> RET_TYPE apply(VISITOR& visitor); template <class RET_TYPE, class VISITOR> RET_TYPE apply(const VISITOR& visitor); // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // (of template parameter 'RET_TYPE') returned by the 'visitor'. If // this variant is unset, a default constructed 'bslmf::Nil' is passed // to the 'visitor'. template <class RET_TYPE, class VISITOR, class TYPE> RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue); template <class RET_TYPE, class VISITOR, class TYPE> RET_TYPE apply(const VISITOR& visitor, const TYPE& defaultValue); // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // (of template parameter 'RET_TYPE') returned by the 'visitor'. If // this variant is unset, the specified 'defaultValue' of template // parameter 'TYPE' is passed to the 'visitor'. 'TYPE' must be the // same as one of the types that this variant can hold. The behavior // is undefined unless this variant is unset or holds a value of // template parameter 'TYPE'. template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type applyRaw(VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // returned by the 'visitor'. The behavior is undefined if this // variant is unset. Note that this method is selected only if the // template parameter type 'VISITOR' defines a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. typedef Variant_RawVisitorHelper<typename VISITOR::ResultType, VISITOR> Helper; return doApplyR<const Helper&, typename VISITOR::ResultType>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type applyRaw(const VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()', and return the value // returned by the 'visitor'. The behavior is undefined if this // variant is unset. Note that this method is selected only if the // template parameter type 'VISITOR' defines a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. typedef Variant_RawVisitorHelper<typename VISITOR::ResultType, const VISITOR> Helper; return doApplyR<const Helper&, typename VISITOR::ResultType>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type applyRaw(VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()'. This method does not // return a value. The behavior is undefined if this variant is unset. // Note that this method is selected only if the template parameter // type 'VISITOR' does not define a 'typedef' of 'ResultType' in its // public interface. Also note that this method is defined inline to // work around a Windows compiler bug with SFINAE functions. typedef Variant_RawVisitorHelper<void, VISITOR> Helper; doApply<const Helper&>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type applyRaw(const VISITOR& visitor) { // Apply the specified 'visitor' to this modifiable variant by passing // the value (of template parameter 'TYPE') this variant currently // holds to the 'visitor' object's 'operator()'. This method does not // return a value. The behavior is undefined if this variant is unset. // Note that this method is selected only if the template parameter // type 'VISITOR' does not define a 'typedef' of 'ResultType' in its // public interface. Also note that this method is defined inline to // work around a Windows compiler bug with SFINAE functions. typedef Variant_RawVisitorHelper<void, const VISITOR> Helper; doApply<const Helper&>(Helper(&visitor), this->d_type); } template <class RET_TYPE, class VISITOR> RET_TYPE applyRaw(VISITOR& visitor); template <class RET_TYPE, class VISITOR> RET_TYPE applyRaw(const VISITOR& visitor); // Apply the specified 'visitor' to this modifiable variant by passing // the value this variant currently holds to the 'visitor' object's // 'operator()', and return the value (of template parameter // 'RET_TYPE') returned by the 'visitor'. The behavior is undefined if // this variant is unset. template <class TYPE> VariantImp& assign(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp& assign(TYPE&& value); #else VariantImp& assign(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. template <class TYPE, class SOURCE_TYPE> VariantImp& assignTo(const SOURCE_TYPE& value); // Assign to this object the specified 'value' of template parameter // 'SOURCE_TYPE' converted to template parameter 'TYPE', and return a // reference providing modifiable access to this object. The value // currently held by this variant (if any) is destroyed if that value's // type is not the same as 'TYPE'. 'TYPE' must be the same as one of // the types that this variant can hold and 'SOURCE_TYPE' must be // convertible to 'TYPE'. template <class TYPE> TYPE& createInPlace(); template <class TYPE, class A1> TYPE& createInPlace(const A1& a1); template <class TYPE, class A1, class A2> TYPE& createInPlace(const A1& a1, const A2& a2); template <class TYPE, class A1, class A2, class A3> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3); template <class TYPE, class A1, class A2, class A3, class A4> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4); template <class TYPE, class A1, class A2, class A3, class A4, class A5> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12, const A13& a13); template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> TYPE& createInPlace(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12, const A13& a13, const A14& a14); // Create an instance of template parameter 'TYPE' in this variant // object with up to 14 parameters using the allocator currently held // by this variant to supply memory, and return a reference providing // modifiable access to the created instance. This method first // destroys the current value held by this variant (even if 'TYPE' is // the same as the type currently held). 'TYPE' must be the same as // one of the types that this variant can hold. Note the order of the // template arguments was chosen so that 'TYPE' must always be // specified. void reset(); // Destroy the current value held by this variant (if any), and reset // this variant to the unset state. void swap(VariantImp& other); // Swap the value of this object with the value of the specified // 'other' object. This method provides the no-throw guarantee if the // 'TYPE' template parameter has a no-throw 'swap' and the two variant // objects being swapped have the same type; otherwise this method // provides the basic guarantee. template <class TYPE> TYPE& the(); // Return a reference providing modifiable access to the value of // template parameter 'TYPE' held by this variant object. 'TYPE' must // be the same as one of the types that this variant can hold. The // behavior is undefined unless 'is<TYPE>()' returns 'true' and 'TYPE' // is not 'void'. Note that 'TYPE' must be specified explicitly, e.g., // 'myValue.the<int>()'. // ACCESSORS template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value returned by the 'visitor'. If this variant is // unset, a default constructed 'bslmf::Nil' is passed to the // 'visitor'. Note that this method is selected only if the template // parameter type 'VISITOR' defines a 'typedef' of 'ResultType' in its // public interface. Also note that this method is defined inline to // work around a Windows compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(const VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value returned by the 'visitor. If this variant is // unset, a default constructed 'bslmf::Nil' is passed to the // 'visitor'. Note that this method is selected only if the template // parameter type 'VISITOR' defines a 'typedef' of 'ResultType' in its // public interface. Also note that this method is defined inline to // work around a Windows compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<const VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(VISITOR& visitor, const TYPE& defaultValue) const { // Apply the specified 'visitor' to this variant by passing the value // (of template parameter 'TYPE') this variant currently holds to the // 'visitor' object's 'operator()', and return the value returned by // the 'visitor'. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // defines a 'typedef' of 'ResultType' in its public interface. Also // note that this method is defined inline to work around a Windows // compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type apply(const VISITOR& visitor, const TYPE& defaultValue) const { // Apply the specified 'visitor' to this variant by passing the value // (of template parameter 'TYPE') this variant currently holds to the // 'visitor' object's 'operator()', and return the value returned by // the 'visitor'. If this variant is unset, the specified // 'defaultValue' of template parameter 'TYPE' is passed to the // 'visitor'. 'TYPE' must be the same as one of the types that this // variant can hold. The behavior is undefined unless this variant is // unset or holds a value of template parameter 'TYPE'. Note that this // method is selected only if the template parameter type 'VISITOR' // defines a 'typedef' of 'ResultType' in its public interface. Also // note that this method is defined inline to work around a Windows // compiler bug with SFINAE functions. if (this->d_type) { return doApplyR<const VISITOR&, typename VISITOR::ResultType>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()'. // This method does not return a value. If this variant is unset, a // default constructed 'bslmf::Nil' is passed to the 'visitor'. Note // that this method is selected only if the template parameter type // 'VISITOR' does not define a 'typedef' of 'ResultType' in its public // interface. Also note that this method is defined inline to work // around a Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<VISITOR&>(visitor, this->d_type); return; // RETURN } bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(const VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()'. // This method does not return a value. If this variant is unset, a // default constructed 'bslmf::Nil' is passed to the 'visitor'. Note // that this method is selected only if the template parameter type // 'VISITOR' does not define a 'typedef' of 'ResultType' in its public // interface. Also note that this method is defined inline to work // around a Windows compiler bug with SFINAE functions. if (this->d_type) { doApply<const VISITOR&>(visitor, this->d_type); return; // RETURN } bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(VISITOR& visitor, const TYPE& defaultValue) const { // Apply the specified 'visitor' to this variant by passing the value // (of template parameter 'TYPE') this variant currently holds to the // 'visitor' object's 'operator()'. This method does not return a // value. If this variant is unset, the specified 'defaultValue' of // template parameter 'TYPE' is passed to the 'visitor'. 'TYPE' must // be the same as one of the types that this variant can hold. The // behavior is undefined unless this variant is unset or holds a value // of template parameter 'TYPE'. Note that this method is selected // only if the template parameter type 'VISITOR' does not define a // 'typedef' of 'ResultType' in its public interface. Also note that // this method is defined inline to work around a Windows compiler bug // with SFINAE functions. if (this->d_type) { doApply<VISITOR&>(visitor, this->d_type); return; // RETURN } visitor(defaultValue); } template <class VISITOR, class TYPE> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type apply(const VISITOR& visitor, const TYPE& defaultValue) const { // Apply the specified 'visitor' to this variant by passing the value // (of template parameter 'TYPE') this variant currently holds to the // 'visitor' object's 'operator()'. This method does not return a // value. If this variant is unset, the specified 'defaultValue' of // template parameter 'TYPE' is passed to the 'visitor'. 'TYPE' must // be the same as one of the types that this variant can hold. The // behavior is undefined unless this variant is unset or holds a value // of template parameter 'TYPE'. Note that this method is selected // only if the template parameter type 'VISITOR' does not define a // 'typedef' of 'ResultType' in its public interface. Also note that // this method is defined inline to work around a Windows compiler bug // with SFINAE functions. if (this->d_type) { doApply<const VISITOR&>(visitor, this->d_type); return; // RETURN } visitor(defaultValue); } template <class RET_TYPE, class VISITOR> RET_TYPE apply(VISITOR& visitor) const; template <class RET_TYPE, class VISITOR> RET_TYPE apply(const VISITOR& visitor) const; // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value (of template parameter 'RET_TYPE') returned by // the 'visitor'. If this variant is unset, a default constructed // 'bslmf::Nil' is passed to the 'visitor'. template <class RET_TYPE, class VISITOR, class TYPE> RET_TYPE apply(VISITOR& visitor, const TYPE& defaultValue) const; template <class RET_TYPE, class VISITOR, class TYPE> RET_TYPE apply(const VISITOR& visitor, const TYPE& defaultValue) const; // Apply the specified 'visitor' to this variant by passing the value // (of template parameter 'TYPE') this variant currently holds to the // 'visitor' object's 'operator()', and return the value (of template // parameter 'RET_TYPE') returned by the 'visitor'. If this variant is // unset, the specified 'defaultValue' of template parameter 'TYPE' is // passed to the 'visitor'. 'TYPE' must be the same as one of the // types that this variant can hold. The behavior is undefined unless // this variant is unset or holds a value of template parameter 'TYPE'. template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type applyRaw(VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value (of template parameter 'RET_TYPE') returned by // the 'visitor'. The behavior is undefined if this variant is unset. // Note that this method is selected only if the template parameter // type 'VISITOR' defines a 'typedef' of 'ResultType' in its public // interface. Also note that this method is defined inline to work // around a Windows compiler bug with SFINAE functions. typedef Variant_RawVisitorHelper<typename VISITOR::ResultType, VISITOR> Helper; return doApplyR<const Helper&, typename VISITOR::ResultType>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 1, typename VISITOR::ResultType>::type applyRaw(const VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value returned by the 'visitor'. The behavior is // undefined if this variant is unset. Note that this method is // selected only if the template parameter type 'VISITOR' defines a // 'typedef' of 'ResultType' in its public interface. Also note that // this method is defined inline to work around a Windows compiler bug // with SFINAE functions. typedef Variant_RawVisitorHelper<typename VISITOR::ResultType, const VISITOR> Helper; return doApplyR<const Helper&, typename VISITOR::ResultType>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type applyRaw(VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()'. // This method does not return a value. The behavior is undefined if // this variant is unset. Note that this method is selected only if // the template parameter type 'VISITOR' does not define a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. typedef Variant_RawVisitorHelper<void, VISITOR> Helper; return doApply<const Helper&>(Helper(&visitor), this->d_type); } template <class VISITOR> typename bsl::enable_if<Variant_ReturnValueHelper<VISITOR>::value == 0, void>::type applyRaw(const VISITOR& visitor) const { // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()'. // This method does not return a value. The behavior is undefined if // this variant is unset. Note that this method is selected only if // the template parameter type 'VISITOR' does not define a 'typedef' of // 'ResultType' in its public interface. Also note that this method is // defined inline to work around a Windows compiler bug with SFINAE // functions. typedef Variant_RawVisitorHelper<void, const VISITOR> Helper; return doApply<const Helper&>(Helper(&visitor), this->d_type); } template <class RET_TYPE, class VISITOR> RET_TYPE applyRaw(VISITOR& visitor) const; template <class RET_TYPE, class VISITOR> RET_TYPE applyRaw(const VISITOR& visitor) const; // Apply the specified 'visitor' to this variant by passing the value // this variant currently holds to the 'visitor' object's 'operator()', // and return the value (of template parameter 'RET_TYPE') returned by // the 'visitor'. The behavior is undefined if this variant is unset. template <class TYPE> bool is() const; // Return 'true' if the value held by this variant object is of // template parameter 'TYPE', and 'false' otherwise. 'TYPE' must be // the same as one of the types that this variant can hold. Note that // 'TYPE' must be specified explicitly, e.g., 'myValue.is<int>()'. bool isUnset() const; // Return 'true' if this variant is currently unset, and 'false' // otherwise. An unset variant does not hold a value or type. Note // that this method should be preferred over checking the type index of // the variant. bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; // Format this object to the specified output 'stream' at the (absolute // value of) the optionally specified indentation 'level', and return a // reference to 'stream'. If 'level' is specified, optionally specify // 'spacesPerLevel', the number of spaces per indentation level for // this and all of its nested objects. If 'level' is negative, // suppress indentation of the first line. If 'spacesPerLevel' is // negative, format the entire output on one line, suppressing all but // the initial indentation (as governed by 'level'). If 'stream' is // not valid on entry, this operation has no effect. Nothing is // printed if this variant is unset. Each type that may be contained // by this variant shall be printable with 'bdlb::PrintMethods' // (typically meaning that they either declare the // 'bdlb::HasPrintMethod' trait or provide the '<<' output streaming // operator). See {'bdlb_printmethods'}. The compiler will emit an // error if 'bdlb::PrintMethods::print' cannot be instantiated for each // type that may be contained by this variant. template <class TYPE> const TYPE& the() const; // Return a reference providing non-modifiable access to the value of // template parameter 'TYPE' held by this variant object. 'TYPE' must // be the same as one of the types that this variant can hold. The // behavior is undefined unless 'is<TYPE>()' returns 'true' and 'TYPE' // is not 'void'. Note that 'TYPE' must be specified explicitly, e.g., // 'myValue.the<int>()'. int typeIndex() const; // Return the index in the list of 'TYPES' corresponding to the type of // the value currently held by this variant object (starting at 1), or // 0 if this object is unset. Note that instead of switching code on // the type index, calling 'apply' is the preferred method of // manipulating different types stored inside a variant. #ifndef BDE_OMIT_INTERNAL_DEPRECATED const bsl::type_info& typeInfo() const; // Return 'typeid(void)'. // // DEPRECATED: Do not use. template <class STREAM> STREAM& bdexStreamIn(STREAM& stream, int version); // DEPRECATED: Do not use. int maxSupportedBdexVersion() const; // DEPRECATED: Do not use. template <class STREAM> STREAM& bdexStreamOut(STREAM& stream, int version) const; // DEPRECATED: Do not use. #endif // BDE_OMIT_INTERNAL_DEPRECATED }; // FREE OPERATORS template <class TYPES> bool operator==(const VariantImp<TYPES>& lhs, const VariantImp<TYPES>& rhs); // Return 'true' if the specified 'lhs' variant object has the same value // as the specified 'rhs' variant object, and 'false' otherwise. Two // variant objects have the same value if they are both set and hold // objects of the same type and same value, or are both unset. template <class TYPES> bool operator!=(const VariantImp<TYPES>& lhs, const VariantImp<TYPES>& rhs); // Return 'true' if the specified 'lhs' variant object does not have the // same value as the specified 'rhs' variant object, and 'false' otherwise. // Two variant objects do not have the same value if one is set and the // other is unset, or if they are both set but hold objects that differ in // type or value. template <class TYPES> bsl::ostream& operator<<(bsl::ostream& stream, const VariantImp<TYPES>& object); // Write the specified variant 'object' to the specified output 'stream' in // a single-line (human-readable) format, and return a reference to // 'stream'. // FREE FUNCTIONS template <class TYPES> void swap(VariantImp<TYPES>& a, VariantImp<TYPES>& b); // Swap the values of the specified 'a' and 'b' objects. This method // provides the no-throw guarantee if the 'TYPE' template parameter has a // no-throw 'swap' and the two variant objects being swapped has the same // type; otherwise this method provides the basic guarantee. // ================== // class Variant<...> // ================== #if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES) template <class ...TYPES> class Variant : public VariantImp<typename bslmf::TypeList<TYPES...>::ListType> { #else template <class A1 = bslmf::Nil, class A2 = bslmf::Nil, class A3 = bslmf::Nil, class A4 = bslmf::Nil, class A5 = bslmf::Nil, class A6 = bslmf::Nil, class A7 = bslmf::Nil, class A8 = bslmf::Nil, class A9 = bslmf::Nil, class A10 = bslmf::Nil, class A11 = bslmf::Nil, class A12 = bslmf::Nil, class A13 = bslmf::Nil, class A14 = bslmf::Nil, class A15 = bslmf::Nil, class A16 = bslmf::Nil, class A17 = bslmf::Nil, class A18 = bslmf::Nil, class A19 = bslmf::Nil, class A20 = bslmf::Nil> class Variant : public VariantImp<typename bslmf::TypeList< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::ListType> { #endif // This class provides a "variant" type, i.e., a type capable of storing // values from a list of template parameter types 'A1' to 'A20'. Note that // if the number 'N' of types is smaller than 20, 'AN+1' up to 'A20' // default to 'bslmf::Nil', but it is more economical to use 'VariantN', // which accepts exactly 'N' template arguments, as this leads to shorter // symbols and debug string information. // PRIVATE TYPES #if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES) typedef VariantImp<typename bslmf::TypeList<TYPES...>::ListType> Imp; typedef Variant<TYPES...> SelfType; // 'SelfType' is an alias to this class. #else typedef VariantImp<typename bslmf::TypeList<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::ListType> Imp; typedef Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20> SelfType; // 'SelfType' is an alias to this class. #endif typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant, HasPrintMethod); // CREATORS Variant(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant(const Variant& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant(bslmf::MovableRef<Variant> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant(bslmf::MovableRef<Variant> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant& operator=(const Variant& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant& operator=(bslmf::MovableRef<Variant> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant2<...> // =================== template <class A1, class A2> class Variant2 : public VariantImp<typename bslmf::TypeList2< A1, A2>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (2) of // types. Its 2 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList2<A1, A2>::ListType> Imp; typedef Variant2<A1, A2> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant2, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant2, HasPrintMethod); // CREATORS Variant2(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant2(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant2(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant2(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant2(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant2(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant2(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant2(const Variant2& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant2(bslmf::MovableRef<Variant2> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant2(bslmf::MovableRef<Variant2> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant2& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant2& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant2& operator=(const Variant2& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant2& operator=(bslmf::MovableRef<Variant2> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant3<...> // =================== template <class A1, class A2, class A3> class Variant3 : public VariantImp<typename bslmf::TypeList3< A1, A2, A3>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (3) of // types. Its 3 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, A3>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList3<A1, A2, A3>::ListType> Imp; typedef Variant3<A1, A2, A3> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant3, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant3, HasPrintMethod); // CREATORS Variant3(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant3(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant3(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant3(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant3(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant3(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant3(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant3(const Variant3& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant3(bslmf::MovableRef<Variant3> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant3(bslmf::MovableRef<Variant3> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant3& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant3& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant3& operator=(const Variant3& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant3& operator=(bslmf::MovableRef<Variant3> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant4<...> // =================== template <class A1, class A2, class A3, class A4> class Variant4 : public VariantImp<typename bslmf::TypeList4< A1, A2, A3, A4>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (4) of // types. Its 4 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A4>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList4<A1, A2, A3, A4>::ListType> Imp; typedef Variant4<A1, A2, A3, A4> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant4, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant4, HasPrintMethod); // CREATORS Variant4(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant4(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant4(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant4(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant4(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant4(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant4(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant4(const Variant4& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant4(bslmf::MovableRef<Variant4> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant4(bslmf::MovableRef<Variant4> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant4& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant4& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant4& operator=(const Variant4& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant4& operator=(bslmf::MovableRef<Variant4> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant5<...> // =================== template <class A1, class A2, class A3, class A4, class A5> class Variant5 : public VariantImp<typename bslmf::TypeList5< A1, A2, A3, A4, A5>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (5) of // types. Its 5 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A5>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList5<A1, A2, A3, A4, A5>::ListType> Imp; typedef Variant5<A1, A2, A3, A4, A5> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant5, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant5, HasPrintMethod); // CREATORS Variant5(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant5(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant5(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant5(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant5(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant5(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant5(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant5(const Variant5& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant5(bslmf::MovableRef<Variant5> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant5(bslmf::MovableRef<Variant5> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant5& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant5& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant5& operator=(const Variant5& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant5& operator=(bslmf::MovableRef<Variant5> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant6<...> // =================== template <class A1, class A2, class A3, class A4, class A5, class A6> class Variant6 : public VariantImp<typename bslmf::TypeList6< A1, A2, A3, A4, A5, A6>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (6) of // types. Its 6 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A6>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList6<A1, A2, A3, A4, A5, A6>::ListType> Imp; typedef Variant6<A1, A2, A3, A4, A5, A6> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant6, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant6, HasPrintMethod); // CREATORS Variant6(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant6(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant6(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant6(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant6(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant6(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant6(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant6(const Variant6& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant6(bslmf::MovableRef<Variant6> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant6(bslmf::MovableRef<Variant6> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant6& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant6& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant6& operator=(const Variant6& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant6& operator=(bslmf::MovableRef<Variant6> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant7<...> // =================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> class Variant7 : public VariantImp<typename bslmf::TypeList7< A1, A2, A3, A4, A5, A6, A7>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (7) of // types. Its 7 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A7>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList7<A1, A2, A3, A4, A5, A6, A7>::ListType> Imp; typedef Variant7<A1, A2, A3, A4, A5, A6, A7> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant7, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant7, HasPrintMethod); // CREATORS Variant7(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant7(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant7(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant7(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant7(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant7(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant7(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant7(const Variant7& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant7(bslmf::MovableRef<Variant7> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant7(bslmf::MovableRef<Variant7> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant7& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant7& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant7& operator=(const Variant7& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant7& operator=(bslmf::MovableRef<Variant7> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant8<...> // =================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> class Variant8 : public VariantImp<typename bslmf::TypeList8< A1, A2, A3, A4, A5, A6, A7, A8>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (8) of // types. Its 8 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A8>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList8<A1, A2, A3, A4, A5, A6, A7, A8>::ListType> Imp; typedef Variant8<A1, A2, A3, A4, A5, A6, A7, A8> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant8, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant8, HasPrintMethod); // CREATORS Variant8(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant8(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant8(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant8(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant8(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant8(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant8(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant8(const Variant8& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant8(bslmf::MovableRef<Variant8> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant8(bslmf::MovableRef<Variant8> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant8& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant8& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant8& operator=(const Variant8& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant8& operator=(bslmf::MovableRef<Variant8> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // =================== // class Variant9<...> // =================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> class Variant9 : public VariantImp<typename bslmf::TypeList9< A1, A2, A3, A4, A5, A6, A7, A8, A9>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (9) of // types. Its 9 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A9>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::ListType> Imp; typedef Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant9, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant9, HasPrintMethod); // CREATORS Variant9(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant9(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant9(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant9(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant9(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant9(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant9(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant9(const Variant9& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant9(bslmf::MovableRef<Variant9> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant9(bslmf::MovableRef<Variant9> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant9& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant9& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant9& operator=(const Variant9& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant9& operator=(bslmf::MovableRef<Variant9> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant10<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> class Variant10 : public VariantImp<typename bslmf::TypeList10< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (10) of // types. Its 10 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A10>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::ListType> Imp; typedef Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant10, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant10, HasPrintMethod); // CREATORS Variant10(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant10(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant10(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant10(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant10(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant10(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant10(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant10(const Variant10& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant10(bslmf::MovableRef<Variant10> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant10(bslmf::MovableRef<Variant10> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant10& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant10& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant10& operator=(const Variant10& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant10& operator=(bslmf::MovableRef<Variant10> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant11<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> class Variant11 : public VariantImp<typename bslmf::TypeList11< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (11) of // types. Its 11 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A11>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::ListType> Imp; typedef Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant11, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant11, HasPrintMethod); // CREATORS Variant11(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant11(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant11(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant11(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant11(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant11(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant11(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant11(const Variant11& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant11(bslmf::MovableRef<Variant11> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant11(bslmf::MovableRef<Variant11> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant11& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant11& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant11& operator=(const Variant11& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant11& operator=(bslmf::MovableRef<Variant11> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant12<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> class Variant12 : public VariantImp<typename bslmf::TypeList12< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (12) of // types. Its 12 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A12>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>::ListType> Imp; typedef Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant12, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant12, HasPrintMethod); // CREATORS Variant12(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant12(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant12(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant12(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant12(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant12(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant12(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant12(const Variant12& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant12(bslmf::MovableRef<Variant12> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant12(bslmf::MovableRef<Variant12> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant12& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant12& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant12& operator=(const Variant12& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant12& operator=(bslmf::MovableRef<Variant12> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant13<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> class Variant13 : public VariantImp<typename bslmf::TypeList13< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (13) of // types. Its 13 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A13>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>::ListType> Imp; typedef Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant13, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant13, HasPrintMethod); // CREATORS Variant13(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant13(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant13(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant13(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant13(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant13(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant13(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant13(const Variant13& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant13(bslmf::MovableRef<Variant13> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant13(bslmf::MovableRef<Variant13> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant13& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant13& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant13& operator=(const Variant13& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant13& operator=(bslmf::MovableRef<Variant13> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant14<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> class Variant14 : public VariantImp<typename bslmf::TypeList14< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (14) of // types. Its 14 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A14>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>::ListType> Imp; typedef Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant14, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant14, HasPrintMethod); // CREATORS Variant14(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant14(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant14(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant14(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant14(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant14(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant14(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant14(const Variant14& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant14(bslmf::MovableRef<Variant14> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant14(bslmf::MovableRef<Variant14> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant14& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant14& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant14& operator=(const Variant14& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant14& operator=(bslmf::MovableRef<Variant14> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant15<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> class Variant15 : public VariantImp<typename bslmf::TypeList15< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (15) of // types. Its 15 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A15>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>::ListType> Imp; typedef Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant15, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant15, HasPrintMethod); // CREATORS Variant15(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant15(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant15(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant15(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant15(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant15(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant15(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant15(const Variant15& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant15(bslmf::MovableRef<Variant15> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant15(bslmf::MovableRef<Variant15> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant15& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant15& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant15& operator=(const Variant15& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant15& operator=(bslmf::MovableRef<Variant15> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant16<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> class Variant16 : public VariantImp<typename bslmf::TypeList16< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (16) of // types. Its 16 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A16>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>::ListType> Imp; typedef Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant16, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant16, HasPrintMethod); // CREATORS Variant16(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant16(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant16(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant16(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant16(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant16(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant16(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant16(const Variant16& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant16(bslmf::MovableRef<Variant16> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant16(bslmf::MovableRef<Variant16> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant16& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant16& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant16& operator=(const Variant16& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant16& operator=(bslmf::MovableRef<Variant16> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant17<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> class Variant17 : public VariantImp<typename bslmf::TypeList17< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (17) of // types. Its 17 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A17>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>::ListType> Imp; typedef Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant17, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant17, HasPrintMethod); // CREATORS Variant17(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant17(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant17(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant17(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant17(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant17(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant17(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant17(const Variant17& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant17(bslmf::MovableRef<Variant17> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant17(bslmf::MovableRef<Variant17> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant17& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant17& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant17& operator=(const Variant17& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant17& operator=(bslmf::MovableRef<Variant17> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant18<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> class Variant18 : public VariantImp<typename bslmf::TypeList18< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (18) of // types. Its 18 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A18>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>::ListType> Imp; typedef Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant18, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant18, HasPrintMethod); // CREATORS Variant18(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant18(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant18(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant18(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant18(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant18(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant18(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant18(const Variant18& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant18(bslmf::MovableRef<Variant18> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant18(bslmf::MovableRef<Variant18> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant18& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant18& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant18& operator=(const Variant18& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant18& operator=(bslmf::MovableRef<Variant18> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ==================== // class Variant19<...> // ==================== template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> class Variant19 : public VariantImp<typename bslmf::TypeList19< A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>::ListType> { // This class is a "specialization" of 'Variant' for a fixed number (19) of // types. Its 19 template arguments *must* all be specified (none are // defaulted to 'bslmf::Nil'). It provides the same functionality as // 'Variant<A1, A2, ..., A19>'. // PRIVATE TYPES typedef VariantImp<typename bslmf::TypeList19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>::ListType> Imp; typedef Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19> SelfType; // 'SelfType' is an alias to this class. typedef VariantImp_Traits<typename Imp::TypeList> Traits; typedef bslmf::MovableRefUtil MoveUtil; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bslma::UsesBslmaAllocator, Traits::k_VARIANT_USES_BSLMA_ALLOCATOR); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bsl::is_trivially_copyable, Traits::k_VARIANT_IS_BITWISE_COPYABLE); BSLMF_NESTED_TRAIT_DECLARATION_IF(Variant19, bslmf::IsBitwiseMoveable, Traits::k_VARIANT_IS_BITWISE_MOVEABLE); BSLMF_NESTED_TRAIT_DECLARATION(Variant19, HasPrintMethod); // CREATORS Variant19(); // Create a variant object in the unset state that uses the currently // installed default allocator to supply memory. template <class TYPE_OR_ALLOCATOR> explicit Variant19(const TYPE_OR_ALLOCATOR& valueOrAllocator); // Create a variant object with the specified 'valueOrAllocator' that // can be either a value of a type that the variant can hold or an // allocator to supply memory. If 'valueOrAllocator' is not a // 'bslma::Allocator *', then the variant will hold the value and type // of 'valueOrAllocator', and use the currently installed default // allocator to supply memory. Otherwise, the variant will be unset // and use 'valueOrAllocator' to supply memory. 'TYPE_OR_ALLOCATOR' // must be the same as one of the types that this variant can hold or // be convertible to 'bslma::Allocator *'. Note that this // parameterized constructor is defined instead of two constructors // (one taking a 'bslma::Allocator *' and the other not) because // template parameter arguments are always a better match than // derived-to-base conversion (a concrete allocator pointer converted // to 'bslma::Allocator *'). template <class TYPE> Variant19(const TYPE& value, bslma::Allocator *basicAllocator); // Create a variant object having the specified 'value' of template // parameter 'TYPE' and that uses the specified 'basicAllocator' to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. 'TYPE' must be the same as one of the // types that this variant can hold. template <class TYPE> explicit #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant19(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type * = 0); #else Variant19(bslmf::MovableRef<TYPE> value); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' by moving the contents of 'value' to the // newly-created object. Use the currently installed default allocator // to supply memory. 'value' is left in a valid but unspecified state. // 'TYPE' must be the same as one of the types that this variant can // hold. Note that in C++11 mode, this method does not participate in // overload resolution if it would lead to ambiguity with the move // constructor that does not take an allocator (below) or with the // constructor taking a 'valueOrAllocator' (above). template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant19(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator); #else Variant19(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator); #endif // Create a variant object having the specified 'value' of template // parameter 'TYPE' that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'value' are moved to the // newly-created object with 'value' left in a valid but unspecified // state. 'TYPE' must be the same as one of the types that this // variant can hold. Note that in C++11 mode, this method does not // participate in overload resolution if it would lead to ambiguity // with the move constructor that takes an allocator (below). Variant19(const Variant19& original, bslma::Allocator *basicAllocator = 0); // Create a variant object having the type and value of the specified // 'original' variant. Optionally specify a 'basicAllocator' used to // supply memory. If 'basicAllocator' is 0, the currently installed // default allocator is used. Variant19(bslmf::MovableRef<Variant19> original); // Create a variant object having the type and value of the specified // 'original' object by moving the contents of 'original' to the // newly-created object. The allocator associated with 'original' (if // any) is propagated for use in the newly-created object. 'original' // is left in a valid but unspecified state. Variant19(bslmf::MovableRef<Variant19> original, bslma::Allocator *basicAllocator); // Create a variant object having the type and value of the specified // 'original' object that uses the specified 'basicAllocator' to supply // memory. If 'basicAllocator' is 0, the currently installed default // allocator is used. The contents of 'original' are moved to the // newly-created object with 'original' left in a valid but unspecified // state. // MANIPULATORS template <class TYPE> Variant19& operator=(const TYPE& value); // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The value currently held by this variant (if any) is // destroyed if that value's type is not the same as 'TYPE'. 'TYPE' // must be the same as one of the types that this variant can hold. template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<SelfType, typename bsl::remove_cvref<TYPE>::type>::value, SelfType>::type& operator=(TYPE&& value); #else Variant19& operator=(bslmf::MovableRef<TYPE> value); #endif // Assign to this object the specified 'value' of template parameter // 'TYPE', and return a reference providing modifiable access to this // object. The contents of 'value' are moved to this object with // 'value' left in a valid but unspecified state. The value currently // held by this variant (if any) is destroyed if that value's type is // not the same as 'TYPE'. 'TYPE' must be the same as one of the types // that this variant can hold. Note that in C++11 mode, this method // does not participate in overload resolution if it would lead to // ambiguity with the move-assignment operator (below). Variant19& operator=(const Variant19& rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. Variant19& operator=(bslmf::MovableRef<Variant19> rhs); // Assign to this object the type and value currently held by the // specified 'rhs' object, and return a reference providing modifiable // access to this object. The value currently held by this variant // (if any) is destroyed if that value's type is not the same as the // type held by the 'rhs' object. The contents of 'rhs' are either // move-inserted into or move-assigned to this object with 'rhs' left // in a valid but unspecified state. }; // ---- Anything below this line is implementation specific. Do not use. ---- // ===================================== // struct Variant_TypeIndex<TYPES, TYPE> // ===================================== template <class TYPES, class TYPE> struct Variant_TypeIndex { // Component-private meta-function. Do not use. This meta-function // computes the index of the template parameter 'TYPE' in the template // parameter list of 'TYPES'. enum { value = bsl::is_same< typename bslmf::TypeListTypeOf< 1, TYPES>::TypeOrDefault, TYPE>::value ? 1 : bsl::is_same< typename bslmf::TypeListTypeOf< 2, TYPES>::TypeOrDefault, TYPE>::value ? 2 : bsl::is_same< typename bslmf::TypeListTypeOf< 3, TYPES>::TypeOrDefault, TYPE>::value ? 3 : bsl::is_same< typename bslmf::TypeListTypeOf< 4, TYPES>::TypeOrDefault, TYPE>::value ? 4 : bsl::is_same< typename bslmf::TypeListTypeOf< 5, TYPES>::TypeOrDefault, TYPE>::value ? 5 : bsl::is_same< typename bslmf::TypeListTypeOf< 6, TYPES>::TypeOrDefault, TYPE>::value ? 6 : bsl::is_same< typename bslmf::TypeListTypeOf< 7, TYPES>::TypeOrDefault, TYPE>::value ? 7 : bsl::is_same< typename bslmf::TypeListTypeOf< 8, TYPES>::TypeOrDefault, TYPE>::value ? 8 : bsl::is_same< typename bslmf::TypeListTypeOf< 9, TYPES>::TypeOrDefault, TYPE>::value ? 9 : bsl::is_same< typename bslmf::TypeListTypeOf<10, TYPES>::TypeOrDefault, TYPE>::value ? 10 : bsl::is_same< typename bslmf::TypeListTypeOf<11, TYPES>::TypeOrDefault, TYPE>::value ? 11 : bsl::is_same< typename bslmf::TypeListTypeOf<12, TYPES>::TypeOrDefault, TYPE>::value ? 12 : bsl::is_same< typename bslmf::TypeListTypeOf<13, TYPES>::TypeOrDefault, TYPE>::value ? 13 : bsl::is_same< typename bslmf::TypeListTypeOf<14, TYPES>::TypeOrDefault, TYPE>::value ? 14 : bsl::is_same< typename bslmf::TypeListTypeOf<15, TYPES>::TypeOrDefault, TYPE>::value ? 15 : bsl::is_same< typename bslmf::TypeListTypeOf<16, TYPES>::TypeOrDefault, TYPE>::value ? 16 : bsl::is_same< typename bslmf::TypeListTypeOf<17, TYPES>::TypeOrDefault, TYPE>::value ? 17 : bsl::is_same< typename bslmf::TypeListTypeOf<18, TYPES>::TypeOrDefault, TYPE>::value ? 18 : bsl::is_same< typename bslmf::TypeListTypeOf<19, TYPES>::TypeOrDefault, TYPE>::value ? 19 : bsl::is_same< typename bslmf::TypeListTypeOf<20, TYPES>::TypeOrDefault, TYPE>::value ? 20 : bsl::is_convertible<TYPE, bslma::Allocator *>::value ? 21 : 0 }; BSLMF_ASSERT(0 != value); #if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES) // See 'testCase17' in the test driver for code snippets that motivate this // compile-time assertion (see the "out of bounds" comments). In C++03, // 'TYPES::LENGTH' yields an incorrect value if 'TYPES' has a trailing // 'bslmf::Nil' (unless the variant is declared using 'VariantN'). It is // arguably dubious to allow 'bslmf::Nil' as one of the types that a // variant may hold, but there is such use in production code that needs to // be considered if that "feature" is to be suppressed. This would do it: //.. // BSLMF_ASSERT((!bsl::is_same<TYPE, bslmf::Nil>::value)); //.. // TBD The following breaks compilation of some client code in C++11 mode // that is most likely misusing 'bslmf::Nil'. // BSLMF_ASSERT(((int)value <= (int)TYPES::LENGTH || 21 == value)); #endif }; // ====================================== // struct Variant_DefaultConstructVisitor // ====================================== struct Variant_DefaultConstructVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', will create a default // instance of 'TYPE'. // PUBLIC DATA bslma::Allocator *d_allocator_p; // CREATORS explicit Variant_DefaultConstructVisitor(bslma::Allocator *allocator) : d_allocator_p(allocator) { } // ACCESSORS template <class TYPE> void operator()(TYPE& value) const { bslma::ConstructionUtil::construct(&value, d_allocator_p); } }; // =================================== // struct Variant_CopyConstructVisitor // =================================== struct Variant_CopyConstructVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', will copy-insert that // instance to create an instance of the same 'TYPE' in an uninitialized // buffer specified at construction of this visitor. // PUBLIC DATA void *d_buffer_p; bslma::Allocator *d_allocator_p; // CREATORS Variant_CopyConstructVisitor(void *buffer, bslma::Allocator *allocator) : d_buffer_p(buffer) , d_allocator_p(allocator) { BSLS_ASSERT_SAFE(d_buffer_p); } // ACCESSORS template <class TYPE> void operator()(const TYPE& value) const { bslma::ConstructionUtil::construct( reinterpret_cast<TYPE *>(d_buffer_p), d_allocator_p, value); } }; // =================================== // struct Variant_MoveConstructVisitor // =================================== struct Variant_MoveConstructVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', will move-insert that // instance to create an instance of the same 'TYPE' in an uninitialized // buffer specified at construction of this visitor. // PUBLIC DATA void *d_buffer_p; bslma::Allocator *d_allocator_p; // CREATORS Variant_MoveConstructVisitor(void *buffer, bslma::Allocator *allocator) : d_buffer_p(buffer) , d_allocator_p(allocator) { BSLS_ASSERT_SAFE(d_buffer_p); } // ACCESSORS template <class TYPE> void operator()(TYPE& value) const { bslma::ConstructionUtil::construct( reinterpret_cast<TYPE *>(d_buffer_p), d_allocator_p, bslmf::MovableRefUtil::move(value)); } }; // ================================ // struct Variant_DestructorVisitor // ================================ struct Variant_DestructorVisitor { // This visitor, when invoked as a function object on an instance of some // template parameter 'TYPE', will destroy that instance. // ACCESSORS template <class TYPE> void operator()(TYPE& object) const { bslma::DestructionUtil::destroy(&object); } }; // ================================ // struct Variant_CopyAssignVisitor // ================================ struct Variant_CopyAssignVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', will copy-assign that // instance to the instance of the same 'TYPE' held in a buffer specified // at construction of this visitor. // PUBLIC DATA void *d_buffer_p; // CREATORS explicit Variant_CopyAssignVisitor(void *buffer) : d_buffer_p(buffer) { BSLS_ASSERT_SAFE(d_buffer_p); } // ACCESSORS template <class TYPE> void operator()(const TYPE& value) { *reinterpret_cast<TYPE *>(d_buffer_p) = value; } }; // ================================ // struct Variant_MoveAssignVisitor // ================================ struct Variant_MoveAssignVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', will move-assign that // instance to the instance of the same 'TYPE' held in a buffer specified // at construction of this visitor. // PUBLIC DATA void *d_buffer_p; // CREATORS explicit Variant_MoveAssignVisitor(void *buffer) : d_buffer_p(buffer) { BSLS_ASSERT_SAFE(d_buffer_p); } // ACCESSORS template <class TYPE> void operator()(TYPE& value) { *reinterpret_cast<TYPE *>(d_buffer_p) = bslmf::MovableRefUtil::move(value); } }; // ========================== // struct Variant_SwapVisitor // ========================== struct Variant_SwapVisitor { // This visitor swaps the variant object data that it holds with another // variant object data of parameterize 'TYPE'. It requires that the two // variant objects being swapped contain data of the same type, and use the // same allocator. // PUBLIC DATA void *d_buffer_p; // CREATORS explicit Variant_SwapVisitor(void *buffer) : d_buffer_p(buffer) { BSLS_ASSERT_SAFE(d_buffer_p); } // MANIPULATORS template <class TYPE> void operator()(TYPE& value) { bslalg::SwapUtil::swap(reinterpret_cast<TYPE *>(d_buffer_p), &value); } }; #ifndef BDE_OMIT_INTERNAL_DEPRECATED // ================================== // struct Variant_BdexStreamInVisitor // ================================== template <class STREAM> struct Variant_BdexStreamInVisitor { // This visitor, when invoked as a non-modifiable function object on an // initialized instance of some parameterized 'TYPE', will stream in // a value of the same 'TYPE' into that instance from a stream specified at // construction of this visitor, using a version also specified at // construction of this visitor. // PUBLIC DATA STREAM& d_stream; // held, not owned int d_version; // BDEX version // CREATORS Variant_BdexStreamInVisitor(STREAM& stream, int version) : d_stream(stream) , d_version(version) { } // ACCESSORS template <class VALUETYPE> inline void operator()(VALUETYPE& object) const { bslx::InStreamFunctions::bdexStreamIn(d_stream, object, d_version); } inline void operator()(bslmf::Nil) const { // no op } }; // =================================== // struct Variant_BdexStreamOutVisitor // =================================== template <class STREAM> struct Variant_BdexStreamOutVisitor { // This visitor, when invoked as a non-modifiable function object on an // initialized instance of some parameterized 'TYPE', will stream out the // value of that instance into a stream specified at construction of this // visitor, using a version also specified at construction of this // visitor. // PUBLIC DATA STREAM& d_stream; // held, not owned int d_version; // BDEX version // CREATORS Variant_BdexStreamOutVisitor(STREAM& stream, int version) : d_stream(stream) , d_version(version) { } // ACCESSORS template <class VALUETYPE> inline void operator()(const VALUETYPE& object) const { bslx::OutStreamFunctions::bdexStreamOut(d_stream, object, d_version); } inline void operator()(bslmf::Nil) const { // no op } }; #endif // =========================== // struct Variant_PrintVisitor // =========================== struct Variant_PrintVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', writes the value of that // instance to a stream specified at construction of this visitor, using // spacing information also specified at construction. // PUBLIC DATA bsl::ostream *d_stream_p; // held, not owned int d_level; int d_spacesPerLevel; // CREATORS Variant_PrintVisitor(bsl::ostream *stream, int level, int spacesPerLevel) : d_stream_p(stream) , d_level(level) , d_spacesPerLevel(spacesPerLevel) { BSLS_ASSERT_SAFE(d_stream_p); } // ACCESSORS template <class TYPE> void operator()(const TYPE& value) const { PrintMethods::print(*d_stream_p, value, d_level, d_spacesPerLevel); } void operator()(bslmf::Nil) const { // no op } }; // ================================== // struct Variant_EqualityTestVisitor // ================================== struct Variant_EqualityTestVisitor { // This visitor, when invoked as a non-modifiable function object on an // instance of some template parameter 'TYPE', tests the equality of the // value of that instance and of another instance held in a buffer // specified at construction of this visitor, and stores the result into // its publicly accessible 'd_result' member. // PUBLIC DATA mutable bool d_result; const void *d_buffer_p; // held, not owned // CREATORS explicit Variant_EqualityTestVisitor(const void *buffer) : d_result(true) , d_buffer_p(buffer) { BSLS_ASSERT_SAFE(d_buffer_p); } // ACCESSORS template <class TYPE> void operator()(const TYPE& value) const { d_result = *reinterpret_cast<const TYPE *>(d_buffer_p) == value; } void operator()(bslmf::Nil) const { d_result = true; } }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------------------- // class VariantImp_AllocatorBase<TYPES> // ------------------------------------- // CREATORS template <class TYPES> inline VariantImp_AllocatorBase<TYPES>:: VariantImp_AllocatorBase(int type, bslma::Allocator *basicAllocator) : d_type(type) , d_allocator_p(bslma::Default::allocator(basicAllocator)) { } template <class TYPES> inline VariantImp_AllocatorBase<TYPES>:: VariantImp_AllocatorBase(int, bslma::Allocator *basicAllocator, bsl::true_type) : d_type(0) , d_allocator_p(bslma::Default::allocator(basicAllocator)) { } template <class TYPES> template <class TYPE> inline VariantImp_AllocatorBase<TYPES>:: VariantImp_AllocatorBase(int type, const TYPE&, bsl::false_type) : d_type(type) , d_allocator_p(bslma::Default::allocator(0)) { } // ACCESSORS template <class TYPES> inline bslma::Allocator * VariantImp_AllocatorBase<TYPES>::getAllocator() const { return d_allocator_p; } // --------------------------------------- // class VariantImp_NoAllocatorBase<TYPES> // --------------------------------------- // CREATORS template <class TYPES> inline VariantImp_NoAllocatorBase<TYPES>:: VariantImp_NoAllocatorBase(int type, bslma::Allocator *) : d_type(type) { } template <class TYPES> inline VariantImp_NoAllocatorBase<TYPES>:: VariantImp_NoAllocatorBase(int, bslma::Allocator *, bsl::true_type) : d_type(0) { } template <class TYPES> template <class TYPE> inline VariantImp_NoAllocatorBase<TYPES>:: VariantImp_NoAllocatorBase(int type, const TYPE&, bsl::false_type) : d_type(type) { } // ACCESSORS template <class TYPES> inline bslma::Allocator * VariantImp_NoAllocatorBase<TYPES>::getAllocator() const { return 0; } // ------------------------------- // class Variant_ReturnAnyTypeUtil // ------------------------------- // CLASS METHODS template <class TYPE> inline TYPE Variant_ReturnAnyTypeUtil<TYPE>::doNotCall(TYPE *dummy) { #ifdef BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES return bslmf::MovableRefUtil::move(*dummy); #else return *dummy; #endif } template <class TYPE> inline TYPE Variant_ReturnAnyTypeUtil<TYPE>::doNotCall() { // Note that IBM xlC requires that we explicitly declare a temporary here, // rather than cast the null pointer directly as a function argument. typedef typename bsl::remove_reference<TYPE>::type UnrefType; UnrefType *const ptr = 0; return doNotCall(ptr); } inline void Variant_ReturnAnyTypeUtil<void>::doNotCall() {} template <class TYPE> inline TYPE& Variant_ReturnAnyTypeUtil<TYPE&>::lvalueRef(TYPE *dummy) { return *dummy; } template <class TYPE> inline TYPE& Variant_ReturnAnyTypeUtil<TYPE&>::doNotCall() { TYPE *const ptr = 0; return lvalueRef(ptr); } #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) template <class TYPE> inline TYPE&& Variant_ReturnAnyTypeUtil<TYPE&&>::rvalueRef(TYPE *dummy) { return bslmf::MovableRefUtil::move(*dummy); } template <class TYPE> inline TYPE&& Variant_ReturnAnyTypeUtil<TYPE&&>::doNotCall() { TYPE *const ptr = 0; return rvalueRef(ptr); } #endif // ------------------------------ // class Variant_RawVisitorHelper // ------------------------------ // CREATORS template <class RESULT_TYPE, class VISITOR> inline Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>:: Variant_RawVisitorHelper(VISITOR *visitor) : d_visitor(visitor) { BSLS_ASSERT_SAFE(0 != visitor); } // MANIPULATORS template <class RESULT_TYPE, class VISITOR> template <class ARGUMENT_TYPE> inline RESULT_TYPE Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>::operator()( ARGUMENT_TYPE& argument) { return static_cast<RESULT_TYPE>((*d_visitor)(argument)); } template <class RESULT_TYPE, class VISITOR> template <class ARGUMENT_TYPE> inline RESULT_TYPE Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>::operator()( const ARGUMENT_TYPE& argument) { return static_cast<RESULT_TYPE>((*d_visitor)(argument)); } // ACCESSORS template <class RESULT_TYPE, class VISITOR> template <class ARGUMENT_TYPE> inline RESULT_TYPE Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>::operator()( ARGUMENT_TYPE& argument) const { return static_cast<RESULT_TYPE>((*d_visitor)(argument)); } template <class RESULT_TYPE, class VISITOR> template <class ARGUMENT_TYPE> inline RESULT_TYPE Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>::operator()( const ARGUMENT_TYPE& argument) const { return static_cast<RESULT_TYPE>((*d_visitor)(argument)); } template <class RESULT_TYPE, class VISITOR> RESULT_TYPE Variant_RawVisitorHelper<RESULT_TYPE, VISITOR>::operator()(bslmf::Nil) const { BSLS_ASSERT_OPT(false); return Variant_ReturnAnyTypeUtil<RESULT_TYPE>::doNotCall(); } // ----------------------- // class VariantImp<TYPES> // ----------------------- // PRIVATE MANIPULATORS template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::false_type) { typedef bsls::ObjectBuffer<TYPE> BufferType; visitor(reinterpret_cast<BufferType *>(&this->d_value)->object()); } template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::true_type) { bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor) { typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset; applyImp<TYPE, VISITOR_REF>(visitor, IsUnset()); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::false_type) { typedef bsls::ObjectBuffer<TYPE> BufferType; return visitor(reinterpret_cast<BufferType *>(&this->d_value)->object()); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::true_type) { bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor) { typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset; return applyImpR<TYPE, VISITOR_REF, RET_TYPE>(visitor, IsUnset()); } template <class TYPES> template <class TYPE, class SOURCE_TYPE> void VariantImp<TYPES>::assignImp(const SOURCE_TYPE& value) { typedef bsls::ObjectBuffer<TYPE> BufferType; reset(); bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), value); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; } template <class TYPES> template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) void VariantImp<TYPES>::assignImp(TYPE&& value) #else void VariantImp<TYPES>::assignImp(bslmf::MovableRef<TYPE> value) #endif { typedef bsls::ObjectBuffer<typename bsl::remove_reference<TYPE>::type> BufferType; reset(); #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), bslmf::MovableRefUtil::move(lvalue)); #endif this->d_type = Variant_TypeIndex<TYPES, typename bsl::remove_reference<TYPE>::type>::value; } template <class TYPES> template <class VISITOR_REF> void VariantImp<TYPES>::doApply(VISITOR_REF visitor, int type) { switch (type) { case 0: { BSLS_ASSERT(!"'doApply' invoked on an unset variant"); } break; case 1: { applyImp<typename Base::Type1, VISITOR_REF>(visitor); } break; case 2: { applyImp<typename Base::Type2, VISITOR_REF>(visitor); } break; case 3: { applyImp<typename Base::Type3, VISITOR_REF>(visitor); } break; case 4: { applyImp<typename Base::Type4, VISITOR_REF>(visitor); } break; case 5: { applyImp<typename Base::Type5, VISITOR_REF>(visitor); } break; case 6: { applyImp<typename Base::Type6, VISITOR_REF>(visitor); } break; case 7: { applyImp<typename Base::Type7, VISITOR_REF>(visitor); } break; case 8: { applyImp<typename Base::Type8, VISITOR_REF>(visitor); } break; case 9: { applyImp<typename Base::Type9, VISITOR_REF>(visitor); } break; case 10: { applyImp<typename Base::Type10, VISITOR_REF>(visitor); } break; case 11: { applyImp<typename Base::Type11, VISITOR_REF>(visitor); } break; case 12: { applyImp<typename Base::Type12, VISITOR_REF>(visitor); } break; case 13: { applyImp<typename Base::Type13, VISITOR_REF>(visitor); } break; case 14: { applyImp<typename Base::Type14, VISITOR_REF>(visitor); } break; case 15: { applyImp<typename Base::Type15, VISITOR_REF>(visitor); } break; case 16: { applyImp<typename Base::Type16, VISITOR_REF>(visitor); } break; case 17: { applyImp<typename Base::Type17, VISITOR_REF>(visitor); } break; case 18: { applyImp<typename Base::Type18, VISITOR_REF>(visitor); } break; case 19: { applyImp<typename Base::Type19, VISITOR_REF>(visitor); } break; case 20: { applyImp<typename Base::Type20, VISITOR_REF>(visitor); } break; default: { BSLS_ASSERT(!"Unreachable by design!"); } break; } } template <class TYPES> template <class TYPE> inline void VariantImp<TYPES>::create(const TYPE& value, bsl::false_type) { typedef bsls::ObjectBuffer<TYPE> BufferType; bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), value); } template <class TYPES> inline void VariantImp<TYPES>::create(bslma::Allocator *, bsl::true_type) { } template <class TYPES> template <class VISITOR_REF, class RET_TYPE> RET_TYPE VariantImp<TYPES>::doApplyR(VISITOR_REF visitor, int type) { switch (type) { case 0: { BSLS_ASSERT(!"'doApplyR' invoked on an unset variant"); } break; case 1: { return applyImpR<typename Base::Type1, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 2: { return applyImpR<typename Base::Type2, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 3: { return applyImpR<typename Base::Type3, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 4: { return applyImpR<typename Base::Type4, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 5: { return applyImpR<typename Base::Type5, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 6: { return applyImpR<typename Base::Type6, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 7: { return applyImpR<typename Base::Type7, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 8: { return applyImpR<typename Base::Type8, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 9: { return applyImpR<typename Base::Type9, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 10: { return applyImpR<typename Base::Type10, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 11: { return applyImpR<typename Base::Type11, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 12: { return applyImpR<typename Base::Type12, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 13: { return applyImpR<typename Base::Type13, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 14: { return applyImpR<typename Base::Type14, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 15: { return applyImpR<typename Base::Type15, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 16: { return applyImpR<typename Base::Type16, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 17: { return applyImpR<typename Base::Type17, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 18: { return applyImpR<typename Base::Type18, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 19: { return applyImpR<typename Base::Type19, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 20: { return applyImpR<typename Base::Type20, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; default: { BSLS_ASSERT(!"Unreachable by design!"); } break; } // Unreachable by design; return something to quiet compiler warnings. return Variant_ReturnAnyTypeUtil<RET_TYPE>::doNotCall(); } // PRIVATE ACCESSORS template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::false_type) const { typedef bsls::ObjectBuffer<TYPE> BufferType; visitor(reinterpret_cast<const BufferType *>(&this->d_value)->object()); } template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor, bsl::true_type) const { bslmf::Nil nil = bslmf::Nil(); visitor(nil); } template <class TYPES> template <class TYPE, class VISITOR_REF> inline void VariantImp<TYPES>::applyImp(VISITOR_REF visitor) const { typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset; applyImp<TYPE, VISITOR_REF>(visitor, IsUnset()); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::false_type) const { typedef bsls::ObjectBuffer<TYPE> BufferType; return visitor(reinterpret_cast<const BufferType *>( &this->d_value)->object()); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor, bsl::true_type) const { bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class TYPE, class VISITOR_REF, class RET_TYPE> inline RET_TYPE VariantImp<TYPES>::applyImpR(VISITOR_REF visitor) const { typedef typename bsl::is_same<TYPE, bslmf::Nil>::type IsUnset; return applyImpR<TYPE, VISITOR_REF, RET_TYPE>(visitor, IsUnset()); } template <class TYPES> template <class VISITOR_REF> void VariantImp<TYPES>::doApply(VISITOR_REF visitor, int type) const { switch (type) { case 0: { BSLS_ASSERT(!"'doApply' invoked on an unset variant"); } break; case 1: { applyImp<typename Base::Type1, VISITOR_REF>(visitor); } break; case 2: { applyImp<typename Base::Type2, VISITOR_REF>(visitor); } break; case 3: { applyImp<typename Base::Type3, VISITOR_REF>(visitor); } break; case 4: { applyImp<typename Base::Type4, VISITOR_REF>(visitor); } break; case 5: { applyImp<typename Base::Type5, VISITOR_REF>(visitor); } break; case 6: { applyImp<typename Base::Type6, VISITOR_REF>(visitor); } break; case 7: { applyImp<typename Base::Type7, VISITOR_REF>(visitor); } break; case 8: { applyImp<typename Base::Type8, VISITOR_REF>(visitor); } break; case 9: { applyImp<typename Base::Type9, VISITOR_REF>(visitor); } break; case 10: { applyImp<typename Base::Type10, VISITOR_REF>(visitor); } break; case 11: { applyImp<typename Base::Type11, VISITOR_REF>(visitor); } break; case 12: { applyImp<typename Base::Type12, VISITOR_REF>(visitor); } break; case 13: { applyImp<typename Base::Type13, VISITOR_REF>(visitor); } break; case 14: { applyImp<typename Base::Type14, VISITOR_REF>(visitor); } break; case 15: { applyImp<typename Base::Type15, VISITOR_REF>(visitor); } break; case 16: { applyImp<typename Base::Type16, VISITOR_REF>(visitor); } break; case 17: { applyImp<typename Base::Type17, VISITOR_REF>(visitor); } break; case 18: { applyImp<typename Base::Type18, VISITOR_REF>(visitor); } break; case 19: { applyImp<typename Base::Type19, VISITOR_REF>(visitor); } break; case 20: { applyImp<typename Base::Type20, VISITOR_REF>(visitor); } break; default: { BSLS_ASSERT(!"Unreachable by design!"); } break; } } template <class TYPES> template <class VISITOR_REF, class RET_TYPE> RET_TYPE VariantImp<TYPES>::doApplyR(VISITOR_REF visitor, int type) const { switch (type) { case 0: { BSLS_ASSERT(!"'doApplyR' invoked on an unset variant"); } break; case 1: { return applyImpR<typename Base::Type1, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 2: { return applyImpR<typename Base::Type2, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 3: { return applyImpR<typename Base::Type3, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 4: { return applyImpR<typename Base::Type4, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 5: { return applyImpR<typename Base::Type5, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 6: { return applyImpR<typename Base::Type6, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 7: { return applyImpR<typename Base::Type7, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 8: { return applyImpR<typename Base::Type8, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 9: { return applyImpR<typename Base::Type9, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 10: { return applyImpR<typename Base::Type10, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 11: { return applyImpR<typename Base::Type11, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 12: { return applyImpR<typename Base::Type12, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 13: { return applyImpR<typename Base::Type13, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 14: { return applyImpR<typename Base::Type14, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 15: { return applyImpR<typename Base::Type15, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 16: { return applyImpR<typename Base::Type16, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 17: { return applyImpR<typename Base::Type17, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 18: { return applyImpR<typename Base::Type18, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 19: { return applyImpR<typename Base::Type19, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; case 20: { return applyImpR<typename Base::Type20, VISITOR_REF, RET_TYPE>(visitor); // RETURN } break; default: { BSLS_ASSERT(!"Unreachable by design!"); } break; } // Unreachable by design; return something to quiet compiler warnings. return Variant_ReturnAnyTypeUtil<RET_TYPE>::doNotCall(); } // CREATORS template <class TYPES> inline VariantImp<TYPES>::VariantImp() : Base(0, 0) { } template <class TYPES> template <class TYPE_OR_ALLOCATOR> inline VariantImp<TYPES>::VariantImp(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Base(Variant_TypeIndex<TYPES, TYPE_OR_ALLOCATOR>::value, valueOrAllocator, bsl::integral_constant<bool, bsl::is_convertible<TYPE_OR_ALLOCATOR, bslma::Allocator *>::value>()) { enum { k_IS_ALLOCATOR = bsl::is_convertible<TYPE_OR_ALLOCATOR, bslma::Allocator *>::value }; create(valueOrAllocator, bsl::integral_constant<bool, k_IS_ALLOCATOR>()); } template <class TYPES> template <class TYPE> inline VariantImp<TYPES>::VariantImp(const TYPE& value, bslma::Allocator *basicAllocator) : Base(Variant_TypeIndex<TYPES, TYPE>::value, basicAllocator) { typedef bsls::ObjectBuffer<TYPE> BufferType; bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), value); } template <class TYPES> template <class TYPE> VariantImp<TYPES>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) #else VariantImp(bslmf::MovableRef<TYPE> value) #endif : Base(Variant_TypeIndex< TYPES, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, 0) { typedef bsls::ObjectBuffer< typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type> BufferType; #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), bslmf::MovableRefUtil::move(lvalue)); #endif } template <class TYPES> template <class TYPE> VariantImp<TYPES>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) #else VariantImp(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) #endif : Base(Variant_TypeIndex< TYPES, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, basicAllocator) { typedef bsls::ObjectBuffer< typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type> BufferType; #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; bslma::ConstructionUtil::construct( reinterpret_cast<BufferType *>(&this->d_value)->address(), this->getAllocator(), bslmf::MovableRefUtil::move(lvalue)); #endif } template <class TYPES> VariantImp<TYPES>::VariantImp(const VariantImp& original, bslma::Allocator *basicAllocator) : Base(original.d_type, basicAllocator) { if (this->d_type) { Variant_CopyConstructVisitor copyConstructor(&this->d_value, this->getAllocator()); original.apply(copyConstructor); } } template <class TYPES> VariantImp<TYPES>::VariantImp(bslmf::MovableRef<VariantImp> original) : Base(MoveUtil::access(original).d_type, MoveUtil::access(original).getAllocator()) { if (this->d_type) { Variant_MoveConstructVisitor moveConstructor(&this->d_value, this->getAllocator()); VariantImp& lvalue = original; lvalue.apply(moveConstructor); } } template <class TYPES> VariantImp<TYPES>::VariantImp(bslmf::MovableRef<VariantImp> original, bslma::Allocator *basicAllocator) : Base(MoveUtil::access(original).d_type, basicAllocator) { if (this->d_type) { Variant_MoveConstructVisitor moveConstructor(&this->d_value, this->getAllocator()); VariantImp& lvalue = original; lvalue.apply(moveConstructor); } } template <class TYPES> inline VariantImp<TYPES>::~VariantImp() { reset(); } // MANIPULATORS template <class TYPES> template <class TYPE> inline VariantImp<TYPES>& VariantImp<TYPES>::operator=(const TYPE& value) { return assign(value); } template <class TYPES> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<VariantImp<TYPES>, typename bsl::remove_cvref<TYPE>::type>::value, VariantImp<TYPES> >::type& VariantImp<TYPES>::operator=(TYPE&& value) #else VariantImp<TYPES>& VariantImp<TYPES>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) return assign(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; return assign(MoveUtil::move(lvalue)); #endif } template <class TYPES> VariantImp<TYPES>& VariantImp<TYPES>::operator=(const VariantImp& rhs) { if (&rhs != this) { if (this->d_type == rhs.d_type) { if (this->d_type) { Variant_CopyAssignVisitor assigner(&this->d_value); rhs.apply(assigner); } } else { reset(); if (rhs.d_type) { Variant_CopyConstructVisitor copyConstructor( &this->d_value, this->getAllocator()); rhs.apply(copyConstructor); this->d_type = rhs.d_type; } } } return *this; } template <class TYPES> VariantImp<TYPES>& VariantImp<TYPES>::operator=(bslmf::MovableRef<VariantImp> rhs) { VariantImp& lvalue = rhs; if (&lvalue != this) { if (this->d_type == lvalue.d_type) { if (this->d_type) { Variant_MoveAssignVisitor assigner(&this->d_value); lvalue.apply(assigner); } } else { reset(); if (lvalue.d_type) { Variant_MoveConstructVisitor moveConstructor( &this->d_value, this->getAllocator()); lvalue.apply(moveConstructor); this->d_type = lvalue.d_type; } } } return *this; } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor) { if (this->d_type) { return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor) { if (this->d_type) { return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class RET_TYPE, class VISITOR, class TYPE> inline RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor, const TYPE& defaultValue) { if (this->d_type) { return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class TYPES> template <class RET_TYPE, class VISITOR, class TYPE> inline RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor, const TYPE& defaultValue) { if (this->d_type) { return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::applyRaw(VISITOR& visitor) { typedef Variant_RawVisitorHelper<RET_TYPE, VISITOR> Helper; return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::applyRaw(const VISITOR& visitor) { typedef Variant_RawVisitorHelper<RET_TYPE, const VISITOR> Helper; return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type); } template <class TYPES> template <class TYPE> VariantImp<TYPES>& VariantImp<TYPES>::assign(const TYPE& value) { typedef bsls::ObjectBuffer<TYPE> BufferType; if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type) { reinterpret_cast<BufferType *>(&this->d_value)->object() = value; } else { assignImp<TYPE, TYPE>(value); } return *this; } template <class TYPES> template <class TYPE> #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) VariantImp<TYPES>& VariantImp<TYPES>::assign(TYPE&& value) #else VariantImp<TYPES>& VariantImp<TYPES>::assign(bslmf::MovableRef<TYPE> value) #endif { typedef bsls::ObjectBuffer<typename bsl::remove_reference<TYPE>::type> BufferType; #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) if (Variant_TypeIndex<TYPES, typename bsl::remove_reference<TYPE>::type>::value == this->d_type) { reinterpret_cast<BufferType *>(&this->d_value)->object() = BSLS_COMPILERFEATURES_FORWARD(TYPE, value); } else { assignImp<TYPE>(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); } #else TYPE& lvalue = value; if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type) { reinterpret_cast<BufferType *>(&this->d_value)->object() = MoveUtil::move(lvalue); } else { assignImp<TYPE>(MoveUtil::move(lvalue)); } #endif return *this; } template <class TYPES> template <class TYPE, class SOURCE_TYPE> VariantImp<TYPES>& VariantImp<TYPES>::assignTo(const SOURCE_TYPE& value) { typedef bsls::ObjectBuffer<TYPE> BufferType; if (Variant_TypeIndex<TYPES, TYPE>::value == this->d_type && bsl::is_same<TYPE, SOURCE_TYPE>::value) { reinterpret_cast<BufferType *>(&this->d_value)->object() = value; } else { assignImp<TYPE, SOURCE_TYPE>(value); } return *this; } template <class TYPES> template <class TYPE> inline TYPE& VariantImp<TYPES>::createInPlace() { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator()); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1> inline TYPE& VariantImp<TYPES>::createInPlace(const A1& a1) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2> inline TYPE& VariantImp<TYPES>::createInPlace(const A1& a1, const A2& a2) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12, const A13& a13) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> template <class TYPE, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline TYPE& VariantImp<TYPES>::createInPlace( const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12, const A13& a13, const A14& a14) { typedef bsls::ObjectBuffer<TYPE> BufferType; BufferType& bufR = *reinterpret_cast<BufferType *>(&this->d_value); reset(); bslma::ConstructionUtil::construct(bufR.address(), this->getAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); this->d_type = Variant_TypeIndex<TYPES, TYPE>::value; return bufR.object(); } template <class TYPES> void VariantImp<TYPES>::reset() { if (this->d_type) { Variant_DestructorVisitor destructor; apply(destructor); this->d_type = 0; } } template <class TYPES> void VariantImp<TYPES>::swap(VariantImp<TYPES>& other) { if (!this->d_type) { if (!other.d_type) { return; // RETURN } *this = other; other.reset(); } else if (!other.d_type) { other = *this; this->reset(); } else { if (this->d_type == other.d_type && this->getAllocator() == other.getAllocator()) { // Same types and same allocators, so use a visitor that calls // 'swap'. Variant_SwapVisitor swapper(&this->d_value); other.apply(swapper); } else { // Different types and/or allocators, so swap via assignment. Note // that this doesn't fit the usual pattern for calling 'swap' // because infinite recursion would result. bsl::swap(*this, other); } } } template <class TYPES> template <class TYPE> inline TYPE& VariantImp<TYPES>::the() { BSLMF_ASSERT((0 != Variant_TypeIndex<TYPES, TYPE>::value)); BSLS_ASSERT_SAFE((this->d_type == Variant_TypeIndex<TYPES, TYPE>::value)); typedef bsls::ObjectBuffer<TYPE> BufferType; return reinterpret_cast<BufferType *>(&this->d_value)->object(); } // ACCESSORS template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor) const { if (this->d_type) { return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor) const { if (this->d_type) { return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } bslmf::Nil nil = bslmf::Nil(); return visitor(nil); } template <class TYPES> template <class RET_TYPE, class VISITOR, class TYPE> inline RET_TYPE VariantImp<TYPES>::apply(VISITOR& visitor, const TYPE& defaultValue) const { if (this->d_type) { return doApplyR<VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class TYPES> template <class RET_TYPE, class VISITOR, class TYPE> inline RET_TYPE VariantImp<TYPES>::apply(const VISITOR& visitor, const TYPE& defaultValue) const { if (this->d_type) { return doApplyR<const VISITOR&, RET_TYPE>(visitor, this->d_type); // RETURN } return visitor(defaultValue); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::applyRaw(VISITOR& visitor) const { typedef Variant_RawVisitorHelper<RET_TYPE, VISITOR> Helper; return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type); } template <class TYPES> template <class RET_TYPE, class VISITOR> inline RET_TYPE VariantImp<TYPES>::applyRaw(const VISITOR& visitor) const { typedef Variant_RawVisitorHelper<RET_TYPE, const VISITOR> Helper; return doApplyR<const Helper&, RET_TYPE>(Helper(&visitor), this->d_type); } template <class TYPES> template <class TYPE> inline bool VariantImp<TYPES>::is() const { return Variant_TypeIndex<TYPES, TYPE>::value == this->d_type; } template <class TYPES> inline bool VariantImp<TYPES>::isUnset() const { return !this->d_type; } template <class TYPES> bsl::ostream& VariantImp<TYPES>::print(bsl::ostream& stream, int level, int spacesPerLevel) const { if (this->d_type) { Variant_PrintVisitor visitor(&stream, level, spacesPerLevel); doApply<const Variant_PrintVisitor&>(visitor, this->d_type); } return stream; } template <class TYPES> template <class TYPE> inline const TYPE& VariantImp<TYPES>::the() const { BSLMF_ASSERT((0 != Variant_TypeIndex<TYPES, TYPE>::value)); BSLS_ASSERT_SAFE((this->d_type == Variant_TypeIndex<TYPES, TYPE>::value)); typedef bsls::ObjectBuffer<TYPE> BufferType; return reinterpret_cast<const BufferType *>(&this->d_value)->object(); } template <class TYPES> inline int VariantImp<TYPES>::typeIndex() const { return this->d_type; } #ifndef BDE_OMIT_INTERNAL_DEPRECATED template <class TYPES> inline const bsl::type_info& VariantImp<TYPES>::typeInfo() const { return typeid(void); } template <class TYPES> template <class STREAM> STREAM& VariantImp<TYPES>::bdexStreamIn(STREAM& stream, int version) { int type; bslx::InStreamFunctions::bdexStreamIn(stream, type, 0); if (!stream || type < 0 || 20 < type) { stream.invalidate(); return stream; } if (type != this->d_type) { reset(); if (type) { Variant_DefaultConstructVisitor defaultConstructor( this->getAllocator()); doApply(defaultConstructor, type); } this->d_type = type; } if (type) { Variant_BdexStreamInVisitor<STREAM> streamer(stream, version); doApply(streamer, type); } return stream; } template <class TYPES> inline int VariantImp<TYPES>::maxSupportedBdexVersion() const { return 1; } template <class TYPES> template <class STREAM> STREAM& VariantImp<TYPES>::bdexStreamOut(STREAM& stream, int version) const { bslx::OutStreamFunctions::bdexStreamOut(stream, this->d_type, 0); if (this->d_type) { typedef Variant_BdexStreamOutVisitor<STREAM> Streamer; Streamer streamer(stream, version); doApply<Streamer&>(streamer, this->d_type); } return stream; } #endif // BDE_OMIT_INTERNAL_DEPRECATED } // close package namespace // FREE OPERATORS template <class TYPES> bool bdlb::operator==(const VariantImp<TYPES>& lhs, const VariantImp<TYPES>& rhs) { if (lhs.typeIndex() != rhs.typeIndex()) { return false; // RETURN } if (0 == lhs.typeIndex()) { return true; // RETURN } Variant_EqualityTestVisitor visitor(&rhs.d_value); lhs.apply(visitor); return visitor.d_result; } template <class TYPES> inline bool bdlb::operator!=(const VariantImp<TYPES>& lhs, const VariantImp<TYPES>& rhs) { return !(lhs == rhs); } template <class TYPES> inline bsl::ostream& bdlb::operator<<(bsl::ostream& stream, const VariantImp<TYPES>& object) { return object.print(stream, 0, -1); } // FREE FUNCTIONS template <class TYPES> inline void bdlb::swap(VariantImp<TYPES>& a, VariantImp<TYPES>& b) { a.swap(b); } namespace bdlb { // ------------------ // class Variant<...> // ------------------ // CREATORS #if defined(BDLB_VARIANT_USING_VARIADIC_TEMPLATES) template <class ...TYPES> inline Variant<TYPES...>::Variant() { } template <class ...TYPES> template <class TYPE_OR_ALLOCATOR> inline Variant<TYPES...>::Variant(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class ...TYPES> template <class TYPE> inline Variant<TYPES...>::Variant(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class ...TYPES> template <class TYPE> inline Variant<TYPES...>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class ...TYPES> template <class TYPE> inline Variant<TYPES...>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class ...TYPES> inline Variant<TYPES...>::Variant(const Variant& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. { } template <class ...TYPES> inline Variant<TYPES...>::Variant(bslmf::MovableRef<Variant> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class ...TYPES> inline Variant<TYPES...>::Variant(bslmf::MovableRef<Variant> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class ...TYPES> template <class TYPE> inline Variant<TYPES...>& Variant<TYPES...>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class ...TYPES> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant<TYPES...>, typename bsl::remove_cvref<TYPE>::type>::value, Variant<TYPES...> >::type& Variant<TYPES...>::operator=(TYPE&& value) #else Variant<TYPES...>& Variant<TYPES...>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class ...TYPES> inline Variant<TYPES...>& Variant<TYPES...>::operator=(const Variant& rhs) { // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class ...TYPES> inline Variant<TYPES...>& Variant<TYPES...>::operator=(bslmf::MovableRef<Variant> rhs) { // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. Variant& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } #else // BDLB_VARIANT_USING_VARIADIC_TEMPLATES template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE_OR_ALLOCATOR> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant( const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant( const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant( const Variant& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant( bslmf::MovableRef<Variant> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::Variant( bslmf::MovableRef<Variant> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>& Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>, typename bsl::remove_cvref<TYPE>::type>::value, Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20> >::type& Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::operator=(TYPE&& value) #else Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>& Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>& Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>::operator=(const Variant& rhs) { // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20> inline Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>& Variant<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20>:: operator=(bslmf::MovableRef<Variant> rhs) { // Up-cast needed since template matching has higher overloading precedence // than derived-to-base matching. Variant& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } #endif // BDLB_VARIANT_USING_VARIADIC_TEMPLATES #ifdef BDLB_VARIANT_USING_VARIADIC_TEMPLATES #undef BDLB_VARIANT_USING_VARIADIC_TEMPLATES #endif // ------------------- // class Variant2<...> // ------------------- // CREATORS template <class A1, class A2> inline Variant2<A1, A2>::Variant2() { } template <class A1, class A2> template <class TYPE_OR_ALLOCATOR> inline Variant2<A1, A2>::Variant2(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2> template <class TYPE> inline Variant2<A1, A2>::Variant2(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2> template <class TYPE> inline Variant2<A1, A2>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant2(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant2(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2> template <class TYPE> inline Variant2<A1, A2>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant2(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant2(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2> inline Variant2<A1, A2>::Variant2(const Variant2& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2> inline Variant2<A1, A2>::Variant2(bslmf::MovableRef<Variant2> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2> inline Variant2<A1, A2>::Variant2(bslmf::MovableRef<Variant2> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2> template <class TYPE> inline Variant2<A1, A2>& Variant2<A1, A2>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant2<A1, A2>, typename bsl::remove_cvref<TYPE>::type>::value, Variant2<A1, A2> >::type& Variant2<A1, A2>::operator=(TYPE&& value) #else Variant2<A1, A2>& Variant2<A1, A2>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2> inline Variant2<A1, A2>& Variant2<A1, A2>::operator=(const Variant2& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2> inline Variant2<A1, A2>& Variant2<A1, A2>::operator=(bslmf::MovableRef<Variant2> rhs) { Variant2& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant3<...> // ------------------- // CREATORS template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>::Variant3() { } template <class A1, class A2, class A3> template <class TYPE_OR_ALLOCATOR> inline Variant3<A1, A2, A3>:: Variant3(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3> template <class TYPE> inline Variant3<A1, A2, A3>:: Variant3(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3> template <class TYPE> inline Variant3<A1, A2, A3>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant3(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant3(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3> template <class TYPE> inline Variant3<A1, A2, A3>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant3(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant3(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>:: Variant3(const Variant3& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>:: Variant3(bslmf::MovableRef<Variant3> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>:: Variant3(bslmf::MovableRef<Variant3> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3> template <class TYPE> inline Variant3<A1, A2, A3>& Variant3<A1, A2, A3>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant3<A1, A2, A3>, typename bsl::remove_cvref<TYPE>::type>::value, Variant3<A1, A2, A3> >::type& Variant3<A1, A2, A3>::operator=(TYPE&& value) #else Variant3<A1, A2, A3>& Variant3<A1, A2, A3>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>& Variant3<A1, A2, A3>::operator=(const Variant3& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3> inline Variant3<A1, A2, A3>& Variant3<A1, A2, A3>::operator=(bslmf::MovableRef<Variant3> rhs) { Variant3& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant4<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>::Variant4() { } template <class A1, class A2, class A3, class A4> template <class TYPE_OR_ALLOCATOR> inline Variant4<A1, A2, A3, A4>:: Variant4(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4> template <class TYPE> inline Variant4<A1, A2, A3, A4>:: Variant4(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4> template <class TYPE> inline Variant4<A1, A2, A3, A4>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant4(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant4(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4> template <class TYPE> inline Variant4<A1, A2, A3, A4>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant4(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant4(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>:: Variant4(const Variant4& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>:: Variant4(bslmf::MovableRef<Variant4> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>:: Variant4(bslmf::MovableRef<Variant4> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4> template <class TYPE> inline Variant4<A1, A2, A3, A4>& Variant4<A1, A2, A3, A4>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant4<A1, A2, A3, A4>, typename bsl::remove_cvref<TYPE>::type>::value, Variant4<A1, A2, A3, A4> >::type& Variant4<A1, A2, A3, A4>::operator=(TYPE&& value) #else Variant4<A1, A2, A3, A4>& Variant4<A1, A2, A3, A4>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>& Variant4<A1, A2, A3, A4>::operator=(const Variant4& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4> inline Variant4<A1, A2, A3, A4>& Variant4<A1, A2, A3, A4>::operator=(bslmf::MovableRef<Variant4> rhs) { Variant4& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant5<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>::Variant5() { } template <class A1, class A2, class A3, class A4, class A5> template <class TYPE_OR_ALLOCATOR> inline Variant5<A1, A2, A3, A4, A5>:: Variant5(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5> template <class TYPE> inline Variant5<A1, A2, A3, A4, A5>:: Variant5(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5> template <class TYPE> inline Variant5<A1, A2, A3, A4, A5>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant5(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant5(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5> template <class TYPE> inline Variant5<A1, A2, A3, A4, A5>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant5(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant5(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>:: Variant5(const Variant5& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>:: Variant5(bslmf::MovableRef<Variant5> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>:: Variant5(bslmf::MovableRef<Variant5> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5> template <class TYPE> inline Variant5<A1, A2, A3, A4, A5>& Variant5<A1, A2, A3, A4, A5>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant5<A1, A2, A3, A4, A5>, typename bsl::remove_cvref<TYPE>::type>::value, Variant5<A1, A2, A3, A4, A5> >::type& Variant5<A1, A2, A3, A4, A5>::operator=(TYPE&& value) #else Variant5<A1, A2, A3, A4, A5>& Variant5<A1, A2, A3, A4, A5>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>& Variant5<A1, A2, A3, A4, A5>::operator=(const Variant5& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5> inline Variant5<A1, A2, A3, A4, A5>& Variant5<A1, A2, A3, A4, A5>::operator=(bslmf::MovableRef<Variant5> rhs) { Variant5& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant6<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>::Variant6() { } template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE_OR_ALLOCATOR> inline Variant6<A1, A2, A3, A4, A5, A6>:: Variant6(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE> inline Variant6<A1, A2, A3, A4, A5, A6>:: Variant6(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE> inline Variant6<A1, A2, A3, A4, A5, A6>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant6(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant6(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE> inline Variant6<A1, A2, A3, A4, A5, A6>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant6(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant6(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>:: Variant6(const Variant6& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>:: Variant6(bslmf::MovableRef<Variant6> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>:: Variant6(bslmf::MovableRef<Variant6> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE> inline Variant6<A1, A2, A3, A4, A5, A6>& Variant6<A1, A2, A3, A4, A5, A6>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant6<A1, A2, A3, A4, A5, A6>, typename bsl::remove_cvref<TYPE>::type>::value, Variant6<A1, A2, A3, A4, A5, A6> >::type& Variant6<A1, A2, A3, A4, A5, A6>::operator=(TYPE&& value) #else Variant6<A1, A2, A3, A4, A5, A6>& Variant6<A1, A2, A3, A4, A5, A6>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>& Variant6<A1, A2, A3, A4, A5, A6>::operator=(const Variant6& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6> inline Variant6<A1, A2, A3, A4, A5, A6>& Variant6<A1, A2, A3, A4, A5, A6>::operator=(bslmf::MovableRef<Variant6> rhs) { Variant6& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant7<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>::Variant7() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE_OR_ALLOCATOR> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: Variant7(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: Variant7(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant7(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant7(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant7(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant7(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: Variant7(const Variant7& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: Variant7(bslmf::MovableRef<Variant7> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>:: Variant7(bslmf::MovableRef<Variant7> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE> inline Variant7<A1, A2, A3, A4, A5, A6, A7>& Variant7<A1, A2, A3, A4, A5, A6, A7>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant7<A1, A2, A3, A4, A5, A6, A7>, typename bsl::remove_cvref<TYPE>::type>::value, Variant7<A1, A2, A3, A4, A5, A6, A7> >::type& Variant7<A1, A2, A3, A4, A5, A6, A7>::operator=(TYPE&& value) #else Variant7<A1, A2, A3, A4, A5, A6, A7>& Variant7<A1, A2, A3, A4, A5, A6, A7>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>& Variant7<A1, A2, A3, A4, A5, A6, A7>:: operator=(const Variant7& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Variant7<A1, A2, A3, A4, A5, A6, A7>& Variant7<A1, A2, A3, A4, A5, A6, A7>:: operator=(bslmf::MovableRef<Variant7> rhs) { Variant7& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant8<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>::Variant8() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE_OR_ALLOCATOR> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: Variant8(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: Variant8(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant8(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant8(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant8(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant8(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: Variant8(const Variant8& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: Variant8(bslmf::MovableRef<Variant8> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: Variant8(bslmf::MovableRef<Variant8> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>& Variant8<A1, A2, A3, A4, A5, A6, A7, A8>::operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant8<A1, A2, A3, A4, A5, A6, A7, A8>, typename bsl::remove_cvref<TYPE>::type>::value, Variant8<A1, A2, A3, A4, A5, A6, A7, A8> >::type& Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: operator=(TYPE&& value) #else Variant8<A1, A2, A3, A4, A5, A6, A7, A8>& Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>& Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: operator=(const Variant8& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Variant8<A1, A2, A3, A4, A5, A6, A7, A8>& Variant8<A1, A2, A3, A4, A5, A6, A7, A8>:: operator=(bslmf::MovableRef<Variant8> rhs) { Variant8& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // ------------------- // class Variant9<...> // ------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::Variant9() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE_OR_ALLOCATOR> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: Variant9(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: Variant9(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant9(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant9(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant9(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant9(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: Variant9(const Variant9& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: Variant9(bslmf::MovableRef<Variant9> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: Variant9(bslmf::MovableRef<Variant9> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>& Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>, typename bsl::remove_cvref<TYPE>::type>::value, Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9> >::type& Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: operator=(TYPE&& value) #else Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>& Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>& Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: operator=(const Variant9& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>& Variant9<A1, A2, A3, A4, A5, A6, A7, A8, A9>:: operator=(bslmf::MovableRef<Variant9> rhs) { Variant9& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant10<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::Variant10() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE_OR_ALLOCATOR> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: Variant10(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: Variant10(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant10(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant10(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant10(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant10(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: Variant10(const Variant10& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: Variant10(bslmf::MovableRef<Variant10> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: Variant10(bslmf::MovableRef<Variant10> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>& Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>, typename bsl::remove_cvref<TYPE>::type>::value, Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> >::type& Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: operator=(TYPE&& value) #else Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>& Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>& Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: operator=(const Variant10& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>& Variant10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>:: operator=(bslmf::MovableRef<Variant10> rhs) { Variant10& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant11<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE_OR_ALLOCATOR> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant11(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant11(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant11(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant11(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11(const Variant11& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11(bslmf::MovableRef<Variant11> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: Variant11(bslmf::MovableRef<Variant11> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>& Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>, typename bsl::remove_cvref<TYPE>::type>::value, Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11> >::type& Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: operator=(TYPE&& value) #else Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>& Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>& Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: operator=(const Variant11& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11> inline Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>& Variant11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>:: operator=(bslmf::MovableRef<Variant11> rhs) { Variant11& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant12<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE_OR_ALLOCATOR> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant12(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant12(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant12(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant12(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12(const Variant12& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12(bslmf::MovableRef<Variant12> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: Variant12(bslmf::MovableRef<Variant12> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>& Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>, typename bsl::remove_cvref<TYPE>::type>::value, Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12> >::type& Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: operator=(TYPE&& value) #else Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>& Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>& Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: operator=(const Variant12& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12> inline Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>& Variant12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>:: operator=(bslmf::MovableRef<Variant12> rhs) { Variant12& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant13<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE_OR_ALLOCATOR> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant13(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant13(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant13(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant13(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13(const Variant13& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13(bslmf::MovableRef<Variant13> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: Variant13(bslmf::MovableRef<Variant13> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>& Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>, typename bsl::remove_cvref<TYPE>::type>::value, Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13> >::type& Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: operator=(TYPE&& value) #else Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>& Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>& Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: operator=(const Variant13& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13> inline Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>& Variant13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>:: operator=(bslmf::MovableRef<Variant13> rhs) { Variant13& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant14<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE_OR_ALLOCATOR> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant14(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant14(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant14(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant14(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14(const Variant14& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14(bslmf::MovableRef<Variant14> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: Variant14(bslmf::MovableRef<Variant14> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>& Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>, typename bsl::remove_cvref<TYPE>::type>::value, Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14> >::type& Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: operator=(TYPE&& value) #else Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>& Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>& Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: operator=(const Variant14& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14> inline Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>& Variant14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>:: operator=(bslmf::MovableRef<Variant14> rhs) { Variant14& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant15<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE_OR_ALLOCATOR> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant15(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant15(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant15(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant15(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15(const Variant15& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15(bslmf::MovableRef<Variant15> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: Variant15(bslmf::MovableRef<Variant15> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>& Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>, typename bsl::remove_cvref<TYPE>::type>::value, Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15> >::type& Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: operator=(TYPE&& value) #else Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>& Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>& Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: operator=(const Variant15& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15> inline Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>& Variant15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>:: operator=(bslmf::MovableRef<Variant15> rhs) { Variant15& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant16<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE_OR_ALLOCATOR> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant16(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant16(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant16(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant16(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16(const Variant16& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16(bslmf::MovableRef<Variant16> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: Variant16(bslmf::MovableRef<Variant16> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>& Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>, typename bsl::remove_cvref<TYPE>::type>::value, Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16> >::type& Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>::operator=(TYPE&& value) #else Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>& Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>& Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: operator=(const Variant16& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16> inline Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>& Variant16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>:: operator=(bslmf::MovableRef<Variant16> rhs) { Variant16& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant17<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE_OR_ALLOCATOR> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant17(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant17(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant17(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant17(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17(const Variant17& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17(bslmf::MovableRef<Variant17> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: Variant17(bslmf::MovableRef<Variant17> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>& Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>, typename bsl::remove_cvref<TYPE>::type>::value, Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17> >::type& Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>::operator=(TYPE&& value) #else Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>& Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>& Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: operator=(const Variant17& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17> inline Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>& Variant17<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17>:: operator=(bslmf::MovableRef<Variant17> rhs) { Variant17& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant18<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE_OR_ALLOCATOR> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant18(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant18(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant18(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant18(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18(const Variant18& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18(bslmf::MovableRef<Variant18> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: Variant18(bslmf::MovableRef<Variant18> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>& Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>, typename bsl::remove_cvref<TYPE>::type>::value, Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18> >::type& Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>::operator=(TYPE&& value) #else Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>& Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>& Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: operator=(const Variant18& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18> inline Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>& Variant18<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18>:: operator=(bslmf::MovableRef<Variant18> rhs) { Variant18& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } // -------------------- // class Variant19<...> // -------------------- // CREATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19() { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE_OR_ALLOCATOR> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19(const TYPE_OR_ALLOCATOR& valueOrAllocator) : Imp(valueOrAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19(const TYPE& value, bslma::Allocator *basicAllocator) : Imp(value, basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant19(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value && !bsl::is_convertible<TYPE, bslma::Allocator *>::value, void>::type *) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)) #else Variant19(bslmf::MovableRef<TYPE> value) : Imp(MoveUtil::move(value)) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Variant19(TYPE&& value, typename bsl::enable_if< !bsl::is_same< SelfType, typename bsl::remove_const< typename bsl::remove_reference<TYPE>::type>::type>::value, bslma::Allocator>::type *basicAllocator) : Imp(BSLS_COMPILERFEATURES_FORWARD(TYPE, value), basicAllocator) #else Variant19(bslmf::MovableRef<TYPE> value, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(value), basicAllocator) #endif { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19(const Variant19& original, bslma::Allocator *basicAllocator) : Imp(static_cast<const Imp&>(original), basicAllocator) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19(bslmf::MovableRef<Variant19> original) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original)))) { } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: Variant19(bslmf::MovableRef<Variant19> original, bslma::Allocator *basicAllocator) : Imp(MoveUtil::move(static_cast<Imp&>(MoveUtil::access(original))), basicAllocator) { } // MANIPULATORS template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>& Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: operator=(const TYPE& value) { Imp::operator=(value); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> template <class TYPE> inline #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) typename bsl::enable_if< !bsl::is_same<Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>, typename bsl::remove_cvref<TYPE>::type>::value, Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19> >::type& Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>::operator=(TYPE&& value) #else Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>& Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>::operator=(bslmf::MovableRef<TYPE> value) #endif { #if defined(BSLMF_MOVABLEREF_USES_RVALUE_REFERENCES) Imp::operator=(BSLS_COMPILERFEATURES_FORWARD(TYPE, value)); #else TYPE& lvalue = value; Imp::operator=(MoveUtil::move(lvalue)); #endif return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>& Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: operator=(const Variant19& rhs) { Imp::operator=(static_cast<const Imp&>(rhs)); return *this; } template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19> inline Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>& Variant19<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19>:: operator=(bslmf::MovableRef<Variant19> rhs) { Variant19& lvalue = rhs; Imp::operator=(MoveUtil::move(static_cast<Imp&>(lvalue))); return *this; } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------