next up previous contents index
Next: Available Glish Clients Up: The Glish Client Library Previous: The Client Class

The Value Class

 

  As noted above, the Value class is both rich and complex. It provides considerable functionality for manipulating Glish-style values. We divide our discussion into constructing Value's, basic operations, type conversions, manipulating records, and accessing and assigning elements. We do not discuss all of the member functions here, as some of them are intended for use only by the Glish interpreter (which uses the Value class internally).

Constructing Value Objects

 

    Value objects can be constructed either from single scalars, in which case a one-element Value is created, or from arrays,   in which case a multi-element Value is created.

To create a scalar Value, use one of the following:  

    Value( glish_bool value )
    Value( byte value )
    Value( short value )
    Value( int value )
    Value( float value )
    Value( double value )
    Value( complex value )
    Value( dcomplex value )
    Value( const char* value )
These create single-element Value objects that correspond to the Glish types                 boolean, byte, short, integer, float, double, complex, dcomplex, and string. Note that in all cases (including the string constructor) the value used to initialize the object is copied.

The C++ glish_bool     type is an enumerated type with two constants, glish_true (= 1) and     glish_false (= 0). This enumeration is defined in Glish/glish.h. This header file is automatically included by Glish/Value.h.

The C++ byte     type holds an unsigned byte. It is also defined in Glish/glish.h.

The C++ complex and dcomplex         types define single- and double-precision complex types. The types     are defined in the header Glish/Complex.h, which is automatically included by Glish/Value.h (see above).

The Value class also has a copy constructor:  

    Value( const Value &v )
    Glish has two systems of reference counting going on at the same time. One is an external sort of reference counting which is handled by the Ref() and Unref() functions (see § 13.1). This sort of reference counting manages a whole value. Internally, though, the Value class has a second type of reference counting. This copy constructor uses this sort of reference counting to avoid copying the underlying data. The reference for the underlying data is incremented and a copy is only made when a write access is made to the underlying memory. This is how copy-on-write is implemented in Glish (see § 3.10). In some of the following functions, there will be a flag to indicate if the access is read only or modify.

To create a new, empty record use:      

    Value* create_record()
The fields of the new record can then be set using the functions discussed in § 13.6.4.

        To create a multi-element Value, use one of the following:

    Value( glish_bool value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( byte value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( short value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( int value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( float value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( double value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( complex value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( dcomplex value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
    Value( const char* value[], int num_elements,
           array_storage_type storage = TAKE_OVER_ARRAY )
Each of these constructors takes a pointer (array) of one of the types discussed above, the number of elements in the array, and an optional argument indicating to what degree that array now ``belongs" to the Value object.

  This last argument defaults to TAKE_OVER_ARRAY, which informs the Value object that it can do whatever it wishes with the array,   including resize it (via a call to realloc())   and delete it when done using it. Thus if TAKE_OVER_ARRAY is used the array must have been dynamically allocated. The following is erroneous:    

    int foo[50];
    Value* v = new Value( foo, 50 );
because foo is not a dynamically allocated array. This, too, is illegal:    
    int* foo = new int[50];
    Value* v = new Value( foo, 50 );
    delete foo;
because foo now belongs to v and should not be deleted by anyone else.

  The storage argument can also be COPY_ARRAY, in which case   the Value object uses a copy of the entire array instead of the original array (string Value's copy each string element   of the string array, too), or PRESERVE_ARRAY, in which case the Value object uses the array as is but does not attempt to grow it or delete it. If the Value object needs to alter a PRESERVE_ARRAY array, it first copies it instead.

Presently, COPY_ARRAY and PRESERVE_ARRAY have the same effect, i.e. a copy is made immediately. The intended PRESERVE_ARRAY functionality was not pushed through when copy-on-write values were added. In the future, this may be corrected, but PRESERVE_ARRAY seems problematic. When using either COPY_ARRAY or PRESERVE_ARRAY, you must consider efficiency.  

Basic Value Operations

 

The Value class provides the following basic member functions:

Type Conversions

 

  The Value class provides the following member functions for manipulating the type of a Value object:

 

Manipulating Records

    Very often record's are used as Glish event values, so it's important that it be easy to manipulate them. The Value class provides a number of member functions for accessing and setting record fields. We first list the most commonly used ones:

In addition to these member functions, several others are available, primarily for when you want to deal with record fields as Value objects themselves:

 

Accessing and Assigning Elements

    Usually the Value class is used to ``wrap" Glish values around C, C++, or FORTRAN data so those values may be communicated as events. As such, the emphasis in using the class is on convenient wrapping and unwrapping. It is also possible to use the class to manipulate Value objects similar to how they can be manipulated in the Glish language. We discuss here some of the member functions available for doing so. I'm interested in hearing from users who find they would like more such functionality.

 

Accessing and Assigning Attributes

  Attributes are also accessible from the Value class. They are accessed using the following functions:

With these functions, one can manage the attributes which are associated with a particular Value.  

 


next up previous contents index
Next: Available Glish Clients Up: The Glish Client Library Previous: The Client Class

Thu Nov 13 16:44:05 EST 1997