Actually make DSF an opaque structure type.

This makes good on all the previous preparatory commits, which I did
separately so that each one individually has a reasonably readable
diff, and all the mechanical changes are separated out from the
rewrites that needed actual thought.

Still no functional change, however: the DSF type wraps nothing but
the same int pointer that 'DSF *' used to store directly.
This commit is contained in:
Simon Tatham
2023-04-20 14:12:11 +01:00
parent 89c438e149
commit 095224d571
2 changed files with 26 additions and 19 deletions

41
dsf.c
View File

@ -9,6 +9,10 @@
#include "puzzles.h" #include "puzzles.h"
struct DSF {
int *p;
};
/*void print_dsf(int *dsf, int size) /*void print_dsf(int *dsf, int size)
{ {
int *printed_elements = snewn(size, int); int *printed_elements = snewn(size, int);
@ -65,7 +69,7 @@ void dsf_init(DSF *dsf, int size)
{ {
int i; int i;
for (i = 0; i < size; i++) dsf[i] = 6; for (i = 0; i < size; i++) dsf->p[i] = 6;
/* Bottom bit of each element of this array stores whether that /* Bottom bit of each element of this array stores whether that
* element is opposite to its parent, which starts off as * element is opposite to its parent, which starts off as
* false. Second bit of each element stores whether that element * false. Second bit of each element stores whether that element
@ -76,14 +80,14 @@ void dsf_init(DSF *dsf, int size)
void dsf_copy(DSF *to, DSF *from, int size) void dsf_copy(DSF *to, DSF *from, int size)
{ {
memcpy(to, from, size * sizeof(int)); memcpy(to->p, from->p, size * sizeof(int));
} }
DSF *snew_dsf(int size) DSF *snew_dsf(int size)
{ {
int *ret; DSF *ret = snew(DSF);
ret->p = snewn(size, int);
ret = snewn(size, int);
dsf_init(ret, size); dsf_init(ret, size);
/*print_dsf(ret, size); */ /*print_dsf(ret, size); */
@ -93,7 +97,10 @@ DSF *snew_dsf(int size)
void dsf_free(DSF *dsf) void dsf_free(DSF *dsf)
{ {
sfree(dsf); if (dsf) {
sfree(dsf->p);
sfree(dsf);
}
} }
int dsf_canonify(DSF *dsf, int index) int dsf_canonify(DSF *dsf, int index)
@ -107,7 +114,7 @@ void dsf_merge(DSF *dsf, int v1, int v2)
} }
int dsf_size(DSF *dsf, int index) { int dsf_size(DSF *dsf, int index) {
return dsf[dsf_canonify(dsf, index)] >> 2; return dsf->p[dsf_canonify(dsf, index)] >> 2;
} }
int edsf_canonify(DSF *dsf, int index, bool *inverse_return) int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
@ -123,9 +130,9 @@ int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
/* Find the index of the canonical element of the 'equivalence class' of /* Find the index of the canonical element of the 'equivalence class' of
* which start_index is a member, and figure out whether start_index is the * which start_index is a member, and figure out whether start_index is the
* same as or inverse to that. */ * same as or inverse to that. */
while ((dsf[index] & 2) == 0) { while ((dsf->p[index] & 2) == 0) {
inverse ^= (dsf[index] & 1); inverse ^= (dsf->p[index] & 1);
index = dsf[index] >> 2; index = dsf->p[index] >> 2;
/* fprintf(stderr, "index = %2d, ", index); */ /* fprintf(stderr, "index = %2d, ", index); */
/* fprintf(stderr, "inverse = %d\n", inverse); */ /* fprintf(stderr, "inverse = %d\n", inverse); */
} }
@ -138,9 +145,9 @@ int edsf_canonify(DSF *dsf, int index, bool *inverse_return)
* canonical member. */ * canonical member. */
index = start_index; index = start_index;
while (index != canonical_index) { while (index != canonical_index) {
int nextindex = dsf[index] >> 2; int nextindex = dsf->p[index] >> 2;
bool nextinverse = inverse ^ (dsf[index] & 1); bool nextinverse = inverse ^ (dsf->p[index] & 1);
dsf[index] = (canonical_index << 2) | inverse; dsf->p[index] = (canonical_index << 2) | inverse;
inverse = nextinverse; inverse = nextinverse;
index = nextindex; index = nextindex;
} }
@ -160,10 +167,10 @@ void edsf_merge(DSF *dsf, int v1, int v2, bool inverse)
/* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */ /* fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
v1 = edsf_canonify(dsf, v1, &i1); v1 = edsf_canonify(dsf, v1, &i1);
assert(dsf[v1] & 2); assert(dsf->p[v1] & 2);
inverse ^= i1; inverse ^= i1;
v2 = edsf_canonify(dsf, v2, &i2); v2 = edsf_canonify(dsf, v2, &i2);
assert(dsf[v2] & 2); assert(dsf->p[v2] & 2);
inverse ^= i2; inverse ^= i2;
/* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */ /* fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
@ -190,13 +197,13 @@ void edsf_merge(DSF *dsf, int v1, int v2, bool inverse)
v1 = v2; v1 = v2;
v2 = v3; v2 = v3;
} }
dsf[v1] += (dsf[v2] >> 2) << 2; dsf->p[v1] += (dsf->p[v2] >> 2) << 2;
dsf[v2] = (v1 << 2) | inverse; dsf->p[v2] = (v1 << 2) | inverse;
} }
v2 = edsf_canonify(dsf, v2, &i2); v2 = edsf_canonify(dsf, v2, &i2);
assert(v2 == v1); assert(v2 == v1);
assert(i2 == inverse); assert(i2 == inverse);
/* fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf[v2]); */ /* fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf->p[v2]); */
} }

View File

@ -426,7 +426,7 @@ char *button2label(int button);
/* /*
* dsf.c * dsf.c
*/ */
typedef int DSF; typedef struct DSF DSF;
DSF *snew_dsf(int size); DSF *snew_dsf(int size);
void dsf_free(DSF *dsf); void dsf_free(DSF *dsf);