shithub: puzzles

Download patch

ref: 095224d5711f3482d6be0ffc01621143f25c7104
parent: 89c438e149a91fffa74b2669f7e0cd05abc3420f
author: Simon Tatham <anakin@pobox.com>
date: Thu Apr 20 10:12:11 EDT 2023

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.

--- a/dsf.c
+++ b/dsf.c
@@ -9,6 +9,10 @@
 
 #include "puzzles.h"
 
+struct DSF {
+    int *p;
+};
+
 /*void print_dsf(int *dsf, int size)
 {
     int *printed_elements = snewn(size, int);
@@ -65,7 +69,7 @@
 {
     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
      * element is opposite to its parent, which starts off as
      * false. Second bit of each element stores whether that element
@@ -76,14 +80,14 @@
 
 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)
 {
-    int *ret;
-    
-    ret = snewn(size, int);
+    DSF *ret = snew(DSF);
+    ret->p = snewn(size, int);
+
     dsf_init(ret, size);
 
     /*print_dsf(ret, size); */
@@ -93,7 +97,10 @@
 
 void dsf_free(DSF *dsf)
 {
-    sfree(dsf);
+    if (dsf) {
+        sfree(dsf->p);
+        sfree(dsf);
+    }
 }
 
 int dsf_canonify(DSF *dsf, int index)
@@ -107,7 +114,7 @@
 }
 
 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)
@@ -123,9 +130,9 @@
     /* 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
      * same as or inverse to that. */
-    while ((dsf[index] & 2) == 0) {
-        inverse ^= (dsf[index] & 1);
-	index = dsf[index] >> 2;
+    while ((dsf->p[index] & 2) == 0) {
+        inverse ^= (dsf->p[index] & 1);
+	index = dsf->p[index] >> 2;
 /*        fprintf(stderr, "index = %2d, ", index); */
 /*        fprintf(stderr, "inverse = %d\n", inverse); */
     }
@@ -138,9 +145,9 @@
      * canonical member. */
     index = start_index;
     while (index != canonical_index) {
-	int nextindex = dsf[index] >> 2;
-        bool nextinverse = inverse ^ (dsf[index] & 1);
-	dsf[index] = (canonical_index << 2) | inverse;
+	int nextindex = dsf->p[index] >> 2;
+        bool nextinverse = inverse ^ (dsf->p[index] & 1);
+	dsf->p[index] = (canonical_index << 2) | inverse;
         inverse = nextinverse;
 	index = nextindex;
     }
@@ -160,10 +167,10 @@
 /*    fprintf(stderr, "Merge [%2d,%2d], %d\n", v1, v2, inverse); */
     
     v1 = edsf_canonify(dsf, v1, &i1);
-    assert(dsf[v1] & 2);
+    assert(dsf->p[v1] & 2);
     inverse ^= i1;
     v2 = edsf_canonify(dsf, v2, &i2);
-    assert(dsf[v2] & 2);
+    assert(dsf->p[v2] & 2);
     inverse ^= i2;
 
 /*    fprintf(stderr, "Doing [%2d,%2d], %d\n", v1, v2, inverse); */
@@ -190,8 +197,8 @@
 	    v1 = v2;
 	    v2 = v3;
 	}
-	dsf[v1] += (dsf[v2] >> 2) << 2;
-	dsf[v2] = (v1 << 2) | inverse;
+	dsf->p[v1] += (dsf->p[v2] >> 2) << 2;
+	dsf->p[v2] = (v1 << 2) | inverse;
     }
     
     v2 = edsf_canonify(dsf, v2, &i2);
@@ -198,5 +205,5 @@
     assert(v2 == v1);
     assert(i2 == inverse);
 
-/*    fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf[v2]); */
+/*    fprintf(stderr, "dsf[%2d] = %2d\n", v2, dsf->p[v2]); */
 }
--- a/puzzles.h
+++ b/puzzles.h
@@ -426,7 +426,7 @@
 /*
  * dsf.c
  */
-typedef int DSF;
+typedef struct DSF DSF;
 DSF *snew_dsf(int size);
 void dsf_free(DSF *dsf);