- ARRAY
- RECORD
Copy-on-write means that when a copy or an assignment is made, a physical copy is not made, the representation is shared via a pointer. However when one of the copies is changed, a physical copy is first made. So, basically this technique avoids the physical copy for as long as possible, in the hope that it might never be needed.The major functionalities provided to end users through the GlishValue class are:
Additionally, various inquiry functions are provided, for example to determine whether this value is an array or a record, and to say how long it is.
For the morbidly curious, here's an example of how one would turn
an AIPS++ Array
A scalar is just a length=1 array in Glish.
This should *only* be used for clients written using the
Create a logical copy of other. The physical copy is avoided for as
long as possible (copy-on-write semantics).
Create a logical copy of other. The physical copy is avoided for as
long as possible (copy-on-write semantics).
Add an attribute (named GlishValue) to this Value. Note that attributes
can in turn have attributes (although this might not be very useful).
The only attribute that is systematically used by Glish presently (Oct
94) is a "shape" which is an integer array containing the axis lengths.
It is automatically supplied however by the GlishArray class.
Is this object an array or a record?
The number of elements in an array (1 for a scalar), or the number of
fields in a record.
Returns a String representation of this GlishValue object. The iostream
output operator is also defined. By default only print the first 10
elements of an array.
Is this GlishValue consistent?
The following might be useful for interfacing to native Glish classes
occasionally - however it was mostly put in to allow testing of whether
copy-on-write was working.
Is the glish value the unset value?
Get the unset value;
Array<Complex ac = ...;
// Get the values from the AIPS++ array
Bool del;
Complex *aipsComplexPtr = ac.getStorage(del);
// Create a receptor array note that complex != Complex!!
complex *glishComplexPtr = new complex[ac.nelements()];
if ((glishComplexPtr) == 0) { ... memory error ...}
// Copy the values
for (uInt i=0; i < ac.nelements(); i++)
glishComplexPtr[i] = complex(aipsComplexPtr[i].real(),
aipsComplexPtr[i].imag());
// Delete pointer, if necessary.
ac.putStorage(aipsComplexPtr, del);
// OK; create the Glish Value from the initialized storage
Value native(ptr, ac.nelements());
// Now we need to attach the shape to the Glish Value as an attribute
IPosition acShape = ac.shape();
int shapeArray[ac.ndim()];
for (i=0; i < ac.ndim(); i++)
shapeArray[i] = acShape(i);
Value *shapeValuePtr = new Value(shapeArray, ac.ndim(), COPY_ARRAY);
if (shapeValuePtr == 0) { ... memory error ...;}
native.AssignAttribute("shape", shapeValuePtr);
Unref(shapeValuePtr);
// Done! native now contains a copy of ac.
To Do
Member Description
enum ValueType
GlishValue()
The default constructor creates a length=1 array with the value of False.
GlishValue(Value *value, Bool copy=False)
GlishValue(const GlishValue &other)
virtual ~GlishValue()
GlishValue &operator=(const GlishValue &other)
void addAttribute(const String &name, const GlishValue &value)
Bool attributeExists(const String &name) const
Determine if attribute "name" exists.
GlishValue getAttribute(const String &name) const
Return attribute "name." Returns the value False if "name" does not
exist.
ValueType type() const
uInt nelements() const
String format(uInt maxArrayLength=10) const
virtual Bool ok() const
const Value *value() const
Bool isUnset() const
static const GlishRecord& getUnset()
void copyset(const Value *value)
Makes this a copy of value
Bool isUnsetPriv() const
output GlishValue to an ostream (in ASCII) (source)
Interface
Description
Member Description
ostream &operator<<(ostream &os, const GlishValue &value)