📄 value.h
字号:
// $Header: /cvsroot/sourcenav/src/snavigator/demo/c++_demo/glish/include/Glish/Value.h,v 1.1.1.1 2002/04/18 23:35:28 mdejong Exp $#ifndef value_h#define value_h#include "Glish/Dict.h"#include "Glish/glish.h"#include "Glish/GlishType.h"#include "Glish/Object.h"#include "Glish/Complex.h"// Different types of values: constant references, references, and// ordinary (non-indirect) values.typedef enum { VAL_CONST, VAL_REF, VAL_VAL } value_type;// Different types of storage for an array used to construct a Value.typedef enum { COPY_ARRAY, // copy the array TAKE_OVER_ARRAY, // use the array, delete it when done with it PRESERVE_ARRAY // use the array, don't delete it or grow it } array_storage_type;class Value;class Agent;class Func;class ArithExpr;class RelExpr;struct complex;struct dcomplex;struct record_header; // Needed when dealing with SDS; see AddToSds()typedef const char* charptr;typedef Func* funcptr;typedef Agent* agentptr;declare(PList,Value);typedef PList(Value) value_list;declare(PDict,Value);typedef PDict(Value)* recordptr;typedef recordptr attributeptr;typedef const Value* const_value;declare(List,const_value);typedef List(const_value) const_value_list;// Classes for subvector references.class VecRef;#define SubVecRef(type) name2(type,SubVecRef)class SubVecRef(glish_bool);class SubVecRef(byte);class SubVecRef(short);class SubVecRef(int);class SubVecRef(float);class SubVecRef(double);class SubVecRef(complex);class SubVecRef(dcomplex);class SubVecRef(charptr);typedef SubVecRef(glish_bool) glish_boolref;typedef SubVecRef(byte) byteref;typedef SubVecRef(short) shortref;typedef SubVecRef(int) intref;typedef SubVecRef(float) floatref;typedef SubVecRef(double) doubleref;typedef SubVecRef(complex) complexref;typedef SubVecRef(dcomplex) dcomplexref;typedef SubVecRef(charptr) charptrref;// Class used to differentiate integers that are SDS indices from// just plain integers.class SDS_Index {public: SDS_Index( int ind ) { index = ind; } int Index() const { return index; }protected: int index; };// Used to create lists of objects or dynamic memory that should be freed.class DelObj;declare(PList,DelObj);typedef PList(DelObj) del_list;#define copy_array(src,dest,len,type) \ memcpy( (void*) dest, (void*) src, sizeof(type) * len )#define copy_values(src,type) \ copy_array( src, (void *) new type[len], length, type )extern Value* copy_value( const Value* value );extern const Value* false_value;extern Value* empty_value();extern Value* error_value();extern Value* create_record();extern recordptr create_record_dict();void delete_record( recordptr r );// The number of Value objects created and deleted. Useful for tracking// down inefficiencies and leaks.extern int num_Values_created;extern int num_Values_deleted;class Value : public GlishObject {public: 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 ); Value( funcptr value ); Value( agentptr value ); Value( recordptr value, Agent* agent = 0 ); Value( SDS_Index& sds_index ); // Reference constructor. Value( Value* ref_value, value_type val_type ); // Subref constructor. Value( Value* ref_value, int index[], int num_elements, value_type val_type ); 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( charptr value[], int num_elements, array_storage_type storage = TAKE_OVER_ARRAY ); Value( funcptr value[], int num_elements, array_storage_type storage = TAKE_OVER_ARRAY ); Value( glish_boolref& value_ref ); Value( byteref& value_ref ); Value( shortref& value_ref ); Value( intref& value_ref ); Value( floatref& value_ref ); Value( doubleref& value_ref ); Value( complexref& value_ref ); Value( dcomplexref& value_ref ); Value( charptrref& value_ref ); // Discard present value and instead take new_value. void TakeValue( Value* new_value ); ~Value(); // A value manager is an object that is Unref()'d upon destruction // of a Value in lieu of deleting the Value's "values" member // variable. Presumably the value manager knows something about // "values" and when deleted performs some sort of cleanup on it // (perhaps by deleting it, perhaps by changing its reference count, // perhaps by leaving it alone, etc.). void SetValueManager( GlishObject* manager ) { value_manager = manager; } glish_type Type() const { return type; } unsigned int Length() const { if ( Type() == TYPE_RECORD ) return RecordPtr()->Length(); else if ( IsRef() ) return Deref()->Length(); else return length; } // True if the value is a reference. int IsRef() const { return type == TYPE_REF || type == TYPE_CONST; } // True if the value is a constant reference. int IsConst() const { return type == TYPE_CONST; } // True if the value is a sub-vector reference. int IsVecRef() const { return type == TYPE_SUBVEC_REF || type == TYPE_SUBVEC_CONST; } // True if the value makes sense as a numeric type (i.e., // bool, integer, or floating-point). int IsNumeric() const; // True if the value is a record corresponding to a agent. int IsAgentRecord() const; // Returns the "n"'th element coereced to the corresponding type. glish_bool BoolVal( int n = 1 ) const; byte ByteVal( int n = 1 ) const; short ShortVal( int n = 1 ) const; int IntVal( int n = 1 ) const; float FloatVal( int n = 1 ) const; double DoubleVal( int n = 1 ) const; complex ComplexVal( int n = 1 ) const; dcomplex DcomplexVal( int n = 1 ) const; // Returns the entire value converted to a single string, with // "sep" used to separate array elements. If "use_attr" is // true, then the value's attributes are used for determining // its shape (as a n-D array). // // Returns a new string, which should be delete'd when done with. char* StringVal( char sep = ' ', int use_attr = 0 ) const; // Returns the agent or function corresponding to the Value. Agent* AgentVal() const; funcptr FuncVal() const; // Returns the Value's SDS index, if TYPE_OPAQUE. Returns // SDS_NO_SUCH_SDS if the value is not TYPE_OPAQUE. int SDS_IndexVal() const; // The following accessors return pointers to the underlying value // array. The "const" versions complain with a fatal error if the // value is not the given type. The non-const versions first // Polymorph() the values to the given type. If called for a // subref, retrieves the complete underlying value, not the // just selected subelements. (See the XXXRef() functions below.) glish_bool* BoolPtr() const; byte* BytePtr() const; short* ShortPtr() const; int* IntPtr() const; float* FloatPtr() const; double* DoublePtr() const; complex* ComplexPtr() const; dcomplex* DcomplexPtr() const; charptr* StringPtr() const; funcptr* FuncPtr() const; agentptr* AgentPtr() const; recordptr RecordPtr() const; glish_bool* BoolPtr(); byte* BytePtr(); short* ShortPtr(); int* IntPtr(); float* FloatPtr(); double* DoublePtr(); complex* ComplexPtr(); dcomplex* DcomplexPtr(); charptr* StringPtr(); funcptr* FuncPtr(); agentptr* AgentPtr(); recordptr RecordPtr(); Value* RefPtr() const { return (Value*) values; } // The following accessors are for accessing sub-array references. // They complain with a fatal error if the value is not a sub-array // reference. Otherwise they return a reference to the underlying // *sub*elements. The "const" versions complain with a fatal error // if the value is not the given type. The non-const versions // first Polymorph() the values to the given type. glish_boolref& BoolRef() const; byteref& ByteRef() const; shortref& ShortRef() const; intref& IntRef() const; floatref& FloatRef() const; doubleref& DoubleRef() const; complexref& ComplexRef() const; dcomplexref& DcomplexRef() const; charptrref& StringRef() const; glish_boolref& BoolRef(); byteref& ByteRef(); shortref& ShortRef(); intref& IntRef(); floatref& FloatRef(); doubleref& DoubleRef(); complexref& ComplexRef(); dcomplexref& DcomplexRef(); charptrref& StringRef(); VecRef* VecRefPtr() const { return (VecRef*) values; } // Follow the reference chain of a non-constant or constant value // until finding its non-reference base value. Value* Deref(); const Value* Deref() const; Value* VecRefDeref(); const Value* VecRefDeref() const; // Return a copy of the Value's contents coerced to an array // of the given type. If the Value has only one element then // "size" copies of that element are returned (this is used // for promoting scalars to arrays in operations that mix // the two). Otherwise, the first "size" elements are coerced // and returned. // // If the value cannot be coerced to the given type then a nil // pointer is returned. glish_bool* CoerceToBoolArray( int& is_copy, int size, glish_bool* result = 0 ) const; byte* CoerceToByteArray( int& is_copy, int size, byte* result = 0 ) const; short* CoerceToShortArray( int& is_copy, int size, short* result = 0 ) const; int* CoerceToIntArray( int& is_copy, int size, int* result = 0 ) const; float* CoerceToFloatArray( int& is_copy, int size, float* result = 0 ) const; double* CoerceToDoubleArray( int& is_copy, int size, double* result = 0 ) const; complex* CoerceToComplexArray( int& is_copy, int size, complex* result = 0 ) const; dcomplex* CoerceToDcomplexArray( int& is_copy, int size, dcomplex* result = 0 ) const; charptr* CoerceToStringArray( int& is_copy, int size, charptr* result = 0 ) const; // These coercions are very limited: they essentially either // return the corresponding xxxPtr() (if the sizes match, // no "result" is prespecified, and the Value is already // the given type) or generate a fatal error. funcptr* CoerceToFuncArray( int& is_copy, int size, funcptr* result = 0 ) const; // The following both return a new value. Value* operator[]( const Value* index ) const; Value* operator[]( const_value_list *index ) const; // Pick distinct elements from an array. Value* Pick( const Value* index ) const; // Return a reference to distinct elements from an array. Value* PickRef( const Value* index ); // Assign to distinct array elements. void PickAssign( const Value* index, Value *value ); // Return a true sub-array reference. Value* SubRef( const Value* index ); Value* SubRef( const_value_list *args_val ); Value* RecordRef( const Value* index ) const; // returns a new Value // Returns an (unmodifiable) existing Value, or false_value if the // given field does not exist. const Value* ExistingRecordElement( const Value* index ) const; const Value* ExistingRecordElement( const char field[] ) const; // Returns a modifiable existing Value. If the given field does // not exist, it is added, with an initial value of F. Value* GetOrCreateRecordElement( const Value* index ); Value* GetOrCreateRecordElement( const char field[] ); // Returns the given record element if it exists, 0 otherwise. // (The value must already have been tested to determine that it's // a record.) Value* HasRecordElement( const char field[] ) const; // Returns a modifiable existing Value, or if no field exists // with the given name, returns 0. Value* Field( const Value* index ); Value* Field( const char field[] ); // Returns the given field, polymorphed to the given type. Value* Field( const char field[], glish_type t ); // Returns a modifiable existing Value of the nth field of a record, // with the first field being numbered 1. Returns 0 if the field // does not exist (n is out of range) or the Value is not a record. Value* NthField( int n ); const Value* NthField( int n ) const; // Returns a non-modifiable pointer to the nth field's name. // Returns 0 in the same cases as NthField does. const char* NthFieldName( int n ) const; // Returns a copy of a unique field name (one not already present) // for the given record, or 0 if the Value is not a record. // // The name has an embedded '*' to avoid collision with user-chosen // names. char* NewFieldName();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -