Pannyx

devel

Request #13

To give you some space to try it out for yourself, first.  Here is a good way how to begin.


~/devel/sleek
% cdq
~/devel/quickie
% pp sandbox_24003_m.c
#include <daejana.h>

static void locate (int_t *, int_t, int_t, int_t *);


static int_t s [] = {
   1, 2, 3, 4, 5,  1, 2, 3, 5, 4,  1, 2, 4, 3, 5,  1, 2, 4, 5, 3,  1, 2, 5, 3, 4,  1, 2, 5, 4, 3,
   1, 3, 2, 4, 5,  1, 3, 2, 5, 4,  1, 3, 4, 2, 5,  1, 3, 4, 5, 2,  1, 3, 5, 2, 4,  1, 3, 5, 4, 2,
   1, 4, 2, 3, 5,  1, 4, 2, 5, 3,  1, 4, 3, 2, 5,  1, 4, 3, 5, 2,  1, 4, 5, 2, 3,  1, 4, 5, 3, 2,
   1, 5, 2, 3, 4,  1, 5, 2, 4, 3,  1, 5, 3, 2, 4,  1, 5, 3, 4, 2,  1, 5, 4, 2, 3,  1, 5, 4, 3, 2,
   2, 1, 3, 4, 5,  2, 1, 3, 5, 4,  2, 1, 4, 3, 5,  2, 1, 4, 5, 3,  2, 1, 5, 3, 4,  2, 1, 5, 4, 3,
   2, 3, 1, 4, 5,  2, 3, 1, 5, 4,  2, 3, 4, 1, 5,  2, 3, 4, 5, 1,  2, 3, 5, 1, 4,  2, 3, 5, 4, 1,
   2, 4, 1, 3, 5,  2, 4, 1, 5, 3,  2, 4, 3, 1, 5,  2, 4, 3, 5, 1,  2, 4, 5, 1, 3,  2, 4, 5, 3, 1,
   2, 5, 1, 3, 4,  2, 5, 1, 4, 3,  2, 5, 3, 1, 4,  2, 5, 3, 4, 1,  2, 5, 4, 1, 3,  2, 5, 4, 3, 1,
   3, 1, 2, 4, 5,  3, 1, 2, 5, 4,  3, 1, 4, 2, 5,  3, 1, 4, 5, 2,  3, 1, 5, 2, 4,  3, 1, 5, 4, 2,
   3, 2, 1, 4, 5,  3, 2, 1, 5, 4,  3, 2, 4, 1, 5,  3, 2, 4, 5, 1,  3, 2, 5, 1, 4,  3, 2, 5, 4, 1,
   3, 4, 1, 2, 5,  3, 4, 1, 5, 2,  3, 4, 2, 1, 5,  3, 4, 2, 5, 1,  3, 4, 5, 1, 2,  3, 4, 5, 2, 1,
   3, 5, 1, 2, 4,  3, 5, 1, 4, 2,  3, 5, 2, 1, 4,  3, 5, 2, 4, 1,  3, 5, 4, 1, 2,  3, 5, 4, 2, 1,
   4, 1, 2, 3, 5,  4, 1, 2, 5, 3,  4, 1, 3, 2, 5,  4, 1, 3, 5, 2,  4, 1, 5, 2, 3,  4, 1, 5, 3, 2,
   4, 2, 1, 3, 5,  4, 2, 1, 5, 3,  4, 2, 3, 1, 5,  4, 2, 3, 5, 1,  4, 2, 5, 1, 3,  4, 2, 5, 3, 1,
   4, 3, 1, 2, 5,  4, 3, 1, 5, 2,  4, 3, 2, 1, 5,  4, 3, 2, 5, 1,  4, 3, 5, 1, 2,  4, 3, 5, 2, 1,
   4, 5, 1, 2, 3,  4, 5, 1, 3, 2,  4, 5, 2, 1, 3,  4, 5, 2, 3, 1,  4, 5, 3, 1, 2,  4, 5, 3, 2, 1,
   5, 1, 2, 3, 4,  5, 1, 2, 4, 3,  5, 1, 3, 2, 4,  5, 1, 3, 4, 2,  5, 1, 4, 2, 3,  5, 1, 4, 3, 2,
   5, 2, 1, 3, 4,  5, 2, 1, 4, 3,  5, 2, 3, 1, 4,  5, 2, 3, 4, 1,  5, 2, 4, 1, 3,  5, 2, 4, 3, 1,
   5, 3, 1, 2, 4,  5, 3, 1, 4, 2,  5, 3, 2, 1, 4,  5, 3, 2, 4, 1,  5, 3, 4, 1, 2,  5, 3, 4, 2, 1,
   5, 4, 1, 2, 3,  5, 4, 1, 3, 2,  5, 4, 2, 1, 3,  5, 4, 2, 3, 1,  5, 4, 3, 1, 2,  5, 4, 3, 2, 1
};


static void
locate (int_t * a, int_t n, int_t t, int_t * r)
{

   …

   * r = n;
   return;

}


