Skip to content

Instantly share code, notes, and snippets.

@joshkel
Created November 10, 2010 20:24
Show Gist options
  • Save joshkel/671452 to your computer and use it in GitHub Desktop.
Save joshkel/671452 to your computer and use it in GitHub Desktop.
boost::scoped_ptr and boost::shared_ptr equivalents for C++Builder forms
/**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