// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MEMORY_SCOPED_GENERIC_OBJ_H_ #define BASE_MEMORY_SCOPED_GENERIC_OBJ_H_ #pragma once #include "base/basictypes.h" #include "base/compiler_specific.h" // ScopedGenericObj<> is patterned after scoped_ptr_malloc<>, except // that it assumes the template argument is typedef'ed to a pointer // type. It does not support retain/release semantics. It takes as its // second template argument a functor which frees the object. // // Example (Mac-specific): // // class ScopedDestroyRendererInfo { // public: // void operator()(CGLRendererInfoObj x) const { // CGLDestroyRendererInfo(x); // } // }; // // ... // // CGLRendererInfoObj renderer_info = NULL; // ... // ScopedGenericObj // scoper(renderer_info); template class ScopedGenericObj { public: // The element type typedef C element_type; // Constructor. Defaults to initializing with NULL. // There is no way to create an uninitialized ScopedGenericObj. // The input parameter must be allocated with an allocator that matches the // Free functor. explicit ScopedGenericObj(C p = NULL): obj_(p) {} // Destructor. If there is a C object, call the Free functor. ~ScopedGenericObj() { reset(); } // Reset. Calls the Free functor on the current owned object, if any. // Then takes ownership of a new object, if given. // this->reset(this->get()) works. void reset(C p = NULL) { if (obj_ != p) { FreeProc free_proc; free_proc(obj_); obj_ = p; } } operator C() const { return obj_; } C get() const { return obj_; } // Comparison operators. // These return whether a ScopedGenericObj and a plain pointer refer // to the same object, not just to two different but equal objects. // For compatibility with the boost-derived implementation, these // take non-const arguments. bool operator==(C p) const { return obj_ == p; } bool operator!=(C p) const { return obj_ != p; } // Swap two ScopedGenericObjs. void swap(ScopedGenericObj& b) { C tmp = b.obj_; b.obj_ = obj_; obj_ = tmp; } // Release a pointer. // The return value is the current pointer held by this object. // If this object holds a NULL pointer, the return value is NULL. // After this operation, this object will hold a NULL pointer, // and will not own the object any more. C release() WARN_UNUSED_RESULT { C tmp = obj_; obj_ = NULL; return tmp; } private: C obj_; // no reason to use these: each ScopedGenericObj should have its own object. template bool operator==(ScopedGenericObj const& p) const; template bool operator!=(ScopedGenericObj const& p) const; // Disallow evil constructors. ScopedGenericObj(const ScopedGenericObj&); void operator=(const ScopedGenericObj&); }; template inline void swap(ScopedGenericObj& a, ScopedGenericObj& b) { a.swap(b); } template inline bool operator==(C* p, const ScopedGenericObj& b) { return p == b.get(); } template inline bool operator!=(C* p, const ScopedGenericObj& b) { return p != b.get(); } #endif // BASE_MEMORY_SCOPED_GENERIC_OBJ_H_