singular_refobj.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef mia_singular_refobj_hh
22 #define mia_singular_refobj_hh
23 
24 
25 #include <mia/core/defines.hh>
26 #include <cassert>
27 
29 
30 
31 
46 template <typename T>
48 public:
49  struct Destructor {
51  virtual void operator ()(T& MIA_PARAM_UNUSED(data)) const = 0;
52  };
53 
54  struct EmptyDestructor : public Destructor{
56  virtual void operator ()(T& MIA_PARAM_UNUSED(data))const {}
57  };
58 
60 
62 
63  TSingleReferencedObject(T data, const Destructor& d = empty_destructor);
64 
66 
68 
70 
72 
73 
75 
76  operator T()const;
77 
78  unsigned get_refcount()const;
79 
80 private:
81  class TheObject {
82  public:
83  TheObject(T data, const TSingleReferencedObject::Destructor& d);
84  ~TheObject();
85  void add_ref();
86  bool del_ref();
87  T get() const;
88 
89  unsigned get_refcount()const;
90  private:
91  TheObject(const TheObject& data) = delete;
92  TheObject& operator = (const TheObject& data) = delete;
93  T m_data;
94  unsigned m_refcount;
95  const Destructor& m_destructor;
96  };
97  TheObject *m_object;
98 };
99 
100 template <typename T>
102 
103 
104 template <typename T>
106  m_object(nullptr)
107 {
108 }
109 
110 template <typename T>
112 {
113  m_object = new TheObject(data, d);
114 }
115 
116 template <typename T>
118 {
119  m_object = other.m_object;
120  if (m_object)
121  m_object->add_ref();
122 }
123 
124 template <typename T>
126 {
127  if (m_object)
128  m_object->del_ref();
129  m_object = other.m_object;
130  if (m_object)
131  m_object->add_ref();
132  return *this;
133 }
134 
135 template <typename T>
137  m_object(other.m_object)
138 {
139  other.m_object = nullptr;
140 }
141 
142 template <typename T>
144 {
145  if (&other != this) {
146  if (m_object)
147  m_object->del_ref();
148  m_object = other.m_object;
149  other.m_object = nullptr;
150  }
151  return *this;
152 }
153 
154 
155 template <typename T>
157 {
158  if (m_object)
159  if (m_object->del_ref())
160  delete m_object;
161 }
162 
163 template <typename T>
165 {
166  return m_object->get();
167 }
168 
169 template <typename T>
171 {
172  if (m_object)
173  return m_object->get_refcount();
174  else
175  return 0;
176 }
177 
178 template <typename T>
180  m_data(data),
181  m_refcount(1),
182  m_destructor(d)
183 {
184 }
185 
186 template <typename T>
188 {
189  assert(m_refcount == 0);
190  m_destructor(m_data);
191 }
192 
193 template <typename T>
195 {
196  ++m_refcount;
197 }
198 
199 template <typename T>
201 {
202  --m_refcount;
203  return (m_refcount <= 0);
204 }
205 
206 template <typename T>
208 {
209  return m_refcount;
210 }
211 
212 template <typename T>
214 {
215  return m_data;
216 }
217 
219 #endif
unsigned get_refcount() const
TSingleReferencedObject & operator=(const TSingleReferencedObject< T > &other)
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
virtual void operator()(T &data) const =0
a singulater reference counted object that gets destroyed when the refount goes to zero ...
static const EmptyDestructor empty_destructor
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36