// bslma_destructorguard.h -*-C++-*- #ifndef INCLUDED_BSLMA_DESTRUCTORGUARD #define INCLUDED_BSLMA_DESTRUCTORGUARD #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a guard to unconditionally manage an object. // //@CLASSES: // bslma::DestructorGuard: guard to unconditionally manage an object // //@SEE_ALSO: bslma_destructorproctor, bslma_autodestructor // //@DESCRIPTION: This component provides a guard class template, // 'bslma::DestructorGuard', to unconditionally manage an (otherwise-unmanaged) // object of parameterized 'TYPE' supplied at construction. The managed object // is destroyed automatically when the guard object goes out of scope by // calling the (managed) object's destructor. // ///Usage ///----- // Suppose we have a situation where one of the two constructors will be called // to create an object on the stack for performance reasons. The construction // thus occurs within either of the branches of an 'if' statement, so the // object itself, to survive the end of the "then" or "else" block, must be // constructed in a 'bsls::ObjectBuffer'. Once constructed, the object would // not be destroyed automatically, so to make sure it will be destroyed, we // place it under the management of a 'bslma::DestructorGuard'. After that, we // know that however the routine exits -- either by a return or as a result of // an exception being thrown -- the object will be destroyed. //.. // double usageExample(double startValue) // { // bsls::ObjectBuffer<std::vector<double> > buffer; // std::vector<double>& myVec = buffer.object(); // // if (startValue >= 0) { // new (&myVec) std::vector<double>(100, startValue); // } // else { // new (&myVec) std::vector<double>(); // } // // //*********************************************************** // // Note the use of the destructor guard on 'myVec' (below). * // //*********************************************************** // // bslma::DestructorGuard<std::vector<double> > guard(&myVec); //.. // Note that regardless of how this routine terminates, 'myVec' will be // destroyed. //.. // // ... // // myVec.push_back(3.0); //.. // Note that 'push_back' could allocate memory and therefore may throw. // However, if it does, 'myVec' will be destroyed automatically along with // 'guard'. //.. // if (myVec[0] >= 5.0) { // return 5.0; // RETURN //.. // Note that 'myVec' is automatically destroyed as the function returns. //.. // } // // return myVec[myVec.size() / 2]; //.. // Note that 'myVec' is destroyed after the temporary containing the return // value is created. //.. // } //.. #include <bslscm_version.h> #include <bsls_assert.h> namespace BloombergLP { namespace bslma { // ===================== // class DestructorGuard // ===================== template <class TYPE> class DestructorGuard { // This class implements a guard that unconditionally destroys a managed // object upon destruction by invoking the (managed) object's destructor. // DATA TYPE *d_object_p; // managed object // NOT IMPLEMENTED DestructorGuard(const DestructorGuard<TYPE>&); DestructorGuard<TYPE>& operator=(const DestructorGuard<TYPE>&); public: // CREATORS explicit DestructorGuard(TYPE *object); // Create a destructor guard that unconditionally manages the specified // 'object', and invokes the destructor of 'object' upon the // destruction of this guard. The behavior is undefined unless // 'object' is non-zero. ~DestructorGuard(); // Destroy this destructor guard and the object it manages by invoking // the destructor of the (managed) object. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // --------------------- // class DestructorGuard // --------------------- // CREATORS template <class TYPE> inline DestructorGuard<TYPE>::DestructorGuard(TYPE *object) : d_object_p(object) { BSLS_ASSERT_SAFE(object); } template <class TYPE> inline DestructorGuard<TYPE>::~DestructorGuard() { BSLS_ASSERT_SAFE(d_object_p); d_object_p->~TYPE(); } } // close package namespace #ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY // ============================================================================ // BACKWARD COMPATIBILITY // ============================================================================ #ifdef bslma_DestructorGuard #undef bslma_DestructorGuard #endif #define bslma_DestructorGuard bslma::DestructorGuard // 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 ----------------------------------