int
main (int argc, char * argv [])
{
   int_t j; int_t k; int_t l; int_t n; int_t t;

   error_flag = false;
   printf("\n");

   l = 0;
   while (l < 600) {
      int_t a [5];

      printf("(");
      n = 0;
      while (n < 5) {
         t = s [l + n] * 10;
         locate(a, n, t, & j);
         printf(" %02lld,", t);
         k = n; while (j < k) { a[k] = a [k - 1]; k -= 1; }
         a[j] = t;
         n += 1;
      }
      printf(" ) → ");
      printf("("); k = 0; while (k < 5) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
      l += 5;
   }
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// sandbox_24003_m.c
% cbr sandbox_24003_m

( 10, 20, 30, 40, 50, ) → ( 10, 20, 30, 40, 50, )
( 10, 20, 30, 50, 40, ) → ( 10, 20, 30, 50, 40, )
( 10, 20, 40, 30, 50, ) → ( 10, 20, 40, 30, 50, )
( 10, 20, 40, 50, 30, ) → ( 10, 20, 40, 50, 30, )
( 10, 20, 50, 30, 40, ) → ( 10, 20, 50, 30, 40, )
( 10, 20, 50, 40, 30, ) → ( 10, 20, 50, 40, 30, )
( 10, 30, 20, 40, 50, ) → ( 10, 30, 20, 40, 50, )
                        …
( 50, 30, 40, 20, 10, ) → ( 50, 30, 40, 20, 10, )
( 50, 40, 10, 20, 30, ) → ( 50, 40, 10, 20, 30, )
( 50, 40, 10, 30, 20, ) → ( 50, 40, 10, 30, 20, )
( 50, 40, 20, 10, 30, ) → ( 50, 40, 20, 10, 30, )
( 50, 40, 20, 30, 10, ) → ( 50, 40, 20, 30, 10, )
( 50, 40, 30, 10, 20, ) → ( 50, 40, 30, 10, 20, )
( 50, 40, 30, 20, 10, ) → ( 50, 40, 30, 20, 10, )

%

Now with the locate procs used as such.  Before we move on to implement the varray components.


~/devel/sleek
% cdq
~/devel/quickie
% pp sandbox_24003_m.c
#include <chars.h>
#include <varray_int.h>


static int_t s [] = {
   1, 2, 3, 4, 5,  …
                                                                                …  5, 4, 3, 2, 1
};


int
main (int argc, char * argv [])
{
   int_t j; int_t k; int_t l; int_t n; int_t t;

   error_flag = false;
   printf("\n");

   l = 0;
   while (l < 600) {
      int_t a [5];

      printf("(");
      n = 0;
      while (n < 5) {
         t = s [l + n] * 10;
         int_locate(a, n, t, & j);
         printf(" %02lld,", t);
         k = n; while (j < k) { a[k] = a [k - 1]; k -= 1; }
         a[j] = t;
         n += 1;
      }
      printf(" ) %s ", s_right);
      printf("("); k = 0; while (k < 5) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
      l += 5;
   }
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// sandbox_24003_m.c
% cbr sandbox_24003_m chars ustring varray_int

( 10, 20, 30, 40, 50, ) → ( 10, 20, 30, 40, 50, )
                        …
( 50, 40, 30, 20, 10, ) → ( 10, 20, 30, 40, 50, )

% pp sandbox_24004_m.c
#include <chars.h>
#include <varray_vptr.h>

static int_t c (vptr_t, vptr_t, vptr_n_items_proc_t);


static int_t s [] = {
   1, 2, 3, 4, 5,  …
                                                                                …  5, 4, 3, 2, 1
};

static int_t
c (vptr_t l, vptr_t r, vptr_n_items_proc_t p) {
      return * int_ptr_c( l) - * int_ptr_c( r); }

int
main (int argc, char * argv [])
{
   int_t j; int_t k; int_t l; int_t n; int_t * t;

   error_flag = false;
   printf("\n");

   l = 0;
   while (l < 600) {
      vptr_t a [5];

      printf("(");
      n = 0;
      while (n < 5) {
         t = & s [l + n];
         * t *= 10;
         vptr_locate(a, n, t, c, NULL, & j);
         printf(" %02lld,", * t);
         k = n; while (j < k) { a[k] = a [k - 1]; k -= 1; }
         a[j] = t;
         n += 1;
      }
      printf(" ) %s ", s_right);
      printf("("); k = 0; while (k < 5) { printf(" %02lld,", * int_ptr_c( a[k])); k += 1; } printf(" )\n");
      l += 5;
   }
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// sandbox_24004_m.c
% cbr sandbox_24004_m chars ustring varray_vptr

( 10, 20, 30, 40, 50, ) → ( 10, 20, 30, 40, 50, )
                        …
( 50, 40, 30, 20, 10, ) → ( 10, 20, 30, 40, 50, )

%

Yo, behold…!  And here they are, for what I wanted to have the prime numbers.


~/devel/sleek
% cda
~/devel/proto/aej
% pp ustring.c ustring.h
#define USTRING_C
#include <ustring.h>

static const int_t to_capacity [] = {
   int_c( 0x000000000003),  //              3 [ 0]
   int_c( 0x000000000005),  //              5 [ 1]
   int_c( 0x000000000007),  //              7 [ 2]
   int_c( 0x00000000000d),  //             13 [ 3]
   int_c( 0x000000000013),  //             19 [ 4]
   int_c( 0x00000000001f),  //             31 [ 5]
   int_c( 0x000000000035),  //             53 [ 6]
   int_c( 0x000000000059),  //             89 [ 7]
   int_c( 0x00000000008b),  //            139 [ 8]
   int_c( 0x0000000000e9),  //            233 [ 9]
   int_c( 0x000000000175),  //            373 [10]
   int_c( 0x00000000025f),  //            607 [11]
   int_c( 0x0000000003d7),  //            983 [12]
   int_c( 0x00000000063d),  //           1597 [13]
   int_c( 0x000000000a13),  //           2579 [14]
   int_c( 0x000000001051),  //           4177 [15]
   int_c( 0x000000001a6b),  //           6763 [16]
   int_c( 0x000000002abb),  //          10939 [17]
   int_c( 0x00000000452b),  //          17707 [18]
   int_c( 0x000000006ff1),  //          28657 [19]
   int_c( 0x00000000b50f),  //          46351 [20]
   int_c( 0x000000012509),  //          75017 [21]
   int_c( 0x00000001da23),  //         121379 [22]
   int_c( 0x00000002ff23),  //         196387 [23]
   int_c( 0x00000004d965),  //         317797 [24]
   int_c( 0x00000007d8b5),  //         514229 [25]
   int_c( 0x0000000cb203),  //         832003 [26]
   int_c( 0x000000148ac9),  //        1346249 [27]
   int_c( 0x000000213ceb),  //        2178283 [28]
   int_c( 0x00000035c7d9),  //        3524569 [29]
   int_c( 0x0000005704d3),  //        5702867 [30]
   int_c( 0x0000008cccb3),  //        9227443 [31]
   int_c( 0x000000e3d1a5),  //       14930341 [32]
   int_c( 0x000001709e73),  //       24157811 [33]
   int_c( 0x00000254701d),  //       39088157 [34]
   int_c( 0x000003c50e93),  //       63245971 [35]
   int_c( 0x000006197eab),  //      102334123 [36]
   int_c( 0x000009de8d5b),  //      165580123 [37]
   int_c( 0x00000ff80c35),  //      267914293 [38]
   int_c( 0x000019d699a5),  //      433494437 [39]
   int_c( 0x000029cea5cd),  //      701408717 [40]
   int_c( 0x000043a53f57),  //     1134903127 [41]
   int_c( 0x00006d73e553),  //     1836311891 [42]
   int_c( 0x0000b11924e1),  //     2971215073 [43]
   int_c( 0x00011e8d0a2f),  //     4807526959 [44]
   int_c( 0x0001cfa62f0d),  //     7778742029 [45]
   int_c( 0x0002ee333947),  //    12586268999 [46]
   int_c( 0x0004bdd96867),  //    20365011047 [47]
   int_c( 0x0007ac0ca1cf),  //    32951280079 [48]
   int_c( 0x000c69e60a5f),  //    53316291167 [49]
   int_c( 0x001415f2ac3f),  //    86267571263 [50]
   int_c( 0x00207fd8b6a1),  //   139583862433 [51]
   int_c( 0x00207fd8b6a1),  //   139583862433 [52]
   int_c( 0x003495cb62d3),  //   225851433683 [53]
   int_c( 0x005515a41985),  //   365435296133 [54]
   int_c( 0x0089ab6f7c73),  //   591286729843 [55]
   int_c( 0x00dec113961b),  //   956722026011 [56]
   int_c( 0x01686c8312a1),  //  1548008755873 [57]
   int_c( 0x02472d96a8d9),  //  2504730781913 [58]
   int_c( 0x03af9a19bbd5),  //  4052739537877 [59]
   int_c( 0x05f6c7b064b5),  //  6557470319797 [60]
   int_c( 0x09a661ca209b),  // 10610209857691 [61]
   int_c( 0x0f9d297a8567),  // 17167680177511 [62]
   int_c( 0x19438b44a63d),  // 27777890035261 [63]
// 2**45, 0x200000000000
};

ustring_t
new_ustring (void)
{
   ustring_t v;
   int_t n;

   n = sizeof (ustring_st) + to_capacity[0] * sizeof (uint_t);
   if (( v = malloc(n)) == NULL) { ouch(); return NULL; }

   memset(v, uchar_c( 0x00), n);
   return v;

}

void
delete_ustring (ustring_t * v) {
      free(* v); * v = NULL;
      return; }

int_t
ustring_n_items (ustring_t q) {
      return int_c( q->u & uint_c( 0x1fffffffffff)); }

const uint_t *
ustring_access (ustring_t q) {
      return & q->v [int_c( q->u >> 51 & uint_c( 0x1fff))]; }

void
ustring_enqueue (ustring_t * q, uint_t t)
{
   int_t m;
   int_t u_h; int_t u_m; int_t u_n;
   ustring_t r;

   r = * q;
   u_h = int_c( r->u >> 51 & uint_c( 0x1fff)); u_m = int_c( r->u >> 45 & uint_c( 0x3f)); u_n = int_c( r->u & uint_c( 0x1fffffffffff));
   m = to_capacity[u_m];
   u_n += 1;
   if (u_n == 1) {
      u_h = 1;
   }
   else if (m - 1 < u_n) {
      if (62 < u_m) { ouch("Limit of storage reached!"); return; }

      u_m += 1;
      if (( r = realloc(r, sizeof (ustring_st) + to_capacity[u_m] * sizeof (uint_t))) == NULL) { ouch(); return; }

      * q = r;
   }
   else if (m - 1 < u_h + u_n) {
      memmove(uchar_ptr_c( & r->v [1]), uchar_ptr_c( & r->v [u_h]), (u_n - 1) * sizeof (uint_t));
      u_h = 1;
   }
   r->v [u_h + u_n - 1] = t;
   r->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;
}

void
ustring_dequeue (ustring_t q, uint_t * r)
{
   int_t u_h; int_t u_m; int_t u_n;

   u_h = int_c( q->u >> 51 & uint_c( 0x1fff)); u_m = int_c( q->u >> 45 & uint_c( 0x3f)); u_n = int_c( q->u & uint_c( 0x1fffffffffff));
   if (u_n < 1) { if (!( r == NULL)) { * r = uint_c( 0x8000000000000000); } ouch(); return; }

   if (!( r == NULL)) { * r = q->v[u_h]; }
   u_n -= 1;
   if (uint_c( 0x1ffe) < uint_c( u_h)) {
      memmove(uchar_ptr_c( & q->v [1]), uchar_ptr_c( & q->v [u_h + 1]), u_n * sizeof (uint_t));
      u_h = 1;
   }
   else {
      u_h += 1;
   }
   q->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;

}

void
ustring_unqueue (ustring_t q, uint_t * r)
{
   int_t u_h; int_t u_m; int_t u_n;

   u_h = int_c( q->u >> 51 & uint_c( 0x1fff)); u_m = int_c( q->u >> 45 & uint_c( 0x3f)); u_n = int_c( q->u & uint_c( 0x1fffffffffff));
   if (u_n < 1) { if (!( r == NULL)) { * r = uint_c( 0x8000000000000000); } ouch(); return; }

   u_n -= 1;
   if (!( r == NULL)) { * r = q->v [u_h + u_n]; }
   q->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;

}

void
ustring_requeue (ustring_t * q, uint_t t)
{
   int_t m;
   int_t u_h; int_t u_m; int_t u_n;
   ustring_t r;

   r = * q;
   u_h = int_c( r->u >> 51 & uint_c( 0x1fff)); u_m = int_c( r->u >> 45 & uint_c( 0x3f)); u_n = int_c( r->u & uint_c( 0x1fffffffffff));
   m = to_capacity[u_m];
   u_n += 1;
   if (u_n == 1) {
      u_h = int_min(m - 1, int_c( 0x1ffe));
   }
   else if (m < u_n) {
      if (62 < u_m) { ouch("Limit of storage reached!"); return; }

      u_m += 1; m = to_capacity[u_m];
      if (( r = malloc(sizeof (ustring_st) + m * sizeof (uint_t))) == NULL) { ouch(); return; }

      u_h = int_min(m - u_n, int_c( 0x1ffe));
      memcpy(uchar_ptr_c( & r->v [u_h + 1]), uchar_ptr_c( (* q)->v), (u_n - 1) * sizeof (uint_t));
      * q = r;
   }
   else if (1 < u_h) {
      u_h -= 1;
   }
   else {
      u_h = int_min(m - u_n, int_c( 0x1ffe));
      memmove(uchar_ptr_c( & r->v [u_h + 1]), uchar_ptr_c( & r->v), (u_n - 1) * sizeof (uint_t));
   }
   r->v [u_h] = t;
   r->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;

}

void
ustring_insert (ustring_t * q, int_t j, uint_t t)
{
   int_t h; int_t m;
   int_t u_h; int_t u_m; int_t u_n;
   ustring_t r;

   r = * q;
   u_h = int_c( r->u >> 51 & uint_c( 0x1fff)); u_m = int_c( r->u >> 45 & uint_c( 0x3f)); u_n = int_c( r->u & uint_c( 0x1fffffffffff));
   if (! int_within(0, j, u_n)) { ouch(); return; }

   m = to_capacity[u_m];
   u_n += 1;
   if (u_n == 1) {
      u_h = m / 2;
   }
   else if (m - 1 < u_n) {
      if (62 < u_m) { ouch("Limit of storage reached!"); return; }

      u_m += 1; m = to_capacity[u_m]; h = int_min((m - u_n) / 2, int_c( 0x1ffe));
      if (( r = malloc(sizeof (ustring_st) + m * sizeof (uint_t))) == NULL) { ouch(); return; }

      memcpy(uchar_ptr_c( & r->v [h]),         uchar_ptr_c( & (* q)->v [u_h]),                 j * sizeof (uint_t));
      memcpy(uchar_ptr_c( & r->v [h + j + 1]), uchar_ptr_c( & (* q)->v [u_h + j]), (u_n - 1 - j) * sizeof (uint_t));
      * q = r; u_h = h;
   }
   else if (j < u_n / 2 && u_h == 0) {
      memmove(uchar_ptr_c( & r->v [u_h + j + 1]), uchar_ptr_c( & r->v [u_h + j]), (u_n - 1 - j) * sizeof (uint_t));
   }
   else if (u_n / 2 - 1 < j && m < u_h + u_n) {
      u_h -= 1;
      memmove(uchar_ptr_c( & r->v [u_h]), uchar_ptr_c( & r->v [u_h + 1]), j * sizeof (uint_t));
   }
   else if (j < u_n / 2) {
      u_h -= 1;
      if (0 < j) { memmove(uchar_ptr_c( & r->v [u_h]), uchar_ptr_c( & r->v [u_h + 1]), j * sizeof (uint_t)); }
   }
   else {  // u_n / 2 - 1 < j
      if (j < u_n - 1) { memmove(uchar_ptr_c( & r->v [u_h + j + 1]), uchar_ptr_c( & r->v [u_h + j]), (u_n - 1 - j) * sizeof (uint_t)); }
   }
   r->v [u_h + j] = t;
   r->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;

}

void
ustring_remove (ustring_t q, int_t j, uint_t * r)
{
   int_t u_h; int_t u_m; int_t u_n;

   u_h = int_c( q->u >> 51 & uint_c( 0x1fff)); u_m = int_c( q->u >> 45 & uint_c( 0x3f)); u_n = int_c( q->u & uint_c( 0x1fffffffffff));
   if (u_n < 1 || ! int_within(0, j, u_n - 1)) { if (!( r == NULL)) { * r = uint_c( 0x8000000000000000); } ouch(); return; }

   if (!( r == NULL)) { * r = q->v [u_h + j]; }
   u_n -= 1;
   if (j < u_n / 2) {
      u_h += 1;
      if (0 < j) { memmove(uchar_ptr_c( & q->v [u_h]), uchar_ptr_c( & q->v [u_h - 1]), j * sizeof (uint_t)); }
   }
   else {  // u_n / 2 - 1 < j
      if (j < u_n) { memmove(uchar_ptr_c( & q->v [u_h + j]), uchar_ptr_c( & q->v [u_h + j + 1]), (u_n - j) * sizeof (uint_t)); }
   }
   q->u = uint_c( u_h) << 51 | uint_c( u_m) << 45 | uint_c( u_n);
   return;

}

void
ustring_update (ustring_t q, int_t j, uint_t * r)
{
   int_t u_h; int_t u_n;

   u_h = int_c( q->u >> 51 & uint_c( 0x1fff)); u_n = int_c( q->u & uint_c( 0x1fffffffffff));
   if (u_n < 1 || ! int_within(0, j, u_n - 1)) { ouch(); return; }

   uint_swap(& q->v [u_h + j], r);
   return;

}

// ustring.c
#ifndef USTRING_H
#define USTRING_H
#include <daejana.h>

struct ustring_struct;
typedef struct ustring_struct * ustring_t;
typedef struct ustring_struct {
   uint_t u;
   uint_t v [];
} ustring_st;


#ifndef USTRING_C
#endif

ustring_t new_ustring (void);
void delete_ustring (ustring_t *);

int_t ustring_n_items (ustring_t);
const uint_t * ustring_access (ustring_t);

void ustring_enqueue (ustring_t *, uint_t);
void ustring_dequeue (ustring_t, uint_t *);
void ustring_unqueue (ustring_t, uint_t *);
void ustring_requeue (ustring_t *, uint_t);

void ustring_insert (ustring_t *, int_t, uint_t);

void ustring_remove (ustring_t, int_t, uint_t *);

void ustring_update (ustring_t, int_t, uint_t *);


#endif
// ustring.h
% pp varray_int.c varray_int.h
#include <chars.h>
#include <shuffle.h>
#include <varray_int.h>

void probe_01 (void);
void probe_02 (void);
void probe_03 (void);


static varray_int_t v;


void
probe_01 (void)
{
   int_t k; int_t t;

   k = 0;
   while (k < 3) {
      varray_int_enqueue(v, k);
      k += 1;
   }
   varray_int_dequeue(v, NULL);
   while (k < 6) {
      varray_int_enqueue(v, k);
      k += 1;
   }
   printf("("); while (0 < varray_int_n_items(v)) { varray_int_dequeue(v, & t); printf(" %02lld,", t); } printf(");\n");
   return;

}

void
probe_02 (void)
{
   int_t k; int_t t;

   k = 0;
   while (k < 3) {
      varray_int_requeue(v, k);
      k += 1;
   }
   varray_int_unqueue(v, NULL);
   while (k < 6) {
      varray_int_requeue(v, k);
      k += 1;
   }
   printf("("); while (0 < varray_int_n_items(v)) { varray_int_unqueue(v, & t); printf(" %02lld,", t); } printf(");\n");
   return;

}

void
probe_03 (void)
{
int_t j;
   int_t k; int_t m; int_t n; int_t t;
   const int_t * a; int_t * s;

   n = 8;
   open_shuffle(n, 10, & m); assert(n == m);
   while (!( (s = take()) == NULL)) {
      if ((v = new_varray_int()) == NULL) { goto Exit_L1; }

      printf("(");
      k = 0;
      while (k < n) {
         t = (s[k] + 1) * 10;
         printf(" %02lld,", t);
         varray_int_locate_insert(v, t);
         k += 1;
      }
      printf(" ) %s ", s_right);
      a = varray_int_access(v);
      printf("("); k = 0; while (k < n) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
// printf(" "); k = 0; while (k < n) { printf("    "); k += 1; } printf("     ");
// j = …; varray_int_remove(v, j, & t); printf("("); k = 0; while (k < j) { printf(" %02lld,", a[k]); k += 1; } printf("    "); while (k < n - 1) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
      delete_varray_int(& v);
   }
   close_shuffle();
Exit_L1:
   return;

}

int
main (int argc, char * argv [])
{

   error_flag = false;
   printf("\n");

   if ((v = new_varray_int()) == NULL) { goto Exit_M1; }

   probe_01();
   printf("\n");
   probe_02();
   delete_varray_int(& v);
   printf("\n");
   probe_03();
Exit_M1:
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// varray_int_m.c
% cdm
~/devel/sleek
% pp varray_int_m.c
#include <chars.h>
#include <shuffle.h>
#include <varray_int.h>

void probe_01 (void);
void probe_02 (void);
void probe_03 (void);


static varray_int_t v;


void
probe_01 (void)
{
   int_t k; int_t t;

   k = 0;
   while (k < 3) {
      varray_int_enqueue(v, k);
      k += 1;
   }
   varray_int_dequeue(v, NULL);
   while (k < 6) {
      varray_int_enqueue(v, k);
      k += 1;
   }
   printf("("); while (0 < varray_int_n_items(v)) { varray_int_dequeue(v, & t); printf(" %02lld,", t); } printf(");\n");
   return;

}

void
probe_02 (void)
{
   int_t k; int_t t;

   k = 0;
   while (k < 3) {
      varray_int_requeue(v, k);
      k += 1;
   }
   varray_int_unqueue(v, NULL);
   while (k < 6) {
      varray_int_requeue(v, k);
      k += 1;
   }
   printf("("); while (0 < varray_int_n_items(v)) { varray_int_unqueue(v, & t); printf(" %02lld,", t); } printf(");\n");
   return;

}

void
probe_03 (void)
{
int_t j;
   int_t k; int_t m; int_t n; int_t t;
   const int_t * a; int_t * s;

   n = 8;
   open_shuffle(n, 10, & m); assert(n == m);
   while (!( (s = take()) == NULL)) {
      if ((v = new_varray_int()) == NULL) { goto Exit_L1; }

      printf("(");
      k = 0;
      while (k < n) {
         t = (s[k] + 1) * 10;
         printf(" %02lld,", t);
         varray_int_locate_insert(v, t);
         k += 1;
      }
      printf(" ) %s ", s_right);
      a = varray_int_access(v);
      printf("("); k = 0; while (k < n) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
// printf(" "); k = 0; while (k < n) { printf("    "); k += 1; } printf("     ");
// j = …; varray_int_remove(v, j, & t); printf("("); k = 0; while (k < j) { printf(" %02lld,", a[k]); k += 1; } printf("    "); while (k < n - 1) { printf(" %02lld,", a[k]); k += 1; } printf(" )\n");
      delete_varray_int(& v);
   }
   close_shuffle();
Exit_L1:
   return;

}

int
main (int argc, char * argv [])
{

   error_flag = false;
   printf("\n");

   if ((v = new_varray_int()) == NULL) { goto Exit_M1; }

   probe_01();
   printf("\n");
   probe_02();
   delete_varray_int(& v);
   printf("\n");
   probe_03();
Exit_M1:
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// varray_int_m.c
% cmr varray_int_m chars shuffle ustring varray_int

( 01, 02, 03, 04, 05,);

( 01, 02, 03, 04, 05,);

( 20, 50, 80, 70, 30, 10, 60, 40, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 40, 30, 80, 70, 10, 20, 60, 50, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 10, 70, 30, 40, 60, 80, 50, 20, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 50, 30, 80, 70, 10, 20, 40, 60, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 10, 70, 80, 20, 50, 60, 30, 40, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 50, 60, 40, 20, 30, 80, 10, 70, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 50, 60, 40, 30, 20, 10, 70, 80, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 60, 20, 50, 70, 30, 10, 40, 80, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 50, 60, 40, 30, 20, 80, 10, 70, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )
( 10, 70, 30, 40, 20, 50, 60, 80, ) → ( 10, 20, 30, 40, 50, 60, 70, 80, )

% cdm
~/devel/proto/aej
% pp varray_vptr.c varray_vptr.h
#define VARRAY_VPTR_C
#include <varray_vptr.h>
#include <ustring.h>
struct varray_vptr_struct { ustring_t v; vptr_compare_proc_t c_p; vptr_delete_item_proc_t d_p; };


varray_vptr_t
new_varray_vptr (vptr_compare_proc_t c_p, vptr_delete_item_proc_t d_p)
{
   varray_vptr_t q;

   if (( q = malloc(sizeof (varray_vptr_st))) == NULL) { ouch(); return NULL; }

   q->v = new_ustring();
   q->c_p = c_p;
   q->d_p = d_p;
   return q;

}

void
delete_varray_vptr (varray_vptr_t * r)
{
   int_t n; vptr_t * a; vptr_delete_item_proc_t d_p;

   if (!( (d_p = (* r)->d_p) == NULL)) {
      a = vptr_ptr_c( ustring_access((* r)->v)); n = varray_vptr_n_items(* r);
      while (0 < n) { n -= 1; d_p(& a [n]); }
   }
   delete_ustring(& (* r)->v); free(* r); * r = NULL;
   return;

}

void
delete_vptr_item (vptr_t * r) {
      free(* r); * r = NULL;
      return; }

int_t
varray_vptr_n_items (varray_vptr_t q) {
      return ustring_n_items(q->v); }

const vptr_t *
varray_vptr_access (varray_vptr_t q) {
      return vptr_ptr_c( ustring_access(q->v)); }

void
varray_vptr_enqueue (varray_vptr_t q, vptr_t t) {
      ustring_enqueue(& q->v, uint_c( t));
      return; }

void
varray_vptr_dequeue (varray_vptr_t q, vptr_t * r)
{

   if (!( r == NULL)) {
      ustring_dequeue(q->v, uint_ptr_c( r));
   }
   else {
      vptr_delete_item_proc_t d_p;

      if ((d_p = q->d_p) == NULL) {
         ustring_dequeue(q->v, NULL);
      }
      else {
         vptr_t t;

         ustring_dequeue(q->v, uint_ptr_c( & t));
         d_p(& t);
      }
   }
   return;

}

void
varray_vptr_unqueue (varray_vptr_t q, vptr_t * r)
{

   if (!( r == NULL)) {
      ustring_unqueue(q->v, uint_ptr_c( r));
   }
   else {
      vptr_delete_item_proc_t d_p;

      if ((d_p = q->d_p) == NULL) {
         ustring_unqueue(q->v, NULL);
      }
      else {
         vptr_t t;

         ustring_unqueue(q->v, uint_ptr_c( & t));
         d_p(& t);
      }
   }
   return;

}

void
varray_vptr_requeue (varray_vptr_t q, vptr_t t) {
      ustring_requeue(& q->v, uint_c( t));
      return; }

void
varray_vptr_insert (varray_vptr_t q, int_t j, vptr_t t) {
      ustring_insert(& q->v, j, uint_c( t));
      return; }

void
varray_vptr_locate_insert (varray_vptr_t q, vptr_t t)
{
   int_t j; int_t n;
   const vptr_t * a;

   a = varray_vptr_access(q); n = varray_vptr_n_items(q);
   if (n == 0 || 0 < q->c_p(t, a [n - 1])) {
      j = n;
   }
   else if (q->c_p(t, a[0]) < 0) {
      j = 0;
   }
   else {
      vptr_locate(varray_vptr_access(q), varray_vptr_n_items(q), t, q->c_p, & j);
      if (j < 0) { ouch(); return; }

   }
   varray_vptr_insert(q, j, t);
   return;

}

void
vptr_locate (const vptr_t * a, int_t n, vptr_t t, vptr_compare_proc_t c_p, int_t * r)
{
   int_t c; int_t d; int_t j; int_t m;

   j = 0; d = n;
   while (0 < d) {
      m = d / 2;
      c = c_p(t, a [j + m]);
      if (c < 0) {
         d = m;
      }
      else if (0 < c) {
         d -= m + 1;
         j += m + 1;
      }
      else {
         * r = j + m - n; return;

      }
   }
   * r = j;
   return;

}

void
varray_vptr_remove (varray_vptr_t q, int_t j, vptr_t * r)
{

   if (j == 0) { ustring_dequeue(q->v, uint_ptr_c( r)); return; }
   if (j == varray_vptr_n_items(q) - 1) { ustring_unqueue(q->v, uint_ptr_c( r)); return; }
   if (!( r == NULL)) {
      ustring_remove(q->v, j, uint_ptr_c( r));
   }
   else {
      vptr_delete_item_proc_t d_p;

      if ((d_p = q->d_p) == NULL) {
         ustring_remove(q->v, j, NULL);
      }
      else {
         vptr_t t;

         ustring_remove(q->v, j, uint_ptr_c( & t));
         d_p(& t);
      }
   }
   return;

}

void
varray_vptr_update (varray_vptr_t q, int_t j, vptr_t t)
{
   vptr_t * r;
   vptr_delete_item_proc_t d_p;

   * r = t;
   ustring_update(q->v, j, uint_ptr_c( r));
   if (!( (d_p = q->d_p) == NULL)) {
      d_p(r);
   }
   return;

}


// varray_vptr.c
#ifndef VARRAY_VPTR_H
#define VARRAY_VPTR_H
#include <daejana.h>

struct varray_vptr_struct;
typedef struct varray_vptr_struct varray_vptr_st, * varray_vptr_t;

typedef int_t (* vptr_compare_proc_t) (vptr_t, vptr_t);
typedef void (* vptr_delete_item_proc_t) (vptr_t *);

#ifndef VARRAY_VPTR_C
#endif

varray_vptr_t new_varray_vptr (vptr_compare_proc_t, vptr_delete_item_proc_t);
void delete_varray_vptr (varray_vptr_t *);
void delete_vptr_item (vptr_t *);

int_t varray_vptr_n_items (varray_vptr_t);
const vptr_t * varray_vptr_access (varray_vptr_t);

void varray_vptr_enqueue (varray_vptr_t, vptr_t);
void varray_vptr_dequeue (varray_vptr_t, vptr_t *);
void varray_vptr_unqueue (varray_vptr_t, vptr_t *);
void varray_vptr_requeue (varray_vptr_t, vptr_t);

void varray_vptr_insert (varray_vptr_t, int_t, vptr_t);
void varray_vptr_locate_insert (varray_vptr_t, vptr_t);
void vptr_locate (const vptr_t *, int_t, vptr_t, vptr_compare_proc_t, int_t *);

void varray_vptr_remove (varray_vptr_t, int_t, vptr_t *);

void varray_vptr_update (varray_vptr_t, int_t, vptr_t);


#endif
// varray_vptr.h
% cdm
~/devel/sleek
% pp varray_vptr_m.c
#include <chars.h>
#include <shuffle.h>
#include <varray_vptr.h>

int_t compare_proc (vptr_t, vptr_t);

void probe_01 (void);
void probe_02 (void);
void probe_03 (void);


static int_t b [5];

static varray_vptr_t v;


int_t
compare_proc (vptr_t l, vptr_t r)
{
   int_t d; int_t k; int_t h; int_t m; int_t n;
   int_t * a; int_t * b;

   m = int_ptr_c( l) [0]; n = int_ptr_c( r) [0]; h = int_min(m, n);
   a = int_ptr_c( & l [1]); b = int_ptr_c( & r [1]);
   k = 0;
   while (k < h) {
      d = a[k] - b[k];
      if (0 < d) { return 1; }
      if (d < 0) { return -1; }
      k += 1;
   }
   if (n < m) { return 1; }
   if (m < n) { return -1; }
   return 0;

}

void
probe_01 (void)
{
   int_t k; int_t * r;

   varray_vptr_enqueue(v, NULL);
   k = 0;
   while (k < 3) {
      varray_vptr_enqueue(v, & b [k]);
      k += 1;
   }
   varray_vptr_dequeue(v, NULL);
   while (k < 5) {
      varray_vptr_enqueue(v, & b [k]);
      k += 1;
   }
// varray_vptr_update(v, …, & b […]);
   printf("("); while (0 < varray_vptr_n_items(v)) { varray_vptr_dequeue(v, vptr_ptr_c( & r)); printf(" %02lld,", * r); } printf(" );\n");
   return;

}

void
probe_02 (void)
{
   int_t k; int_t * r;

   varray_vptr_requeue(v, NULL);
   k = 0;
   while (k < 3) {
      varray_vptr_requeue(v, & b [k]);
      k += 1;
   }
   varray_vptr_unqueue(v, vptr_ptr_c( NULL));
   while (k < 5) {
      varray_vptr_requeue(v, & b [k]);
      k += 1;
   }
// varray_vptr_update(v, …, & b […]);
   printf("("); while (0 < varray_vptr_n_items(v)) { varray_vptr_unqueue(v, vptr_ptr_c( & r)); printf(" %02lld,", * r); } printf(" );\n");
   return;

}

void
probe_03 (void)
{
   int_t j; int_t k; int_t l; int_t m; int_t n;
   const vptr_t * a; int_t * s; int_t * t;

   if ((v = new_varray_vptr(compare_proc, delete_vptr_item)) == NULL) { return; }

   n = 8;
   open_shuffle(n, 10, & m); assert(n == m);
   while (!( (s = take()) == NULL)) {
      n = rand() % m + 1;
      if (( t = malloc((n + 1) * sizeof (int_t))) == NULL) { ouch(); return; }

      t[0] = n; k = 0; while (k < n) { t [k + 1] = (s[k] + 1) * 10; k += 1; }
      printf("("); k = 1; while (k < n + 1) { printf(" %02lld,", t[k]); k += 1; } printf(" )\n");

      vptr_locate(varray_vptr_access(v), varray_vptr_n_items(v), t, compare_proc, & j);
      if (!( j < 0)) {
         varray_vptr_insert(v, j, t);
      }
   }
   close_shuffle();
   a = varray_vptr_access(v);
   printf("  %s\n", s_down);
   l = 0; m = varray_vptr_n_items(v);
   while (l < m) {
      n = int_ptr_c( a[l]) [0]; printf("("); k = 0; while ( k < n) { t = & int_ptr_c( a[l]) [1]; printf(" %02lld,", t[k]); k += 1; } printf(" )\n");
      l += 1;
   }
// printf("\n");
// j = …; varray_vptr_remove(v, j, vptr_c( & t)); a = varray_vptr_access(v); l = 0; m -= 1;
// while (l < j) { n = int_ptr_c( a[l]) [0]; printf("("); k = 0; while ( k < n) { t = & int_ptr_c( a[l]) [1]; printf(" %02lld,", t[k]); k += 1; } printf(" )\n"); l += 1; }
// printf("  %s\n", s_ellipsis);
// while (l < m) { n = int_ptr_c( a[l]) [0]; printf("("); k = 0; while ( k < n) { t = & int_ptr_c( a[l]) [1]; printf(" %02lld,", t[k]); k += 1; } printf(" )\n"); l += 1; }
   delete_varray_vptr(& v);
   return;

}

int
main (int argc, char * argv [])
{
   int_t k;

   error_flag = false;
   printf("\n");

   k = 0; while (k < 5) { b[k] = k + 1; k += 1; }
   if ((v = new_varray_vptr(NULL, NULL)) == NULL) { goto Exit_M1; }

   probe_01();
   printf("\n");
   probe_02();
   delete_varray_vptr(& v);
   printf("\n");
   probe_03();
Exit_M1:
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// varray_vptr_m.c
% cmr varray_vptr_m chars shuffle ustring varray_vptr

( 01, 02, 03, 04, 05, );

( 01, 02, 03, 04, 05, );

( 80, )
( 80, )
( 20, 80, 10, 70, 30, )
( 30, 70, 20, 40, 50, 80, 10, 60, )
( 40, 70, 10, 80, 50, )
( 60, 40, )
( 70, 80, 50, 20, 40, 60, 30, )
( 20, 40, 60, 50, 10, 70, 30, 80, )
( 10, 60, 70, 30, 50, 80, )
( 30, 70, )
  ↓
( 10, 60, 70, 30, 50, 80, )
( 20, 40, 60, 50, 10, 70, 30, 80, )
( 20, 80, 10, 70, 30, )
( 30, 70, )
( 30, 70, 20, 40, 50, 80, 10, 60, )
( 40, 70, 10, 80, 50, )
( 60, 40, )
( 70, 80, 50, 20, 40, 60, 30, )
( 80, )

%