// bslalg_constructorproxy.h -*-C++-*- #ifndef INCLUDED_BSLALG_CONSTRUCTORPROXY #define INCLUDED_BSLALG_CONSTRUCTORPROXY #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a proxy for constructing and destroying objects. // //@CLASSES: // bslalg::ConstructorProxy: proxy for constructing and destroying objects // //@SEE_ALSO: bslma_allocator // //@DESCRIPTION: This component provides a proxy for constructing and // automatically destroying objects. The proxy class // 'bslalg::ConstructorProxy' is parameterized on a 'OBJECT_TYPE', where // 'OBJECT_TYPE' may or may not use a 'bslma' allocator to supply memory. Upon // construction of a proxy, a proxied 'OBJECT_TYPE' instance is also // constructed; the 'bslma' allocator supplied to the proxy constructor is // passed to the constructor of the proxied object only if 'OBJECT_TYPE' // declares the 'bslma::UsesBslmaAllocator' trait. If this trait is // not declared for 'OBJECT_TYPE', the allocator is ignored. // // Following construction of the proxied object, it is held by the proxy. // Modifiable and non-modifiable access to the proxied object may be obtained // using the overloaded 'object' methods. When the proxy is destroyed, the // proxied object is automatically destroyed. // // This proxy is useful in situations where an object of a given type must be // constructed, but it is not known whether the object's constructor takes a // 'bslma' allocator to supply memory. This occurs frequently in generic // programming. // // See the 'bslma' package-level documentation for more information about using // 'bslma' allocators. // ///Usage ///----- // The snippets of code in the first usage example below illustrate very basic // use of the constructor proxy. The second usage example provides a more // extended illustration of a scenario that can occur in generic programming. // ///Example 1 ///- - - - - // Suppose we have an arbitrary class: //.. // class SomeClass { // // ... class definition ... // }; //.. // 'SomeClass' may optionally declare the 'bslma::UsesBslmaAllocator' // trait. The following code illustrates how a 'SomeClass' object can be // constructed using a constructor proxy that detects this trait: //.. // using namespace BloombergLP; // // bslma::TestAllocator testAllocator; // bslalg::ConstructorProxy<SomeClass> proxy(&testAllocator); // // SomeClass& myObject = proxy.object(); //.. // If 'SomeClass' declares the 'bslma::UsesBslmaAllocator' trait, // then the object of type 'SomeClass' held by 'proxy' will obtain its memory // from the supplied 'testAllocator'. Otherwise, 'testAllocator' will be // ignored. // ///Example 2 ///- - - - - // The following snippets of code illustrate a use of this component in a more // typical scenario. // // The 'MyContainer' class below contains an object of the specified parameter // 'TYPE': //.. // template <typename TYPE> // class MyContainer { // // This class contains an object of parameterized 'TYPE'. // // // PRIVATE DATA MEMBERS // TYPE d_object; // contained object // // public: // // CREATORS // explicit MyContainer(bslma::Allocator *basicAllocator = 0); // // Construct a container using the specified 'basicAllocator' to // // supply memory. If 'basicAllocator' is 0, the currently // // installed default allocator is used. // // ~MyContainer(); // // Destroy this container. // // // ACCESSORS // const TYPE& getObject() const; // // Return a reference to the non-modifiable object stored in this // // container. // // // ... rest of class definition ... // }; //.. // The implementation for the 'MyContainer' constructor is a little tricky // without a constructor proxy. One possible implementation is as follows: //.. // template <typename TYPE> // MyContainer<TYPE>::MyContainer(bslma::Allocator *basicAllocator) // { // } //.. // This implementation will compile successfully for each 'TYPE' that has a // default constructor, but it will not behave as documented. In particular, // the specified 'basicAllocator' will not be used to supply memory. // // Another possible implementation for the 'MyContainer' constructor is as // follows: //.. // template <typename TYPE> // MyContainer<TYPE>::MyContainer(bslma::Allocator *basicAllocator) // : d_object(basicAllocator) // { // } //.. // This implementation behaves as documented, but it will not compile unless // 'TYPE' has a constructor taking a 'bslma::Allocator *'. For example, the // following declaration of 'container' will fail to compile: //.. // bslma::TestAllocator testAllocator; // // MyContainer<int> container(&testAllocator); //.. // The solution to this problem is to use the constructor proxy provided by // this component. The following definition of 'MyContainer' uses a // constructor proxy for the contained object of parameterized 'TYPE': //.. // template <typename TYPE> // class MyContainer { // // This class contains an object of parameterized 'TYPE'. // // // PRIVATE DATA MEMBERS // bslalg::ConstructorProxy<TYPE> d_proxy; // // public: // // CREATORS // explicit MyContainer(bslma::Allocator *basicAllocator = 0); // // Construct a container using the specified 'basicAllocator' to // // supply memory. If 'basicAllocator' is 0, the currently // // installed default allocator is used. // // ~MyContainer(); // // Destroy this container. // // // ACCESSORS // const TYPE& getObject() const; // // Return a reference to the non-modifiable object stored in this // // container. // // // ... rest of class definition ... // }; //.. // The constructor for 'MyContainer' can now be implemented as follows: //.. // template <typename TYPE> // MyContainer<TYPE>::MyContainer(bslma::Allocator *basicAllocator) // : d_proxy(basicAllocator) // { // } //.. // The 'getObject' method of 'MyContainer' is implemented as follows: //.. // template <typename TYPE> // const TYPE& MyContainer<TYPE>::getObject() const // { // return d_proxy.object(); // } //.. // Now the following code, which previously did not compile, *will* compile // successfully: //.. // bslma::TestAllocator testAllocator; // // MyContainer<int> container(&testAllocator); //.. // The specified 'testAllocator' will simply be ignored because 'int' does not // use a 'bslma' allocator to supply memory. // // Next suppose we have a class defined as follows: //.. // class SomeClassUsingAllocator { // // This class uses a 'bslma' allocator. // // // PRIVATE DATA MEMBERS // bslma::Allocator *d_allocator_p; // // public: // // CREATORS // explicit SomeClassUsingAllocator(bslma::Allocator *basicAllocator = 0) // : d_allocator_p(bslma::Default::allocator(basicAllocator)) // { // } // // // ACCESSORS // bslma::Allocator *getAllocator() const // { // return d_allocator_p; // } // }; // // // TRAITS // namespace bslma { // // template <> // struct UsesBslmaAllocator<SomeClassUsingAllocator> : bsl::true_type // {}; // // } //.. // The following code will compile and run without an assertion failure: //.. // bslma::TestAllocator testAllocator; // // MyContainer<SomeClassUsingAllocator> container(&testAllocator); // // assert(&testAllocator == container.getObject().getAllocator()); //.. // Finally, since the 'MyContainer' class uses a 'bslma' allocator to supply // memory, it is useful to expose this property. This is done by declaring the // 'bslma::UsesBslmaAllocator' trait to complete the definition of // 'MyContainer': //.. // template <typename TYPE> // class MyContainer { // // This class contains an object of parameterized 'TYPE' and declares // // the 'bslma::UsesBslmaAllocator' trait. // // // PRIVATE DATA MEMBERS // bslalg::ConstructorProxy<TYPE> d_proxy; // // public: // // CREATORS // explicit MyContainer(bslma::Allocator *basicAllocator = 0); // // Construct a container using the specified 'basicAllocator' to // // supply memory. If 'basicAllocator' is 0, the currently // // installed default allocator is used. // // ~MyContainer(); // // Destroy this container. // // // ACCESSORS // const TYPE& getObject() const; // // Return a reference to the non-modifiable object stored in this // // container. // // // ... rest of class definition ... // }; // // // TRAITS // namespace bslma { // // template <typename TYPE> // struct UsesBslmaAllocator<MyContainer<TYPE> > : bsl::true_type // {}; // // } //.. // The following code will also compile and run without an assertion failure: //.. // bslma::TestAllocator testAllocator; // // MyContainer<MyContainer<SomeClassUsingAllocator> > // containedContainer(&testAllocator); // // assert(&testAllocator // == containedContainer.getObject().getObject().getAllocator()); //.. #include <bslscm_version.h> #include <bslma_constructionutil.h> #include <bslma_destructionutil.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_enableif.h> #include <bslmf_decay.h> #include <bslmf_integralconstant.h> #include <bslmf_movableref.h> #include <bslmf_util.h> // 'forward(V)' #include <bsls_compilerfeatures.h> #include <bsls_keyword.h> #include <bsls_objectbuffer.h> #include <bsls_util.h> // 'forward<T>(V)' #ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES #include <bslalg_scalarprimitives.h> #endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES namespace BloombergLP { namespace bslma { class Allocator; } namespace bslalg { template <class> class ConstructorProxy; // =============================== // struct ConstructorProxy_IsProxy // =============================== template <class TYPE> struct ConstructorProxy_IsProxy : bsl::false_type { // Provides a metafunction to determine if the specified 'TYPE' is // 'ConstructorProxy'. This non-specialized class template always returns // 'false'. }; template <class TYPE> struct ConstructorProxy_IsProxy<ConstructorProxy<TYPE> > : bsl::true_type { // Provides a metafunction to determine if the specified 'TYPE' is // 'ConstructorProxy'. This specialized class template always returns // 'true'. }; // ====================== // class ConstructorProxy // ====================== template <class OBJECT_TYPE> class ConstructorProxy { // This class acts as a proxy for constructing and destroying an object of // parameterized 'OBJECT_TYPE', where 'OBJECT_TYPE' may or may not use a // 'bslma' allocator for supplying memory. The constructors for this proxy // class take a 'bslma::Allocator *'. If 'OBJECT_TYPE' has the // 'bslma::UsesBslmaAllocator' trait declared, then the supplied // allocator will be used to construct the proxied object. Otherwise, the // allocator is ignored. // DATA bsls::ObjectBuffer<OBJECT_TYPE> d_objectBuffer; // footprint of proxied // object (raw buffer) private: // NOT IMPLEMENTED ConstructorProxy(const ConstructorProxy&) BSLS_KEYWORD_DELETED; ConstructorProxy& operator=(const ConstructorProxy&) BSLS_KEYWORD_DELETED; public: // CREATORS explicit ConstructorProxy(bslma::Allocator *basicAllocator); // Construct a proxy, and a proxied object of parameterized // 'OBJECT_TYPE'. Use the specified 'basicAllocator' to supply memory // to the proxied object if 'OBJECT_TYPE' declares the // 'bslma::UsesBslmaAllocator' trait, and ignore 'basicAllocator' // otherwise. template <class SOURCE_TYPE> ConstructorProxy( const ConstructorProxy<SOURCE_TYPE>& original, bslma::Allocator *basicAllocator); template <class SOURCE_TYPE> ConstructorProxy( bslmf::MovableRef<ConstructorProxy<SOURCE_TYPE> > original, bslma::Allocator *basicAllocator); // Construct a proxy, and a proxied object of the parameterized // 'OBJECT_TYPE' having the value of the object of the parameterized // 'SOURCE_TYPE' held by the specified 'original' proxy. Use the // specified 'basicAllocator' to supply memory to the proxied object if // 'OBJECT_TYPE' declares the 'bslma::UsesBslmaAllocator' trait, and // ignore 'basicAllocator' otherwise. Note that a compilation error // will result unless an instance of 'OBJECT_TYPE' can be constructed // from an instance of 'SOURCE_TYPE'. template <class ARG01> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, typename bsl::enable_if< !ConstructorProxy_IsProxy< typename bsl::decay<ARG01>::type>::value, bslma::Allocator>::type *basicAllocator); template <class ARG01, class ARG02> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12, class ARG13> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, BSLS_COMPILERFEATURES_FORWARD_REF(ARG13) a13, bslma::Allocator *basicAllocator); template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12, class ARG13, class ARG14> ConstructorProxy(BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, BSLS_COMPILERFEATURES_FORWARD_REF(ARG13) a13, BSLS_COMPILERFEATURES_FORWARD_REF(ARG14) a14, bslma::Allocator *basicAllocator); // Construct a proxy, and a proxied object of the parameterized // 'OBJECT_TYPE' using the specified arguments 'a01' up to 'a14' of the // respective parameterized 'ARG01' up to 'ARG14' types. Use the // specified 'basicAllocator' to supply memory to the proxied object if // 'OBJECT_TYPE' declares the 'bslma::UsesBslmaAllocator' trait, and // ignore 'basicAllocator' otherwise. If 'basicAllocator' is 0, the // currently installed default allocator is used. Note that a // compilation error will result unless 'OBJECT_TYPE' has a constructor // of signature compatible with 'OBJECT_TYPE(ARG01&&, ARG2&&, ...)'. ~ConstructorProxy(); // Destroy this proxy and the object held by this proxy. // MANIPULATORS OBJECT_TYPE& object() BSLS_KEYWORD_NOEXCEPT; // Return a reference to the modifiable object held by this proxy. // ACCESSORS const OBJECT_TYPE& object() const BSLS_KEYWORD_NOEXCEPT; // Return a reference to the non-modifiable object held by this proxy. }; // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // ---------------------- // class ConstructorProxy // ---------------------- // CREATORS template <class OBJECT_TYPE> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct(d_objectBuffer.address(), basicAllocator); } template <class OBJECT_TYPE> template <class SOURCE_TYPE> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( const ConstructorProxy<SOURCE_TYPE>& original, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct(d_objectBuffer.address(), basicAllocator, original.object()); } template <class OBJECT_TYPE> template <class SOURCE_TYPE> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( bslmf::MovableRef<ConstructorProxy<SOURCE_TYPE> > original, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, bslmf::MovableRefUtil::move( bslmf::MovableRefUtil::access(original).object())); } template <class OBJECT_TYPE> template <class ARG01> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, typename bsl::enable_if< !ConstructorProxy_IsProxy< typename bsl::decay<ARG01>::type>::value, bslma::Allocator>::type *basicAllocator) { // NOTE: 'enable_if' is here so this constructor won't overshadow the copy // and move constructors. bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09), BSLS_COMPILERFEATURES_FORWARD(ARG10, a10)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09), BSLS_COMPILERFEATURES_FORWARD(ARG10, a10), BSLS_COMPILERFEATURES_FORWARD(ARG11, a11)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09), BSLS_COMPILERFEATURES_FORWARD(ARG10, a10), BSLS_COMPILERFEATURES_FORWARD(ARG11, a11), BSLS_COMPILERFEATURES_FORWARD(ARG12, a12)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12, class ARG13> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, BSLS_COMPILERFEATURES_FORWARD_REF(ARG13) a13, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09), BSLS_COMPILERFEATURES_FORWARD(ARG10, a10), BSLS_COMPILERFEATURES_FORWARD(ARG11, a11), BSLS_COMPILERFEATURES_FORWARD(ARG12, a12), BSLS_COMPILERFEATURES_FORWARD(ARG13, a13)); } template <class OBJECT_TYPE> template <class ARG01, class ARG02, class ARG03, class ARG04, class ARG05, class ARG06, class ARG07, class ARG08, class ARG09, class ARG10, class ARG11, class ARG12, class ARG13, class ARG14> inline ConstructorProxy<OBJECT_TYPE>::ConstructorProxy( BSLS_COMPILERFEATURES_FORWARD_REF(ARG01) a01, BSLS_COMPILERFEATURES_FORWARD_REF(ARG02) a02, BSLS_COMPILERFEATURES_FORWARD_REF(ARG03) a03, BSLS_COMPILERFEATURES_FORWARD_REF(ARG04) a04, BSLS_COMPILERFEATURES_FORWARD_REF(ARG05) a05, BSLS_COMPILERFEATURES_FORWARD_REF(ARG06) a06, BSLS_COMPILERFEATURES_FORWARD_REF(ARG07) a07, BSLS_COMPILERFEATURES_FORWARD_REF(ARG08) a08, BSLS_COMPILERFEATURES_FORWARD_REF(ARG09) a09, BSLS_COMPILERFEATURES_FORWARD_REF(ARG10) a10, BSLS_COMPILERFEATURES_FORWARD_REF(ARG11) a11, BSLS_COMPILERFEATURES_FORWARD_REF(ARG12) a12, BSLS_COMPILERFEATURES_FORWARD_REF(ARG13) a13, BSLS_COMPILERFEATURES_FORWARD_REF(ARG14) a14, bslma::Allocator *basicAllocator) { bslma::ConstructionUtil::construct( d_objectBuffer.address(), basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARG01, a01), BSLS_COMPILERFEATURES_FORWARD(ARG02, a02), BSLS_COMPILERFEATURES_FORWARD(ARG03, a03), BSLS_COMPILERFEATURES_FORWARD(ARG04, a04), BSLS_COMPILERFEATURES_FORWARD(ARG05, a05), BSLS_COMPILERFEATURES_FORWARD(ARG06, a06), BSLS_COMPILERFEATURES_FORWARD(ARG07, a07), BSLS_COMPILERFEATURES_FORWARD(ARG08, a08), BSLS_COMPILERFEATURES_FORWARD(ARG09, a09), BSLS_COMPILERFEATURES_FORWARD(ARG10, a10), BSLS_COMPILERFEATURES_FORWARD(ARG11, a11), BSLS_COMPILERFEATURES_FORWARD(ARG12, a12), BSLS_COMPILERFEATURES_FORWARD(ARG13, a13), BSLS_COMPILERFEATURES_FORWARD(ARG14, a14)); } template <class OBJECT_TYPE> inline ConstructorProxy<OBJECT_TYPE>::~ConstructorProxy() { bslma::DestructionUtil::destroy(d_objectBuffer.address()); } // MANIPULATORS template <class OBJECT_TYPE> inline OBJECT_TYPE& ConstructorProxy<OBJECT_TYPE>::object() BSLS_KEYWORD_NOEXCEPT { return d_objectBuffer.object(); } // ACCESSORS template <class OBJECT_TYPE> inline const OBJECT_TYPE& ConstructorProxy<OBJECT_TYPE>::object() const BSLS_KEYWORD_NOEXCEPT { return d_objectBuffer.object(); } } // close package namespace // ============================================================================ // TYPE TRAITS // ============================================================================ namespace bslma { template <class OBJECT_TYPE> struct UsesBslmaAllocator<bslalg::ConstructorProxy<OBJECT_TYPE> > : bsl::true_type {}; } // close namespace bslma namespace bslmf { template <class OBJECT_TYPE> struct IsBitwiseMoveable<bslalg::ConstructorProxy<OBJECT_TYPE> > : IsBitwiseMoveable<OBJECT_TYPE> {}; } // close namespace bslmf #ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY // ============================================================================ // BACKWARD COMPATIBILITY // ============================================================================ #ifdef bslalg_ConstructorProxy #undef bslalg_ConstructorProxy #endif #define bslalg_ConstructorProxy bslalg::ConstructorProxy // This alias is defined for backward compatibility. #endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2013 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 ----------------------------------