+
+static int
+compare_ctables_values_3way (const void *a_, const void *b_, const void *width_)
+{
+ const struct ctables_value *const *ap = a_;
+ const struct ctables_value *const *bp = b_;
+ const struct ctables_value *a = *ap;
+ const struct ctables_value *b = *bp;
+ const int *width = width_;
+ return value_compare_3way (&a->value, &b->value, *width);
+}
+
+static void
+ctables_sort_clabels_values (struct ctables_table *t)
+{
+ const struct variable *v0 = t->clabels_example;
+ int width = var_get_width (v0);
+
+ struct ctables_categories *c0 = t->categories[var_get_dict_index (v0)];
+ if (c0->show_empty)
+ {
+ const struct val_labs *val_labs = var_get_value_labels (v0);
+ for (const struct val_lab *vl = val_labs_first (val_labs); vl;
+ vl = val_labs_next (val_labs, vl))
+ if (ctables_categories_match (c0, &vl->value, v0))
+ ctables_value_insert (t, &vl->value, width);
+ }
+
+ size_t n = hmap_count (&t->clabels_values_map);
+ t->clabels_values = xnmalloc (n, sizeof *t->clabels_values);
+
+ 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;
+ t->n_clabels_values = n;
+ assert (i == n);
+
+ sort (t->clabels_values, n, sizeof *t->clabels_values,
+ compare_ctables_values_3way, &width);
+
+ for (size_t i = 0; i < n; i++)
+ t->clabels_values[i]->leaf = i;
+}