+static void
+ctables_section_clear (struct ctables_section *s)
+{
+ for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
+ {
+ const struct ctables_nest *nest = s->nests[a];
+ for (size_t i = 0; i < nest->n; i++)
+ if (i != nest->scale_idx)
+ {
+ const struct variable *var = nest->vars[i];
+ int width = var_get_width (var);
+ struct ctables_occurrence *o, *next;
+ struct hmap *map = &s->occurrences[a][i];
+ HMAP_FOR_EACH_SAFE (o, next, struct ctables_occurrence, node, map)
+ {
+ value_destroy (&o->value, width);
+ hmap_delete (map, &o->node);
+ free (o);
+ }
+ hmap_shrink (map);
+ }
+ }
+
+ struct ctables_cell *cell, *next_cell;
+ HMAP_FOR_EACH_SAFE (cell, next_cell, struct ctables_cell, node, &s->cells)
+ {
+ for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
+ {
+ const struct ctables_nest *nest = s->nests[a];
+ for (size_t i = 0; i < nest->n; i++)
+ if (i != nest->scale_idx)
+ value_destroy (&cell->axes[a].cvs[i].value,
+ var_get_width (nest->vars[i]));
+ free (cell->axes[a].cvs);
+ }
+
+ const struct ctables_nest *ss = s->nests[s->table->summary_axis];
+ const struct ctables_summary_spec_set *specs = &ss->specs[cell->sv];
+ for (size_t i = 0; i < specs->n; i++)
+ ctables_summary_uninit (&cell->summaries[i], &specs->specs[i]);
+ free (cell->summaries);
+
+ hmap_delete (&s->cells, &cell->node);
+ free (cell);
+ }
+ hmap_shrink (&s->cells);
+
+ for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++)
+ {
+ struct ctables_domain *domain, *next_domain;
+ HMAP_FOR_EACH_SAFE (domain, next_domain, struct ctables_domain, node,
+ &s->domains[dt])
+ {
+ free (domain->sums);
+ hmap_delete (&s->domains[dt], &domain->node);
+ free (domain);
+ }
+ hmap_shrink (&s->domains[dt]);
+ }
+}
+
+static void
+ctables_table_clear (struct ctables_table *t)
+{
+ for (size_t i = 0; i < t->n_sections; i++)
+ ctables_section_clear (&t->sections[i]);
+
+ if (t->clabels_example)
+ {
+ int width = var_get_width (t->clabels_example);
+ struct ctables_value *value, *next_value;
+ HMAP_FOR_EACH_SAFE (value, next_value, struct ctables_value, node,
+ &t->clabels_values_map)
+ {
+ value_destroy (&value->value, width);
+ hmap_delete (&t->clabels_values_map, &value->node);
+ free (value);
+ }
+ hmap_shrink (&t->clabels_values_map);
+
+ free (t->clabels_values);
+ t->clabels_values = NULL;
+ t->n_clabels_values = 0;
+ }
+}
+