* acl4のページ0003
-(by [[K]], 2026.01.28)

** (1)
 #if (a_Version >= 1)
     #define VecChr              a_VecChr
     #define VecChr_ini          a_VecChr_ini
     #define VecChr_ini4         a_VecChr_ini4
     #define VecChr_din          a_VecChr_din
     #define VecChr_din4         a_VecChr_din4
     #define VecChr_reserve      a_VecChr_reserve
     #define VecChr_resize       a_VecChr_resize
     #define VecChr_resizeDiff   a_VecChr_resizeDiff
     #define VecChr_reserveDiff  a_VecChr_reserveDiff
     #define VecChr_push         a_VecChr_push
     #define VecChr_reserve0     a_VecChr_reserve0
     #define VecChr_align        a_VecChr_align
     #define VecChr_shrink       a_VecChr_shrink
     #define VecChr_pushMem      a_VecChr_pushMem
 #endif
 
 a_class(a_VecChr) {
     char *p;
     intptr_t n, n1;
 };
 
 a_static void a_VecChr_ini(a_VecChr *w) { w->p = NULL; w->n = w->n1 = 0; }
 
 a_static void a_VecChr_ini4(a_VecChr *w0, a_VecChr *w1, a_VecChr *w2, a_VecChr *w3)
 {
     if (w0 != NULL) a_VecChr_ini(w0);
     if (w1 != NULL) a_VecChr_ini(w1);
     if (w2 != NULL) a_VecChr_ini(w2);
     if (w3 != NULL) a_VecChr_ini(w3);
 }
 
 a_static void a_VecChr_din(a_VecChr *w) { a_free(_arg_  w->p, w->n1); }
 
 a_static void a_VecChr_din4(a_VecChr *w0, a_VecChr *w1, a_VecChr *w2, a_VecChr *w3)
 {
     if (w0 != NULL) a_VecChr_din(w0);
     if (w1 != NULL) a_VecChr_din(w1);
     if (w2 != NULL) a_VecChr_din(w2);
     if (w3 != NULL) a_VecChr_din(w3);
 }
 
 a_static void a_VecChr_reserve(a_VecChr *w, intptr_t n)
 {
     if (w->n1 < n) {
         intptr_t n1 = w->n1;
         if (n1 < 16/2) n1 = 16/2;
         do {
             n1 *= 2;
         } while (n1 < n);
         w->p = a_realloc(_arg_  w->p, w->n1, n1);
         w->n1 = n1;
     }
 }
 
 a_static void a_VecChr_resize(_argDef_  a_VecChr *w, intptr_t n)
 {
     #if (a_DbgLv >= 2)
         if (n < 0)
             a_errExit("%s(%d): VecChr_resize: bad size: n=%d", a_fil, a_lin, n);
     #endif
     a_VecChr_reserve(w, n); w->n = n;
 }
 
 a_static void a_VecChr_resizeDiff(_argDef_  a_VecChr *w, intptr_t d)
 {
     #if (a_DbgLv >= 2)
         if (w->n + d < 0)
             a_errExit("%s(%d): a_VecChr_resizeDiff: bad diff: d=%d", a_fil, a_lin, d);
     #endif
     a_VecChr_resize(_arg_  w, w->n + d);
 }
 
 a_static void a_VecChr_reserveDiff(a_VecChr *w, intptr_t d) { a_VecChr_reserve(w, w->n + d); }
 a_static void a_VecChr_push(a_VecChr *w, int c) { a_VecChr_reserveDiff(w, 1); w->p[w->n++] = c; }
 a_static void a_VecChr_reserve0(a_VecChr *w) { a_VecChr_reserveDiff(w, 1); w->p[w->n] = '\0'; }
 
 a_static void a_VecChr_align(_argDef_  a_VecChr *w, intptr_t a)
 {
     #if (a_DbgLv >= 2)
         if (a <= 0 || (a & (a - 1)) != 0)
             a_errExit("%s(%d): VecChr_align: bad align: a=%d", a_fil, a_lin, a);
     #endif
     while ((w->n & (a - 1)) > 0)
         a_VecChr_push(w, '\0');
     while ((w->n & (a - 1)) > 0) {
         a_VecChr_resizeDiff(_arg_  w, 1);
         w->p[w->n - 1] = '\0';
     }
 }
 
 a_static void a_VecChr_shrink(_argDef_  a_VecChr *w, intptr_t r)
 {
     #if (a_DbgLv >= 2)
         if (r < 0)
             a_errExit("%s(%d): VecChr_shrink: bad reserve: r=%d", a_fil, a_lin, r);
     #endif
     w->p = a_realloc(_arg_  w->p, w->n1, w->n + r);
     w->n1 = w->n + r;
 }
 
 a_static void a_VecChr_pushMem(_argDef_  a_VecChr *w, const void *p, intptr_t n)
 {
     if (n > 0) {
         #if (a_DbgLv >= 2)
             if (p == NULL)
                 a_errExit("%s(%d): VecChr_pushMem: error: p=NULL", a_fil, a_lin);
         #endif
         a_VecChr_resizeDiff(_arg_  w, n);
         memcpy(w->p + w->n - n, p, n);
     }
 }

** (2) VecChr
-私の大好きな自動伸長型のchar配列です。C++の vector<char> を意識してクラス名や関数名を整備しました。

-ini (init): 初期化です。
-din (deinit): 解放です。
-ini4, din4: 初期化や解放をたくさんやることがあるので、4個まとめて書けるようにしています。
-reserve: 必要に応じてreallocをして、指定したサイズまで使用可能にします。サイズを縮めることはしません。
-resize: サイズを指定しますが、これは C++ の vector を真似して作っただけで、私はほとんど使いません。
-resizeDiff: resizeを指定するときに、現在のsizeに対しての増分値で指定します。
-reserveDiff: reserveを指定するときに、現在のsizeに対しての増分値で指定します。
-push (push_back): 1バイト追加します。
-reserve0: VecChrで文字列を生成することがよくあります。その時に、末尾に'\0'がないと困ることがあるので、そういう時はこれを使って末尾に'\0'をつけます。この'\0'はsizeにはカウントされません。
-align: バイナリデータを作ったりするときには、アライン機能が欲しくなるので、用意してあります。
-shrink (shrink_to_fit): 現在のsizeに合わせて配列長を縮小します。その際に保持する予約領域の大きさも指定できます。
-pushMem: nバイト追加します。

-ここまでだけでみると、これがなんでそんなに便利なんだ?ってなりますが、次の[[a4_0004]]にVecChrを利用した関数群があります。


** (99) 更新履歴
-2026.01.28(水) 初版。
-2026.01.30(金) VecChr_pushは使わないので削除。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS