📄 value.cc
字号:
sprintf( &result[strlen( result )], "%s=%s, ", key_strs[i], element_strs[i] ); delete element_strs[i]; } // Now add the final ']', taking care to wipe out the trailing // ", ". strcpy( &result[strlen( result ) - 2], "]" ); return result; }Agent* Value::AgentVal() const { if ( type == TYPE_AGENT ) return AgentPtr()[0]; if ( VecRefDeref()->Type() == TYPE_RECORD ) { Value* member = (*RecordPtr())[AGENT_MEMBER_NAME]; if ( member ) return member->AgentVal(); } error->Report( this, " is not an agent value" ); return 0; }Func* Value::FuncVal() const { if ( type != TYPE_FUNC ) { error->Report( this, " is not a function value" ); return 0; } if ( length == 0 ) { error->Report( "empty function array" ); return 0; } if ( length > 1 ) warn->Report( "more than one function element in", this, ", excess ignored" ); return FuncPtr()[0]; }int Value::SDS_IndexVal() const { if ( type != TYPE_OPAQUE ) { error->Report( this, " is not an opaque value" ); return SDS_NO_SUCH_SDS; } return int(values); }Value* Value::Deref() { if ( IsRef() ) return RefPtr()->Deref(); else return this; }const Value* Value::Deref() const { if ( IsRef() ) return ((const Value*) RefPtr())->Deref(); else return this; }Value* Value::VecRefDeref() { if ( IsVecRef() ) return VecRefPtr()->Val()->VecRefDeref(); else if ( IsRef() ) return RefPtr()->VecRefDeref(); else return this; }const Value* Value::VecRefDeref() const { if ( IsVecRef() ) return ((const Value*) VecRefPtr()->Val())->VecRefDeref(); else if ( IsRef() ) return ((const Value*) RefPtr())->VecRefDeref(); else return this; }#define COERCE_HDR(name, ctype, gtype, type_name, accessor) \ if ( IsRef() ) \ return Deref()->name( is_copy, size, result ); \ \ if ( ! IsNumeric() ) \ fatal->Report( "non-numeric type in coercion of", this, \ "to ", type_name ); \ \ if ( ! result && length == size && type == gtype ) \ { \ is_copy = 0; \ return accessor(); \ } \ \ is_copy = 1; \ if ( ! result ) \ result = new ctype[size]; \ \ int incr = (length == 1 ? 0 : 1); \ int i, j;glish_bool* Value::CoerceToBoolArray( int& is_copy, int size, glish_bool* result ) const { COERCE_HDR(CoerceToBoolArray, glish_bool, TYPE_BOOL, "bool", BoolPtr) switch ( type ) {#define BOOL_COERCE_BOOL_ACTION(OFFSET,XLATE) \ case TYPE_BOOL: \ { \ glish_bool* bool_ptr = BoolPtr(); \ for ( i = 0, j = 0; i < size; ++i, j += incr ) \ { \ XLATE \ result[i] = bool_ptr[ OFFSET ]; \ } \ break; \ }#define BOOL_COERCE_ACTION(tag,type,rhs_elm,accessor,OFFSET,XLATE) \ case tag: \ { \ type* ptr = accessor; \ for ( i = 0, j = 0; i < size; ++i, j += incr ) \ { \ XLATE \ result[i] = (ptr[ OFFSET ] rhs_elm ? glish_true : glish_false);\ } \ break; \ }BOOL_COERCE_BOOL_ACTION(j,)BOOL_COERCE_ACTION(TYPE_BYTE,byte,,BytePtr(),j,)BOOL_COERCE_ACTION(TYPE_SHORT,short,,ShortPtr(),j,)BOOL_COERCE_ACTION(TYPE_INT,int,,IntPtr(),j,)BOOL_COERCE_ACTION(TYPE_FLOAT,float,,FloatPtr(),j,)BOOL_COERCE_ACTION(TYPE_DOUBLE,double,,DoublePtr(),j,)BOOL_COERCE_ACTION(TYPE_COMPLEX,complex,.r,ComplexPtr(),j,)BOOL_COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,.r,DcomplexPtr(),j,) case TYPE_SUBVEC_REF: case TYPE_SUBVEC_CONST: { VecRef *ref = VecRefPtr(); switch ( ref->Type() ) {#define COERCE_ACTION_XLATE \ int err; \ int off = ref->TranslateIndex( j, &err ); \ if ( err ) \ { \ error->Report( "index (=",j, \ ") is out of range. Sub-vector reference may be invalid" );\ return 0; \ }BOOL_COERCE_BOOL_ACTION(off,COERCE_ACTION_XLATE)BOOL_COERCE_ACTION(TYPE_INT,int,,IntPtr(),off,COERCE_ACTION_XLATE)BOOL_COERCE_ACTION(TYPE_FLOAT,float,,FloatPtr(),off,COERCE_ACTION_XLATE)BOOL_COERCE_ACTION(TYPE_DOUBLE,double,,DoublePtr(),off,COERCE_ACTION_XLATE)BOOL_COERCE_ACTION(TYPE_COMPLEX,complex,.r,ComplexPtr(),off,COERCE_ACTION_XLATE)BOOL_COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,.r,DcomplexPtr(),off,COERCE_ACTION_XLATE) default: error->Report( "bad type in Value::CoerceToBoolArray()" ); return 0; } } break; default: error->Report( "bad type in Value::CoerceToBoolArray()" ); return 0; } return result; }#define COERCE_ACTION(tag,rhs_type,rhs_elm,lhs_type,accessor,OFFSET,XLATE)\ case tag: \ { \ rhs_type* rhs_ptr = accessor; \ for ( i = 0, j = 0; i < size; ++i, j += incr ) \ { \ XLATE \ result[i] = \ lhs_type(rhs_ptr[OFFSET] rhs_elm); \ } \ break; \ }#define COERCE_ACTIONS(type,error_msg) \COERCE_ACTION(TYPE_BOOL,glish_bool,,type,BoolPtr(),j,) \COERCE_ACTION(TYPE_BYTE,byte,,type,BytePtr(),j,) \COERCE_ACTION(TYPE_SHORT,short,,type,ShortPtr(),j,) \COERCE_ACTION(TYPE_INT,int,,type,IntPtr(),j,) \COERCE_ACTION(TYPE_FLOAT,float,,type,FloatPtr(),j,) \COERCE_ACTION(TYPE_DOUBLE,double,,type,DoublePtr(),j,) \COERCE_ACTION(TYPE_COMPLEX,complex,.r,type,ComplexPtr(),j,) \COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,.r,type,DcomplexPtr(),j,) \ \ case TYPE_SUBVEC_REF: \ case TYPE_SUBVEC_CONST: \ { \ VecRef *ref = VecRefPtr(); \ switch ( ref->Type() ) \ { \ \COERCE_ACTION(TYPE_BOOL,glish_bool,,type,BoolPtr(),off,COERCE_ACTION_XLATE)\COERCE_ACTION(TYPE_BYTE,byte,,type,BytePtr(),off,COERCE_ACTION_XLATE) \COERCE_ACTION(TYPE_SHORT,short,,type,ShortPtr(),off,COERCE_ACTION_XLATE)\COERCE_ACTION(TYPE_INT,int,,type,IntPtr(),off,COERCE_ACTION_XLATE) \COERCE_ACTION(TYPE_FLOAT,float,,type,FloatPtr(),off,COERCE_ACTION_XLATE)\COERCE_ACTION(TYPE_DOUBLE,double,,type,DoublePtr(),off,COERCE_ACTION_XLATE)\COERCE_ACTION(TYPE_COMPLEX,complex,.r,type,ComplexPtr(),off,COERCE_ACTION_XLATE)\COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,.r,type,DcomplexPtr(),off,COERCE_ACTION_XLATE)\ \ default: \ error->Report( \ "bad type in Value::",error_msg);\ return 0; \ } \ } \ break;byte* Value::CoerceToByteArray( int& is_copy, int size, byte* result ) const { COERCE_HDR(CoerceToByteArray, byte, TYPE_BYTE, "byte", BytePtr) switch ( type ) { COERCE_ACTIONS(byte,"CoerceToByteArray()") default: error->Report( "bad type in Value::CoerceToByteArray()" ); return 0; } return result; }short* Value::CoerceToShortArray( int& is_copy, int size, short* result ) const { COERCE_HDR(CoerceToShortArray, short, TYPE_SHORT, "short", ShortPtr) switch ( type ) { COERCE_ACTIONS(short,"CoerceToShortArray()") default: error->Report( "bad type in Value::CoerceToShortArray()" ); return 0; } return result; }int* Value::CoerceToIntArray( int& is_copy, int size, int* result ) const { COERCE_HDR(CoerceToIntArray, int, TYPE_INT, "integer", IntPtr) switch ( type ) { COERCE_ACTIONS(int,"CoerceToIntArray()") default: error->Report( "bad type in Value::CoerceToIntArray()" ); return 0; } return result; }float* Value::CoerceToFloatArray( int& is_copy, int size, float* result ) const { COERCE_HDR(CoerceToFloatArray, float, TYPE_FLOAT, "float", FloatPtr) switch ( type ) { COERCE_ACTIONS(float,"CoerceToFloatArray()") default: error->Report( "bad type in Value::CoerceToFloatArray()" ); return 0; } return result; }double* Value::CoerceToDoubleArray( int& is_copy, int size, double* result ) const { COERCE_HDR(CoerceToDoubleArray, double, TYPE_DOUBLE, "double", DoublePtr) switch ( type ) { COERCE_ACTIONS(double,"CoerceToDoubleArray()") default: error->Report( "bad type in Value::CoerceToDoubleArray()" ); return 0; } return result; }// Coercion builtin->complex.#define COMPLEX_BIN_COERCE_ACTION(tag,rhs_type,lhs_type,accessor,OFFSET,XLATE)\ case tag: \ { \ rhs_type* rhs_ptr = accessor; \ for ( i = 0, j = 0; i < size; ++i, j += incr ) \ { \ XLATE \ result[i].r = \ lhs_type(rhs_ptr[OFFSET]); \ result[i].i = lhs_type(0); \ } \ break; \ }// Coercion complex->complex.#define COMPLEX_CPX_COERCE_ACTION(tag,rhs_type,lhs_type,accessor,OFFSET,XLATE)\ case tag: \ { \ rhs_type* rhs_ptr = accessor; \ for ( i = 0, j = 0; i < size; ++i, j += incr ) \ { \ XLATE \ result[i].r = lhs_type(rhs_ptr[OFFSET].r); \ result[i].i = lhs_type(rhs_ptr[OFFSET].i); \ } \ break; \ }#define COERCE_COMPLEX_ACTIONS(type,error_msg) \COMPLEX_BIN_COERCE_ACTION(TYPE_BOOL,glish_bool,type,BoolPtr(),j,) \COMPLEX_BIN_COERCE_ACTION(TYPE_BYTE,byte,type,BytePtr(),j,) \COMPLEX_BIN_COERCE_ACTION(TYPE_SHORT,short,type,ShortPtr(),j,) \COMPLEX_BIN_COERCE_ACTION(TYPE_INT,int,type,IntPtr(),j,) \COMPLEX_BIN_COERCE_ACTION(TYPE_FLOAT,float,type,FloatPtr(),j,) \COMPLEX_BIN_COERCE_ACTION(TYPE_DOUBLE,double,type,DoublePtr(),j,) \COMPLEX_CPX_COERCE_ACTION(TYPE_COMPLEX,complex,type,ComplexPtr(),j,) \COMPLEX_CPX_COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,type,DcomplexPtr(),j,) \ \ case TYPE_SUBVEC_REF: \ case TYPE_SUBVEC_CONST: \ { \ VecRef *ref = VecRefPtr(); \ switch ( ref->Type() ) \ { \ \COMPLEX_BIN_COERCE_ACTION(TYPE_BOOL,glish_bool,type,BoolPtr(),off,COERCE_ACTION_XLATE)\COMPLEX_BIN_COERCE_ACTION(TYPE_BYTE,byte,type,BytePtr(),off,COERCE_ACTION_XLATE)\COMPLEX_BIN_COERCE_ACTION(TYPE_SHORT,short,type,ShortPtr(),off,COERCE_ACTION_XLATE)\COMPLEX_BIN_COERCE_ACTION(TYPE_INT,int,type,IntPtr(),off,COERCE_ACTION_XLATE)\COMPLEX_BIN_COERCE_ACTION(TYPE_FLOAT,float,type,FloatPtr(),off,COERCE_ACTION_XLATE)\COMPLEX_BIN_COERCE_ACTION(TYPE_DOUBLE,double,type,DoublePtr(),off,COERCE_ACTION_XLATE)\COMPLEX_CPX_COERCE_ACTION(TYPE_COMPLEX,complex,type,ComplexPtr(),off,COERCE_ACTION_XLATE)\COMPLEX_CPX_COERCE_ACTION(TYPE_DCOMPLEX,dcomplex,type,DcomplexPtr(),off,COERCE_ACTION_XLATE)\ \ default: \ error->Report( \ "bad type in Value::",error_msg );\ return 0; \ } \ } \ break;complex* Value::CoerceToComplexArray( int& is_copy, int size, complex* result ) const { COERCE_HDR(CoerceToComplexArray, complex, TYPE_COMPLEX, "complex", ComplexPtr) switch ( type ) { COERCE_COMPLEX_ACTIONS(float,"CoerceToComplexArray()") default: error->Report( "bad type in Value::CoerceToComplexArray()" ); return 0; } return result; }dcomplex* Value::CoerceToDcomplexArray( int& is_copy, int size, dcomplex* result ) const { COERCE_HDR(CoerceToDcomplexArray, dcomplex, TYPE_DCOMPLEX, "dcomplex", DcomplexPtr) switch ( type ) { COERCE_COMPLEX_ACTIONS(float,"CoerceToDcomplexArray()") default: error->Report( "bad type in Value::CoerceToDcomplexArray()" ); return 0; } return result; }charptr* Value::CoerceToStringArray( int& is_copy, int size, charptr* result ) const { if ( IsRef() ) return Deref()->CoerceToStringArray(is_copy,size,result ); if ( VecRefDeref()->Type() != TYPE_STRING ) { error->Report( "non-string type in coercion of", this, "to string" ); return 0; } if ( ! result && Length() == size && ! IsVecRef() ) { is_copy = 0; return StringPtr(); } is_copy = 1; if ( ! result ) result = new charptr[size]; int incr = (Length() == 1 ? 0 : 1); int i, j; charptr* string_ptr = StringPtr(); if ( IsVecRef() ) { VecRef* ref = VecRefPtr(); for ( i = 0, j = 0; i < size; ++i, j += incr ) { int err; int off = ref->TranslateIndex( j, &err ); if ( err ) { error->Report( "index (=",j, ") is out of range. Sub-vector reference may be invalid" ); return 0; } result[i] = string_ptr[off]; } } else { for ( i = 0, j = 0; i < size; ++i, j += incr ) result[i] = string_ptr[j]; } return result; }funcptr* Value::CoerceToFuncArray( int& is_copy, int size, funcptr* result ) const { if ( type != TYPE_FUNC ) fatal->Report( "non-func type in CoerceToFuncArray()" ); if ( size != length ) fatal->Report( "size != length in CoerceToFuncArray()" ); if ( result ) fatal->Report( "prespecified result in CoerceToFuncArray()" ); is_copy = 0; return FuncPtr(); }Value* Value::operator []( const Value* index ) const { if ( index->Type() == TYPE_STRING ) return RecordRef( index ); int indices_are_copy; int num_indices; int* indices = GenerateIndices( index, num_indices, indices_are_copy ); if ( indices ) { Value* result = ArrayRef( indices, num_indices ); if ( indices_are_copy ) delete indices; return result; } else return error_value(); }Value* Value::operator []( const_value_list* args_val ) const {// These are a bunch of macros for cleaning up the dynamic memory used// by this routine (and Value::SubRef) prior to exit.#define SUBOP_CLEANUP_1 \ if ( shape_is_copy ) \ delete shape; \ delete factor;#define SUBOP_CLEANUP_2(length) \ { \ SUBOP_CLEANUP_1 \ for ( int x = 0; x < length; ++x ) \ if ( index_is_copy[x] ) \ delete index[x]; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -