DGtal 1.3.0
Loading...
Searching...
No Matches
CowPtr.h
1
17#pragma once
18
33#if defined(CowPtr_RECURSES)
34#error Recursive header files inclusion detected in CowPtr.h
35#else // defined(CowPtr_RECURSES)
37#define CowPtr_RECURSES
38
39#if !defined CowPtr_h
41#define CowPtr_h
42
44// Inclusions
45#include <iostream>
46#include <type_traits>
47#include "DGtal/base/Common.h"
48#include "DGtal/base/CountedPtr.h"
50
51namespace DGtal
52{
53
55 // template class CowPtr
66 template <typename T>
67 class CowPtr
68 {
69 // ----------------------- Standard services ------------------------------
70 public:
71public:
72 typedef T element_type;
73
74 explicit CowPtr(T* p = 0) noexcept : myPtr(p) {}
75 // no need for ~CowPtr - the CountedPtr takes care of everything.
76 CowPtr(const CowPtr& r) noexcept : myPtr(r.myPtr) {}
106 CowPtr(const CountedPtr<T> & r, bool /* unused */ ) : myPtr( r ) {}
108 {
109 if (this != &r)
110 myPtr = r.myPtr;
111 return *this;
112 }
113
114
115 const T& operator*() const noexcept {return *myPtr;}
116 const T* operator->() const noexcept {return myPtr.get();}
117 const T* get() const noexcept {return myPtr.get();}
118
119 /* The following non-const methods are deactivated if T is a const type.
120 * The goal here is to avoid unecessary copies when it is known that
121 * the T object will not be modified.
122 *
123 * The problem is that C++ uses the non-const methods whenever it's possible
124 * (ie when CowPtr<T> is non-const), even if the full expression doesn't
125 * modify the object. A solution is to const_cast the CowPtr<T> before
126 * using one of these methods to force the usage of the const versions above.
127 *
128 * However, in the trivial case when T is a const type, we can simplify this
129 * by deactivating those methods.
130 *
131 * To do that, we use std::enable_if (see http://en.cppreference.com/w/cpp/types/enable_if )
132 * in the template parameters (it is also possible in the return type or
133 * as a parameter but it will change the signature). It depends on
134 * the constness of T returned by the type trait std::is_const.
135 * The `typename U = T` is necessary in order that the SFINAE rule works at the overload
136 * resolution step.
137 */
138 template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
139 T& operator*() {copy(); return *myPtr;}
140
141 template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
142 T* operator->() {copy(); return myPtr.get();}
143
144 template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
145 T* get() {copy(); return myPtr.get();}
146
153 bool operator==( const T* other ) const
154 {
155 return get() == other;
156 }
157
164 bool operator!=( const T* other ) const
165 {
166 return get() != other;
167 }
168
169
173 unsigned int count() const { return myPtr.count(); }
174 inline T* drop() { return myPtr.drop(); }
175 inline bool unique() const noexcept { return myPtr.unique(); }
176
177 private:
178
179 // ------------------------- Private Datas --------------------------------
180 private:
181
183
184 // ------------------------- Internals ------------------------------------
185 private:
186 void copy() // create a new copy of myPtr
187 {
188 if (!myPtr.unique()) {
189 T* old_p = myPtr.get();
190 myPtr = CountedPtr<T>(new T(*old_p));
191 }
192 }
193
194
195 // ----------------------- Interface --------------------------------------
196 public:
197
202 void selfDisplay ( std::ostream & out ) const;
203
208 bool isValid() const;
209
210 // ------------------------- Protected Datas ------------------------------
211 private:
212
213 // ------------------------- Hidden services ------------------------------
214 protected:
215
216
217
218 }; // end of class CowPtr
219
220
227 template <typename T>
228 std::ostream&
229 operator<< ( std::ostream & out, const CowPtr<T> & object );
230
231} // namespace DGtal
232
233
235// Includes inline functions.
236#include "DGtal/base/CowPtr.ih"
237
238// //
240
241#endif // !defined CowPtr_h
242
243#undef CowPtr_RECURSES
244#endif // else defined(CowPtr_RECURSES)
Aim: Smart pointer based on reference counts.
Definition: CountedPtr.h:80
Aim: Copy on write shared pointer.
Definition: CowPtr.h:68
void selfDisplay(std::ostream &out) const
const T * operator->() const noexcept
Definition: CowPtr.h:116
T * operator->()
Definition: CowPtr.h:142
bool isValid() const
T & operator*()
Definition: CowPtr.h:139
void copy()
Definition: CowPtr.h:186
T * get()
Definition: CowPtr.h:145
CowPtr(const CowPtr &r) noexcept
Definition: CowPtr.h:76
CowPtr(const CountedPtr< T > &r, bool)
Definition: CowPtr.h:106
bool operator!=(const T *other) const
Definition: CowPtr.h:164
T element_type
Definition: CowPtr.h:72
bool operator==(const T *other) const
Definition: CowPtr.h:153
unsigned int count() const
Definition: CowPtr.h:173
CowPtr(T *p=0) noexcept
Definition: CowPtr.h:74
bool unique() const noexcept
Definition: CowPtr.h:175
const T * get() const noexcept
Definition: CowPtr.h:117
CountedPtr< T > myPtr
Definition: CowPtr.h:182
T * drop()
Definition: CowPtr.h:174
const T & operator*() const noexcept
Definition: CowPtr.h:115
CowPtr & operator=(const CowPtr &r)
Definition: CowPtr.h:107
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)