blob: 4b3cb867f7134ab7f93e88d24ee76b4406143022 [file] [log] [blame]
// Copyright (c) 2012 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_
#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<CGLRendererInfoObj, ScopedDestroyRendererInfo>
// scoper(renderer_info);
template<class C, class FreeProc>
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 = C()): 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 = C()) {
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 <class C2, class GP>
bool operator==(ScopedGenericObj<C2, GP> const& p) const;
template <class C2, class GP>
bool operator!=(ScopedGenericObj<C2, GP> const& p) const;
// Disallow evil constructors.
ScopedGenericObj(const ScopedGenericObj&);
void operator=(const ScopedGenericObj&);
};
template<class C, class FP> inline
void swap(ScopedGenericObj<C, FP>& a, ScopedGenericObj<C, FP>& b) {
a.swap(b);
}
template<class C, class FP> inline
bool operator==(C* p, const ScopedGenericObj<C, FP>& b) {
return p == b.get();
}
template<class C, class FP> inline
bool operator!=(C* p, const ScopedGenericObj<C, FP>& b) {
return p != b.get();
}
#endif // BASE_MEMORY_SCOPED_GENERIC_OBJ_H_