template<class C, class FreeProc = ScopedPtrMallocFree>
class scoped_ptr_malloc {
public:
// The element type
typedef C element_type;
// Constructor. Defaults to intializing with NULL.
// There is no way to create an uninitialized scoped_ptr.
// The input parameter must be allocated with an allocator that matches the
// Free functor. For the default Free functor, this is malloc, calloc, or
// realloc.
explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
// Destructor. If there is a C object, call the Free functor.
~scoped_ptr_malloc() {
free_(ptr_);
}
// 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 (ptr_ != p) {
free_(ptr_);
ptr_ = p;
}
}
// Get the current object.
// operator* and operator-> will cause an assert() failure if there is
// no current object.
C& operator*() const {
assert(ptr_ != NULL);
return *ptr_;
}
C* operator->() const {
assert(ptr_ != NULL);
return ptr_;
}
C* get() const {
return ptr_;
}
// Comparison operators.
// These return whether a scoped_ptr_malloc and a plain pointer refer
// to the same object, not just to two different but equal objects.
// For compatibility wwith the boost-derived implementation, these
// take non-const arguments.
bool operator==(C* p) const {
return ptr_ == p;
}
bool operator!=(C* p) const {
return ptr_ != p;
}
// Swap two scoped pointers.
void swap(scoped_ptr_malloc & b) {
C* tmp = b.ptr_;
b.ptr_ = ptr_;
ptr_ = 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() {
C* tmp = ptr_;
ptr_ = NULL;
return tmp;
}
private:
C* ptr_;
// no reason to use these: each scoped_ptr_malloc should have its own object
template <class C2, class GP>
bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
template <class C2, class GP>
bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
static FreeProc const free_;
// Disallow evil constructors
scoped_ptr_malloc(const scoped_ptr_malloc&);
void operator=(const scoped_ptr_malloc&);
};
template<class C, class FP>
FP const scoped_ptr_malloc<C, FP>::free_ = FP();
template<class C, class FP> inline
void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
a.swap(b);
}
template<class C, class FP> inline
bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
return p == b.get();
}
template<class C, class FP> inline
bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
return p != b.get();
}