/* Quick sort */

state =
{
  ulong rq_greater_or_lesser;
};

cmp = ((vb, vb) byte);

sort (vb -w dest, vb src, cmp compare, SORT_* order_by = SORT_ASC)
{
  sort (dest, src, &st, compare), 
  {
    state st = {
                 rq_greater_or_lesser : (order_by == SORT_ASC) ? 1 : 0
               }
  };
}

sort _ -rc (vb -w dest, vb src, p_state st, cmp compare)
{
  vb first = alloc (&_, T_LINK);

  length = _ (src); 
  half_length = (length - (length %% 2)) / 2;

  left = alloc (&_, T_LIST, half_length);
  right = alloc (&_, T_LIST, half_length);
  others = alloc (&_, T_SLICE, length, ALLOW_EMPTY);

  detach (first, others, src, ALLOW_EMPTY);

  while (remainder > 0)
  {
    vb current = alloc (&_, T_LINK);

    detach (current, others, REDUCE_SLICE); remainder = length (others);

    if (compare (first, current) == st->rq_greater_or_lesser)
    {
      attach (right, &current);
    }
    else 
    {
      attach (left, &current);
    }
  },
  {
    int remainder = length (others)
  }

  if (length > 0, { length = _ (src) })
  {
    vb left_sorted = alloc (&_, T_LIST, length (left));
    vb right_sorted = alloc (&_, T_LIST, length (right));

    attach (dest, &left_sorted, &first, &right_sorted),
    {
      sort (right_sorted, right, st, compare),      
      {
        sort (left_sorted, left, st, compare)
      }
    };
  }
}
/
{
  free (&others,
        &right,
        &left);
}

