Code

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