DGtal 1.3.0
Loading...
Searching...
No Matches
CountedPtrOrPtr.h
1
17#pragma once
18
33#if defined(CountedPtrOrPtr_RECURSES)
34#error Recursive header files inclusion detected in CountedPtrOrPtr.h
35#else // defined(CountedPtrOrPtr_RECURSES)
37#define CountedPtrOrPtr_RECURSES
38
39#if !defined CountedPtrOrPtr_h
41#define CountedPtrOrPtr_h
42
44// Inclusions
45#include <iostream>
46#include "DGtal/base/Common.h"
47#include "DGtal/base/CountedPtr.h"
49
50namespace DGtal
51{
52 template <typename T> class CountedConstPtrOrConstPtr;
53
55 // template class CountedPtrOrPtr
94 template <typename T>
96 {
97 public:
98 friend class CountedConstPtrOrConstPtr<T>;
99
100 // ----------------------- Standard services ------------------------------
101 public:
102
105
121 inline explicit CountedPtrOrPtr( T* p = 0, bool isCountedPtr = true )
122 : myAny(0), myIsCountedPtr( isCountedPtr )
123 {
124 if ( isCountedPtr ) {
125 if (p) myAny = static_cast<void*>( new Counter( p ) );
126 }
127 else
128 myAny = static_cast<void*>( p );
129 }
130
138 {
139 if ( myIsCountedPtr ) release();
140 }
141
149 CountedPtrOrPtr( const CountedPtr<T> & r ) noexcept
150 : myIsCountedPtr( true )
151 {
152 acquire( r.myCounter );
153 }
154
165 : myIsCountedPtr( r.myIsCountedPtr )
166 {
167 if ( myIsCountedPtr )
168 acquire( r.counterPtr() );
169 else
170 myAny = r.myAny;
171 }
172
186 {
187 if ( this != & r ) {
188 if ( myIsCountedPtr ) release();
189 myIsCountedPtr = r.myIsCountedPtr;
190 if ( r.myIsCountedPtr ) acquire( r.counterPtr() );
191 else myAny = r.myAny;
192 }
193 return *this;
194 }
195
207 {
208 if ( myIsCountedPtr ) release();
209 myIsCountedPtr = true;
210 acquire( r.myCounter );
211 return *this;
212 }
213
217 bool isSmart() const
218 {
219 return myIsCountedPtr;
220 }
221
225 bool isSimple() const
226 {
227 return ! myIsCountedPtr;
228 }
229
236 bool operator==( const T* other ) const
237 {
238 return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) == other : ptr() == other;
239 }
240
247 bool operator!=( const T* other ) const
248 {
249 return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) != other : ptr() != other;
250 }
251
260 T& operator*() const noexcept
261 {
262 // Travis is too slow in Debug mode with this ASSERT.
263 ASSERT( isValid() );
264 return myIsCountedPtr ? ( * counterPtr()->ptr ) : ( * ptr() );
265 }
266
276 T* operator->() const noexcept
277 {
278 // Travis is too slow in Debug mode with this ASSERT.
279 ASSERT( isValid() );
280 return myIsCountedPtr ? counterPtr()->ptr : ptr();
281 }
282
290 T* get() const noexcept
291 {
292 return myIsCountedPtr ? ( myAny ? counterPtr()->ptr : 0 ) : ptr();
293 }
294
300 bool unique() const noexcept
301 {
302 return myIsCountedPtr
303 ? ( myAny ? counterPtr()->count == 1 : true )
304 : true;
305 }
306
314 unsigned int count() const
315 {
316 return myIsCountedPtr ? counterPtr()->count : 0;
317 }
318
329 inline T* drop()
330 { // Gives back the pointer without deleting him. Delete only the counter.
331 ASSERT( isValid() );
332 if ( myIsCountedPtr ) {
333 ASSERT( unique() );
334 T* tmp = counterPtr()->ptr;
335 delete counterPtr();
336 myAny = 0;
337 return tmp;
338 } else {
339 return ptr();
340 }
341 }
342
343private:
344
347 void* myAny;
350
356 inline Counter* counterPtr() const
357 {
358 // Travis is too slow in Debug mode with this ASSERT.
359 ASSERT( myIsCountedPtr );
360 return static_cast<Counter*>( myAny );
361 }
362
368 inline T* ptr() const
369 {
370 // Travis is too slow in Debug mode with this ASSERT.
371 ASSERT( ! myIsCountedPtr );
372 return static_cast<T*>( myAny );
373 }
374
382 inline void acquire(Counter* c) noexcept
383 { // increment the count
384 // Travis is too slow in Debug mode with this ASSERT.
385 ASSERT( myIsCountedPtr );
386 myAny = static_cast<void*>( c );
387 if (c) ++c->count;
388 }
389
398 void release()
399 { // decrement the count, delete if it is 0
400 // Travis is too slow in Debug mode with this ASSERT.
401 ASSERT( myIsCountedPtr );
402 if (myAny) {
403 Counter * counter = counterPtr();
404 if (--counter->count == 0) {
405 delete counter->ptr;
406 delete counter;
407 }
408 myAny = 0;
409 }
410 }
411
412
413 // ----------------------- Interface --------------------------------------
414 public:
415
420 void selfDisplay ( std::ostream & out ) const;
421
426 bool isValid() const;
427
428 // ------------------------- Protected Datas ------------------------------
429 private:
430 // ------------------------- Private Datas --------------------------------
431 private:
432
433 // ------------------------- Hidden services ------------------------------
434 protected:
435
436
437 // ------------------------- Internals ------------------------------------
438 private:
439
440 }; // end of class CountedPtrOrPtr
441
442
449 template <typename T>
450 std::ostream&
451 operator<< ( std::ostream & out, const CountedPtrOrPtr<T> & object );
452
453} // namespace DGtal
454
455
457// Includes inline functions.
458#include "DGtal/base/CountedPtrOrPtr.ih"
459
460// //
462
463#endif // !defined CountedPtrOrPtr_h
464
465#undef CountedPtrOrPtr_RECURSES
466#endif // else defined(CountedPtrOrPtr_RECURSES)
Aim: Smart or simple const pointer on T. It can be a smart pointer based on reference counts or a sim...
Aim: Smart or simple pointer on T. It can be a smart pointer based on reference counts or a simple po...
T * get() const noexcept
CountedPtrOrPtr(const CountedPtr< T > &r) noexcept
unsigned int count() const
Counter * counterPtr() const
bool myIsCountedPtr
If true, 'this' pointer object is smart, otherwise it is simple.
CountedPtrOrPtr & operator=(const CountedPtr< T > &r)
void acquire(Counter *c) noexcept
CountedPtrOrPtr(T *p=0, bool isCountedPtr=true)
CountedPtrOrPtr & operator=(const CountedPtrOrPtr &r)
bool operator==(const T *other) const
T & operator*() const noexcept
CountedPtrOrPtr(const CountedPtrOrPtr &r) noexcept
bool operator!=(const T *other) const
void selfDisplay(std::ostream &out) const
T * operator->() const noexcept
bool unique() const noexcept
CountedPtr< T >::Counter Counter
The counter is the same as CountedPtr.
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:80
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)
T * ptr
A pointer to a (shared) dynamically allocated object of type T.
Definition: CountedPtr.h:105
unsigned count
The number of CountedPtr pointing to this counter.
Definition: CountedPtr.h:107