Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / ETL / tags / ETL_0_04_10 / ETL / _ref_count.h
1 /*! ========================================================================
2 ** Extended Template Library
3 **
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
12 **
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
22 **
23 ** ========================================================================= */
24
25 /* === S T A R T =========================================================== */
26
27 #ifndef __ETL_REF_COUNT_H
28 #define __ETL_REF_COUNT_H
29
30 /* === H E A D E R S ======================================================= */
31
32 #include "_curve_func.h"
33 #include <cassert>
34
35 /* === M A C R O S ========================================================= */
36
37 /* === T Y P E D E F S ===================================================== */
38
39 /* === C L A S S E S & S T R U C T S ======================================= */
40
41 _ETL_BEGIN_NAMESPACE
42
43 class weak_reference_counter;
44
45 // ========================================================================
46 /*!     \class  reference_counter       _ref_count.h    ETL/ref_count
47 **      \brief  Reference counter
48 **      \see weak_reference_counter
49 **      \writeme
50 */
51 class reference_counter
52 {
53         friend class weak_reference_counter;
54 private:
55         int* counter_;
56 public:
57
58         reference_counter(const bool &x=true):counter_(x?new int(1):0) { }
59
60         reference_counter(const reference_counter &x):counter_(x.counter_)
61                 { if(counter_) (*counter_)++; }
62
63         reference_counter(const weak_reference_counter &x);
64
65         ~reference_counter() { detach(); }
66
67         reference_counter& operator=(const reference_counter &rhs)
68         {
69                 detach();
70                 counter_=rhs.counter_;
71                 if(counter_)
72                 {
73                         assert(*counter_>0);
74                         (*counter_)++;
75                 }
76                 return *this;
77         }
78
79         void detach()
80         {
81                 if(counter_)
82                 {
83                         assert(*counter_>0);
84                         if(!--(*counter_))
85                                 delete counter_;
86                         counter_=0;
87                 }
88         }
89
90         void reset()
91         {
92                 detach();
93                 counter_=new int(1);
94         }
95
96         int count()const { return counter_?*counter_:0; }
97
98         bool unique()const { return counter_?*counter_==1:0; }
99
100         operator int()const { return count(); }
101 }; // END of class reference_counter
102
103 // ========================================================================
104 /*!     \class  weak_reference_counter  _ref_count.h    ETL/ref_count
105 **      \brief  Weak Reference counter
106 **      \see reference_counter
107 **      \writeme
108 */
109 class weak_reference_counter
110 {
111         friend class reference_counter;
112 private:
113         int* counter_;
114 public:
115         weak_reference_counter():counter_(0) { }
116
117         weak_reference_counter(const weak_reference_counter &x):counter_(x.counter_) { }
118
119         weak_reference_counter(const reference_counter &x):counter_(x.counter_) { }
120
121         ~weak_reference_counter() { }
122
123         weak_reference_counter& operator=(const reference_counter &rhs)
124         {
125                 counter_=rhs.counter_;
126                 assert(*counter_>0);
127                 return *this;
128         }
129
130         weak_reference_counter& operator=(const weak_reference_counter &rhs)
131         {
132                 counter_=rhs.counter_;
133                 assert(*counter_>0);
134                 return *this;
135         }
136
137         void detach() { counter_=0; }
138
139         int count()const { return counter_?*counter_:0; }
140
141         bool unique()const { return counter_?*counter_==1:0; }
142
143         operator int()const { return count(); }
144 }; // END of class weak_reference_counter
145
146 inline reference_counter::reference_counter(const weak_reference_counter &x):
147         counter_(x.counter_)
148 {
149         if(counter_) (*counter_)++;
150 }
151
152 _ETL_END_NAMESPACE
153
154 /* === E X T E R N S ======================================================= */
155
156 /* === E N D =============================================================== */
157
158 #endif