+static void
+ctables_insert_clabels_values (struct ctables_table *t, const struct ccase *c,
+ enum pivot_axis_type a)
+{
+ struct ctables_stack *stack = &t->stacks[a];
+ for (size_t i = 0; i < stack->n; i++)
+ {
+ const struct ctables_nest *nest = &stack->nests[i];
+ const struct variable *v = nest->vars[nest->n - 1];
+ int width = var_get_width (v);
+ const union value *value = case_data (c, v);
+ unsigned int hash = value_hash (value, width, 0);
+
+ struct ctables_value *clv;
+ HMAP_FOR_EACH_WITH_HASH (clv, struct ctables_value, node, hash,
+ &t->clabels_values_map)
+ if (value_equal (value, &clv->value, width))
+ goto next_stack;
+
+ clv = xmalloc (sizeof *clv);
+ value_clone (&clv->value, value, width);
+ hmap_insert (&t->clabels_values_map, &clv->node, hash);
+
+ next_stack: ;
+ }
+}
+
+static int
+compare_clabels_values_3way (const void *a_, const void *b_, const void *width_)
+{
+ const union value *a = a_;
+ const union value *b = b_;
+ const int *width = width_;
+ return value_compare_3way (a, b, *width);
+}
+
+static void
+ctables_sort_clabels_values (struct ctables_table *t)
+{
+ int width = var_get_width (t->clabels_example);
+
+ size_t n = hmap_count (&t->clabels_values_map);
+ t->clabels_values = xnmalloc (n, sizeof *t->clabels_values);
+
+ const struct ctables_value *clv;
+ size_t i = 0;
+ HMAP_FOR_EACH (clv, struct ctables_value, node, &t->clabels_values_map)
+ t->clabels_values[i++] = clv->value;
+ assert (i == n);
+
+ sort (t->clabels_values, n, sizeof *t->clabels_values,
+ compare_clabels_values_3way, &width);
+}
+