Make cases simpler, faster, and easier to understand.
Cases (struct ccase) is reference-counted to avoid copying more
data than necessary. But the existing implementation that uses
separate structures for references to cases (struct ccase) and
the cases themselves (struct case_data) has a number of issues:
- The semantics of struct ccase are tricky to remember; one
has to remember to treat struct ccase as essentially a
pointer type. I get confused sometimes myself.
(One of the symptoms of this was the existence of
the case_nullify and case_is_null functions, which are
exactly analogous to setting a pointer to null and comparing
one against null, respectively.)
- Every reference to data in a case involves two levels of
indirection, which is one more than actually necessary.
- The implementation is somewhat complicated.
This commit simplifies things, by dropping a level of indirection.
Now, a case is just a pointer to a struct ccase, which contains
the actual data. Reference counting is still present, but it is
simplified. The only thing that must be remembered is that, before
modifying a case that may be shared, it must be passed through
case_unshare() to make a new unshared copy if necessary.