G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsMemory.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsTemplateTools.h>
17 
18 #ifdef __MINGW32__
19 //#include <malloc/malloc.h> //xcode
20 #include <malloc.h>
21 #endif
22 
23 #if __cplusplus < 201103 && defined( __GLIBCXX__ )
24 # if defined(__INTEL_COMPILER)
25 # include <boost/shared_ptr.hpp>
26 # include <boost/weak_ptr.hpp>
27 # else
28 # include <tr1/memory>
29 # endif
30 #else // libc++ or other
31 # include <memory>
32 #endif
33 
34 namespace gismo {
35 
43 namespace memory
44 {
45 
46 /* \brief Adaptor for a shared pointer
47 
48 usage:
49 \code
50 memory::shared_ptr<int> B;
51 \endcode
52 */
53 
54 #if __cplusplus < 201103 && defined( __GLIBCXX__ )
55 # if defined(__INTEL_COMPILER)
56 using boost::shared_ptr;
57 using boost::weak_ptr;
58 # else
59 using std::tr1::shared_ptr;
60 using std::tr1::weak_ptr;
61 # endif
62 #else // libc++ or other
63 using std::shared_ptr;
64 using std::weak_ptr;
65 #endif
66 
67 /* \brief Adaptor for a unique pointer
68 
69 usage:
70 \code
71 memory::unique_ptr<int> B;
72 \endcode
73 */
74 #if __cplusplus >= 201103 || _MSC_VER >= 1600
75 using std::unique_ptr;
76 using std::nullptr_t;
77 #else
78 
79 template <typename T>
80 class unique_ptr : public std::auto_ptr<T>
81 {
82  typedef std::auto_ptr<T> Base;
83  typedef std::auto_ptr_ref<T> unique_ptr_ref;
84 
85  //struct Cannot_Convert_Pointer;
86 
87 public :
88  explicit unique_ptr(T* p = 0) throw() : Base(p) { }
89 
90  unique_ptr(const unique_ptr& r) : Base( const_cast<unique_ptr&>(r) ) { }
91 
92  unique_ptr(unique_ptr_ref m) throw() : Base(m) { }
93 
94  template<typename U>
95  unique_ptr(const unique_ptr<U> & r
96  // unique_ptr<typename conditional<is_base_of<U,T>::value, U,
97  // Cannot_Convert_Pointer >::type>
98  ) throw()
99  : Base( const_cast<unique_ptr<U>&>(r) ) { }
100 
101  unique_ptr & operator=(const unique_ptr& other) throw()
102  {
103  Base::operator=(const_cast<unique_ptr&>(other));
104  return *this;
105  }
106 
107  template<class U>
108  unique_ptr & operator=(const unique_ptr<U> & other) throw()
109  {
110  Base::operator=(const_cast<unique_ptr<U>&>(other));
111  return *this;
112  }
113 
114  //operator shared_ptr<T> () { return shared_ptr<T>(this->release()); }
115 
116  template<class U> operator shared_ptr<U>()
117  // shared_ptr<typename conditional<is_base_of<U,T>::value, U,
118  // Cannot_Convert_Pointer >::type> ()
119  { return shared_ptr<U>(Base::release()); }
120 
121  bool operator!() const { return Base::get() == NULL; }
122 
123 private:
124 
125  struct SafeBool
126  { SafeBool(int) {}
127  void dummy() {} };
128 
129  typedef void (SafeBool::*bool_cast_type)();
130 
131 public:
132 
133  operator bool_cast_type() const
134  { return !Base::get() ? 0 : &SafeBool::dummy; }
135 };
136 
137 template<class T>
138 bool operator==(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
139 { return p1.get()==p2.get(); }
140 template<class T>
141 bool operator!=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
142 { return p1.get()!=p2.get(); }
143 template<class T>
144 bool operator<(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
145 { return p1.get()<p2.get(); }
146 template<class T>
147 bool operator>(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
148 { return p1.get()>p2.get(); }
149 template<class T>
150 bool operator<=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
151 { return p1.get()<=p2.get(); }
152 template<class T>
153 bool operator>=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
154 { return p1.get()>=p2.get(); }
155 
156 class nullptr_t
157 {
158 public:
159  /* Return 0 for any class pointer */
160  template<typename T> operator T*() const {return 0;}
161  /* Return 0 for any member pointer */
162  template<typename T, typename U> operator T U::*() const {return 0;}
163  /* Safe boolean conversion */
164  operator void*() const {return 0;}
165 private:
166  /* Not allowed to get the address */
167  void operator&() const;
168 };
169 #endif
170 
172 template <typename T> void null_deleter(T *) {}
173 
174 
180 template <typename T>
181 inline shared_ptr<T> make_shared(T *x) { return shared_ptr<T>(x); }
182 
188 template <typename T>
189 inline shared_ptr<T> make_shared_not_owned(const T *x)
190 { return shared_ptr<T>(const_cast<T*>(x), null_deleter<T>); }
191 
197 template <typename T>
198 inline unique_ptr<T> make_unique(T * x) { return unique_ptr<T>(x); }
199 
202 template<class toC, typename from>
203 inline unique_ptr<toC> convert_ptr(from p)
204 { return unique_ptr<toC>( dynamic_cast<toC*>(p.release()) ); }
205 
207 template <typename T>
208 inline std::vector<T*> get_raw(const std::vector< unique_ptr<T> >& cont)
209 {
210  std::vector<T*> result;
211  for (typename std::vector< unique_ptr<T> >::const_iterator it = cont.begin(); it != cont.end(); ++it)
212  result.push_back(const_cast<T*>( (*it).get() ));
213  return result;
214 }
215 
217 template <typename T>
218 inline std::vector<T*> get_raw(const std::vector< shared_ptr<T> >& cont)
219 {
220  std::vector<T*> result;
221  for (typename std::vector< shared_ptr<T> >::const_iterator it = cont.begin(); it != cont.end(); ++it)
222  result.push_back(const_cast<T*>( (*it).get() ));
223  return result;
224 }
225 
227 template <typename T>
228 inline std::vector<T*> release(std::vector< unique_ptr<T> >& cont)
229 {
230  std::vector<T*> result;
231  for (typename std::vector< unique_ptr<T> >::iterator it = cont.begin(); it != cont.end(); ++it)
232  result.push_back( (*it).release() );
233  cont.clear();
234  return result;
235 }
236 
237 } // namespace memory
238 
239 #if __cplusplus >= 201103 || _MSC_VER >= 1900
240 // fix MSVC 2013- (_MSC_VER < 1900)
241 // MSVC < 1900 do not work probably. give makes a deep copy for return value,
242 // losses left value. But the alternative code results in segmentation vaults
243 // because a swap/give loop leads to a stack overflow.
244 // From the adresses, it seams that Eigen do not support rvalue with MSVC < 1900
245 // Therefore disabled EIGEN_HAS_RVALUE_REFERENCES for MSVC < 1900 and use
246 // alternative code.
247 
253 template <class T> inline
254 auto give(T&& t) -> decltype(std::move(std::forward<T>(t)))
255 {
256  return std::move(std::forward<T>(t));
257 }
258 
259 #else
260 
266 template <typename S> inline S give(S & x)
267 { S t; t.swap(x); return t; }
268 
269 template <typename T> inline
270 memory::unique_ptr<T> give(memory::unique_ptr<T> & x)
271 { return memory::unique_ptr<T>(x.release()); }
272 
273 template <typename T> inline
274 memory::shared_ptr<T> give(memory::shared_ptr<T> & x)
275 { memory::shared_ptr<T> result = x; x.reset(); return result; }
276 
277 #endif
278 
279 // Small, dynamically sized arrays on the stack, for POD types.
280 // Only use this if the size is guaranteed not to be more than a few
281 // hundred bytes! Be warned: overflow occurs without any warning
282 #if defined(gsGmp_ENABLED) || defined(gsMpfr_ENABLED)
283  #define STACK_ARRAY( T, name, sz ) T name[sz];
284 #else
285 // Note: VLAs(following line) can be buggy on some compilers/versions,
286 // also not nececarily on the stack
287 // #define STACK_ARRAY( T, name, sz ) T name[sz];
288 #define STACK_ARRAY( T, name, sz ) T * name = (T*) alloca ( (sz) * sizeof(T) );
289 #endif
290 
291 
294 template <typename It, typename ItOut>
295 void cloneAll(It start, It end, ItOut out)
296 {
297  for (It i = start; i != end; ++i)
298  *out++ = dynamic_cast<typename std::iterator_traits<ItOut>::value_type>((*i)->clone().release());
299 }
300 
303 template <typename ContIn, typename ContOut>
304 void cloneAll(const ContIn& in, ContOut& out)
305 {
306  out.resize(in.size());
307  cloneAll(in.begin(), in.end(), out.begin());
308 }
309 
311 template <typename It>
312 void freeAll(It begin, It end)
313 {
314  for (It it = begin; it != end; ++it)
315  {
316  delete (*it);
317  *it = NULL;
318  }
319 }
320 
322 template <typename Cont>
323 void freeAll(Cont& cont)
324 {
325  for (typename Cont::iterator it = cont.begin(); it != cont.end(); ++it)
326  delete (*it);
327  cont.clear();
328 }
329 
331 template<typename obj> inline
332 std::vector<obj*> asVectorPtr(const std::vector<obj> & matv)
333 {
334  std::vector<obj*> result;
335  const size_t d = matv.size();
336  result.reserve(d);
337  for ( size_t i = 0; i!=d; ++i)
338  result.push_back( const_cast<obj*>(&matv[i]) );
339  return result;
340 }
341 
343 template <typename Base, typename Derived>
344 std::vector<Base*> castVectorPtr(std::vector<Derived*> pVec)
345 {
346  std::vector<Base*> result(pVec.size());
347  std::copy(pVec.begin(), pVec.end(), result.begin() );
348  return result;
349 }
350 
352 template <typename Derived, typename Base>
353 bool checkVectorPtrCast(std::vector<Base*> pVec)
354 {
355  for (typename std::vector<Base*>::iterator it = pVec.begin(); it != pVec.end(); ++it)
356  if ( ! dynamic_cast<Derived*>(*it) )
357  return false;
358  return true;
359 }
360 
367 template <class T, class U>
368 inline void copy_n(T begin, const size_t n, U* result)
369 {
370  std::copy(begin, begin+n,
371 # ifdef _MSC_VER
372  // Take care of C4996 warning
373  //stdext::checked_array_iterator<U*>(result,n));
374  stdext::unchecked_array_iterator<U*>(result));
375 # else
376  result);
377 // Note: in C++11 there is:
378 // std::copy_n(begin, n, result);
379 # endif
380 }
381 
382 namespace util
383 {
390 template <class T, class U>
391 inline void copy(T begin, T end, U* result)
392 {
393  std::copy(begin, end,
394 # ifdef _MSC_VER
395  // Take care of C4996 warning
396  //stdext::checked_array_iterator<U*>(result,n));
397  stdext::unchecked_array_iterator<U*>(result));
398 # else
399  result);
400 # endif
401 }
402 
403 }
404 
405 } // namespace gismo
406 
407 #if __cplusplus < 201103L && _MSC_VER < 1600 && !defined(nullptr)
408 // Define nullptr for compatibility with newer C++
409 static const gismo::memory::nullptr_t nullptr ={};
410 #endif
unique_ptr< T > make_unique(T *x)
Definition: gsMemory.h:198
shared_ptr< T > make_shared_not_owned(const T *x)
Creates a shared pointer which does not eventually delete the underlying raw pointer. Usefull to refer to objects which should not be destroyed.
Definition: gsMemory.h:189
std::vector< obj * > asVectorPtr(const std::vector< obj > &matv)
Constructs a vector of pointers from a vector of objects.
Definition: gsMemory.h:332
std::vector< T * > release(std::vector< unique_ptr< T > > &cont)
Takes a vector of smart pointers, releases them and returns the corresponding raw pointers...
Definition: gsMemory.h:228
unique_ptr< toC > convert_ptr(from p)
Converts an uPtr p to an uPtr of class toC and gives it back as return value.
Definition: gsMemory.h:203
std::vector< Base * > castVectorPtr(std::vector< Derived * > pVec)
Casts a vector of pointers.
Definition: gsMemory.h:344
S give(S &x)
Definition: gsMemory.h:266
std::vector< T * > get_raw(const std::vector< unique_ptr< T > > &cont)
Takes a vector of smart pointers and returns the corresponding raw pointers.
Definition: gsMemory.h:208
void cloneAll(It start, It end, ItOut out)
Clones all pointers in the range [start end) and stores new raw pointers in iterator out...
Definition: gsMemory.h:295
void copy_n(T begin, const size_t n, U *result)
Small wrapper for std::copy mimicking memcpy (or std::copy_n) for a raw pointer destination, copies n positions starting from begin into result. The latter is expected to have been allocated in advance.
Definition: gsMemory.h:368
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
void null_deleter(T *)
Deleter function that does not delete an object pointer.
Definition: gsMemory.h:172
bool checkVectorPtrCast(std::vector< Base * > pVec)
Returns true if all instances of Base cast to Derived.
Definition: gsMemory.h:353
Utilities related to template programming.
void copy(T begin, T end, U *result)
Small wrapper for std::copy mimicking std::copy for a raw pointer destination, copies n positions sta...
Definition: gsMemory.h:391
shared_ptr< T > make_shared(T *x)
Definition: gsMemory.h:181