⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 value.cc

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 CC
📖 第 1 页 / 共 5 页
字号:
									\	delete index;							\	delete index_is_copy;						\	delete cur;							\	}#define SUBOP_ABORT(length,retval)				\	SUBOP_CLEANUP_2(length)					\	delete len;						\	return retval;	if ( ! IsNumeric() && VecRefDeref()->Type() != TYPE_STRING )		{		error->Report( "invalid type in n-D array operation:",				this );		return error_value();		}	// Collect attributes.	int args_len = args_val->length();	const attributeptr ptr = AttributePtr();	const Value* shape_val = ptr ? (*ptr)["shape"] : 0;	if ( ! shape_val || ! shape_val->IsNumeric() )		{		warn->Report( "invalid or non-existant \"shape\" attribute" );		if ( args_len >= 1 )			return operator[]( (*args_val)[0] );		else			return copy_value( this );		}	int shape_len = shape_val->Length();	if ( shape_len != args_len )		{		error->Report( "invalid number of indexes for:", this );		return error_value();		}	int shape_is_copy;	int* shape = shape_val->CoerceToIntArray( shape_is_copy, shape_len );	Value* op_val = (*ptr)["op[]"];	int* factor = new int[shape_len];	int cur_factor = 1;	int offset = 0;	int max_len = 0;	for ( int i = 0; i < args_len; ++i )		{		const Value* arg = (*args_val)[i];		if ( arg )			{			if ( ! arg->IsNumeric() )				{				error->Report( "index #", i+1, "into", this,						"is not numeric");				SUBOP_CLEANUP_1				return error_value();				}			if ( arg->length > max_len )				max_len = arg->length;			if ( max_len == 1 )				{				int ind = arg->IntVal();				if ( ind < 1 || ind > shape[i] )					{					error->Report( "index #", i+1, "into",						this, "is out of range");					SUBOP_CLEANUP_1					return error_value();					}				offset += cur_factor * (ind - 1);				}			}		else			{ // Missing subscript.			if ( shape[i] > max_len )				max_len = shape[i];			if ( max_len == 1 )				offset += cur_factor * (shape[i] - 1);			}		factor[i] = cur_factor;		cur_factor *= shape[i];		}	// Check to see if we're valid.	if ( cur_factor > Length() )		{		error->Report( "\"::shape\"/length mismatch" );		SUBOP_CLEANUP_1		return error_value();		}	if ( max_len == 1 ) 		{		SUBOP_CLEANUP_1		++offset;		// Should separate ArrayRef to get a single value??		return ArrayRef( &offset, 1 );		}	int* index_is_copy = new int[shape_len];	int** index = new int*[shape_len];	int* cur = new int[shape_len];	int* len = new int[shape_len];	int vecsize = 1;	int is_element = 1;	int spoof_dimension = 0;	for ( i = 0; i < args_len; ++i )		{		const Value* arg = (*args_val)[i];		if ( arg )			{			index[i] = GenerateIndices( arg, len[i],						index_is_copy[i], 0 );			spoof_dimension = 0;			}		else			{ // Spoof entire dimension.			len[i] = shape[i];			index[i] = new int[len[i]];			for ( int j = 0; j < len[i]; j++ )				index[i][j] = j+1;			index_is_copy[i] = 1;			spoof_dimension = 1;			}		if ( is_element && len[i] > 1 )			is_element = 0;		vecsize *= len[i];		cur[i] = 0;		if ( ! spoof_dimension )			{			for ( int j = 0; j < len[i]; ++j )				{				if ( index[i][j] >= 1 &&				     index[i][j] <= shape[i] )					continue;				if ( len[i] > 1 )					error->Report( "index #", i+1, ",",							j+1, " into ", this, 							"is out of range.");				else					error->Report( "index #", i+1, "into",						this, "is out of range.");				SUBOP_ABORT(i, error_value())				}			}		}	// Loop through filling resultant vector.	Value* result;	switch ( Type() )		{#define SUBSCRIPT_OP_ACTION(tag,type,accessor,LEN,OFFSET,copy_func,ERROR)\	case tag:							\		{							\		type* vec = accessor;					\		type* ret = new type[vecsize];				\									\		for ( int v = 0; v < vecsize; ++v )			\			{						\			/**** Calculate offset ****/			\			for ( i = 0, offset = 0; i < shape_len; ++i )	\				offset += factor[i] *			\						(index[i][cur[i]]-1);	\			/**** Set Value ****/				\			ERROR						\			ret[v] = copy_func( vec[OFFSET] );		\			/****  Advance counters ****/			\			for ( i = 0; i < shape_len; ++i )		\				if ( ++cur[i] < len[i] )		\					break;				\				else					\					cur[i] = 0;			\			}						\									\		result = new Value( ret, vecsize );			\		if ( ! is_element )					\			{						\			for ( int x = 0, z = 0; x < shape_len; ++x )	\				if ( len[x] > 1 )			\					len[z++] = len[x];		\									\			result->AssignAttribute( "shape",		\						new Value( len, z ) );	\			if ( op_val )					\				result->AssignAttribute( "op[]", op_val );\			}						\		else							\			delete len;					\		}							\		break;SUBSCRIPT_OP_ACTION(TYPE_BOOL,glish_bool,BoolPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_BYTE,byte,BytePtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_SHORT,short,ShortPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_INT,int,IntPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_FLOAT,float,FloatPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_DOUBLE,double,DoublePtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_COMPLEX,complex,ComplexPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_DCOMPLEX,dcomplex,DcomplexPtr(),length,offset,,)SUBSCRIPT_OP_ACTION(TYPE_STRING,charptr,StringPtr(),length,offset,strdup,)		case TYPE_SUBVEC_REF:		case TYPE_SUBVEC_CONST:			{			VecRef* ref = VecRefPtr();			Value* theVal = ref->Val();			int theLen = theVal->Length();			switch ( theVal->Type() )				{#define SUBSCRIPT_OP_ACTION_XLATE(EXTRA_ERROR)		\	int err;					\	int off = ref->TranslateIndex( offset, &err );	\	if ( err )					\		{					\		EXTRA_ERROR				\		delete ret;				\		SUBOP_CLEANUP_2(shape_len)		\		return error_value();			\		}SUBSCRIPT_OP_ACTION(TYPE_BOOL, glish_bool, theVal->BoolPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_BYTE, byte, theVal->BytePtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_SHORT, short, theVal->ShortPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_INT, int, theVal->IntPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_FLOAT, float, theVal->FloatPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_DOUBLE, double, theVal->DoublePtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_COMPLEX, complex, theVal->ComplexPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_DCOMPLEX, dcomplex, theVal->DcomplexPtr(),	theLen, off,,SUBSCRIPT_OP_ACTION_XLATE(;))SUBSCRIPT_OP_ACTION(TYPE_STRING, charptr, theVal->StringPtr(),	theLen, off,strdup,SUBSCRIPT_OP_ACTION_XLATE(for(int X=0;X<v;X++) delete (char *) ret[X];))				default:					fatal->Report(				"bad subref type in Value::operator[]" );				}			}			break;		default:			fatal->Report( "bad type in Value::operator[]" );		}	SUBOP_CLEANUP_2(shape_len)	return result;	}Value* Value::Pick( const Value *index ) const	{#define PICK_CLEANUP				\	if ( shape_is_copy )			\		delete shape;			\	if ( ishape_is_copy )			\		delete ishape;			\	if ( indx_is_copy )			\		delete indx;			\	delete factor;#define PICK_INITIALIZE(error_return,SHORT)				\	const attributeptr attr = AttributePtr();			\	const attributeptr iattr = index->AttributePtr();		\	const Value* shape_val = 0;					\	const Value* ishape_val = 0;					\	int shape_len = 0;						\	int ishape_len = 0;						\									\	if ( attr && (shape_val = (*attr)["shape"]) &&			\	     shape_val->IsNumeric() )					\		shape_len = shape_val->Length();			\	if ( iattr && (ishape_val = (*iattr)["shape"]) &&		\	     ishape_val->IsNumeric() )					\		ishape_len = ishape_val->Length();			\									\	/* Neither has a shape so pick from the vector. */		\	if ( ishape_len <= 1 && shape_len <= 1 )			\		{							\		SHORT							\		}							\									\	if ( ! ishape_len )						\		{							\		if ( ishape_val )					\			error->Report("error in the array \"::shape\": ",\				ishape_val );				\		else							\			error->Report( "no \"::shape\" for ", index,	\				" but the array has \"::shape\"" );	\		return error_return;					\		}							\	if ( ! shape_len )						\		{							\		if ( shape_val )					\			error->Report("error in the array \"::shape\": ",\				shape_val );				\		else							\			error->Report( "no \"::shape\" for ", this,	\				" but the index has \"::shape\"" );	\		return error_return;					\		}							\									\	if ( ishape_len > 2 )						\		{							\		error->Report("invalid index of dimension (=", ishape_len, \				") greater than 2");			\		return error_return;					\		}							\									\	int shape_is_copy = 0;						\	int ishape_is_copy = 0;						\	int indx_is_copy = 0;						\	int* shape = shape_val->CoerceToIntArray( shape_is_copy, shape_len );\	int* ishape =							\		ishape_val->CoerceToIntArray( ishape_is_copy, ishape_len );\	int ilen = index->Length();					\	int len = Length();						\	int* factor = new int[shape_len];				\	int offset = 1;							\	int* indx = index->CoerceToIntArray( indx_is_copy, ilen );	\	Value* result = 0;						\									\	if ( ishape[1] != shape_len )					\		{							\		PICK_CLEANUP						\		error->Report( "wrong number of columns in index (=",	\			ishape[1], ") expected ", shape_len );		\		return error_return;					\		}							\	if ( ilen < ishape[0] * ishape[1] )				\		{							\		PICK_CLEANUP						\			error->Report( "Index \"::shape\"/length mismatch" );\		return error_return;					\		}							\	for ( int i = 0; i < shape_len; ++i )				\		{							\		factor[i] = offset;					\		offset *= shape[i];					\		}							\									\	if ( len < offset )						\		{							\		PICK_CLEANUP						\		error->Report("Array \"::shape\"/length mismatch");	\		return error_return;					\		}	PICK_INITIALIZE(error_value(),return this->operator[]( index );)	switch ( Type() )		{#define PICK_ACTION_CLEANUP for(int X=0;X<i;X++) delete (char *) ret[X];#define PICK_ACTION(tag,type,accessor,OFFSET,COPY_FUNC,XLATE,CLEANUP)	\	case tag:							\		{							\		type* ptr = accessor();					\		type* ret = new type[ishape[0]];			\		int cur = 0;						\		for ( i = 0; i < ishape[0]; ++i )			\			{						\			for ( int j = 0, offset = 0; j < ishape[1]; ++j )\				{					\				cur = indx[i + j * ishape[0]];		\				if ( cur < 1 || cur > shape[j] )	\					{				\					PICK_CLEANUP			\					CLEANUP				\					delete ret;			\					error->Report( "index number ", j,\					" (=", cur, ") is out of range" );\					return error_value();		\					}				\				offset += factor[j] * (cur-1);		\				}					\			XLATE						\			ret[i] = COPY_FUNC( ptr[ OFFSET ] );		\			}						\		result = new Value( ret, ishape[0] );			\		}							\		break;		PICK_ACTION(TYPE_BOOL,glish_bool,BoolPtr,offset,,,)		PICK_ACTION(TYPE_BYTE,byte,BytePtr,offset,,,)		PICK_ACTION(TYPE_SHORT,short,ShortPtr,offset,,,)		PICK_ACTION(TYPE_INT,int,IntPtr,offset,,,)		PICK_ACTION(TYPE_FLOAT,float,FloatPtr,offset,,,)		PICK_ACTION(TYPE_DOUBLE,double,DoublePtr,offset,,,)		PICK_ACTION(TYPE_COMPLEX,complex,ComplexPtr,offset,,,)		PICK_ACTION(TYPE_DCOMPLEX,dcomplex,DcomplexPtr,offset,,,)		PICK_ACTION(TYPE_STRING,charptr,StringPtr,offset,strdup,,			PICK_ACTION_CLEANUP)		case TYPE_SUBVEC_REF:		case TYPE_SUBVEC_CONST:			{			VecRef* ref = VecRefPtr();			Value* theVal = ref->Val();			int theLen = theVal->Length();			switch ( theVal->Type() )				{#define PICK_ACTION_XLATE(CLEANUP)					\	int err;							\	int off = ref->TranslateIndex( offset, &err );			\	if ( err )							\		{							\		CLEANUP							\		delete ret;						\		error->Report( "index number ", j, " (=",cur,		\			") is out of range. Sub-vector reference may be invalid" );\		return error_value();					\		}PICK_ACTION(TYPE_BOOL,glish_bool,theVal->BoolPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_BYTE,byte,theVal->BytePtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_SHORT,short,theVal->ShortPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_INT,int,theVal->IntPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_FLOAT,float,theVal->FloatPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_DOUBLE,double,theVal->DoublePtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_COMPLEX,complex,theVal->ComplexPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_DCOMPLEX,dcomplex,theVal->DcomplexPtr,off,,PICK_ACTION_XLATE(;),)PICK_ACTION(TYPE_STRING,charptr,theVal->StringPtr,off,strdup,	PICK_ACTION_XLATE(PICK_ACTION_CLEANUP),PICK_ACTION_CLEANUP)				default:					fatal->Report(					"bad subref type in Value::Pick" );				}			}			break;		default:			fatal->Report( "bad subref type in Value::Pick" );		}	PICK_CLEANUP	return result;	}Value* Value::PickRef( const Value *index )	{	if ( ! IsNumeric() && Type() != TYPE_STRING )		{		error->Report( "non-numeric type in subreference operation:",				this );		return error_value();		}	PICK_INITIALIZE(error_value(),return this->operator[]( index );)	int* ret = new int[ishape[0]];	int cur = 0;	for ( i = 0; i < ishape[0]; ++i )		{		for ( int j = 0, offset = 0; j < ishape[1]; ++j )			{			cur = indx[i + j * ishape[0]];			if ( cur < 1 || cur > shape[j] )				{				PICK_CLEANUP				delete ret;				error->Report( "index number ", j, " (=",cur,						") is out of range" );				return error_value();				}			offset += factor[j] * (cur-1);			}		ret[i] = offset + 1;		}	result = new Value((Value*)this,ret,ishape[0],VAL_REF);	const attributeptr cap = result->AttributePtr();	if ( (*cap)["shape"] )		{		if ( cap->Length() == 1 )			result->DeleteAttributes();		else			{			attributeptr ap = result->ModAttributePtr();			delete ap->Remove( "shape" );			}		}	PICK_CLEANUP	return result;	}void Value::PickAssign( const Value* index, Value* value )	{#define PICKASSIGN_SHORT		\	AssignElements( index, value );	\	return;	PICK_INITIALIZE(,PICKASSIGN_SHORT)	switch ( Type() )		{#define PICKASSIGN_ACTION(tag,type,to_accessor,from_accessor,COPY_FUNC,XLATE)\	case tag:							\		{							\		int cur = 0;						\		int* offset_vec = new int[ishape[0]];			\		for ( i = 0; i < ishape[0]; ++i )			\			{						\			offset_vec[i] = 0;				\			for ( int j = 0; j < ishape[1]; ++j )		\				{					\				cur = indx[i + j * ishape[0]];		\				if ( cur < 1 || cur > shape[j] )	\					{				\					PICK_CLEANUP			\					delete offset_vec;		\					error->Report("index number ", i,\							" (=", cur,	\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -