summaryrefslogtreecommitdiffstats
path: root/src/gc-anchored.h
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/gc-anchored.h
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/gc-anchored.h')
-rw-r--r--src/gc-anchored.h185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/gc-anchored.h b/src/gc-anchored.h
new file mode 100644
index 000000000..f9d609074
--- /dev/null
+++ b/src/gc-anchored.h
@@ -0,0 +1,185 @@
+/** \file
+ * Inkscape::GC::Anchored - base class for anchored GC-managed objects
+ *
+ * Authors:
+ * MenTaLguY <mental@rydia.net>
+ *
+ * Copyright (C) 2004 MenTaLguY
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_GC_ANCHORED_H
+#define SEEN_INKSCAPE_GC_ANCHORED_H
+
+#include <glib/gmessages.h>
+#include "gc-managed.h"
+
+namespace Inkscape {
+
+namespace GC {
+
+/**
+ * A base class for anchored objects.
+ *
+ * Objects are managed by our mark-and-sweep collector, but are anchored
+ * against garbage collection so long as their reference count is nonzero.
+ *
+ * Object and member destructors will not be called on destruction
+ * unless a subclass also inherits from Inkscape::GC::Finalized.
+ *
+ * New instances of anchored objects should be created using the C++ new
+ * operator. Under normal circumstances they should not be created on
+ * the stack.
+ *
+ * A newly created anchored object begins with a refcount of one, and
+ * will not be collected unless the refcount is zero.
+ *
+ * NOTE: If you create an object yourself, it is already anchored for
+ * you. You do not need to anchor it a second time.
+ *
+ * Note that a cycle involving an anchored object (with nonzero refcount)
+ * cannot be collected. To avoid this, don't increment refcounts for
+ * pointers between two garbage-collected objects.
+ *
+ * @see Inkscape::GC::Managed
+ * @see Inkscape::GC::Finalized
+ * @see Inkscape::GC::anchor
+ * @see Inkscape::GC::release
+ */
+
+class Anchored {
+public:
+ void anchor() const {
+ if (!_anchor) {
+ _anchor = _new_anchor();
+ }
+ _anchor->refcount++;
+ }
+
+ void release() const {
+ if (!--_anchor->refcount) {
+ _free_anchor(_anchor);
+ _anchor = NULL;
+ }
+ }
+
+protected:
+ Anchored() : _anchor(NULL) { anchor(); } // initial refcount of one
+
+private:
+ struct Anchor : public Managed<SCANNED, MANUAL> {
+ Anchor() : refcount(0) {}
+ Anchor(Anchored const *obj) : refcount(0) {
+ base = Core::base(const_cast<Anchored *>(obj));
+ }
+ int refcount;
+ void *base;
+ };
+
+ mutable Anchor *_anchor;
+
+ Anchor *_new_anchor() const;
+ void _free_anchor(Anchor *anchor) const;
+
+ Anchored(Anchored const &); // no copy
+ void operator=(Anchored const &); // no assign
+};
+
+/**
+ * @brief Increments the reference count of a anchored object.
+ *
+ * This function template generates functions which take
+ * a reference to a anchored object of a given type, increment
+ * that object's reference count, and return a reference to the
+ * object of the same type as the function's parameter.
+ *
+ * @param m a reference to a anchored object
+ *
+ * @return the reference to the object
+ */
+template <typename R>
+static R &anchor(R &r) {
+ static_cast<Anchored const &>(const_cast<R const &>(r)).anchor();
+ return r;
+}
+
+/**
+ * @brief Increments the reference count of a anchored object.
+ *
+ * This function template generates functions which take
+ * a pointer to a anchored object of a given type, increment
+ * that object's reference count, and return a pointer to the
+ * object of the same type as the function's parameter.
+ *
+ * @param m a pointer to anchored object
+ *
+ * @return the pointer to the object
+ */
+template <typename R>
+static R *anchor(R *r) {
+ static_cast<Anchored const *>(const_cast<R const *>(r))->anchor();
+ return r;
+}
+
+/**
+ * @brief Decrements the reference count of a anchored object.
+ *
+ * This function template generates functions which take
+ * a reference to a anchored object of a given type, increment
+ * that object's reference count, and return a reference to the
+ * object of the same type as the function's parameter.
+ *
+ * The return value is safe to use since the object, even if
+ * its refcount has reached zero, will not actually be collected
+ * until there are no references to it in local variables or
+ * parameters.
+ *
+ * @param m a reference to a anchored object
+ *
+ * @return the reference to the object
+ */
+template <typename R>
+static R &release(R &r) {
+ static_cast<Anchored const &>(const_cast<R const &>(r)).release();
+ return r;
+}
+
+/**
+ * @brief Decrements the reference count of a anchored object.
+ *
+ * This function template generates functions which take
+ * a pointer to a anchored object of a given type, increment
+ * that object's reference count, and return a pointer to the
+ * object of the same type as the function's parameter.
+ *
+ * The return value is safe to use since the object, even if
+ * its refcount has reached zero, will not actually be collected
+ * until there are no references to it in local variables or
+ * parameters.
+ *
+ * @param m a pointer to a anchored object
+ *
+ * @return the pointer to the object
+ */
+template <typename R>
+static R *release(R *r) {
+ static_cast<Anchored const *>(const_cast<R const *>(r))->release();
+ return r;
+}
+
+}
+
+}
+
+#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 :