ReferenceTo.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2004 - 2025 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// psrchive/Util/units/ReferenceTo.h
10
11#ifndef __psrchive_util_units_ReferenceTo_h
12#define __psrchive_util_units_ReferenceTo_h
13
14// #define _DEBUG 1
15#include "debug.h"
16#include "ReferenceAble.h"
17#include "Error.h"
18
19#include <typeinfo>
20#include <string>
21
22namespace Reference {
23
25 template<class Type, bool active = true> class To {
26
27 public:
28
30 constexpr To () = default;
31
33 To (const To&);
34
36 ~To ();
37
39 To& operator = (const To&);
40
42 To (Type* ptr);
43
45 To& operator = (Type *);
46
48 Type& operator * () const { return *get(); }
49
51 Type* operator -> () const { return get(); }
52
54 bool operator == (const Type* ptr) const;
55
57 bool operator != (const Type* ptr) const;
58
60
61 bool is_equal_to (const Type* ptr) const;
62
64 operator Type* () const { return get(); }
65
67 bool operator ! () const;
68
70 operator bool () const;
71
73 void set (Type*);
74
76 Type* get () const;
77
79 Type* release ();
80
82 const Type* ptr () const;
83
85 Type* ptr ();
86
88 std::string name () const;
89
90 private:
91
93 void hook (const Able*);
94
96 void unhook (bool auto_delete = true);
97
99 Able::Handle* the_handle = nullptr;
100
101 };
102}
103
104template<class Type, bool active>
106{
107 DEBUG("Reference::To<"+name()+">::operator ==");
108 return is_equal_to(ptr);
109}
110
111template<class Type, bool active>
113{
114 DEBUG("Reference::To<"+name()+">::operator !=");
115 return !is_equal_to(ptr);
116}
117
118template<class Type, bool active>
120{
121 if (!ptr)
122 return !the_handle || the_handle->pointer == nullptr;
123 else
124 return the_handle && the_handle->pointer == ptr;
125}
126
127template<class Type, bool active>
128void Reference::To<Type,active>::unhook (bool auto_delete)
129{
130 DEBUG("Reference::To<"+name()+">::unhook handle=" << the_handle << " auto_delete=" << auto_delete);
131
132 if (!the_handle)
133 return;
134
135 Able::Handle* temp = the_handle;
136
137 the_handle = 0;
138
139 // thread-safe handle detachment
140 temp->decrement (active, auto_delete);
141}
142
143template<class Type, bool active>
144void Reference::To<Type,active>::hook (const Able* pointer)
145{
146 DEBUG("Reference::To<"+name()+">::handle Able*="<< pointer);
147
148 if (!pointer)
149 the_handle = 0;
150 else
151 the_handle = pointer->__reference (active);
152}
153
154template<class Type, bool active>
156{
157#ifdef _DEBUG
158 return "T";
159#else
160 return typeid(Type).name();
161#endif
162}
163
164template<class Type, bool active>
166{
167 DEBUG("Reference::To<"+name()+">::To (Type*="<< (void*)ref_pointer <<")");
168
169 the_handle = 0;
170 hook (ref_pointer);
171}
172
173template<class Type, bool active>
175{
176 DEBUG("Reference::To<"+name()+">::~To");
177
178 unhook ();
179}
180
181template<class Type, bool active>
183{
184 DEBUG("Reference::To<"+name()+">::operator !");
185
186 return !the_handle || the_handle->pointer == 0;
187}
188
189template<class Type, bool active>
191{
192 DEBUG("Reference::To<"+name()+">::operator bool");
193
194 return the_handle && the_handle->pointer;
195}
196
197// copy constructor
198template<class Type, bool active>
199Reference::To<Type,active>::To (const To& another_reference)
200{
201 DEBUG("Reference::To<"+name()+">::To (To<Type>)");
202
203 // thread-safe copy
204 the_handle = 0;
205 Able::Handle::copy (the_handle, another_reference.the_handle, active);
206}
207
208
209// operator = copy assignment operator
210template<class Type, bool active>
213{
214 DEBUG("Reference::To<"+name()+">::operator = (To<Type>)");
215
216 if (the_handle == oref.the_handle)
217 return *this;
218
219 unhook ();
220
221 // thread-safe copy
222 Able::Handle::copy (the_handle, oref.the_handle, active);
223
224 return *this;
225}
226
227// operator = assignment operator
228template<class Type, bool active>
231{
232 DEBUG("Reference::To<"+name()+">::operator = (Type*=" << (void*)ref_pointer <<")");
233 set (ref_pointer);
234 return *this;
235}
236
237// operator = assignment operator
238template<class Type, bool active>
239void Reference::To<Type,active>::set (Type* ref_pointer)
240{
241 DEBUG("Reference::To<"+name()+">::set (Type*=" << (void*)ref_pointer <<")");
242
243 if (the_handle && the_handle->pointer == ref_pointer)
244 return;
245
246 unhook ();
247 hook (ref_pointer);
248}
249
250template<class Type, bool active>
252{
253 DEBUG("Reference::To<"+name()+">::get");
254
255 if (!the_handle || the_handle->pointer == 0)
256 throw Error (InvalidPointer, "Reference::To<"+name()+">::get");
257
258 return reinterpret_cast<Type*>( the_handle->pointer );
259}
260
261
262template<class Type, bool active>
264{
265 DEBUG("Reference::To<"+name()+">::release");
266
267 if (!the_handle || the_handle->pointer == 0)
268 throw Error (InvalidPointer, "Reference::To<"+name()+">::release");
269
270 Type* copy = reinterpret_cast<Type*>( the_handle->pointer );
271
272 unhook (false);
273
274 return copy;
275}
276
278template<class Type, bool active>
280{
281 if (the_handle)
282 return reinterpret_cast<const Type*>( the_handle->pointer );
283 else
284 return 0;
285}
286
288template<class Type, bool active>
290{
291 if (the_handle && the_handle->pointer)
292 return reinterpret_cast<Type*>( the_handle->pointer );
293 else
294 return 0;
295}
296
297template<class Type, bool active>
299{
300 DEBUG("swap (Reference::To<Type>, ditto)");
301
302 Type* ref1_ptr = ref1.release();
303 Type* ref2_ptr = ref2.release();
304
305 ref1 = ref2_ptr;
306 ref2 = ref1_ptr;
307}
308
310template<class Type1, bool active1, class Type2, bool active2>
311bool operator == (const Reference::To<Type1,active1>& ref1,
313{
314 DEBUG("operator == (Reference::To<Type>&, Reference::To<Type2>&)");
315
316 if (!ref1)
317 return !ref2;
318
319 if (!ref2)
320 return false;
321
322 return ref1.ptr() == ref2.ptr();
323}
324
326template<class Type1, bool active1, class Type2, bool active2>
327bool operator != (const Reference::To<Type1,active1>& ref1,
329{
330 DEBUG("operator != (Reference::To<Type>&, Reference::To<Type2>&)");
331
332 if (!ref1)
333 return ref2;
334
335 if (!ref2)
336 return true;
337
338 return ref1.ptr() != ref2.ptr();
339}
340
341
343template<class Type, bool active, class Type2>
344bool operator == (const Reference::To<Type,active>& ref, const Type2* instance)
345{
346 DEBUG("operator == (Reference::To<Type>&, Type*)");
347 return ref.is_equal_to(instance);
348}
349
351template<class Type, bool active, class Type2>
352bool operator == (const Type2* instance, const Reference::To<Type,active>& ref)
353{
354 DEBUG("operator == (T2*, Reference::To<T1>&)");
355 return ref.is_equal_to(instance);
356}
357
358template<typename C, typename P, bool A>
359C* dynamic_kast (Reference::To<P,A>& p)
360{
361 return dynamic_cast<C*> (p.ptr());
362}
363
364template<typename P, bool A>
365P* const_kast (Reference::To<const P,A>& p)
366{
367 return const_cast<P*> (p.ptr());
368}
369
370#endif // #ifndef __psrchive_util_units_ReferenceTo_h
371
A convenient exception handling class.
Definition Error.h:54
Definition ReferenceAble.h:81
void decrement(bool active, bool auto_delete)
Thread-safe decrement and delete.
Definition ReferenceAble.C:249
static void copy(Handle *&to, Handle *const &from, bool active)
Thread-safe copy and increment.
Definition ReferenceAble.C:305
Manages Reference::To references to the instance.
Definition ReferenceAble.h:35
Template class manages Reference::Able objects.
Definition ReferenceTo.h:25
Type * get() const
Return the pointer.
Definition ReferenceTo.h:251
bool operator==(const Type *ptr) const
Comparison operator.
Definition ReferenceTo.h:105
bool operator!() const
Returns true if reference is null.
Definition ReferenceTo.h:182
std::string name() const
Return the name of the object, as returned by typeid.
Definition ReferenceTo.h:155
Type & operator*() const
Object dereferencing operator.
Definition ReferenceTo.h:48
bool is_equal_to(const Type *ptr) const
Work around "warning: ISO C++ says that these are ambiguous.
Definition ReferenceTo.h:119
Type * operator->() const
Member dereferencing operator.
Definition ReferenceTo.h:51
Type * release()
Return the pointer and unhook without deleting the object.
Definition ReferenceTo.h:263
const typename FFTW3::Plan * ptr() const
Definition ReferenceTo.h:279
void set(Type *)
Set the pointer.
Definition ReferenceTo.h:239
bool operator!=(const Type *ptr) const
Comparison operator.
Definition ReferenceTo.h:112
To & operator=(const To &)
Assignment operator.
Definition ReferenceTo.h:212
~To()
Destructor.
Definition ReferenceTo.h:174
constexpr To()=default
Default constructor.
Contains two basic classes that simplify dynamic memory management.
Definition HeapTracked.h:17

Generated using doxygen 1.14.0