+case_data_all_rw (struct ccase *c)
+{
+ assert (!case_is_shared (c));
+ return c->values;
+}
+
+/* Internal helper function for case_unshare. */
+struct ccase *
+case_unshare__ (struct ccase *old)
+{
+ struct ccase *new = case_create (old->proto);
+ case_copy (new, 0, old, 0, caseproto_get_n_widths (new->proto));
+ --old->ref_cnt;
+ return new;
+}
+
+/* Internal helper function for case_unref. */
+void
+case_unref__ (struct ccase *c)
+{
+ caseproto_destroy_values (c->proto, c->values);
+ caseproto_unref (c->proto);
+ free (c);
+}
+\f
+/* Returns the number of bytes needed by a case for case
+ prototype PROTO. */
+static size_t
+case_size (const struct caseproto *proto)
+{
+ return (offsetof (struct ccase, values)
+ + caseproto_get_n_widths (proto) * sizeof (union value));
+}
+
+/* Returns true if C contains a value at V's case index with the
+ same width as V; that is, if V may plausibly be used to read
+ or write data in C.
+
+ Useful in assertions. */
+static bool UNUSED
+variable_matches_case (const struct ccase *c, const struct variable *v)
+{
+ size_t case_idx = var_get_case_index (v);
+ return (case_idx < caseproto_get_n_widths (c->proto)
+ && caseproto_get_width (c->proto, case_idx) == var_get_width (v));
+}
+
+/* Internal helper function for case_copy(). */
+static void
+copy_forward (struct ccase *dst, size_t dst_idx,
+ const struct ccase *src, size_t src_idx,
+ size_t n_values)