From: mental Date: Thu, 15 May 2008 17:01:15 +0000 (+0000) Subject: introduce lifecycle stuff which will replace libgc X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=738d7f16efb5ce2f9529f05af975af160d0ea31b;p=inkscape.git introduce lifecycle stuff which will replace libgc --- diff --git a/src/Makefile_insert b/src/Makefile_insert index f39ad098f..62d6b92ce 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -327,6 +327,7 @@ libinkpost_a_SOURCES = \ gradient-chemistry.cpp gradient-chemistry.h \ ink-action.cpp \ ink-action.h \ + lifecycle.h \ memeq.h \ round.h \ streq.h \ diff --git a/src/lifecycle.h b/src/lifecycle.h new file mode 100644 index 000000000..7e37bd852 --- /dev/null +++ b/src/lifecycle.h @@ -0,0 +1,134 @@ +/** \file + * Inkscape::Lifecycle - automatic object lifecycle management + * + * Copyright 2008 MenTaLguY + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + * + */ + +#ifndef SEEN_INKSCAPE_LIFECYCLE_H +#define SEEN_INKSCAPE_LIFECYCLE_H + +#include +#include + +namespace Inkscape { +namespace Lifecycle { + +class BaseManagedPtr; + +// Abstract base class for managed objects +class AbstractManaged { +public: + AbstractManaged() {} + virtual ~AbstractManaged() {} +protected: + virtual void managedAddReference() const=0; + virtual void managedRemoveReference() const=0; + friend class BaseManagedPtr; +private: + AbstractManaged(AbstractManaged &); // no copy + void operator=(AbstractManaged &); // no assign +}; + +// Base class for managed pointers; not intended for direct use +class BaseManagedPtr { +protected: + BaseManagedPtr() : ptr(NULL) {} + BaseManagedPtr(AbstractManaged const *managed) : ptr(NULL) { + set(managed); + } + BaseManagedPtr(BaseManagedPtr const &other) : ptr(NULL) { + set(other.ptr); + } + + AbstractManaged const *get() const { return ptr; } + void set(AbstractManaged const *managed) { + if (managed) { + ptr->managedAddReference(); + } + if (ptr) { + ptr->managedRemoveReference(); + } + ptr = managed; + } + +private: + AbstractManaged const *ptr; +}; + +// Type-safe managed pointer +template +class ManagedPtr : public BaseManagedPtr { +public: + ManagedPtr() : BaseManagedPtr() {} + ManagedPtr(T *managed) : BaseManagedPtr(managed) {} + ManagedPtr(ManagedPtr const &other) : BaseManagedPtr(other) {} + + operator T *() const { return get_recast(); } + T &operator*() const { return *get_recast(); } + T *operator->() const { return get_recast(); } + ManagedPtr &operator=(T *managed) { + set(managed); + return *this; + } + ManagedPtr &operator=(ManagedPtr const &other) { + set(other.get()); + return *this; + } + +private: + T *get_recast() const { + return const_cast(static_cast(get())); + } +}; + +// Dummy implementation of AbstractManaged to ease migration +class DummyManaged : public virtual AbstractManaged { +protected: + virtual void managedAddReference() const {} + virtual void managedRemoveReference() const {} +}; + +// Straightforward refcounting implementation of AbstractManaged +class SimpleManaged : public virtual AbstractManaged { +protected: + SimpleManaged() : refcount(0) {} + virtual ~SimpleManaged() {} + + virtual void managedAddReference() const { + g_atomic_int_inc(&refcount); + } + virtual void managedRemoveReference() const { + if (g_atomic_int_dec_and_test(&refcount)) { + const_cast(this)->managedDispose(); + } + } + virtual void managedDispose() { + delete this; + } + +private: + mutable volatile gint refcount; +}; + +} +} + +#endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :