Beispiel #1
0
int DaoTuple_Compare( DaoTuple *lt, DaoTuple *rt )
{
	int i, lb, rb, res;
	if( lt->size < rt->size ) return -100;
	if( lt->size > rt->size ) return 100;

	for(i=0; i<lt->size; i++){
		DaoValue *lv = lt->items[i];
		DaoValue *rv = rt->items[i];
		int lb = lv ? lv->type : 0;
		int rb = rv ? rv->type : 0;
		if( lb == rb && lb == DAO_TUPLE ){
			res = DaoTuple_Compare( (DaoTuple*) lv, (DaoTuple*) rv );
			if( res != 0 ) return res;
		}else if( lb != rb || lb ==0 || lb > DAO_ARRAY || lb == DAO_COMPLEX ){
			if( lv < rv ){
				return -100;
			}else if( lv > rv ){
				return 100;
			}
		}else{
			res = DaoValue_Compare( lv, rv );
			if( res != 0 ) return res;
		}
	}
	return 0;
}
Beispiel #2
0
int DaoValue_Compare( DaoValue *left, DaoValue *right )
{
	double L, R;
	int res = 0;
	if( left == right ) return 0;
	if( left == NULL || right == NULL ) return left < right ? -100 : 100;
	if( left->type != right->type ){
		res = left->type < right->type ? -100 : 100;
		if( right->type == DAO_TUPLE && right->xTuple.subtype == DAO_PAIR ){
			if( (res = DaoValue_Compare( left, right->xTuple.items[0] )) <= 0 ) return res;
			if( (res = DaoValue_Compare( left, right->xTuple.items[1] )) >= 0 ) return res;
			return 0;
		}else if( left->type == DAO_TUPLE && left->xTuple.subtype == DAO_PAIR ){
			if( (res = DaoValue_Compare( left->xTuple.items[0], right )) >= 0 ) return res;
			if( (res = DaoValue_Compare( left->xTuple.items[1], right )) <= 0 ) return res;
			return 0;
		}
#ifdef DAO_WITH_LONGINT
		if( left->type == DAO_LONG && (right->type && right->type <= DAO_DOUBLE) ){
			if( right->type == DAO_INTEGER ){
				return DLong_CompareToInteger( left->xLong.value, right->xInteger.value );
			}
			return DLong_CompareToDouble( left->xLong.value, DaoValue_GetDouble( right ) );
		}else if( right->type == DAO_LONG && (left->type && left->type <= DAO_DOUBLE) ){
			if( left->type == DAO_INTEGER ){
				return - DLong_CompareToInteger( right->xLong.value, left->xInteger.value );
			}
			return - DLong_CompareToDouble( right->xLong.value, DaoValue_GetDouble( left ) );
		}
#endif
		if( left->type < DAO_INTEGER || left->type > DAO_DOUBLE ) return res;
		if( right->type < DAO_INTEGER || right->type > DAO_DOUBLE ) return res;
		L = DaoValue_GetDouble( left );
		R = DaoValue_GetDouble( right );
		return L == R ? 0 : (L < R ? -1 : 1);
	}
	switch( left->type ){
	case DAO_NONE : return 0;
	case DAO_INTEGER : return number_compare( left->xInteger.value, right->xInteger.value );
	case DAO_FLOAT   : return number_compare( left->xFloat.value, right->xFloat.value );
	case DAO_DOUBLE  : return number_compare( left->xDouble.value, right->xDouble.value );
	case DAO_COMPLEX : return DaoComplex_Compare( & left->xComplex, & right->xComplex );
#ifdef DAO_WITH_LONGINT
	case DAO_LONG    : return DLong_Compare( left->xLong.value, right->xLong.value );
#endif
	case DAO_STRING  : return DString_Compare( left->xString.data, right->xString.data );
	case DAO_ENUM    : return DaoEnum_Compare( & left->xEnum, & right->xEnum );
	case DAO_TUPLE   : return DaoTuple_Compare( & left->xTuple, & right->xTuple );
	case DAO_LIST    : return DaoList_Compare( & left->xList, & right->xList );
	case DAO_CDATA :
	case DAO_CSTRUCT :
	case DAO_CTYPE : return DaoCstruct_Compare( left, right );
#ifdef DAO_WITH_NUMARRAY
	case DAO_ARRAY   : return DaoArray_Compare( & left->xArray, & right->xArray );
#endif
	}
	return left < right ? -100 : 100; /* needed for map */
}
Beispiel #3
0
int DaoValue_CompareExt( DaoValue *left, DaoValue *right, DMap *cycmap )
{
	DMap *input = cycmap;
	void *pters[2];
	int res = 0;

	if( left == right ) return 0;
	if( left == NULL || right == NULL ) return left < right ? -100 : 100;
	if( left->type != right->type ){
		double L, R;
		res = left->type < right->type ? -100 : 100;
		if( left->type < DAO_BOOLEAN || left->type > DAO_FLOAT ) return res;
		if( right->type < DAO_BOOLEAN || right->type > DAO_FLOAT ) return res;
		L = DaoValue_GetFloat( left );
		R = DaoValue_GetFloat( right );
		return L == R ? 0 : (L < R ? -1 : 1);
	}
	switch( left->type ){
	case DAO_TUPLE   :
	case DAO_LIST    :
	case DAO_OBJECT  :
	case DAO_CDATA   :
	case DAO_CSTRUCT :
		pters[0] = left;
		pters[1] = right;
		if( cycmap != NULL ){
			DNode *it = DMap_Find( cycmap, pters );
			if( it != NULL ) return left < right ? -100 : 100;
		}
		if( cycmap == NULL ) cycmap = DHash_New(DAO_DATA_VOID2,0);
		DMap_Insert( cycmap, pters, NULL );
		break;
	}
	switch( left->type ){
	case DAO_NONE : break;
	case DAO_BOOLEAN : res = number_compare( left->xBoolean.value, right->xBoolean.value ); break;
	case DAO_INTEGER : res = number_compare( left->xInteger.value, right->xInteger.value ); break;
	case DAO_FLOAT   : res = number_compare( left->xFloat.value, right->xFloat.value ); break;
	case DAO_COMPLEX : res = DaoComplex_Compare( (DaoComplex*) left, (DaoComplex*) right ); break;
	case DAO_STRING  : res = DString_CompareUTF8( left->xString.value, right->xString.value ); break;
	case DAO_ENUM    : res = DaoEnum_Compare( (DaoEnum*) left, (DaoEnum*) right ); break;
	case DAO_TUPLE   : res = DaoTuple_Compare( (DaoTuple*) left, (DaoTuple*) right, cycmap ); break;
	case DAO_LIST    : res = DaoList_Compare( (DaoList*) left, (DaoList*) right, cycmap ); break;
	case DAO_OBJECT  : res = DaoObject_Compare( (DaoObject*)left, (DaoObject*)right, cycmap ); break;
	case DAO_CDATA   :
	case DAO_CSTRUCT : res = DaoCstruct_Compare( (DaoCstruct*)left, (DaoCstruct*)right, cycmap ); break;
	case DAO_TYPE    : res = DaoType_Compare( (DaoType*) left, (DaoType*) right ); break;
#ifdef DAO_WITH_NUMARRAY
	case DAO_ARRAY   : res = DaoArray_Compare( (DaoArray*) left, (DaoArray*) right ); break;
#endif
	default: res = left < right ? -100 : 100; break; /* Needed for map; */
	}
	if( cycmap != input ) DMap_Delete( cycmap );
	return res;
}