Code

minor comment tweak
[inkscape.git] / src / gc-anchored.h
1 /** \file
2  * Inkscape::GC::Anchored - base class for anchored GC-managed objects
3  *
4  * Authors:
5  *   MenTaLguY <mental@rydia.net>
6  *
7  * Copyright (C) 2004 MenTaLguY
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #ifndef SEEN_INKSCAPE_GC_ANCHORED_H
13 #define SEEN_INKSCAPE_GC_ANCHORED_H
15 #include <glib/gmessages.h>
16 #include "gc-managed.h"
18 namespace Inkscape {
20 namespace GC {
22 /**
23  * A base class for anchored objects.  
24  *
25  * Objects are managed by our mark-and-sweep collector, but are anchored 
26  * against garbage collection so long as their reference count is nonzero.
27  *
28  * Object and member destructors will not be called on destruction
29  * unless a subclass also inherits from Inkscape::GC::Finalized.
30  *
31  * New instances of anchored objects should be created using the C++ new
32  * operator.  Under normal circumstances they should not be created on
33  * the stack.
34  *
35  * A newly created anchored object begins with a refcount of one, and
36  * will not be collected unless the refcount is zero.
37  *
38  * NOTE: If you create an object yourself, it is already anchored for
39  *       you.  You do not need to anchor it a second time.
40  *
41  * Note that a cycle involving an anchored object (with nonzero refcount)
42  * cannot be collected.  To avoid this, don't increment refcounts for
43  * pointers between two GC-managed objects.
44  *
45  * @see Inkscape::GC::Managed
46  * @see Inkscape::GC::Finalized
47  * @see Inkscape::GC::anchor
48  * @see Inkscape::GC::release
49  */
51 class Anchored {
52 public:
53     void anchor() const {
54         if (!_anchor) {
55             _anchor = _new_anchor();
56         }
57         _anchor->refcount++;
58     }
60     void release() const {
61         if (!--_anchor->refcount) {
62             _free_anchor(_anchor);
63             _anchor = NULL;
64         }
65     }
67 protected:
68     Anchored() : _anchor(NULL) { anchor(); } // initial refcount of one
70 private:
71     struct Anchor : public Managed<SCANNED, MANUAL> {
72         Anchor() : refcount(0) {}
73         Anchor(Anchored const *obj) : refcount(0) {
74             base = Core::base(const_cast<Anchored *>(obj));
75         }
76         int refcount;
77         void *base;
78     };
80     mutable Anchor *_anchor;
82     Anchor *_new_anchor() const;
83     void _free_anchor(Anchor *anchor) const;
85     Anchored(Anchored const &); // no copy
86     void operator=(Anchored const &); // no assign
87 };
89 /**
90  * @brief Increments the reference count of a anchored object.
91  *
92  * This function template generates functions which take
93  * a reference to a anchored object of a given type, increment
94  * that object's reference count, and return a reference to the
95  * object of the same type as the function's parameter.
96  *
97  * @param m a reference to a anchored object
98  *
99  * @return the reference to the object
100  */
101 template <typename R>
102 static R &anchor(R &r) {
103     static_cast<Anchored const &>(const_cast<R const &>(r)).anchor();
104     return r;
107 /**
108  * @brief Increments the reference count of a anchored object.
109  *
110  * This function template generates functions which take
111  * a pointer to a anchored object of a given type, increment
112  * that object's reference count, and return a pointer to the
113  * object of the same type as the function's parameter.
114  *
115  * @param m a pointer to anchored object
116  *
117  * @return the pointer to the object
118  */
119 template <typename R>
120 static R *anchor(R *r) {
121     static_cast<Anchored const *>(const_cast<R const *>(r))->anchor();
122     return r;
125 /**
126  * @brief Decrements the reference count of a anchored object.
127  *
128  * This function template generates functions which take
129  * a reference to a anchored object of a given type, increment
130  * that object's reference count, and return a reference to the
131  * object of the same type as the function's parameter.
132  *
133  * The return value is safe to use since the object, even if
134  * its refcount has reached zero, will not actually be collected
135  * until there are no references to it in local variables or
136  * parameters.
137  *
138  * @param m a reference to a anchored object
139  *
140  * @return the reference to the object
141  */
142 template <typename R>
143 static R &release(R &r) {
144     static_cast<Anchored const &>(const_cast<R const &>(r)).release();
145     return r;
148 /**
149  * @brief Decrements the reference count of a anchored object.
150  *
151  * This function template generates functions which take
152  * a pointer to a anchored object of a given type, increment
153  * that object's reference count, and return a pointer to the
154  * object of the same type as the function's parameter.
155  *
156  * The return value is safe to use since the object, even if
157  * its refcount has reached zero, will not actually be collected
158  * until there are no references to it in local variables or
159  * parameters.
160  *
161  * @param m a pointer to a anchored object
162  *
163  * @return the pointer to the object
164  */
165 template <typename R>
166 static R *release(R *r) {
167     static_cast<Anchored const *>(const_cast<R const *>(r))->release();
168     return r;
175 #endif
176 /*
177   Local Variables:
178   mode:c++
179   c-file-style:"stroustrup"
180   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
181   indent-tabs-mode:nil
182   fill-column:99
183   End:
184 */
185 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :