Block
The net effect of this class is meant to be unsurprising to users who think
of arrays as first class objects. The name "Block" is intended to convey
the concept of a solid "chunk" of things without any intervening "fancy"
memory management, etc. This class was written to be
used in the implementations of more functional Vector, Matrix, etc. classes,
although it is expected Block
The Block class should be efficient. You should normally use Block
in preference to C-style arrays, particularly those obtained from "new".
Block
Assign other to this. this resizes itself to the size of other, so after
the assignment, this->nelements() == other.elements() always.
Frees up the storage pointed contained in the Block.
Resizes the Block. If "n == nelements()" resize just returns. If
A larger size is requested ("n > nelements()") the Block always
resizes. If the requested size is smaller ("n < nelements()"),
by default the Block does not resize smaller, although it can be
forced to with "forceSmaller". The reasoning behind this is that
often the user will just want a buffer of at least a certain size,
and won't want to pay the cost of multiple resizings.
This is written as three functions because default parameters do
not always work properly with templates.
Remove a single element from the Block. This forces a new allocations
and copy, so it is relatively expensive.
Replace the internal storage with a C-array (i.e. pointer).
If takeOverStorage is True, The Block assumes that it
owns the pointer, i.e. that it is safe to delete[] it when the Block
is destructed, otherwise the actual storage is not destroyed. If true,
storagePointer is set to NULL.
Index into the block (0-based). If the preprocessor symbol
AIPS_ARRAY_INDEX_CHECK is defined, index checking will be done
and an out-of-bounds index will cause an indexError
Set all values in the block to "val".
If you really, really, need a "raw" pointer to the beginning of the
storage area this will give it to you. This may leave dangling pointers
if the block is destructed or if the assignment operator or resize
is used. Returns a null pointer if nelements() == 0.
It is best to only use this if you completely control the extent and
lifetime of the Block.
The number of elements contained in this Block Copyright © 1995 Associated Universities Inc., Washington, D.C.
Currently the AllocError is thrown are in response to new[] failing.
If index checking is turned on, an out-of-bounds index will
generate an indexError If you use the assignment operator on an element of this class, you
will may leave dangling references to pointers released from storage().
Resizing the array will also have this effect if the underlying storage
is actually affected.
Examples
Block<Int> a(100,0); // 100 ints initialized to 0
Block<Int> b; // 0-length Block
// ...
b = a; // resize b and copy a into it
for (uInt i=0; i < a.nelements(); i++) {
a[i] = i; // Generate a sequence
// with Vectors, could simply say "indgen(myVector);"
}
b.set(-1); // All positions in b have the value -1
b.resize(b.nelements()*2); // Make b twice as long, by default the old
// elements are copied over, although this can
// be defeated.
some_c_function(b.storage()); // Use a fn that takes an Int * pointer
Member Description
Block()
Create a zero-length Block. Note that any index into this Block
is an error.
Block(uInt n)
Create a Block with the given number of points. The values in Block
are uninitialized. Note that indices range between 0 and n-1.
Block(uInt n, T val)
Create a Block of the given length, and initialize (via operator= for
objects of type T) with the provided value.
Block(uInt n, T *&storagePointer, Bool takeOverStorage = True)
Create a Block from a C-array (i.e. pointer). If takeOverStorage is
True, The Block assumes that it
owns the pointer, i.e. that it is safe to delete[] it when the Block
is destructed, otherwise the actual storage is not destroyed. If true,
storagePointer is set to NULL.
Block(const Block<T> &other)
Copy the other block into this one. Uses copy, not reference, semantics.
Block<T> &operator=(const Block<T> &other)
~Block()
void resize(uInt n, Bool forceSmaller, Bool copyElements)
void resize(uInt n)
void resize(uInt n, Bool forceSmaller)
Block<float> bf(100, 0.0);
bf.resize(10); // bf.nelements() == 100
bf.resize(10, True) // bf.nelements() == 10
bf.resize(200) // bf.nelements() == 200
Normally the old elements are copied over (although if the
Block is lengthened the trailing elements will have undefined
values), however this can be turned off by setting copyElements to
False.
void remove(uInt whichOne)
void replaceStorage(uInt n, T *&storagePointer, Bool takeOverStorage=True)
T &operator[](uInt index)
const T &operator[](uInt index) const
Thrown Exceptions
void set(const T &val)
T *storage()
const T *storage() const
Examples of misuse
Block<int> *bp = new Block<int>(100);
int *ip = bp->storage();
delete bp; // Oops, ip is now dangling
Block<int> a(100),b(100);
int *ip = a.storage();
a = b; // Likewise
uInt nelements() const