+\f
+struct ccase *case_unshare__ (struct ccase *);
+void case_unref__ (struct ccase *);
+
+/* If C is a shared case, that is, if it has a reference count
+ greater than 1, makes a new unshared copy and returns it,
+ decrementing C's reference count. If C is not shared (its
+ reference count is 1), returns C.
+
+ This function should be used before attempting to modify any
+ of the data in a case that might be shared, e.g.:
+ c = case_unshare (c); // Make sure that C is not shared.
+ case_data_rw (c, myvar)->f = 1; // Modify data in C.
+*/
+static inline struct ccase *
+case_unshare (struct ccase *c)
+{
+ if (case_is_shared (c))
+ c = case_unshare__ (c);
+ return c;
+}
+
+/* Increments case C's reference count and returns C. Afterward,
+ case C is shared among its reference count holders. */
+static inline struct ccase *
+case_ref (const struct ccase *c_)
+{
+ struct ccase *c = (struct ccase *) c_;
+ c->ref_cnt++;
+ return c;
+}
+
+/* Decrements case C's reference count. Frees C if its
+ reference count drops to 0.
+
+ If C is a null pointer, this function has no effect. */
+static inline void
+case_unref (struct ccase *c)
+{
+ if (c != NULL && !--c->ref_cnt)
+ case_unref__ (c);
+}
+
+/* Returns true if case C is shared. A case that is shared
+ cannot be modified directly. Instead, an unshared copy must
+ first be made with case_unshare(). */
+static inline bool
+case_is_shared (const struct ccase *c)
+{
+ return c->ref_cnt > 1;
+}
+
+/* Returns the number of union values in C. */
+static inline size_t
+case_get_value_cnt (const struct ccase *c)
+{
+ return caseproto_get_n_widths (c->proto);
+}
+
+/* Returns the prototype that describes the format of case C.
+ The caller must not unref the returned prototype. */
+static inline const struct caseproto *
+case_get_proto (const struct ccase *c)
+{
+ return c->proto;
+}
+
+#endif /* data/case.h */