23 #ifndef PLLL_INCLUDE_GUARD__MATRIX_MEM_HPP
24 #define PLLL_INCLUDE_GUARD__MATRIX_MEM_HPP
31 #if __cplusplus >= 201103L
63 #define __VECMAT_MM_RELEASE
65 #ifdef __VECMAT_MM_DEBUG
67 #define __VECMAT_MM_DEBUG__BEGIN_OK 0xAFFE1234
68 #define __VECMAT_MM_DEBUG__END_OK 0x1234AFFE
69 #define __VECMAT_MM_DEBUG__BEGIN_REL 0xF8E8F8E8
70 #define __VECMAT_MM_DEBUG__END_REL 0x1E1F1E1F
71 #define __VECMAT_MM_DEBUG__DEAD 0xDEADBEEF
77 enum { DEBUG_PAD_BEGIN = 4,
80 static T * create(
unsigned int n,
bool dontconstruct)
82 unsigned SIZE = ((n *
sizeof(T) + 3) & (unsigned)(~3));
83 assert(SIZE >= n *
sizeof(T));
84 char * realptr =
reinterpret_cast<char *
>(malloc(SIZE + (DEBUG_PAD_BEGIN + DEBUG_PAD_END) * 4));
85 char * realptrend = realptr + SIZE + DEBUG_PAD_BEGIN * 4;
86 for (
int i = 0; i < DEBUG_PAD_BEGIN; ++i)
87 ((
unsigned int*)realptr)[i] = __VECMAT_MM_DEBUG__BEGIN_OK;
88 for (
int i = 0; i < DEBUG_PAD_END; ++i)
89 ((
unsigned int*)realptrend)[i] = __VECMAT_MM_DEBUG__END_OK;
90 T * ptr =
reinterpret_cast<T*
>(realptr + DEBUG_PAD_BEGIN * 4);
93 for (
unsigned i = 0; i < n; ++i)
94 ::
new(static_cast<void *>(ptr + i)) T();
95 for (
int i = 0; i < DEBUG_PAD_BEGIN; ++i)
96 assert(((
unsigned int*)realptr)[i] == __VECMAT_MM_DEBUG__BEGIN_OK);
97 for (
int i = 0; i < DEBUG_PAD_END; ++i)
98 assert(((
unsigned int*)realptrend)[i] == __VECMAT_MM_DEBUG__END_OK);
102 static void release(T * ptr,
unsigned int n)
109 unsigned SIZE = ((n *
sizeof(T) + 3) & (unsigned)(~3));
110 char * realptr =
reinterpret_cast<char *
>(ptr) - DEBUG_PAD_BEGIN * 4;
111 char * realptrend = realptr + SIZE + DEBUG_PAD_BEGIN * 4;
113 for (
int i = 0; i < DEBUG_PAD_BEGIN; ++i)
114 assert(((
unsigned int*)realptr)[i] == __VECMAT_MM_DEBUG__BEGIN_OK);
115 for (
int i = 0; i < DEBUG_PAD_END; ++i)
116 assert(((
unsigned int*)realptrend)[i] == __VECMAT_MM_DEBUG__END_OK);
118 for (
unsigned i = 0; i < n; ++i)
121 for (
unsigned i = 0; i < n *
sizeof(T) / 4; ++i)
122 (reinterpret_cast<unsigned int*>(ptr))[i] = __VECMAT_MM_DEBUG__DEAD;
124 for (
int i = 0; i < DEBUG_PAD_BEGIN; ++i)
126 assert((reinterpret_cast<unsigned int*>(realptr))[i] == __VECMAT_MM_DEBUG__BEGIN_OK);
127 (
reinterpret_cast<unsigned int*
>(realptr))[i] = __VECMAT_MM_DEBUG__BEGIN_REL;
129 for (
int i = 0; i < DEBUG_PAD_END; ++i)
131 assert((reinterpret_cast<unsigned int*>(realptrend))[i] == __VECMAT_MM_DEBUG__END_OK);
132 (
reinterpret_cast<unsigned int*
>(realptrend))[i] = __VECMAT_MM_DEBUG__END_REL;
138 static void check(T * ptr,
unsigned int n)
145 unsigned SIZE = ((n *
sizeof(T) + 3) & (unsigned)(~3));
146 char * realptr =
reinterpret_cast<char *
>(ptr) - DEBUG_PAD_BEGIN * 4;
147 char * realptrend = realptr + SIZE + DEBUG_PAD_BEGIN * 4;
149 for (
int i = 0; i < DEBUG_PAD_BEGIN; ++i)
150 assert((reinterpret_cast<unsigned int*>(realptr))[i] == __VECMAT_MM_DEBUG__BEGIN_OK);
151 for (
int i = 0; i < DEBUG_PAD_END; ++i)
152 assert((reinterpret_cast<unsigned int*>(realptrend))[i] == __VECMAT_MM_DEBUG__END_OK);
155 typedef T * pointer_type;
156 typedef const T * constpointer_type;
157 typedef T & ref_type;
158 typedef const T & constref_type;
163 ::new(static_cast<void *>(&ref)) T();
170 ::new(static_cast<void *>(&ref)) T(obj);
173 #if __cplusplus >= 201103L
175 static void move_construct(ref_type ref, S && obj)
178 ::new(static_cast<void *>(&ref)) T(std::move(obj));
182 static pointer_type
alloc(
unsigned int n)
186 pointer_type newptr = create(n,
false);
194 pointer_type newptr = create(n,
true);
200 static pointer_type
alloc(
const S & obj,
unsigned int n)
203 pointer_type newptr = create(n,
true);
205 for (
unsigned i = 0; i < n; ++i)
211 static pointer_type
clone(S * ptr,
unsigned int n)
215 pointer_type newptr = create(n,
true);
217 for (
unsigned i = 0; i < n; ++i)
223 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy)
227 pointer_type newptr = create(n,
true);
229 for (
unsigned i = 0; i < ncopy; ++i)
231 for (
unsigned i = ncopy; i < n; ++i)
236 template<
class S,
class SS>
237 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy,
const SS & copyobj)
241 pointer_type newptr = create(n,
true);
243 for (
unsigned i = 0; i < ncopy; ++i)
245 for (
unsigned i = ncopy; i < n; ++i)
250 #if __cplusplus >= 201103L
252 static pointer_type clone_move(S * ptr,
unsigned int n)
256 pointer_type newptr = create(n,
true);
258 for (
unsigned i = 0; i < n; ++i)
264 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy)
268 pointer_type newptr = create(n,
true);
270 for (
unsigned i = 0; i < ncopy; ++i)
272 for (
unsigned i = ncopy; i < n; ++i)
277 template<
class S,
class SS>
278 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy,
const & SS copyobj)
282 pointer_type newptr = create(n,
true);
284 for (
unsigned i = 0; i < ncopy; ++i)
286 for (
unsigned i = ncopy; i < n; ++i)
292 static void free(pointer_type ptr,
unsigned int n)
302 #ifdef __VECMAT_MM_FAILSAFE
308 typedef T * pointer_type;
309 typedef T & ref_type;
310 typedef const T * constpointer_type;
311 typedef const T & constref_type;
316 ::new(static_cast<void *>(&ref)) T();
323 ::new(static_cast<void *>(&ref)) T(obj);
326 #if __cplusplus >= 201103L
328 static void move_construct(ref_type ref, S && obj)
331 ::new(static_cast<void *>(&ref)) T(std::move(obj));
335 static pointer_type
alloc(
unsigned int n)
345 return reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
349 static pointer_type
alloc(
const S & obj,
unsigned int n)
352 pointer_type newptr =
new T[n];
353 for (
unsigned i = 0; i < n; ++i)
359 static pointer_type
clone(S * ptr,
unsigned int n)
363 pointer_type newptr =
new T[n];
364 for (
unsigned i = 0; i < n; ++i)
370 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy)
374 pointer_type newptr =
new T[n];
375 for (
unsigned i = 0; i < ncopy; ++i)
380 template<
class S,
class SS>
381 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy,
const SS & copyobj)
385 pointer_type newptr =
new T[n];
386 for (
unsigned i = 0; i < ncopy; ++i)
388 for (
unsigned i = ncopy; i < n; ++i)
393 #if __cplusplus >= 201103L
395 static pointer_type clone_move(S * ptr,
unsigned int n)
399 pointer_type newptr =
new T[n];
400 for (
unsigned i = 0; i < n; ++i)
401 newptr[i] = std::move(ptr[i]);
406 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy)
410 pointer_type newptr =
new T[n];
411 for (
unsigned i = 0; i < ncopy; ++i)
412 newptr[i] = std::move(ptr[i]);
416 template<
class S,
class SS>
417 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy,
const SS & copyobj)
421 pointer_type newptr =
new T[n];
422 for (
unsigned i = 0; i < ncopy; ++i)
423 newptr[i] = std::move(ptr[i]);
424 for (
unsigned i = ncopy; i < n; ++i)
430 static void free(pointer_type ptr,
unsigned int n)
436 inline static void check(pointer_type ptr,
unsigned int n)
443 #ifdef __VECMAT_MM_RELEASE
453 typedef T * pointer_type;
454 typedef T & ref_type;
455 typedef const T * constpointer_type;
456 typedef const T & constref_type;
461 ::new(static_cast<void *>(&ref)) T();
468 ::new(static_cast<void *>(&ref)) T(obj);
471 #if __cplusplus >= 201103L
473 static void move_construct(ref_type ref, S && obj)
476 ::new(static_cast<void *>(&ref)) T(std::move(obj));
480 static pointer_type
alloc(
unsigned int n)
486 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
487 for (
unsigned i = 0; i < n; ++i)
488 ::
new(static_cast<void *>(newptr + i)) T();
498 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
503 static pointer_type
alloc(
const S & obj,
unsigned int n)
509 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
510 for (
unsigned i = 0; i < n; ++i)
511 ::
new(static_cast<void *>(newptr + i)) T(obj);
516 static pointer_type
clone(S * ptr,
unsigned int n)
522 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
523 for (
unsigned i = 0; i < n; ++i)
524 ::
new(static_cast<void *>(newptr + i)) T(ptr[i]);
529 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy)
537 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
538 for (
unsigned i = 0; i < ncopy; ++i)
539 ::
new(static_cast<void *>(newptr + i)) T(ptr[i]);
540 for (
unsigned i = ncopy; i < n; ++i)
541 ::
new(static_cast<void *>(newptr + i)) T();
545 template<
class S,
class SS>
546 static pointer_type
clone(S * ptr,
unsigned int n,
unsigned int ncopy,
const SS & copyobj)
554 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
555 for (
unsigned i = 0; i < ncopy; ++i)
556 ::
new(static_cast<void *>(newptr + i)) T(ptr[i]);
557 for (
unsigned i = ncopy; i < n; ++i)
558 ::
new(static_cast<void *>(newptr + i)) T(copyobj);
562 #if __cplusplus >= 201103L
564 static pointer_type clone_move(S * ptr,
unsigned int n)
570 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
571 for (
unsigned i = 0; i < n; ++i)
572 ::
new(static_cast<void *>(newptr + i)) T(std::move(ptr[i]));
577 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy)
585 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
586 for (
unsigned i = 0; i < ncopy; ++i)
587 ::
new(static_cast<void *>(newptr + i)) T(std::move(ptr[i]));
588 for (
unsigned i = ncopy; i < n; ++i)
589 ::
new(static_cast<void *>(newptr + i)) T();
593 template<
class S,
class SS>
594 static pointer_type clone_move(S * ptr,
unsigned int n,
unsigned int ncopy,
const SS & copyobj)
602 pointer_type newptr =
reinterpret_cast<pointer_type
>(::operator
new(
sizeof(T) * n));
603 for (
unsigned i = 0; i < ncopy; ++i)
604 ::
new(static_cast<void *>(newptr + i)) T(std::move(ptr[i]));
605 for (
unsigned i = ncopy; i < n; ++i)
606 ::
new(static_cast<void *>(newptr + i)) T(copyobj);
611 static void free(pointer_type ptr,
unsigned int n)
616 for (
unsigned i = 0; i < n; ++i)
618 ::operator
delete(ptr);
621 inline static void check(pointer_type ptr,
unsigned int n)
static pointer_type clone(S *ptr, unsigned int n, unsigned int ncopy)
Creates an array of n elements of type T. The first ncopy elements are copy-constructed from the give...
static void free(pointer_type ptr, unsigned int n)
Destroys an array of n elements of type T.
static void construct(ref_type ref)
Constructs an object via default constructor.
static pointer_type clone(S *ptr, unsigned int n, unsigned int ncopy, const SS ©obj)
Creates an array of n elements of type T. The first ncopy elements are copy-constructed from the give...
static void copy_construct(ref_type ref, const S &obj)
Constructs an object via copy constructor.
Provides means to allocate, reallocate and release (linear) arrays of objects of type T...
static pointer_type clone(S *ptr, unsigned int n)
Creates an array of n elements of type T. The entries are copy-constructed from the given array ptr (...
static void check(pointer_type ptr, unsigned int n)
Verifies the integrity of an array of n elements of type T. Does nothing for the release memory manag...
static pointer_type alloc(const S &obj, unsigned int n)
Creates an array of n elements of type T, all being copies of obj (of type S).
static pointer_type alloc_dontconstruct(unsigned int n)
Creates an array of n elements of type T. The entries are not constructed.
static pointer_type alloc(unsigned int n)
Creates an array of n elements of type T. The entries are created using the default constructor...