rt_public void ecopy(register EIF_REFERENCE source, register EIF_REFERENCE target) { /* Copy Eiffel object `source' into Eiffel object `target'. * Problem: updating intra-references on expanded object * because the garbage collector needs to explore those references. */ register uint16 flags; REQUIRE ("source_not_null", source); REQUIRE ("target_not_null", target); REQUIRE ("Same type", Dftype(source) == Dftype(target)); flags = HEADER(source)->ov_flags; if (flags & EO_SPEC) { spcopy(source, target); } else { eif_std_ref_copy(source, target); } ENSURE ("equals", eequal (target, source)); }
rt_private EIF_BOOLEAN e_field_equal(register EIF_REFERENCE target, register EIF_REFERENCE source) { /* Eiffel standard field-by-field equality: * Since target and source have the same dynamic type we iterate * on the attributes of target. * Return a boolean. */ struct cnode *skeleton; /* Target skeleton */ uint32 *types; /* Target attribute types */ #ifndef WORKBENCH long *offsets; /* Target attribute tables */ #else int32 *cn_attr; /* Array of attribute keys for target object */ int32 attr_key; /* Attribute key */ #endif long offset; long index; /* Target attribute index */ EIF_REFERENCE t_ref, s_ref; int attribute_type; /* Attribute type in skeleton */ EIF_TYPE_INDEX dtype; REQUIRE("target not null", target); REQUIRE("source not null", source); REQUIRE("Same full dynamic type", Dftype(target) == Dftype(source)); dtype = Dtype(target); /* Doesn't matter to take target or source since they are supposed to be the same type.*/ skeleton = &System(dtype); types = skeleton->cn_types; #ifndef WORKBENCH offsets = skeleton->cn_offsets; #else cn_attr = skeleton->cn_attr; #endif /* Iteration on the target attributes */ for (index = skeleton->cn_nbattr - 1; index >= 0; index--) { #ifndef WORKBENCH offset = offsets[index]; t_ref = target + offset; s_ref = source + offset; #else /* Evaluation of the attribute key */ attr_key = cn_attr[index]; /* Evaluation of the target attribute offset */ CAttrOffs(offset,attr_key,dtype); t_ref = target + offset; /* Evaluation of the source attribute offset */ /* It is the same as the target, since they have the same dynamic type */ s_ref = source + offset; #endif attribute_type = types[index]; switch (attribute_type & SK_HEAD) { case SK_BOOL: case SK_CHAR8: if (*t_ref != *s_ref) return EIF_FALSE; break; case SK_CHAR32: if (*(EIF_CHARACTER_32 *) t_ref != *(EIF_CHARACTER_32 *) s_ref) return EIF_FALSE; break; case SK_UINT8: if (*(EIF_NATURAL_8 *) t_ref != *(EIF_NATURAL_8 *) s_ref) return EIF_FALSE; break; case SK_UINT16: if (*(EIF_NATURAL_16 *) t_ref != *(EIF_NATURAL_16 *) s_ref) return EIF_FALSE; break; case SK_UINT32: if (*(EIF_NATURAL_32 *) t_ref != *(EIF_NATURAL_32 *) s_ref) return EIF_FALSE; break; case SK_UINT64: if (*(EIF_NATURAL_64 *) t_ref != *(EIF_NATURAL_64 *) s_ref) return EIF_FALSE; break; case SK_INT8: if (*(EIF_INTEGER_8 *) t_ref != *(EIF_INTEGER_8 *) s_ref) return EIF_FALSE; break; case SK_INT16: if (*(EIF_INTEGER_16 *) t_ref != *(EIF_INTEGER_16 *) s_ref) return EIF_FALSE; break; case SK_INT32: if (*(EIF_INTEGER_32 *) t_ref != *(EIF_INTEGER_32 *) s_ref) return EIF_FALSE; break; case SK_INT64: if (*(EIF_INTEGER_64 *) t_ref != *(EIF_INTEGER_64 *) s_ref) return EIF_FALSE; break; case SK_REAL32: if (*(EIF_REAL_32 *) t_ref != *(EIF_REAL_32 *) s_ref) return EIF_FALSE; break; case SK_REAL64: if (*(EIF_REAL_64 *) t_ref != *(EIF_REAL_64 *) s_ref) return EIF_FALSE; break; case SK_POINTER: if (*(fnptr *) t_ref != *(fnptr *) s_ref) return EIF_FALSE; break; case SK_EXP: /* Source and target attribute are expanded of the same type. * Block comparison if the attribute type is not composite * itself else field-by-field comparison. */ if (!eequal(t_ref, s_ref)) return EIF_FALSE; break; default: if (*(EIF_REFERENCE *)t_ref != *(EIF_REFERENCE *)s_ref) /* Check equality of references */ return EIF_FALSE; } } return EIF_TRUE; }