コード例 #1
0
ファイル: refdb.c プロジェクト: JakeSc/tig
static int
compare_refs(const void *ref1_, const void *ref2_)
{
	const struct ref *ref1 = *(const struct ref **)ref1_;
	const struct ref *ref2 = *(const struct ref **)ref2_;

	return ref_compare(ref1, ref2);
}
コード例 #2
0
ファイル: refdb.c プロジェクト: ChunHungLiu/tig
static enum status_code
add_ref_to_id_map(struct ref *ref)
{
	void **ref_lists_slot = string_map_put_to(&refs_by_id, ref->id);

	if (!ref_lists_slot)
		return SUCCESS;

	/* First remove the ref from the ID list, to ensure that it is
	 * reinserted at the right position if the type changes. */
	{
		struct ref *list, *prev;

		for (list = *ref_lists_slot, prev = NULL; list; prev = list, list = list->next)
			if (list == ref) {
				if (!prev)
					*ref_lists_slot = ref->next;
				else
					prev->next = ref->next;
			}

		ref->next = NULL;
	}

	if (*ref_lists_slot == NULL || ref_compare(ref, *ref_lists_slot) <= 0) {
		ref->next = *ref_lists_slot;
		*ref_lists_slot = ref;

	} else {
		struct ref *list;

		for (list = *ref_lists_slot; list->next; list = list->next) {
			if (ref_compare(ref, list->next) <= 0)
				break;
		}

		ref->next = list->next;
		list->next = ref;
	}

	return SUCCESS;
}
コード例 #3
0
ファイル: compare.c プロジェクト: MCRedJay/ling
int is_term_smaller(term_t a, term_t b)
{
	if (a == b)
		return 0;

	if (are_both_immed(a, b))
	{
		if (are_both_int(a, b))
			return int_value(a) < int_value(b);

		if (is_int(a))	// !is_int(b)
			return 1;

		if (is_nil(a))	// !is_nil(b)
			return 0;
		if (is_nil(b))	// !is_nil(a)
			return 1;

		if (is_atom(a))
		{
			if (is_int(b))
				return 0;
			else if (is_atom(b))
			{
				uint8_t *print1 = atoms_get(atom_index(a));
				uint8_t *print2 = atoms_get(atom_index(b));
				int short_len = (print1[0] < print2[0])
					? print1[0]
					: print2[0];
				int d = memcmp(print1+1, print2+1, short_len);
				if (d == 0)
					return print1[0] < print2[0];
				return d < 0;
			}
			else
				return 1;
		}
		else if (is_short_oid(a))
		{
			if (is_int(b) || is_atom(b))
				return 0;
			else if (is_short_oid(b))
				return short_oid_id(a) < short_oid_id(b);
			else
				return 1;
		}
		else if (is_short_pid(a))
		{
			if (is_int(b) || is_atom(b) || is_short_oid(b))
				return 0;
			else
			{
				assert(is_short_pid(b));
				return short_pid_id(a) < short_pid_id(b);
			}
		}
	}

	//TODO: comparison of bignum and float: docs mention the
	// number 9007199254740992.0 and a loss of transitivity
	
	if (!is_immed(a) && !is_immed(b) &&
				primary_tag(a) == primary_tag(b))
	{
		if (is_cons(a))
			return is_term_smaller_1(a, b);
		else if (is_tuple(a))
			return is_term_smaller_2(a, b);
		else
		{
			assert(is_boxed(a) && is_boxed(b));
			uint32_t *adata = peel_boxed(a);
			uint32_t *bdata = peel_boxed(b);
			if (boxed_tag(adata) == boxed_tag(bdata) ||
					(is_binary(adata) && is_binary(bdata)) ||
					(is_bignum(adata) && is_bignum(bdata)))
			{
				switch(boxed_tag(adata))
				{
				case SUBTAG_POS_BIGNUM:
				case SUBTAG_NEG_BIGNUM:
					return bignum_compare((bignum_t *)adata,
										  (bignum_t *)bdata) < 0;
				case SUBTAG_FUN:
					return fun_compare((t_fun_t *)adata,
									   (t_fun_t *)bdata) < 0;
				case SUBTAG_EXPORT:
					return export_compare((t_export_t *)adata,
									   	  (t_export_t *)bdata) < 0;

				case SUBTAG_PID:
					return pid_compare((t_long_pid_t *)adata,
									   (t_long_pid_t *)bdata) < 0;

				case SUBTAG_OID:
					return oid_compare((t_long_oid_t *)adata,
									   (t_long_oid_t *)bdata) < 0;

				case SUBTAG_REF:
					return ref_compare((t_long_ref_t *)adata,
									   (t_long_ref_t *)bdata) < 0;

				case SUBTAG_PROC_BIN:
				case SUBTAG_HEAP_BIN:
				case SUBTAG_MATCH_CTX:
				case SUBTAG_SUB_BIN:
					return is_term_smaller_3(adata, bdata);

				default:
					assert(boxed_tag(adata) == SUBTAG_FLOAT);
					return float_value(adata) < float_value(bdata);
				}
			}
		}
	}

	// Number comparison with (mandatory) coercion
	//
	int use_float = (is_boxed(a) && boxed_tag(peel_boxed(a)) == SUBTAG_FLOAT) ||
					(is_boxed(b) && boxed_tag(peel_boxed(b)) == SUBTAG_FLOAT);

	if (use_float)
	{
		if (is_int(a))	// b is always float
			return (double)int_value(a) < float_value(peel_boxed(b));
		else if (is_boxed(a))
		{
			uint32_t *adata = peel_boxed(a);
			if (is_bignum(adata))	// b is always float
				return bignum_to_double((bignum_t *)adata) < float_value(peel_boxed(b));

			if (boxed_tag(adata) == SUBTAG_FLOAT)
			{
				if (is_int(b))
					return float_value(adata) < (double)int_value(b);
				if (is_boxed(b))
				{
					uint32_t *bdata = peel_boxed(b);
					if (is_bignum(bdata))
						return float_value(adata) < bignum_to_double((bignum_t *)bdata);
				}
			}
		}
	}
	else	// use integer
	{
		if (is_int(a))
		{
			if (is_boxed(b))
			{
				uint32_t *bdata = peel_boxed(b);
				if (is_bignum(bdata))
				{
					bignum_t *bbn = (bignum_t *)bdata;
					return !bignum_is_neg(bbn);
				}
				assert(boxed_tag(bdata) != SUBTAG_FLOAT);
			}
		}
		else if (is_boxed(a))
		{
			uint32_t *adata = peel_boxed(a);
			if (is_bignum(adata))
			{
				bignum_t *abn = (bignum_t *)adata;
				if (is_int(b))
					return bignum_is_neg(abn);

				if (is_boxed(b))
				{
					uint32_t *bdata = peel_boxed(b);
					if (is_bignum(bdata))
						return bignum_compare(abn, (bignum_t *)bdata);
					assert(boxed_tag(bdata) != SUBTAG_FLOAT);
				}
			}

			assert(boxed_tag(adata) != SUBTAG_FLOAT);
		}
	}

	// a and b are quaranteed to have different types
	// 
	
	return term_order(a) < term_order(b);
}
コード例 #4
0
ファイル: bind_template.hpp プロジェクト: 4eek/xtractorfan
 bool compare(this_type const & rhs) const
 {
     return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_;
 }