Created
November 10, 2010 20:24
-
-
Save joshkel/671452 to your computer and use it in GitHub Desktop.
boost::scoped_ptr and boost::shared_ptr equivalents for C++Builder forms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**Releases or immediately deletes a form, as appropriate. Deleting a form | |
* has unprocessed events or messages may cause memory errors, but calling | |
* Release() on a form that only exists in memory (with no corresponding window) | |
* needlessly creates a window (by accessing the Handle property). See | |
* CodeGear's documentation for TCustomForm::Release. | |
*/ | |
inline void DeleteOrRelease(TCustomForm *f) | |
{ | |
if (f->HandleAllocated()) { | |
f->Release(); | |
} else { | |
delete f; | |
} | |
} | |
/**Shared pointer that automatically calls TCustomForm::Release instead of | |
* deleting the form. See DeleteOrRelease for details. | |
* | |
* Note that this class has some garbage-collection semantics rather than | |
* strict C++ RAII; i.e., you don't actually know when the form | |
* will be deleted and resources reclaimed. | |
*/ | |
template<typename T = TForm> | |
class SharedFormPtr : public boost::shared_ptr<T> | |
{ | |
public: | |
class Releaser | |
{ | |
public: | |
void operator()(TCustomForm* f) { DeleteOrRelease(f); } | |
}; | |
SharedFormPtr() : boost::shared_ptr<T>() {} | |
explicit SharedFormPtr(T* p) | |
: boost::shared_ptr<T>(p, Releaser()) {} | |
void reset() { | |
boost::shared_ptr<T>::reset(); | |
} | |
void reset(T* p) { | |
boost::shared_ptr<T>::reset(p, Releaser()); | |
} | |
}; | |
/**Scoped pointer that automatically calls TCustomForm::Release instead of | |
* deleting the form. See SharedFormPtr. It's used almost identically to | |
* boost::scoped_ptr. */ | |
template<typename T = TForm> | |
class ScopedFormPtr | |
{ | |
private: | |
typedef ScopedFormPtr this_type; | |
T *ptr; | |
public: | |
ScopedFormPtr() : ptr(NULL) {} | |
explicit ScopedFormPtr(T* p) : ptr(p) {} | |
~ScopedFormPtr() | |
{ | |
if (ptr) { | |
DeleteOrRelease(ptr); | |
} | |
} | |
T& operator*() const | |
{ | |
BOOST_ASSERT(ptr != NULL); | |
return *ptr; | |
} | |
T* operator->() const | |
{ | |
BOOST_ASSERT(ptr != NULL); | |
return ptr; | |
} | |
T* get() const { return ptr; } | |
bool operator!() const { return ptr == NULL; } | |
typedef T * this_type::*unspecified_bool_type; | |
operator unspecified_bool_type() const { | |
return ptr == NULL ? NULL : &this_type::ptr; | |
} | |
void swap (ScopedFormPtr &b) { | |
T * tmp = b.ptr; | |
b.ptr = ptr; | |
ptr = tmp; | |
} | |
void reset(T* p = NULL) { | |
BOOST_ASSERT(p == NULL || p != ptr); | |
this_type(p).swap(*this); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment