casacore
Loading...
Searching...
No Matches
Block.h
Go to the documentation of this file.
1//# Block.h: Simple templated array classes
2//# Copyright (C) 1993-1997,2000,2002,2005,2015
3//# Associated Universities, Inc. Washington DC, USA.
4//# National Astronomical Observatory of Japan
5//# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
6//#
7//# This library is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU Library General Public License as published by
9//# the Free Software Foundation; either version 2 of the License, or (at your
10//# option) any later version.
11//#
12//# This library is distributed in the hope that it will be useful, but WITHOUT
13//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15//# License for more details.
16//#
17//# You should have received a copy of the GNU Library General Public License
18//# along with this library; if not, write to the Free Software Foundation,
19//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning AIPS++ should be addressed as follows:
22//# Internet email: casa-feedback@nrao.edu.
23//# Postal address: AIPS++ Project Office
24//# National Radio Astronomy Observatory
25//# 520 Edgemont Road
26//# Charlottesville, VA 22903-2475 USA
27
28#ifndef CASA_BLOCK_H
29#define CASA_BLOCK_H
30
31#include <casacore/casa/aips.h>
32#include <casacore/casa/Utilities/Assert.h>
33#include <casacore/casa/Utilities/Copy.h>
34#include <casacore/casa/Utilities/DataType.h>
35#include <casacore/casa/Containers/Allocator.h>
36#include <cstddef> // for ptrdiff_t
37#include <algorithm> // for std:min/max
38#include <type_traits>
39
40//# For index checking
41#if defined(AIPS_ARRAY_INDEX_CHECK)
42#include <casacore/casa/Exceptions/Error.h>
43#endif
44
45namespace casacore { //# NAMESPACE CASACORE - BEGIN
46
48{
49public:
50 // Set the trace size. The (de)allocation of Blocks with >= sz elements
51 // will be traced using the MemoryTrace class.
52 // A value 0 means no tracing.
53 static void setTraceSize (size_t sz);
54protected:
55 // Write alloc and free trace messages.
56 static void doTraceAlloc (const void* addr, size_t nelem,
57 DataType type, size_t sz);
58 static void doTraceFree (const void* addr, size_t nelem,
59 DataType type, size_t sz);
60protected:
61 static size_t itsTraceSize;
62};
63
64template<typename T> class Block;
65
66
67template<typename T>
69 template<typename U> friend class Block;
70 static constexpr int value = static_cast<int>(std::is_fundamental<T>::value);
71};
72
73template<typename T>
75 template<typename U> friend class Block;
76 static constexpr int value = static_cast<int>(std::is_pointer<T>::value);
77};
78
79
80
81// <summary>simple 1-D array</summary>
82// <use visibility=export>
83//
84// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
85// </reviewed>
86//
87// <etymology>
88// This should be viewed as a <em>block</em> of memory without sophisticated
89// manipulation functions. Thus it is called <src>Block</src>.
90// </etymology>
91//
92// <synopsis>
93// <src>Block<T></src> is a simple templated 1-D array class. Indices are always
94// 0-based. For efficiency reasons, no index checking is done unless the
95// preprocessor symbol <src>AIPS_ARRAY_INDEX_CHECK</src> is defined.
96// <src>Block<T></src>'s may be assigned to and constructed from other
97// <src>Block<T></src>'s.
98// As no reference counting is done this can be an expensive operation, however.
99//
100// The net effect of this class is meant to be unsurprising to users who think
101// of arrays as first class objects. The name "Block" is intended to convey
102// the concept of a solid "chunk" of things without any intervening "fancy"
103// memory management, etc. This class was written to be
104// used in the implementations of more functional Vector, Matrix, etc. classes,
105// although it is expected <src>Block<T></src> will be useful on its own.
106//
107// The Block class should be efficient. You should normally use <src>Block</src>.
108//
109// <note role=warning> If you use the assignment operator on an element of this
110// class, you may leave dangling references to pointers released from
111// <src>storage()</src>.
112// Resizing the array will also have this effect if the underlying storage
113// is actually affected.
114// </note>
115//
116// If index checking is turned on, an out-of-bounds index will
117// generate an <src>indexError<uInt></src> exception.
118// </synopsis>
119//
120// <example>
121// <srcblock>
122// Block<Int> a(100,0); // 100 ints initialized to 0
123// Block<Int> b; // 0-length Block
124// // ...
125// b = a; // resize b and copy a into it
126// for (size_t i=0; i < a.nelements(); i++) {
127// a[i] = i; // Generate a sequence
128// // with Vectors, could simply say "indgen(myVector);"
129// }
130// b.set(-1); // All positions in b have the value -1
131// b.resize(b.nelements()*2); // Make b twice as long, by default the old
132// // elements are copied over, although this can
133// // be defeated.
134// some_c_function(b.storage()); // Use a fn that takes an
135// // <src>Int *</src> pointer
136// </srcblock>
137// </example>
138//
139template<class T> class Block: public BlockTrace
140{
141public:
142 // Create a zero-length Block. Note that any index into this Block
143 // is an error.
144 // DefaultAllocator<T> is used as an allocator.
147 0), used_p(0), array(0), destroyPointer(True) {
148 }
149 // Create a zero-length Block. Note that any index into this Block
150 // is an error.
151 template<typename Allocator>
152 explicit Block(AllocSpec<Allocator> const &) :
153 allocator_p(get_allocator<typename Allocator::type>()), capacity_p(0), used_p(
154 0), array(0), destroyPointer(True) {
155 }
156
157 // Create a Block with the given number of points. The values in Block
158 // are initialized. Note that indices range between 0 and n-1.
159 // DefaultAllocator<T> is used as an allocator.
165
166 // Create a Block with the given number of points. The values in Block
167 // are initialized. Note that indices range between 0 and n-1.
168 template<typename Allocator>
174
175 // Create a Block with the given number of points. The values in Block
176 // are uninitialized. Note that indices range between 0 and n-1.
177 // DefaultAllocator<T> is used as an allocator.
178 Block(size_t n, ArrayInitPolicy initPolicy) :
180 n), destroyPointer(True) {
181 init(initPolicy);
182 }
183
184 // Create a Block with the given number of points.
185 // Note that indices range between 0 and n-1.
186 template<typename Allocator>
187 Block(size_t n, ArrayInitPolicy initPolicy,
188 AllocSpec<Allocator> const &) :
189 allocator_p(get_allocator<typename Allocator::type>()), used_p(n), destroyPointer(
190 True) {
191 init(initPolicy);
192 }
193
194 // Create a Block of the given length, and initialize (via copy constructor for
195 // objects of type T) with the provided value.
196 // DefaultAllocator<T> is used as an allocator.
197 Block(size_t n, T const &val) :
199 n), destroyPointer(True) {
201 try {
202 allocator_p->construct(array, get_size(), val);
203 } catch (...) {
204 dealloc();
205 throw;
206 }
207 }
208
209 // Create a Block of the given length, and initialize (via copy constructor for
210 // objects of type T) with the provided value.
211 template<typename Allocator>
212 Block(size_t n, T const &val, AllocSpec<Allocator> const &) :
213 allocator_p(get_allocator<typename Allocator::type>()), used_p(n), destroyPointer(
214 True) {
216 try {
217 allocator_p->construct(array, get_size(), val);
218 } catch (...) {
219 dealloc();
220 throw;
221 }
222 }
223
224 // Create a <src>Block</src> from a C-array (i.e. pointer). If
225 // <src>takeOverStorage</src> is <src>True</src>, The Block assumes that
226 // it owns the pointer, i.e. that it is safe to release it via <src>allocator</src> when
227 // the Block is destructed, otherwise the actual storage is not destroyed.
228 // If true, <src>storagePointer</src> is set to <src>0</src>.
229 // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
230 // whenever <src>takeOverStorage</src> == True
231 // to let <src>Block</src> to know how to release the <src>storagePointer</src>.
232 // The default allocator set by this constructor will be changed from <src>NewDelAllocator<T>::value</src>
233 // to <src>DefaultAllocator<T>::value</src> in future.
234 Block(size_t n, T *&storagePointer, Bool takeOverStorage = True) :
236 n), used_p(n), array(storagePointer), destroyPointer(takeOverStorage) {
237 if (destroyPointer)
238 storagePointer = 0;
239 }
240 // Create a <src>Block</src> from a C-array (i.e. pointer). If
241 // <src>takeOverStorage</src> is <src>True</src>, The Block assumes that
242 // it owns the pointer, i.e. that it is safe to release it via <src>allocator</src> when
243 // the Block is destructed, otherwise the actual storage is not destroyed.
244 // If true, <src>storagePointer</src> is set to <src>0</src>.
245 template<typename Allocator>
246 Block(size_t n, T *&storagePointer, Bool takeOverStorage,
247 AllocSpec<Allocator> const &) :
248 allocator_p(get_allocator<typename Allocator::type>()), capacity_p(n), used_p(
249 n), array(storagePointer), destroyPointer(takeOverStorage) {
250 if (destroyPointer)
251 storagePointer = 0;
252 }
253
254 // Copy the other block into this one. Uses copy, not reference, semantics.
255 Block(const Block<T> &other) :
257 True) {
259
260 try {
261 objthrowcp1(array, other.array, get_size());
262 allocator_p->construct(array, get_size(), other.array);
263 } catch (...) {
264 dealloc();
265 throw;
266 }
267 }
268
269 Block(Block<T> &&other) noexcept :
270 allocator_p(other.allocator_p), capacity_p(other.capacity_p), used_p(other.used_p),
271 array(other.array), destroyPointer(other.destroyPointer) {
272 // The allocator of other is left as is; the storage is emptied so no need to change it.
273 other.capacity_p = 0;
274 other.used_p = 0;
275 other.array = nullptr;
276 other.destroyPointer = false;
277 }
278
279 // Assign other to this. this resizes itself to the size of other, so after
280 // the assignment, this->nelements() == other.nelements() always.
281 Block<T> &operator=(const Block<T> &other) {
282 if (&other != this) {
283 T *old = array;
284 this->resize(other.size(), True, False, ArrayInitPolicies::NO_INIT);
285 if (array == old) {
286 objcopy(array, other.array, get_size());
287 } else {
288 objthrowcp1(array, other.array, get_size());
289 allocator_p->construct(array, get_size(), other.array);
290 }
291 }
292 return *this;
293 }
294
295 Block<T>& operator=(Block<T> &&other) noexcept
296 {
297 if (this == &other) {
298 return *this;
299 }
300 deinit();
301 allocator_p = other.allocator_p;
302 capacity_p = other.capacity_p;
303 used_p = other.used_p;
304 destroyPointer = other.destroyPointer;
305 array = other.array;
306 // The allocator of other is left as is; the storage is emptied so no need to change it.
307 other.capacity_p = 0;
308 other.used_p = 0;
309 other.array = nullptr;
310 other.destroyPointer = false;
311 return *this;
312 }
313
314 // Frees up the storage pointed contained in the Block.
315 ~Block() noexcept {
316 deinit();
317 }
318
319 // Resizes the Block. If <src>n == nelements()</src> resize just returns. If
320 // a larger size is requested (<src>n > nelements()</src>) the Block always
321 // resizes. If the requested size is smaller (<src>n < nelements()</src>),
322 // by default the Block does not resize smaller, although it can be
323 // forced to with <src>forceSmaller</src>. The reasoning behind this is that
324 // often the user will just want a buffer of at least a certain size,
325 // and won't want to pay the cost of multiple resizings.
326 // <srcblock>
327 // Block<float> bf(100, 0.0);
328 // bf.resize(10); // bf.nelements() == 100
329 // bf.resize(10, True) // bf.nelements() == 10
330 // bf.resize(200) // bf.nelements() == 200
331 // </srcblock>
332 // Normally the old elements are copied over (although if the
333 // Block is lengthened the trailing elements will have undefined
334 // values), however this can be turned off by setting copyElements to
335 // False.
336 //
337 // This is written as three functions because default parameters do
338 // not always work properly with templates.
339 //
340 // <src>initPolicy</src> makes sense to determine whether extended elements
341 // should be initialized or not when you enlarge Block.
342 // <group>
343 void resize(size_t n, Bool forceSmaller = False, Bool copyElements = True) {
344 resize(n, forceSmaller, copyElements,
346 }
347 void resize(size_t n, Bool forceSmaller, Bool copyElements,
348 ArrayInitPolicy initPolicy) {
349 if (n == get_size()) {
350 return;
351 }
352 if (n < get_size() && forceSmaller == False) {
353 return;
354 }
355 if (get_size() < n && n <= get_capacity()) {
356 allocator_p->construct(&array[get_size()], n - get_size());
357 set_size(n);
358 return;
359 }
360 T *tp = n > 0 ? allocator_p->allocate(n) : 0;
361 traceAlloc(tp, n);
362 if (n > 0) {
363 size_t start = 0;
364 if (copyElements) {
365 size_t nmin = std::min(get_size(), n); // Don't copy too much!
366 if (nmin > 0) {
367 try {
368 allocator_p->construct(tp, nmin, array);
369 } catch (...) {
370 traceFree(tp, n);
371 allocator_p->deallocate(tp, n);
372 throw;
373 }
374 }
375 start = nmin;
376 }
377 if (initPolicy == ArrayInitPolicies::INIT) {
378 try {
379 allocator_p->construct(&tp[start], n - start);
380 } catch (...) {
381 allocator_p->destroy(tp, start);
382 traceFree(tp, n);
383 allocator_p->deallocate(tp, n);
384 throw;
385 }
386 }
387 }
388 deinit();
390 array = tp; // ... and update pointer
391 set_capacity(n);
392 set_size(n);
393 }
394 // </group>
395
396 // Remove a single element from the Block. If forceSmaller is True this
397 // will resize the Block and hence involve new memory allocations. This is
398 // relatively expensive so setting forceSmaller to False is preferred. When
399 // forceSmaller is False the Block is not resized but the elements with an
400 // index above the removed element are shuffled down by one. For backward
401 // compatibility forceSmaller is True by default.
402 //
403 // <src>initPolicy</src> makes sense to determine whether new storage
404 // should be initialized or not before copying when <src>forceSmaller</src> is True.
405 // <group>
406 void remove(size_t whichOne, Bool forceSmaller = True) {
407 remove(whichOne, forceSmaller,
409 }
410 void remove(size_t whichOne, Bool forceSmaller, ArrayInitPolicy initPolicy) {
411 if (whichOne >= get_size()) {
412#if defined(AIPS_ARRAY_INDEX_CHECK)
413 throw(indexError<uInt>(whichOne, "Block::remove() - "
414 "index out of range"));
415#else
416 return;
417#endif
418 }
419 size_t n = get_size() - 1;
420 if (forceSmaller == True) {
421 T *tp = n > 0 ? allocator_p->allocate(n) : 0;
422 traceAlloc(array, n);
423 if (initPolicy == ArrayInitPolicies::INIT && n > 0) {
424 try {
425 allocator_p->construct(tp, n);
426 } catch (...) {
427 traceFree(tp, n);
428 allocator_p->deallocate(tp, n);
429 throw;
430 }
431 }
432 try {
433 objcopy(tp, array, whichOne);
434 } catch (...) {
435 traceFree(tp, n);
436 allocator_p->deallocate(tp, n);
437 throw;
438 }
439 try {
440 objcopy(tp + whichOne, array + whichOne + 1, get_size() - whichOne - 1);
441 } catch (...) {
442 allocator_p->destroy(tp, whichOne);
443 traceFree(tp, n);
444 allocator_p->deallocate(tp, n);
445 throw;
446 }
447 if (array && destroyPointer) {
449 allocator_p->destroy(array, get_size());
450 allocator_p->deallocate(array, get_capacity());
451 array = 0;
452 };
453 set_capacity(n);
454 set_size(n);
455 array = tp;
457 } else {
458 objmove(&array[whichOne], &array[whichOne + 1], get_size() - whichOne - 1);
459 }
460 }
461 // </group>
462
463 // </group>
464
465 // Replace the internal storage with a C-array (i.e. pointer).
466 // If <src>takeOverStorage</src> is True, The Block assumes that it
467 // owns the pointer, i.e. that it is safe to release it via <src>allocator</src> when the
468 // <src>Block</src>is destructed, otherwise the actual storage is not destroyed.
469 // If true, storagePointer is set to <src>NULL</src>.
470 // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
471 // whenever <src>takeOverStorage</src> == True
472 // to let <src>Block</src> to know how to release the <src>storagePointer</src>.
473 // The default parameter of allocator will be changed from <src>AllocSpec<NewDelAllocator<T> >::value</src>
474 // to <src>AllocSpec<DefaultAllocator<T> >::value</src> in future.
475 // AipsError is thrown if allocator is incompatible with the current allocator of the instance and changing allocator is prohibited,
476 // even if takeOverStorage == False.
477 // <group>
478 void replaceStorage(size_t n, T *&storagePointer, Bool takeOverStorage=True) {
479 replaceStorage(n, storagePointer, takeOverStorage, AllocSpec<NewDelAllocator<T> >::value);
480 }
481 template<typename Allocator>
482 void replaceStorage(size_t n, T *&storagePointer, Bool takeOverStorage, AllocSpec<Allocator> const &) {
483 if (array && destroyPointer) {
485 allocator_p->destroy(array, get_size());
486 allocator_p->deallocate(array, get_capacity());
487 array = 0;
488 };
489 set_capacity(n);
490 set_size(n);
492 array = storagePointer;
493 destroyPointer = takeOverStorage;
494 if (destroyPointer) storagePointer = 0;
495 }
496 // </group>
497
498 // Index into the block (0-based). If the preprocessor symbol
499 // <src>AIPS_ARRAY_INDEX_CHECK</src> is defined, index checking will be done
500 // and an out-of-bounds index will cause an <src>indexError<uInt></src> to be
501 // thrown. Note that valid indices range between 0 and <src>nelements()-1</src>.
502 // <thrown>
503 // <li> indexError
504 // </thrown>
505 // <group>
506 T &operator[](size_t index) {
507#if defined(AIPS_ARRAY_INDEX_CHECK)
508 // Write it this way to avoid casts; remember index and get_size() are
509 // unsigned.
510 if ((get_size() == 0) || (index > get_size() - 1)) {
511 throw(indexError<uInt>(index, "Block::operator[] - "
512 "index out of range"));
513 };
514#endif
515 return array[index];
516 }
517 const T &operator[](size_t index) const {
518#if defined(AIPS_ARRAY_INDEX_CHECK)
519 if ((get_size() == 0) || (index > get_size() - 1)) {
520 throw(indexError<uInt>(index, "Block::operator[] const - "
521 "index out of range"));
522 };
523#endif
524 return array[index];
525 }
526 // </group>
527
528 // Set all values in the block to "val".
529 // <group>
530 Block<T> &operator=(const T &val)
531 { T tmp=val; objset(array, tmp, get_size()); return *this;}
532 void set(const T &val) { *this = val; }
533 // </group>
534
535 // If you really, really, need a "raw" pointer to the beginning of the
536 // storage area this will give it to you. This may leave dangling pointers
537 // if the block is destructed or if the assignment operator or resize
538 // is used. Returns a null pointer if <src>nelements() == 0</src>.
539 // It is best to only use this if you completely control the extent and
540 // lifetime of the <src>Block</src>.
541 // <h3> Examples of misuse </h3> <srcblock>
542 // Block<Int> *bp = new Block<Int>(100);
543 // Int *ip = bp->storage();
544 // DefaultAllocator<Int>::value.deallocate(bp, bp->capacity()); // Oops, ip is now dangling
545 // Block<Int> a(100),b(100);
546 // Int *ip = a.storage();
547 // a = b; // Likewise
548 // </srcblock>
549 // <group>
550 T *storage() {return array;}
551 const T *storage() const {return array;}
552 // </group>
553
554 // The number of elements contained in this <src>Block<T></src>.
555 // <group>
556 size_t nelements() const {return size();}
557 size_t size() const {return get_capacity();}
558 // </group>
559
560 // The capacity in this <src>Block<T></src>.
561 // <src>size() <= capacity()</src> is always true.
562 size_t capacity() const {return get_capacity();}
563
564 // Is the block empty (i.e. no elements)?
565 Bool empty() const {return size() == 0;}
566
567 // Define the STL-style iterators.
568 // It makes it possible to iterate through all data elements.
569 // <srcblock>
570 // Block<Int> bl(100,0);
571 // for (Block<Int>::iterator iter=bl.begin(); iter!=bl.end(); iter++) {
572 // *iter += 1;
573 // }
574 // </srcblock>
575 // <group name=STL-iterator>
576 // STL-style typedefs.
577 // <group>
578 typedef T value_type;
579 typedef T* iterator;
580 typedef const T* const_iterator;
582 typedef const value_type* const_pointer;
585 typedef size_t size_type;
586 typedef ptrdiff_t difference_type;
587 // </group>
588 // Get the begin and end iterator object for this block.
589 // <group>
591 { return array; }
592 const_iterator begin() const
593 { return array; }
595 { return array + size(); }
596 const_iterator end() const
597 { return array + size(); }
598 // </group>
599 // </group>
600
601 inline void traceAlloc (const void* addr, size_t sz) const
602 {
603 if (itsTraceSize>0 && sz>=itsTraceSize) {
604 doTraceAlloc (addr, sz, whatType<T>(), sizeof(T));
605 }
606 }
607 inline void traceFree (const void* addr, size_t sz) const
608 {
609 if (itsTraceSize>0 && sz>=itsTraceSize) {
610 doTraceFree (addr, sz, whatType<T>(), sizeof(T));
611 }
612 }
613
614 private:
615 static constexpr bool init_anyway() {
618 }
619
620 void init(ArrayInitPolicy initPolicy) {
622 if (get_capacity() > 0) {
623 array = allocator_p->allocate(get_capacity());
625 if (initPolicy == ArrayInitPolicies::INIT) {
626 try {
627 allocator_p->construct(array, get_size());
628 } catch (...) {
629 dealloc();
630 throw;
631 }
632 }
633 } else {
634 array = 0;
635 }
636 }
637
638 void deinit() {
639 if (array && destroyPointer) {
640 allocator_p->destroy(array, get_size());
641 dealloc();
642 }
643 }
644 void dealloc() {
645 if (array && destroyPointer) {
647 allocator_p->deallocate(array, get_capacity());
648 array = 0;
649 }
650 }
651
652 template<typename Allocator>
653 static typename Allocator_private::BulkAllocator<
654 typename Allocator::value_type> *get_allocator() {
656 Allocator>();
657 }
658
659 template<typename Allocator>
662 typename Allocator::type::value_type> *other_allocator =
664 return other_allocator == allocator_p;
665 }
666
667 // The number of used elements in the vector
668 size_t get_size() const { return used_p;}
669 // Set the number of used elements in the vector
670 void set_size(size_t new_value) {
671 AlwaysAssert(new_value <= get_capacity(), AipsError);
672 used_p = new_value;
673 }
674 // The capacity of the vector
675 size_t get_capacity() const { return capacity_p;}
676 // Set the capacity of the vector
677 void set_capacity(size_t new_value) {
678 capacity_p = new_value;
679 set_size(std::min(get_size(), capacity_p));
680 }
681
682 // The allocator
684 // The capacity of the vector
686 // The number of used elements in the vector
687 size_t used_p;
688 // The actual storage
690 // Can we delete the storage upon destruction?
692};
693
694
699template<typename T>
700using PtrBlock [[deprecated("Use Block<T> or std::vector<T>: the original motivation for this class no longer holds")]]
701 = Block<T>;
702
703//# Instantiate extern templates for often used types.
704extern template class Block<Bool>;
705extern template class Block<Char>;
706extern template class Block<Short>;
707extern template class Block<uShort>;
708extern template class Block<Int>;
709extern template class Block<uInt>;
710extern template class Block<Int64>;
711extern template class Block<Float>;
712extern template class Block<Double>;
713extern template class Block<Complex>;
714extern template class Block<DComplex>;
715extern template class Block<String>;
716extern template class Block<void*>;
717
718
719} //# NAMESPACE CASACORE - END
720
721#endif
#define AlwaysAssert(expr, exception)
These marcos are provided for use instead of simply using the assert_ function directly.
Definition Assert.h:134
static BulkAllocator< typename Allocator::value_type > * get_allocator()
Definition Allocator.h:296
static void doTraceAlloc(const void *addr, size_t nelem, DataType type, size_t sz)
Write alloc and free trace messages.
static size_t itsTraceSize
Definition Block.h:61
static void setTraceSize(size_t sz)
Set the trace size.
static void doTraceFree(const void *addr, size_t nelem, DataType type, size_t sz)
static constexpr int value
Definition Block.h:70
static constexpr int value
Definition Block.h:76
Block(size_t n, T const &val)
Create a Block of the given length, and initialize (via copy constructor for objects of type T) with ...
Definition Block.h:197
void remove(size_t whichOne, Bool forceSmaller=True)
Remove a single element from the Block.
Definition Block.h:406
Block< T > & operator=(const Block< T > &other)
Assign other to this.
Definition Block.h:281
Block(size_t n, T *&storagePointer, Bool takeOverStorage, AllocSpec< Allocator > const &)
Create a Block from a C-array (i.e.
Definition Block.h:246
Block< T > & operator=(Block< T > &&other) noexcept
Definition Block.h:295
void resize(size_t n, Bool forceSmaller=False, Bool copyElements=True)
Resizes the Block.
Definition Block.h:343
void remove(size_t whichOne, Bool forceSmaller, ArrayInitPolicy initPolicy)
Definition Block.h:410
Block(AllocSpec< Allocator > const &)
Create a zero-length Block.
Definition Block.h:152
void resize(size_t n, Bool forceSmaller, Bool copyElements, ArrayInitPolicy initPolicy)
Definition Block.h:347
Block(size_t n, T const &val, AllocSpec< Allocator > const &)
Create a Block of the given length, and initialize (via copy constructor for objects of type T) with ...
Definition Block.h:212
Block(size_t n, ArrayInitPolicy initPolicy)
Create a Block with the given number of points.
Definition Block.h:178
Block(Block< T > &&other) noexcept
Definition Block.h:269
Block()
Create a zero-length Block.
Definition Block.h:145
Block(size_t n, AllocSpec< Allocator > const &)
Create a Block with the given number of points.
Definition Block.h:169
Block(size_t n)
Create a Block with the given number of points.
Definition Block.h:160
Block(size_t n, T *&storagePointer, Bool takeOverStorage=True)
Create a Block from a C-array (i.e.
Definition Block.h:234
~Block() noexcept
Frees up the storage pointed contained in the Block.
Definition Block.h:315
Block(const Block< T > &other)
Copy the other block into this one.
Definition Block.h:255
Block(size_t n, ArrayInitPolicy initPolicy, AllocSpec< Allocator > const &)
Create a Block with the given number of points.
Definition Block.h:187
An aligned allocator with the default alignment.
Definition Allocator.h:386
An allocator behaves like operator new[]/delete[].
Definition Allocator.h:360
Index errors returning the bad index.
Definition Error.h:317
this file contains all the compiler specific defines
Definition mainpage.dox:28
const T * const_iterator
Definition Block.h:580
size_t nelements() const
The number of elements contained in this Block<T>.
Definition Block.h:556
const Bool False
Definition aipstype.h:42
static Allocator_private::BulkAllocator< typename Allocator::value_type > * get_allocator()
Definition Block.h:654
void traceAlloc(const void *addr, size_t sz) const
Definition Block.h:601
Allocator_private::BulkAllocator< T > * allocator_p
The allocator.
Definition Block.h:683
T value_type
Define the STL-style iterators.
Definition Block.h:578
size_t capacity() const
The capacity in this Block<T>.
Definition Block.h:562
void deinit()
Definition Block.h:638
size_t capacity_p
The capacity of the vector.
Definition Block.h:685
void set(const T &val)
Definition Block.h:532
T * array
The actual storage.
Definition Block.h:689
const value_type * const_pointer
Definition Block.h:582
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
Definition Block.h:550
ptrdiff_t difference_type
Definition Block.h:586
size_t size_type
Definition Block.h:585
Bool empty() const
Is the block empty (i.e.
Definition Block.h:565
void dealloc()
Definition Block.h:644
iterator begin()
Get the begin and end iterator object for this block.
Definition Block.h:590
Bool isCompatibleAllocator()
Definition Block.h:660
static constexpr bool init_anyway()
Definition Block.h:615
T * iterator
Definition Block.h:579
void set_capacity(size_t new_value)
Set the capacity of the vector.
Definition Block.h:677
Bool destroyPointer
Can we delete the storage upon destruction?
Definition Block.h:691
size_t used_p
The number of used elements in the vector.
Definition Block.h:687
void init()
Other internal helper function(s).
const value_type & const_reference
Definition Block.h:584
size_t get_size() const
The number of used elements in the vector.
Definition Block.h:668
value_type * pointer
Definition Block.h:581
void traceFree(const void *addr, size_t sz) const
Definition Block.h:607
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
size_t size() const
Definition Block.h:557
value_type & reference
Definition Block.h:583
void replaceStorage(size_t n, T *&storagePointer, Bool takeOverStorage=True)
Replace the internal storage with a C-array (i.e.
Definition Block.h:478
const Bool True
Definition aipstype.h:41
NewDelAllocator< T > NewDelAllocator< T >::value
Definition Allocator.h:369
void set_size(size_t new_value)
Set the number of used elements in the vector.
Definition Block.h:670
size_t get_capacity() const
The capacity of the vector.
Definition Block.h:675
iterator end()
Definition Block.h:594
T & operator[](size_t index)
Index into the block (0-based).
Definition Block.h:506
Block< T > & operator=(const T &val)
Set all values in the block to "val".
Definition Block.h:530
Allocator specifier.
Definition Allocator.h:402
static constexpr ArrayInitPolicy NO_INIT
Don't initialize elements in the array.
Definition Allocator.h:70
static constexpr ArrayInitPolicy INIT
Initialize all elements in the array with the default value.
Definition Allocator.h:72