G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMemory.h
Go to the documentation of this file.
1
14#pragma once
15
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
34namespace gismo {
35
43namespace memory
44{
45
46/* \brief Adaptor for a shared pointer
47
48usage:
49\code
50memory::shared_ptr<int> B;
51\endcode
52*/
53
54#if __cplusplus < 201103 && defined( __GLIBCXX__ )
55# if defined(__INTEL_COMPILER)
56using boost::shared_ptr;
57using boost::weak_ptr;
58# else
59using std::tr1::shared_ptr;
60using std::tr1::weak_ptr;
61# endif
62#else // libc++ or other
63using std::shared_ptr;
64using std::weak_ptr;
65#endif
66
67/* \brief Adaptor for a unique pointer
68
69usage:
70\code
71memory::unique_ptr<int> B;
72\endcode
73*/
74#if __cplusplus >= 201103 || _MSC_VER >= 1600
75using std::unique_ptr;
76using std::nullptr_t;
77#else
78
79template <typename T>
80class 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
87public :
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
123private:
124
125 struct SafeBool
126 { SafeBool(int) {}
127 void dummy() {} };
128
129 typedef void (SafeBool::*bool_cast_type)();
130
131public:
132
133 operator bool_cast_type() const
134 { return !Base::get() ? 0 : &SafeBool::dummy; }
135};
136
137template<class T>
138bool operator==(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
139{ return p1.get()==p2.get(); }
140template<class T>
141bool operator!=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
142{ return p1.get()!=p2.get(); }
143template<class T>
144bool operator<(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
145{ return p1.get()<p2.get(); }
146template<class T>
147bool operator>(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
148{ return p1.get()>p2.get(); }
149template<class T>
150bool operator<=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
151{ return p1.get()<=p2.get(); }
152template<class T>
153bool operator>=(const unique_ptr<T> & p1, const unique_ptr<T> & p2)
154{ return p1.get()>=p2.get(); }
155
156class nullptr_t
157{
158public:
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;}
165private:
166 /* Not allowed to get the address */
167 void operator&() const;
168};
169#endif
170
172template <typename T> void null_deleter(T *) {}
173
174
180template <typename T>
181inline shared_ptr<T> make_shared(T *x) { return shared_ptr<T>(x); }
182
188template <typename T>
189inline shared_ptr<T> make_shared_not_owned(const T *x)
190{ return shared_ptr<T>(const_cast<T*>(x), null_deleter<T>); }
191
197template <typename T>
198inline unique_ptr<T> make_unique(T * x) { return unique_ptr<T>(x); }
199
202template<class toC, typename from>
203inline unique_ptr<toC> convert_ptr(from p)
204{ return unique_ptr<toC>( dynamic_cast<toC*>(p.release()) ); }
205
207template <typename T>
208inline 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
217template <typename T>
218inline 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
227template <typename T>
228inline 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
253template <class T> inline
254auto give(T&& t) -> decltype(std::move(std::forward<T>(t)))
255{
256 return std::move(std::forward<T>(t));
257}
258
259#else
266template <typename S> inline S give(S & x)
267{ S t; t.swap(x); return t; }
268
269template <typename T> inline
270memory::unique_ptr<T> give(memory::unique_ptr<T> & x)
271{ return memory::unique_ptr<T>(x.release()); }
272
273template <typename T> inline
274memory::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
294template <typename It, typename ItOut>
295void 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
303template <typename ContIn, typename ContOut>
304void cloneAll(const ContIn& in, ContOut& out)
305{
306 out.resize(in.size());
307 cloneAll(in.begin(), in.end(), out.begin());
308}
309
311template <typename It>
312void freeAll(It begin, It end)
313{
314 for (It it = begin; it != end; ++it)
315 {
316 delete (*it);
317 *it = NULL;
318 }
319}
320
322template <typename Cont>
323void freeAll(Cont& cont)
324{
325 for (typename Cont::iterator it = cont.begin(); it != cont.end(); ++it)
326 delete (*it);
327 cont.clear();
328}
329
331template<typename obj> inline
332std::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
343template <typename Base, typename Derived>
344std::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
352template <typename Derived, typename Base>
353bool 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
367template <class T, class U>
368inline 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
382namespace util
383{
390template <class T, class U>
391inline 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++
409static const gismo::memory::nullptr_t nullptr ={};
410#endif
Utilities related to template programming.
void null_deleter(T *)
Deleter function that does not delete an object pointer.
Definition gsMemory.h:172
shared_ptr< T > make_shared_not_owned(const T *x)
Creates a shared pointer which does not eventually delete the underlying raw pointer....
Definition gsMemory.h:189
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
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
unique_ptr< T > make_unique(T *x)
Definition gsMemory.h:198
shared_ptr< T > make_shared(T *x)
Definition gsMemory.h:181
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
The G+Smo namespace, containing all definitions for the library.
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
std::vector< Base * > castVectorPtr(std::vector< Derived * > pVec)
Casts a vector of pointers.
Definition gsMemory.h:344
bool checkVectorPtrCast(std::vector< Base * > pVec)
Returns true if all instances of Base cast to Derived.
Definition gsMemory.h:353
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,...
Definition gsMemory.h:368
std::vector< obj * > asVectorPtr(const std::vector< obj > &matv)
Constructs a vector of pointers from a vector of objects.
Definition gsMemory.h:332
S give(S &x)
Definition gsMemory.h:266
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition gsMemory.h:312
This namespace gathers several utility functions for miscellaneous tasks.