Listx.h

[大目次 | 目次 | 型・クラス・構造体 | マクロ]

大目次

目次

型・クラス・構造体一覧

マクロ一覧


   1|/*************************************************************************
   2|*  1. <<< 単方向リスト構造 (ListX) >>> 
   3|*【情報】
   4|*・作成者:Masanori Toda
   5|*・作成開始日時:Apr.13.1999
   6|**************************************************************************/
   7|
   8|#ifndef __LISTX_H
   9|#define __LISTX_H
  10|
  11| 
  12|/*************************************************************************
  13|*  2. <<< モジュール・プロパティ >>> 
  14|**************************************************************************/
  15|/*----------------------------------------------------------------------
  16|[Module Property]
  17|name = ListX
  18|title = 単方向リスト構造
  19|category =
  20|src = ListX.c
  21|depend = Types
  22|priority =
  23|accord =
  24|----------------------------------------------------------------------*/
  25|
  26|
  27| 
  28|/*************************************************************************
  29|*  3. <<< モジュール設定 >>> 
  30|**************************************************************************/
  31|#ifndef  LISTX_SETTING
  32|#define  LISTX_SETTING
  33|
  34|  #define  LISTX_USE_MALLOC
  35|
  36|#endif
  37|
  38| 
  39|/*************************************************************************
  40|*  4. <<< 優先ヘッダ >>> 
  41|**************************************************************************/
  42|#ifndef USES_PRIORITY_HEADER
  43|/*[START_OF_PRIORITY_HEADER]*/
  44|
  45|#define  USES_LISTX
  46|
  47|typedef struct _ListX  ListX;
  48|typedef void*  ListX_Elem;
  49|typedef struct _ListX_ElemX  ListX_ElemX;
  50|
  51|typedef void** ListX_Builder;
  52|typedef void** ListX_Adder;
  53|
  54|typedef struct _ListX_Plus  ListX_Plus;
  55|typedef void*  ListX_PlusElem;
  56|
  57|typedef struct _ListX_Dic  ListX_Dic;
  58|
  59|/*[END_OF_PRIORITY_HEADER]*/
  60|#endif /* USES_PRIORITY_HEADER */
  61|
  62|
  63|
  64| 
  65|/*-----------------------------------------------------------------*/
  66|/* 5. <<< Interface Area ---------------------------------------- >>> */ 
  67|/*-----------------------------------------------------------------*/
  68|
  69|#ifdef __cplusplus
  70|extern "C" {
  71|#endif
  72|
  73| 
  74|/*************************************************************************
  75|*  6. <<< [ListX] 単方向リスト構造・コンテナ >>> 
  76|*【補足】
  77|*・引数の説明には、要素の型を記述しておいた方がいいでしょう。
  78|*・ListX_Dic は多重継承対応のコンテナ多態(→COOL)です。
  79|**************************************************************************/
  80|struct _ListX {
  81|  void*  first;
  82|};
  83|
  84|void  ListX_init( ListX* );
  85|/*void  ListX_finish2( ListX*, elem_type, Elem_finish ); */
  86|ListX_Builder  ListX_initForBuilder( ListX* );
  87|#ifdef  USES_ARRX
  88| /*void  ListX_init_byAble( ListX*, ArrX_Able*, elem_type );*/
  89| /*void  ListX_init_byArrXBuf( ListX*, ArrX_Buf*, elem_type );*/
  90|#endif
  91|bool  ListX_isEmpty( ListX* );
  92|void  ListX_toEmpty( ListX* );
  93|/* void  ListX_toEmptyFinish( ListX*, elem_type, Elem_finish ); */
  94|/* void  ListX_toEmptyDelete( ListX*, elem_type, Elem_finish ); */
  95|/* void  ListX_toEmptyOfsDelete( ListX*, elem_type, elem_inherit, Elem_finish ); */
  96|void  ListX_addFirst( ListX*, ListX_Elem* );
  97|void  ListX_addLast( ListX*, ListX_Elem* );
  98|void  ListX_insert( ListX*, ListX_Elem* pos, ListX_Elem* ins );
  99|void  ListX_move( ListX*, ListX_Elem* pos, ListX_Elem* moving );
 100|void  ListX_moveStep( ListX*, ListX_Elem* moving, int plus );
 101|void  ListX_moveSet( ListX*, ListX_Elem* from_start, ListX_Elem* from_endNext,
 102|  ListX_Elem* to );
 103|/* elem_type*  ListX_addFirstMalloc( ListX*, elem_type ); */
 104|/* elem_type*  ListX_addLastMalloc( ListX*, elem_type ); */
 105|/* elem_type*  ListX_insertMalloc( ListX*, pos, elem_type ); */
 106|void  ListX_remove( ListX*, ListX_Elem* );
 107|void  ListX_remove2( ListX*, ListX_Elem*, ListX_Adder* );
 108|void  ListX_removeFree( ListX*, ListX_Elem* );
 109|/* void  ListX_removeDelete( ListX*, ListX_Elem*, elem_type_finish ); */
 110|/* void  ListX_reverse( ListX*, elem_type ); */
 111|/* elem_type*  ListX_getFirst( ListX*, elem_type ); */
 112|/* elem_type*  ListX_getLast( ListX*, elem_type ); */
 113|/* elem_type*  ListX_get( ListX*, int i, elem_type ); */
 114|int       ListX_getI( ListX*, ListX_Elem* );
 115|/* int    ListX_getN( ListX*, elem_type ); */
 116|/* elem_type*  ListX_getPrev( ListX*, elem_type*, elem_type ); */
 117|
 118|/* ListX_search_s( ListX*, Offset_Key*, const char* kword, elem_type ); */
 119|/* ListX_searchOfs_s( ListX*, Offset_Key*, const char* kword, elem_type,
 120|     elem_inherit ); */
 121|/*    ListX_forEach( ListX*, elem_type**, elem_type ); */
 122|/*    ListX_forEachFree( ListX*, elem_type**, elem_type, elem_type** work, _free ); */
 123|
 124|/* void  ListX_printElem( ListX*, elem_type, const char* title ); */
 125|
 126|#ifdef  USES_SYM
 127|  bool  ListX_doLoopFunc( Sym_Ref* container, Sym_Ref* elem );
 128|  void  ListX_doReadMemb( Sym_Ref* obj, char* name, Sym_Ref* ret );
 129|  extern  Sym_Struct*  ListX_registSymStruct( Sym* );
 130|  extern  Sym_Struct   ListX_symStruct;
 131|  #define  ListX_SymElem_new( container_type, elem_type )  Offset_init(elem_type, inherit_ListX_Elem)
 132|  #define  ListX_SymElem_delete  NULL
 133|#endif
 134|
 135|/* 内部用 */
 136|#ifdef  USES_ARRX
 137|void  ListX_init_byAble_imp( ListX*, ArrX_Able*, Offset list_elem,
 138|  Offset able_elem, int elem_size );
 139|void  ListX_init_byArrXBuf_imp( ListX*, ArrX_Buf*, Offset elem_list,
 140|  int elem_size );
 141|#endif
 142|#ifdef  USES_INF
 143|void  ListX_toEmptyDelete_imp( ListX*, Offset elem_offset,
 144|  Inf_FinishFunc Elem_finish );
 145|#endif
 146|void  ListX_insert_imp( ListX*, void* pos, void* ins, Offset ofs );
 147|#ifdef LISTX_USE_MALLOC
 148| void*  ListX_addFirstMalloc_imp( ListX*, Offset elem_offset, int size );
 149| void*  ListX_insertMalloc_imp( ListX*, void* pos, Offset elem_offset, int size );
 150|#endif
 151|void  ListX_move_imp( ListX*, void* pos, void* moving, Offset elem_offset );
 152|void  ListX_moveStep_imp( ListX*, void* moving, Offset elem_offset, int plus );
 153|void  ListX_moveSet_imp( ListX*, void* from_start, void* from_endNext,
 154|  void* to, Offset elem_offset );
 155|void  ListX_remove_imp( ListX*, void* elem, Offset ofs );
 156|void  ListX_reverse_imp( ListX*, Offset ofs );
 157|void* ListX_getLast_imp( ListX*, Offset elem_offset );
 158|void* ListX_get_imp( ListX*, int i, Offset elem_offset );
 159|int   ListX_getI_imp( ListX*, void* elem, Offset elem_offset );
 160|int   ListX_getN_imp( ListX*, Offset elem_offset );
 161|void* ListX_getPrev_imp( ListX*, void* elem, Offset elem_offset );
 162|void* ListX_search_s_imp( ListX*, Offset_Key* key, const char* kword,
 163|  Offset elem_offset );
 164|void  ListX_printElem_imp( ListX*, Offset elem_offset, const char* title );
 165|
 166| 
 167|/*************************************************************************
 168|*  7. <<< [ListX_Elem] 単方向リスト構造・要素(抽象クラス) >>> 
 169|*【補足】
 170|*・多重継承的な委譲に対応しています。
 171|*・inherit_ListX_Elem は、ListX_Builder 等が初期化します。
 172|*  それ以外のメンバ変数を初期化してください。
 173|*・複数のリストに同時に所属することはできません。
 174|*  そのときは、ListX_PlusElem を使用します。
 175|*・リスト要素は、すべて同じ型である必要があります。
 176|**************************************************************************/
 177|void  ListX_Elem_insertNext( ListX_Elem*, ListX_Elem* );
 178|ListX_Elem*  ListX_Elem_getNext( ListX_Elem* );
 179|/* type*  ListX_Elem_getNextT( ListX_Elem*, type ); */
 180|#ifdef  USES_ARRX
 181|/*ListX_Elem*  ListX_Elem_allocNext( ListX_Elem*, ArrX_Buf*, elem_type );*/
 182|#endif
 183|/* ListX_Elem_forEachFrom( ListX_Elem*, elem_type**, elem_type ); */
 184|
 185| 
 186|/*************************************************************************
 187|*  8. <<< [ListX_ElemX] 単方向リスト構造・ポインタリストの要素 >>> 
 188|**************************************************************************/
 189|struct _ListX_ElemX {
 190|  ListX_Elem  inherit_ListX_Elem;
 191|  void*  p;
 192|};
 193|
 194|/* type*  ListX_ElemX_refP( ListX_ElemX*, type ); */
 195| 
 196|/*************************************************************************
 197|*  9. <<< [ListX_Builder] 単方向リスト構造・構築子 >>> 
 198|*【補足】
 199|*・コンテナを構築するときに使用します。
 200|*・構築子は、ListX_initForBuilder 関数を用いて初期化します。
 201|*・ツリー構造を構築するときは、それぞれのノードごとに構築子を用意します。
 202|*【内部補足】
 203|*・内容は、ListX または、inherit_ListX_Elem のアドレスです。
 204|**************************************************************************/
 205|void  ListX_Builder_add( ListX_Builder*, ListX_Elem* );
 206|void  ListX_Builder_add2( ListX_Builder*, void* elem, Offset elem_list );
 207|#ifdef  USES_ARRX
 208| /* ListX_Elem*  ListX_Builder_alloc( ListX_Builder*, ArrX_Buf*, type ); */
 209|#endif
 210|void  ListX_Builder_finish( ListX_Builder* );
 211|
 212|
 213| 
 214|/*************************************************************************
 215|*  10. <<< [ListX_Adder] 単方向リスト構造・末尾追加子 >>> 
 216|*【補足】
 217|*・ListX_Elem_insertNext で代用できるので、廃止になるかもしれません。
 218|*・コンテナをリストの末尾に追加していくときに使用します。
 219|*  先頭に追加するときは ListX_addFirst を使用してください。
 220|*・構築子は、ListX_initForAdder 関数を用いて初期化します。
 221|*・ListX_remove で最後の要素を削除したときは、動作不定になります。
 222|*  ListX_remove2 を使用してください。
 223|*【例】
 224|*・ListX_Adder ArrX_Buf を用いてリスト構造を追加します
 225|*    ListX        list;
 226|*    ListX_Adder  p;
 227|*    ArrX_Buf*    buf;
 228|*
 229|*    ListX_init( &list );
 230|*    ListX_Adder_init( &p, &list );
 231|*    ListX_Adder_add( &p, ArrX_Buf_alloc(&buf, Elem), Elem );
 232|*【内部補足】
 233|*・内容は、ListX または、inherit_ListX_Elem のアドレスです。
 234|**************************************************************************/
 235|#ifdef  USES_OFFSET
 236|
 237|void  ListX_Adder_init( ListX_Adder*, ListX* );
 238|/* void  ListX_Adder_add( ListX_Adder*, elem ); */
 239|
 240|#endif
 241|
 242| 
 243|/*************************************************************************
 244|*  11. <<< [ListX_Plus] 単方向リスト構造・追加リスト用・コンテナ >>> 
 245|*【補足】
 246|*・複数のリストに同時に所属するときに使用する、追加用リスト・コンテナです。
 247|*・要素の型は、ListX_PlusElem 型の説明を参照してください。
 248|*・リスト要素は、すべて同じ型である必要があります。
 249|*・引数の説明には、要素の型と ListX_PlusElem 型の要素メンバ名を記述して
 250|*  おいた方がいいでしょう。
 251|*・ListX_Dic は重複継承対応のコンテナ多態(→COOL)です。
 252|**************************************************************************/
 253|#ifdef  USES_OFFSET
 254|
 255|struct _ListX_Plus {
 256|  void*  first;
 257|  Offset  next;    /* ListX_PlusElem 型のメンバ変数へのオフセット */
 258|};
 259|/* void  ListX_Plus_init( ListX_Plus*, elem_type, elem_member_name );*/
 260|#ifdef  USES_ARRX
 261| /*void  ListX_Plus_init_byAble( ListX_Plus*, ArrX_Able*, elem_type,
 262|     member_name );*/
 263|#endif
 264|   void  ListX_Plus_toEmpty( ListX_Plus* );
 265|/* void  ListX_Plus_addFirst( ListX_Plus*, elem_type* );*/
 266|/* void  ListX_Plus_addLast( ListX_Plus*, elem_type* );*/
 267|/* void  ListX_Plus_insert( ListX_Plus*, elem_type* pos, elem_type* ins );*/
 268|/* void  ListX_Plus_insertNext( ListX_Plus*, elem_type* pos, elem_type* ins );*/
 269|/* void  ListX_Plus_remove( ListX_Plus*, elem_type* );*/
 270|/* void  ListX_Plus_reverse( ListX_Plus*, type ); */
 271|/* type* ListX_Plus_getFirst( ListX_Plus*, elem_type ); */
 272|/* elem_type*  ListX_Plus_getNext( ListX_Plus*, elem_type* elem, elem_type ); */
 273|/* type* ListX_Plus_get( ListX_Plus*, int i, elem_type ); */
 274|/* int   ListX_Plus_getN( ListX_Plus*, elem_type );*/
 275|/*       ListX_Plus_forEach( ListX_Plus*, type**, elem_type ); */
 276|
 277|
 278|#endif /* USES_OFFSET */
 279|
 280| 
 281|/*************************************************************************
 282|*  12. <<< [ListX_PlusElem] 単方向リスト構造・追加リスト用・要素のメンバ >>> 
 283|*【補足】
 284|*・複数のリストに同時に所属するときに、リスト要素のメンバ変数に使用します。
 285|*・リスト要素の構造体に ListX_PlusElem 型のメンバ変数を追加します。
 286|*  変数名は任意で構いません。ただし、変数名は、ListX_Plus_init 関数で
 287|*  指定するので注意してください。
 288|*・ListX_Elem_insertNext に相当するマクロは、ListX_Plus_insertNext です。
 289|*【例】
 290|* typedef  struct _Data {
 291|*   ListX_Elem  inherit_ListX_Elem;
 292|*   ListX_PlusElem  forXContainer;
 293|*   int  data;
 294|* } Data;
 295|*
 296|* void  func()
 297|* {
 298|*   ListX_Plus_init( xlist, Data, forXContainer );
 299|* }
 300|**************************************************************************/
 301|
 302| 
 303|/***********************************************************************
 304|*  13. <<< [ListX_Dic] ハッシュテーブルを用いた辞書(ヒープ使用) >>> 
 305|*【補足】
 306|*・ListX_Dic のヒープ版です。ヒープが許す限り辞書を大きくできます。
 307|*・ListX_Dic はコンテナ多態(→COOL)です。
 308|************************************************************************/
 309|#if defined(USES_INF) && defined(USES_ARRX) && defined(USES_STRX) && defined(USES_STDPLUS)
 310|struct _ListX_Dic {
 311|  ArrX   table;     /* ハッシュテーブル, ListX_Plus 型, ヒープ所有 */
 312|  int    width;     /* ハッシュテーブルの幅 */
 313|  Offset_Key  key;   /* キー */
 314|  StrX_HashFunc  hash;  /* ハッシュ関数 */
 315|};
 316|
 317|/* void   ListX_Dic_init( ListX_Dic*, int width, elem_type, Offset_Key* key,
 318|  StrX_HashFunc hash ); */
 319|/* void   ListX_Dic_toEmpty( ListX_Dic*, elem_type, Inf_FinishFunc finish ); */
 320|/* void   ListX_Dic_finish( ListX_Dic*, elem_type, Inf_FinishFunc finish ); */
 321|/* elem_type*  ListX_Dic_search( ListX_Dic*, const char* kword, elem_type ); */
 322|/* elem_type*  ListX_Dic_searchNext( ListX_Dic*, elem_type* prev, elem_type ); */
 323|/* elem_type*  ListX_Dic_alloc( ListX_Dic*, const char* kword, elem_type ); */
 324|int   ListX_Dic_getN( ListX_Dic* );
 325|void  ListX_Dic_print( ListX_Dic*, const char* title );
 326|
 327|/* 以下は内部用 */
 328|void  ListX_Dic_init_imp( ListX_Dic*, int width, Offset_Key* key,
 329|  StrX_HashFunc hash, Offset ofsElem );
 330|void   ListX_Dic_finish_imp( ListX_Dic*, Offset elem_offset,
 331|  /* Inf_FinishFunc */ void* Elem_finish );
 332|void*  ListX_Dic_search_imp( ListX_Dic*, const char* kword, Offset ofsElem );
 333|void*  ListX_Dic_searchNext_imp( ListX_Dic*, void* prev, Offset ofsElem );
 334|void*  ListX_Dic_alloc_imp( ListX_Dic*, const char* kword,
 335|  Offset ofsElem, size_t elem_size );
 336|
 337|#endif
 338| 
 339|#ifdef __cplusplus
 340|}
 341|#endif
 342|
 343|/*-----------------------------------------------------------------*/
 344|/* 14. <<< Mapping Area ------------------------------------------ >>> */ 
 345|/*-----------------------------------------------------------------*/
 346|
 347|
 348| 
 349|/*-----------------------------------------------------------------------*/
 350|/*  15. <<<< ◆(ListX) 単方向リスト構造・コンテナ >>>> */ 
 351|/*-----------------------------------------------------------------------*/
 352|
 353|
 354| 
 355|/*************************************************************************
 356|*  15-1. <<< [ListX_init] 空のリストに初期化する >>> 
 357|*【補足】
 358|*・初期値としてリスト要素を入れる場合は、ListX_initForBuilder を
 359|*  用いると高速になります。
 360|*【型】
 361|*・void  ListX_init( ListX* );
 362|**************************************************************************/
 363|#define  ListX_init( this ) \
 364|  (this)->first = NULL
 365|
 366| 
 367|/*************************************************************************
 368|*  15-2. <<< [ListX_finish2] 要素も含めて後始末する >>> 
 369|*【引数】
 370|*  ・ListX*  this;                   単方向リスト
 371|*  ・elem_inherit;                   ListX_Elem 型スーパークラス・メンバ変数名
 372|*  ・Inf_FinishFunc  Elem_finish;    要素の後始末(削除)関数(NULL可)
 373|*【補足】
 374|*・ListX_addFirstMalloc など malloc を使用した要素追加関数を使用したときのみ、
 375|*  本マクロを使って後始末する必要があります。
 376|**************************************************************************/
 377|#ifdef LISTX_USE_MALLOC
 378|#define  ListX_finish2( this, elem_type, Elem_finish ) \
 379|  ListX_toEmptyDelete_imp( this, Offset_init( elem_type, inherit_ListX_Elem ), \
 380|   (Inf_FinishFunc) Elem_finish )
 381|#endif
 382| 
 383|/*************************************************************************
 384|*  15-3. <<< [ListX_initForBuilder] 構築子を用いて初期化を開始する >>> 
 385|*【補足】
 386|*・本マクロを呼び出しても、構築子に対して ListX_Builder_finish マクロを
 387|*  呼び出すまでリストの初期化が完了していないので、それまでは ListX_...
 388|*  のマクロは使用しないでください。
 389|*【型】
 390|*・ListX_Builder  ListX_initForBuilder( ListX* );
 391|**************************************************************************/
 392|#define   ListX_initForBuilder( this ) \
 393|  (&(this)->first)
 394|
 395| 
 396|/*************************************************************************
 397|*  15-4. <<< [ListX_init_byAble] ArrX_Able 配列から初期化する >>> 
 398|*【補足】
 399|*・ArrX_Able 型の配列から有効な要素を要素番号順にリストにします。
 400|*・要素は、ArrX_AbleElem ListX_Elem から静的多重継承します。
 401|*【型】
 402|*・void  ListX_init_byAble( ListX*, ArrX_Able*, elem_type );
 403|**************************************************************************/
 404|#ifdef  USES_ARRX
 405|#define  ListX_init_byAble( list, able, elem_type ) \
 406|  ListX_init_byAble_imp( list, able, \
 407|    Offset_init( elem_type, inherit_ListX_Elem ), \
 408|    Offset_init( elem_type, inherit_ArrX_AbleElem ), \
 409|    sizeof( elem_type ) )
 410|#endif
 411|
 412| 
 413|/*************************************************************************
 414|*  15-5. <<< [ListX_init_byArrXBuf] ArrX_Buf 配列から初期化する >>> 
 415|*【補足】
 416|*・ArrX_Buf 型の配列から有効な要素を要素番号順にリストにします。
 417|*【型】
 418|*・void  ListX_init_byArrXBuf( ListX*, ArrX_Buf*, elem_type );
 419|**************************************************************************/
 420|#ifdef  USES_ARRX
 421|#define  ListX_init_byArrXBuf( list, buf, elem_type ) \
 422|  ListX_init_byArrXBuf_imp( list, buf, \
 423|    Offset_init( elem_type, inherit_ListX_Elem ), \
 424|    sizeof( elem_type ) )
 425|#endif
 426|
 427| 
 428|/*************************************************************************
 429|*  15-6. <<< [ListX_isEmpty] リストが空かどうかを返す >>> 
 430|*【型】
 431|*・bool  ListX_isEmpty( ListX* );
 432|**************************************************************************/
 433|#define  ListX_isEmpty( this ) \
 434|  ( (this)->first == NULL )
 435|
 436| 
 437|/*************************************************************************
 438|*  15-7. <<< [ListX_toEmpty] 空のリストにする >>> 
 439|*【型】
 440|*・void  ListX_toEmpty( ListX* );
 441|**************************************************************************/
 442|#define  ListX_toEmpty( this ) \
 443|  (this)->first = NULL
 444|
 445| 
 446|/*************************************************************************
 447|*  15-8. <<< [ListX_toEmptyFinish] 全要素に後始末関数を呼び出しながら空のリストにする >>> 
 448|*【引数】
 449|*  ・ListX*  this;   単方向リスト
 450|*  ・type;           要素の型
 451|*  ・type_finish;    要素の後始末(削除)関数(型は、void  type_delete( type* ); )
 452|*【補足】
 453|*・本関数は、全要素に StdPlus_delete を呼び出しません。
 454|**************************************************************************/
 455|#define  ListX_toEmptyFinish( this, type, type_finish ) \
 456|  { \
 457|    type*  pp;  type*  work; \
 458|    for ( ListX_forEachFree( this, &pp, type, &(work), (Inf_FinishFunc)(type_finish) ) ); \
 459|    ListX_toEmpty( this ); \
 460|  }
 461| 
 462|/*************************************************************************
 463|*  15-9. <<< [ListX_toEmptyDelete] 全要素に後始末関数を呼び出しながら空のリストにする >>> 
 464|*  15-10. <<< [ListX_toEmptyOfsDelete] 全要素に後始末関数を呼び出しながら空のリストにする(Offset使用) >>>
 465|*【引数】
 466|*  ・ListX*  this;                   単方向リスト
 467|*  ・elem_inherit;                   ListX_Elem 型スーパークラス・メンバ変数名
 468|*  ・Inf_FinishFunc  Elem_finish;    要素の後始末(削除)関数(NULL可)
 469|*【補足】
 470|*・本関数は、全要素に StdPlus_delete を呼び出すことと同じ効果があります。
 471|**************************************************************************/
 472|#define  ListX_toEmptyDelete( this, elem_type, Elem_finish ) \
 473|  ListX_toEmptyDelete_imp( this, Offset_init( elem_type, inherit_ListX_Elem ), \
 474|   (Inf_FinishFunc) Elem_finish )
 475|
 476|#define  ListX_toEmptyOfsDelete( this, elem_type, elem_inherit, Elem_finish ) \
 477|  ListX_toEmptyDelete_imp( this, Offset_init( elem_type, elem_inherit ), \
 478|   (Inf_FinishFunc) Elem_finish )
 479|
 480|
 481|
 482| 
 483|/*************************************************************************
 484|*  15-11. <<< [ListX_addFirst] リストの先頭に要素を追加する >>> 
 485|*  15-12. <<< [ListX_addFirstMalloc] malloc してリストの先頭に要素を追加する >>>
 486|*【補足】
 487|*・malloc で確保した領域は ListX_toEmptyDelete を使用して開放してください。
 488|*【型】
 489|*・void  ListX_addFirst( ListX*, ListX_Elem* );
 490|*・elem_type*  ListX_addFirstMalloc( ListX*, elem_type );
 491|**************************************************************************/
 492|#define  ListX_addFirst( this, elem ) \
 493|  ListX_addFirst_imp( this, elem, Offset_init2( elem, inherit_ListX_Elem ) )
 494|
 495|#define  ListX_addFirst_imp( this, elem, elem_offset ) \
 496|  ( Offset_ref( elem_offset, elem, ListX_Elem ) = (this)->first, \
 497|    (this)->first = (elem) )
 498|
 499|#ifdef LISTX_USE_MALLOC
 500| #define  ListX_addFirstMalloc( this, type ) \
 501|   ( (type*) ListX_addFirstMalloc_imp( this, \
 502|     Offset_init( type, inherit_ListX_Elem ), sizeof(type) ) )
 503|#endif
 504|
 505| 
 506|/*************************************************************************
 507|*  15-13. <<< [ListX_addLast] リストの末尾に要素を追加する >>> 
 508|*  15-14. <<< [ListX_addLastMalloc] malloc してリストの末尾に要素を追加する >>>
 509|*【補足】
 510|*・内部で末尾の要素を線形検索しています。
 511|*・malloc で確保した領域は ListX_toEmptyDelete を使用して開放してください。
 512|*【型】
 513|*・void  ListX_addLast( ListX*, ListX_Elem* );
 514|*・elem_type*  ListX_addLastMalloc( ListX*, elem_type );
 515|**************************************************************************/
 516|#define  ListX_addLast( this, elem ) \
 517|  ListX_insert_imp( this, NULL, elem, Offset_init2( elem, inherit_ListX_Elem ) )
 518|
 519|
 520|#ifdef LISTX_USE_MALLOC
 521| #define  ListX_addLastMalloc( this, type ) \
 522|  ( (type*) ListX_insertMalloc_imp( \
 523|     this, NULL, Offset_init( type, inherit_ListX_Elem ), sizeof(type) ) )
 524|#endif
 525| 
 526|/*************************************************************************
 527|*  15-15. <<< [ListX_insert] 指定の位置にリスト要素を追加する >>> 
 528|*  15-16. <<< [ListX_insertMalloc] malloc して指定の位置にリスト要素を追加する >>>
 529|*【引数】
 530|*  ・ListX_Elem*  pos;  追加する位置
 531|*  ・ListX_Elem*  ins;  追加する要素
 532|*【補足】
 533|*・リストの末尾に追加するときは、pos=NULL にします。
 534|*・内部で追加する直前の要素を線形検索しています。
 535|*・malloc で確保した領域は ListX_toEmptyDelete を使用して開放してください。
 536|*【型】
 537|*・void  ListX_insert( ListX*, ListX_Elem* pos, ListX_Elem* ins );
 538|*・elem_type*  ListX_insertMalloc( ListX*, ListX_Elem* pos, elem_type );
 539|**************************************************************************/
 540|#define  ListX_insert( this, pos, ins ) \
 541|  ListX_insert_imp( this, pos, ins, Offset_init2( ins, inherit_ListX_Elem ) )
 542|
 543|
 544|#ifdef LISTX_USE_MALLOC
 545| #define  ListX_insertMalloc( this, pos, type ) \
 546|  ( (type*) ListX_insertMalloc_imp( \
 547|     this, pos, Offset_init( type, inherit_ListX_Elem ), sizeof(type) ) )
 548|#endif
 549|
 550|
 551|
 552| 
 553|/*************************************************************************
 554|*  15-17. <<< [ListX_remove] 要素をリストから除外する >>> 
 555|*  15-18. <<< [ListX_removeFree] free して要素をリストから除外する >>>
 556|*  15-19. <<< [ListX_removeDelete] free と後始末をして要素をリストから除外する >>>
 557|*【補足】
 558|*・内部で除外する直前の要素を線形検索しています。
 559|*・elem 引数には、ListX_getFirst などの this のリストに関する関数を
 560|*  使用すると別のリスト要素が free や delete されるので注意してください。
 561|*【型】
 562|*・void  ListX_remove( ListX*, ListX_Elem* );
 563|*・void  ListX_removeDelete( ListX*, ListX_Elem*, Inf_FinishFunc );
 564|**************************************************************************/
 565|#define  ListX_remove( this, elem ) \
 566|  ListX_remove_imp( this, elem, Offset_init2( elem, inherit_ListX_Elem ) )
 567|
 568|#define  ListX_removeFree( this, elem ) \
 569|  ListX_remove_imp( this, elem, Offset_init2( elem, inherit_ListX_Elem ) ), \
 570|  free( elem )
 571|
 572|#define  ListX_removeDelete( this, elem, type_finish ) \
 573|  ListX_remove_imp( this, elem, Offset_init2( elem, inherit_ListX_Elem ) ), \
 574|  StdPlus_delete( elem, type_finish )
 575|
 576| 
 577|/*************************************************************************
 578|*  15-20. <<< [ListX_reverse] リストの順番を逆にする >>> 
 579|*【引数】
 580|*  ・ListX*  this;    単方向リスト構造・コンテナ
 581|**************************************************************************/
 582|#define  ListX_reverse( this, type ) \
 583|  ListX_reverse_imp( this, Offset_init( type, inherit_ListX_Elem ) );
 584|
 585|
 586| 
 587|/*************************************************************************
 588|*  15-21. <<< [ListX_move] 指定した要素のリストの位置を移動する(挿入先指定) >>> 
 589|*【引数】
 590|*  ・ListX*  this;         単方向リスト構造・コンテナ
 591|*  ・ListX_Elem*  pos;     移動する位置(NULL=末尾)
 592|*  ・ListX_Elem*  moving;  移動する要素
 593|**************************************************************************/
 594|#define  ListX_move( this, pos, moving ) \
 595|  ListX_move_imp( this, pos, moving, Offset_init2( moving, inherit_ListX_Elem ) )
 596|
 597| 
 598|/*************************************************************************
 599|*  15-22. <<< [ListX_moveStep] 指定した要素のリストの位置を移動する(相対値指定) >>> 
 600|*【引数】
 601|*  ・ListX*  this;         単方向リスト構造・コンテナ
 602|*  ・ListX_Elem*  moving;  移動する要素
 603|*  ・int  plus;            移動先の番号の相対値
 604|*【補足】
 605|*・plus は、大きすぎたり小さすぎたりしたときは、端に飽和します。
 606|**************************************************************************/
 607|#define  ListX_moveStep( this, moving, plus ) \
 608|  ListX_moveStep_imp( this, moving, Offset_init2( moving, inherit_ListX_Elem ), plus )
 609|
 610| 
 611|/*************************************************************************
 612|*  15-23. <<< [ListX_moveSet] 指定した要素の集合の位置を移動する >>> 
 613|*【引数】
 614|*  ・ListX*  this;         単方向リスト構造・コンテナ
 615|*  ・ListX_Elem*  from_start;    移動する要素集合の開始要素
 616|*  ・ListX_Elem*  from_endNext;  移動する要素集合の最後の次の要素
 617|*  ・ListX_Elem*  to;            移動先の要素
 618|**************************************************************************/
 619|#define  ListX_moveSet( this, from_start, from_endNext, to ) \
 620|  ListX_moveSet_imp( this, from_start, from_endNext, to, \
 621|    Offset_init2( from_start, inherit_ListX_Elem ) )
 622|
 623| 
 624|/*************************************************************************
 625|*  15-24. <<< [ListX_getFirst] リストの先頭の要素を参照する >>> 
 626|*【引数】
 627|*  ・ListX*  this;         単方向リスト構造・コンテナ
 628|*  ・type;    リスト要素の型
 629|*【型】
 630|*・type*  ListX_getFirst( ListX*, type );
 631|**************************************************************************/
 632|#define  ListX_getFirst( this, type ) \
 633|  ((type*)(this)->first)
 634|
 635| 
 636|/*************************************************************************
 637|*  15-25. <<< [ListX_getLast] リストの末尾の要素を参照する >>> 
 638|*【引数】
 639|*  ・ListX*  this;         単方向リスト構造・コンテナ
 640|*  ・type;    リスト要素の型
 641|*【型】
 642|*・type*  ListX_getLast( ListX*, type );
 643|**************************************************************************/
 644|#define  ListX_getLast( this, type ) \
 645|  ((type*)ListX_getLast_imp( this, Offset_init( type, inherit_ListX_Elem ) ) )
 646|
 647| 
 648|/*************************************************************************
 649|*  15-26. <<< [ListX_get] 指定番目の要素を参照する >>> 
 650|*【引数】
 651|*  ・ListX*  this;         単方向リスト構造・コンテナ
 652|*  ・int  i;         要素番号(先頭=0)
 653|*  ・type;           リスト要素の型
 654|*  ・type*  返り値;  要素のアドレス
 655|*【補足】
 656|*・本マクロを使用するたびにリストの先頭から走査していくので、すべての要素を
 657|*  参照する場合は、実行効率が悪くなります。ListX_forEach を使用してください。
 658|*・指定した要素番号 i が大きすぎるとエラーになります。本関数を呼び出す前に
 659|*  ListX_getN 関数を使用してチェックしてください。
 660|*【型】
 661|*・type*  ListX_get( ListX*, int i, type );
 662|**************************************************************************/
 663|#define  ListX_get( this, i, type ) \
 664|  ((type*)ListX_get_imp( this, i, Offset_init( type, inherit_ListX_Elem ) ))
 665|
 666| 
 667|/*************************************************************************
 668|*  15-27. <<< [ListX_getI] 指定要素の要素番号を返す >>> 
 669|*【引数】
 670|*  ・ListX*  this;         単方向リスト構造・コンテナ
 671|*  ・ListX_Elem*  elem;    要素のアドレス
 672|*  ・int  返り値;          要素番号(先頭=0、見つからない=-1)
 673|**************************************************************************/
 674|#define  ListX_getI( this, elem ) \
 675|  ListX_getI_imp( this, elem, Offset_init2( elem, inherit_ListX_Elem ) )
 676|
 677| 
 678|/*************************************************************************
 679|*  15-28. <<< [ListX_getN] 要素数を返す >>> 
 680|*【引数】
 681|*  ・type;           要素の型
 682|*  ・int  返り値;    要素数
 683|*【型】
 684|*・int  ListX_getN( ListX*, type );
 685|**************************************************************************/
 686|#define  ListX_getN( this, type ) \
 687|  ListX_getN_imp( this, Offset_init( type, inherit_ListX_Elem ) )
 688|
 689| 
 690|/*************************************************************************
 691|*  15-29. <<< [ListX_getPrev] リストの直前の要素を返す >>> 
 692|*【引数】
 693|*  ・elem_type* elem;      基準となる要素
 694|*  ・elem_type;            要素の型
 695|*  ・elem_type*  返り値;   リストの直前の要素
 696|*【補足】
 697|*・elem に先頭の要素を指定したときは NULL を返します。
 698|**************************************************************************/
 699|#define  ListX_getPrev( this, elem, elem_type ) \
 700|  ( (elem_type*) ListX_getPrev_imp( this, elem, \
 701|                  Offset_init( elem_type, inherit_ListX_Elem ) ) )
 702|
 703| 
 704|/***********************************************************************
 705|*  15-30. <<< [ListX_search_s] 検索する >>> 
 706|*【引数】
 707|*  ・Offset_Key*  key;   要素のキー情報
 708|*  ・char*  kword;       検索するキー文字列
 709|*  ・elem_type;          要素の型名
 710|*  ・elem_type*  返り値; ヒットした要素のアドレス(NULL=ヒットなし)
 711|************************************************************************/
 712|#define  ListX_search_s( this, key, kword, elem_type ) \
 713|  ( (elem_type*) ListX_search_s_imp( this, key, kword, \
 714|     Offset_init( elem_type, inherit_ListX_Elem ) ) )
 715|
 716|
 717|/***********************************************************************
 718|*  15-31. <<< [ListX_searchOfs_s] 検索する >>>
 719|*【引数】
 720|*  ・Offset_Key*  key;   要素のキー情報
 721|*  ・char*  kword;       検索するキー文字列
 722|*  ・elem_type;          要素の型名
 723|*  ・elem_inherit;       要素の ListX_Elem クラス・メンバ変数
 724|*  ・elem_type*  返り値; ヒットした要素のアドレス(NULL=ヒットなし)
 725|************************************************************************/
 726|#define  ListX_searchOfs_s( this, key, kword, elem_type, elem_inherit ) \
 727|  ( (elem_type*) ListX_search_s_imp( this, key, kword, \
 728|     Offset_init( elem_type, elem_inherit ) ) )
 729| 
 730|/*************************************************************************
 731|*  15-32. <<< [ListX_forEach] リストを走査する >>> 
 732|*【例】
 733|*  ListX*  this;  リスト(コンテナ)
 734|*  Elem*   p;     走査中の要素のアドレス
 735|*
 736|*  for ( ListX_forEach( this, &p, Elem ) );
 737|**************************************************************************/
 738|#define  ListX_forEach( list, pp, elem_type ) \
 739|  *(pp) = (elem_type*)((list)->first);  \
 740|  *(pp) != NULL;  \
 741|  *(pp) = (elem_type*)((elem_type*)*(pp))->inherit_ListX_Elem
 742|
 743| 
 744|/*************************************************************************
 745|*  15-33. <<< [ListX_forEachOfs] リストを走査する >>> 
 746|*  15-34. <<< [ListX_forEachOfs_imp] リストを走査する >>>
 747|*【例】
 748|*  ListX*     this;   リスト(コンテナ)
 749|*  ListX_Elem*   p;   走査中の要素のアドレス(のアドレスを指定)
 750|*  elem_inherit;      要素の ListX_Elem クラス・メンバ変数
 751|*
 752|*  for ( ListX_forEachOfs( this, &p, elem_type, elem_inherit ) );
 753|*  for ( ListX_forEach_imp( this, &p, elem_offset ) );
 754|**************************************************************************/
 755|#define  ListX_forEachOfs( this, pp, elem_type, elem_inherit ) \
 756|  *(pp) = (elem_type*)((this)->first);  \
 757|  *(pp) != NULL;  \
 758|  *(pp) = (elem_type*)(*(pp))->elem_inherit
 759|
 760|
 761|#define  ListX_forEach_imp( this, pp, elem_offset ) \
 762|  *(pp) = (ListX_Elem*)((this)->first);  \
 763|  *(pp) != NULL;  \
 764|  *(pp) = Offset_ref( elem_offset, *(pp), ListX_Elem* )
 765| 
 766|/*************************************************************************
 767|*  15-35. <<< [ListX_forEachFree] リストを走査して要素を free する >>> 
 768|*【補足】
 769|*・リスト要素を削除するときは、ListX_toEmptyDelete を使用してください。
 770|*・内部用です
 771|**************************************************************************/
 772|#define  ListX_forEachFree( this, pp, type, pWork, _free ) \
 773|  *(pp) = (type*)((this)->first);  \
 774|  *(pp) != NULL;  \
 775|  *(pWork)=*(pp), *(pp) = (*(pp))->inherit_ListX_Elem, (_free)(*(pWork))
 776|
 777| 
 778|/*************************************************************************
 779|*  15-36. <<< [ListX_forEachOfsFree] リストを走査して要素を free する(Offset 指定) >>> 
 780|*【補足】
 781|*・ListX_forEachFree マクロの説明を参照してください。
 782|*【例】
 783|*  ListX*  this;         リスト(コンテナ)
 784|*  void*   p;            走査中の要素のアドレス(のアドレスを指定)
 785|*  Offset  ofsElem;      リスト要素の ListX_Elem 型抽象クラスのオフセット
 786|*  void*   work;         ワーク用(ユーザは参照できません)
 787|*  void    free(void*);  free する関数
 788|*
 789|*  for ( ListX_forEachOfsFree( this, &p, ofsElem, &work, free ) );
 790|**************************************************************************/
 791|#define  ListX_forEachOfsFree( this, pp, ofsElem, pWork, _free ) \
 792|  *(pp) = ((this)->first);  \
 793|  *(pp) != NULL;  \
 794|  *(pWork)=*(pp), *(pp) = Offset_ref( ofsElem, *(pp), ListX_Elem ), (_free)(*(pWork))
 795|
 796| 
 797|/*************************************************************************
 798|*  15-37. <<< [ListX_printElem] リストの要素のアドレスを列挙、表示する >>> 
 799|*【引数】
 800|*  ListX*  this;         リスト(コンテナ)
 801|*  type;                 リスト要素の型
 802|*  Offset  elem_offset;  リスト要素の ListX_Elem 型抽象クラスのオフセット
 803|*【型】
 804|* void  ListX_printElem( ListX*, type, const char* title );
 805|**************************************************************************/
 806|#define  ListX_printElem( this, type, title ) \
 807|  ListX_printElem_imp( this, Offset_init( type, inherit_ListX_Elem ), title )
 808|
 809| 
 810|/*-----------------------------------------------------------------------*/
 811|/*  16. <<<< ◆(ListX_Elem) 単方向リスト構造・要素 >>>> */ 
 812|/*-----------------------------------------------------------------------*/
 813|
 814|
 815| 
 816|/*************************************************************************
 817|*  16-1. <<< [ListX_Elem_insertNext] 指定要素の次に要素を追加する >>> 
 818|*【引数】
 819|*  ・ListX_Elem*  sub;     追加する直前の要素
 820|*  ・ListX_Elem*  add;     追加する要素
 821|*  ・ListX_Elem*  返り値;  追加した要素(add と同じ)
 822|*【型】
 823|*・ListX_Elem*  ListX_Elem_insertNext( ListX_Elem*, ListX_Elem* );
 824|**************************************************************************/
 825|#define  ListX_Elem_insertNext( sub, add ) \
 826|( \
 827|  (add)->inherit_ListX_Elem = (sub)->inherit_ListX_Elem, \
 828|  (sub)->inherit_ListX_Elem = (add), \
 829|  (add) \
 830|)
 831|
 832| 
 833|/*************************************************************************
 834|*  16-2. <<< [ListX_Elem_getNext] 次の要素を返す(キャストなし) >>> 
 835|*【引数】
 836|*  ・ListX_Elem*  elem;     基準となる要素
 837|*  ・ListX_Elem*  返り値;   elem の次の要素(NULL=末尾の要素の次)
 838|**************************************************************************/
 839|#define  ListX_Elem_getNext( elem ) \
 840|  (elem)->inherit_ListX_Elem
 841| 
 842|/*************************************************************************
 843|*  16-3. <<< [ListX_Elem_getNextT] 次の要素を返す(型指定あり) >>> 
 844|*【引数】
 845|*  ・type*  elem;     基準となる要素
 846|*  ・type;            要素の型
 847|*  ・type*  返り値;   elem の次の要素(NULL=末尾の要素の次)
 848|**************************************************************************/
 849|#define  ListX_Elem_getNextT( elem, type ) \
 850|  ((type*)(elem)->inherit_ListX_Elem)
 851| 
 852|/*************************************************************************
 853|*  16-4. <<< [ListX_Elem_allocNext] 領域を確保して、指定要素の次に要素を追加する >>> 
 854|*【引数】
 855|*  ・ListX_Elem*  sub;     追加する場所の直前のリスト要素
 856|*  ・ArrX_Buf*    buf;     追加するリスト要素の記憶領域
 857|*  ・type;                 追加するリスト要素の型
 858|*  ・ListX_Elem*  返り値;  追加したリスト要素のアドレス
 859|*【型】
 860|*・ListX_Elem*  ListX_Elem_allocNext( ListX_Elem*, ArrX_Buf*, type );
 861|**************************************************************************/
 862|#ifdef  USES_ARRX
 863|#define  ListX_Elem_allocNext( sub, buf, type ) \
 864|    ( ((type*)(buf)->last)->inherit_ListX_Elem = (sub)->inherit_ListX_Elem, \
 865|      (sub)->inherit_ListX_Elem = ArrX_Buf_alloc( buf, type ) )
 866|#endif
 867|
 868| 
 869|/*************************************************************************
 870|*  16-5. <<< [ListX_Elem_forEachFrom] 指定のリスト要素以降を走査する >>> 
 871|*【引数】
 872|*  ・ListX_Elem*  prevElem;  走査を開始する直前の要素
 873|*  ・elem_type**  pp;        走査中の要素へのポインタのアドレス
 874|*  ・elem_type;              要素の型
 875|**************************************************************************/
 876|#define  ListX_Elem_forEachFrom( prevElem, pp, elem_type ) \
 877|  *(pp) = (elem_type*)((prevElem)->inherit_ListX_Elem);  \
 878|  *(pp) != NULL;  \
 879|  *(pp) = (elem_type*)((elem_type*)*(pp))->inherit_ListX_Elem
 880| 
 881|/*-----------------------------------------------------------------------*/
 882|/*  17. <<<< ◆(ListX_ElemX) 単方向リスト構造・ポインタリストの要素 >>>> */ 
 883|/*-----------------------------------------------------------------------*/
 884|
 885|
 886| 
 887|/*************************************************************************
 888|  17-1. <<< [ListX_ElemX_refP] ポインタを参照する >>> 
 889|【引数】
 890|  ・ListX_ElemX*  this;   単方向リスト構造・ポインタリストの要素
 891|  ・type;                 リスト要素の型(ポインタ型)
 892|  ・type  返り値;         ポインタの参照
 893|【補足】
 894|・参照だけでなく代入もできます。
 895|**************************************************************************/
 896|#define  ListX_ElemX_refP( this, type ) \
 897|  ((type)((this)->p))
 898| 
 899|/*-----------------------------------------------------------------------*/
 900|/*  17-2. <<< ◆(ListX_Builder) 単方向リスト構造・構築子 >>> */ 
 901|/*-----------------------------------------------------------------------*/
 902|
 903|
 904| 
 905|/*************************************************************************
 906|*  17-3. <<< [ListX_Builder_add] リストの末尾に要素を追加する >>> 
 907|*【引数】
 908|*  ・ListX_Builder*  this;    追加する場所の直前のリスト要素
 909|*  ・ListX_Elem*     elem;    追加するリスト要素
 910|*【型】
 911|*・void  ListX_Builder_add( ListX_Builder*, elem );
 912|*【補足】
 913|*・本マクロは、今追加しようとしている直前の要素の inherit_ListX_Elem メンバ変数
 914|*  (先頭の要素の場合は ListX 型のメンバ変数)を初期化しています。
 915|**************************************************************************/
 916|#define  ListX_Builder_add( this, elem ) \
 917|    **(this) = elem, \
 918|    *(this) = &(elem)->inherit_ListX_Elem
 919| 
 920|/*************************************************************************
 921|*  17-4. <<< [ListX_Builder_add2] リストの末尾に要素を追加する(Offset版) >>> 
 922|*【引数】
 923|*  ・ListX_Builder*  this;    追加する場所の直前のリスト要素
 924|*  ・ListX_Elem*     elem;    追加するリスト要素
 925|*  ・inherit_ListX_Elem;      スーパークラスへ委譲する変数
 926|*【型】
 927|*・void  ListX_Builder_add2( ListX_Builder*, elem, inherit_ListX_Elem );
 928|*【補足】
 929|*・本マクロは、今追加しようとしている直前の要素の inherit_ListX_Elem メンバ変数
 930|*  (先頭の要素の場合は ListX 型のメンバ変数)を初期化しています。
 931|**************************************************************************/
 932|#define  ListX_Builder_add2( this, elem, elem_list ) \
 933|  **(this) = (void*)(elem), *(this) = &Offset_ref( elem_list, elem, ListX_Elem )
 934| 
 935|/*************************************************************************
 936|*  17-5. <<< [ListX_Builder_alloc] 領域を確保して、リストの末尾に要素を追加する >>> 
 937|*【引数】
 938|*  ・ListX_Builder*  this;    追加する場所の直前のリスト要素
 939|*  ・ArrX_Buf*       buf;     追加するリスト要素の記憶領域
 940|*  ・type;                    追加するリスト要素の型
 941|*  ・ListX_Elem*     返り値;  追加したリスト要素のアドレス
 942|*【型】
 943|*・ListX_Elem*  ListX_Builder_alloc( ListX_Builder*, ArrX_Buf*, type );
 944|*【補足】
 945|*・本マクロは、今追加しようとしている直前の要素の inherit_ListX_Elem メンバ変数
 946|*  (先頭の要素の場合は ListX 型のメンバ変数)を初期化しています。
 947|**************************************************************************/
 948|#ifdef  USES_ARRX
 949|#define  ListX_Builder_alloc( this, buf, type ) \
 950|    ( **(this) = (buf)->last, \
 951|      *(this) = &((type*)(buf)->last)->inherit_ListX_Elem, \
 952|      ArrX_Buf_alloc( buf, type ) )
 953|#endif
 954|
 955| 
 956|/*************************************************************************
 957|*  17-6. <<< [ListX_Builder_finish] 構築子を後始末して、リストを完成させる >>> 
 958|*【型】
 959|*・void  ListX_Builder_finish( ListX_Builder* );
 960|*【補足】
 961|*・本マクロは、最後に追加した要素の inherit_ListX_Elem メンバ変数を
 962|*  初期化しています。
 963|**************************************************************************/
 964|#define  ListX_Builder_finish( this ) \
 965|    **(this) = NULL
 966|
 967| 
 968|/*-----------------------------------------------------------------------*/
 969|/*  18. <<<< ◆(ListX_Adder) 単方向リスト構造・末尾追加子 >>>> */ 
 970|/*-----------------------------------------------------------------------*/
 971|
 972|
 973| 
 974|/*************************************************************************
 975|*  18-1. <<< [ListX_Adder_init] 初期化する >>> 
 976|*【引数】
 977|*  ・ListX_Adder*  this;   単方向リスト構造・末尾追加子
 978|*  ・ListX*        list;   要素を追加されるリスト・コンテナ
 979|*  ・typeOfElem;           リスト要素の型
 980|*【型】
 981|*・void  ListX_Adder_init( ListX_Adder*, ListX*, typeOfElem );
 982|**************************************************************************/
 983|#ifdef  USES_OFFSET
 984|
 985|#define  ListX_Adder_init( this, list, type ) \
 986|  ListX_Adder_init_imp( this, list, Offset_init( type, inherit_ListX_Elem ) )
 987|
 988|void  ListX_Adder_init_imp( ListX_Adder*, ListX* list, Offset elemOfs );
 989|
 990|#endif
 991| 
 992|/*************************************************************************
 993|*  18-2. <<< [ListX_Adder_add] 末尾にリスト要素を追加する >>> 
 994|*【引数】
 995|*  ・ListX_Adder*  this;    単方向リスト構造・追加子
 996|*  ・ListX_Elem*   elem;    追加するリスト要素
 997|*【型】
 998|*・void  ListX_Adder_add( ListX_Adder*, elem );
 999|*【補足】
1000|*・本マクロは、今追加しようとしている直前の要素の inherit_ListX_Elem メンバ変数
1001|*  (先頭の要素の場合は ListX 型のメンバ変数)を初期化しています。
1002|**************************************************************************/
1003|#ifdef  USES_OFFSET
1004|
1005|#define  ListX_Adder_add( this, elem ) \
1006|    *(this)->first = elem, \
1007|    (this)->first = &(elem)->inherit_ListX_Elem, \
1008|    *(this)->first = NULL
1009|
1010|#endif
1011| 
1012|/*-----------------------------------------------------------------------*/
1013|/*  19. <<<< ◆(ListX_Plus) 単方向リスト構造・追加リスト用・コンテナ >>>> */ 
1014|/*-----------------------------------------------------------------------*/
1015|
1016| 
1017|/*************************************************************************
1018|*  19-1. <<< [ListX_Plus_init] 初期化する(要素は空にする) >>> 
1019|*【引数】
1020|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1021|*  ・elem_type;            要素の型
1022|*  ・elem_member_name;     elem_type 内の ListX_PlusElem 型メンバ変数名
1023|*【補足】
1024|*・リストに追加できる要素は、本マクロで指定した elem_type 型のみに
1025|*  限られます。
1026|**************************************************************************/
1027|#define   ListX_Plus_init( this, elem_type, elem_member_name ) \
1028|  ( (this)->first = NULL, \
1029|    (this)->next = Offset_init( elem_type, elem_member_name ) )
1030|
1031|
1032| 
1033|/*************************************************************************
1034|*  19-2. <<< [ListX_Plus_init2] 初期化する(要素は空にする)(Offset使用) >>> 
1035|*【引数】
1036|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1037|*  ・Offset  ofsPlusElem;  ListX_PlusElem 型メンバ変数のオフセット
1038|*【補足】
1039|*・リストに追加できる要素は、本マクロの ofsPlusElem で指定したものと
1040|*  同じオフセットの型に限られます。
1041|*・ofsPlusElem に ListX_Elem 型のメンバ変数を指定しても構いませんが、
1042|*  そのときは ListX_init が使えます。
1043|**************************************************************************/
1044|#define   ListX_Plus_init2( this, ofsPlusElem ) \
1045|  ( (this)->first = NULL, (this)->next = (ofsPlusElem) )
1046|
1047|
1048| 
1049|/*************************************************************************
1050|*  19-3. <<< [ListX_Plus_init_byAble] ArrX_Able 配列から初期化する >>> 
1051|*【補足】
1052|*・ArrX_Able 型の配列から有効な要素を要素番号順にリストにします。
1053|*・要素は、ArrX_AbleElem ListX_PlusElem から静的多重継承します。
1054|*【型】
1055|*・void  ListX_Plus_init_byAble( ListX_Plus*, ArrX_Able*, elem_type,
1056|*     member_name );
1057|**************************************************************************/
1058|#ifdef  USES_ARRX
1059|#define  ListX_Plus_init_byAble( list, able, elem_type, member_name ) \
1060|  ListX_init_byAble_imp( &(list)->first, able, \
1061|    Offset_init( elem_type, member_name ), \
1062|    Offset_init( elem_type*, inherit_ArrX_AbleElem ), \
1063|    sizeof( elem_type ) ), \
1064|  (list)->next = Offset_init( elem_type, member_name )
1065|#endif
1066|
1067| 
1068|/*************************************************************************
1069|*  19-4. <<< [ListX_Plus_toEmpty] 空のリストにする >>> 
1070|*【型】
1071|*・void  ListX_Plus_toEmpty( ListX_Plus* );
1072|**************************************************************************/
1073|#define  ListX_Plus_toEmpty( this ) \
1074|  (this)->first = NULL
1075|
1076| 
1077|/*************************************************************************
1078|*  19-5. <<< [ListX_Plus_addFirst] リストの先頭に追加する >>> 
1079|*【引数】
1080|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1081|*  ・elem_type*  elem;     要素のアドレス(elem_type は要素の構造体型)
1082|*【型】
1083|*・void  ListX_Plus_addFirst( ListX_Plus*, elem_type* elem );
1084|**************************************************************************/
1085|#define  ListX_Plus_addFirst( this, elem ) \
1086|  ListX_addFirst_imp( this, elem, (this)->next )
1087|
1088|
1089|
1090|
1091| 
1092|/*************************************************************************
1093|*  19-6. <<< [ListX_Plus_addLast] リストの末尾に追加する >>> 
1094|*【引数】
1095|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1096|*  ・elem_type*  elem;     要素のアドレス(elem_type は要素の構造体型)
1097|*【補足】
1098|*・内部で末尾の要素を線形検索しています。
1099|*【型】
1100|*・void  ListX_Plus_addLast( ListX_Plus*, elem_type* elem );
1101|**************************************************************************/
1102|#define  ListX_Plus_addLast( this, elem ) \
1103|  ListX_insert_imp( (ListX*)&(this)->first, NULL, elem, (this)->next )
1104|
1105|
1106| 
1107|/*************************************************************************
1108|*  19-7. <<< [ListX_Plus_insert] 指定要素の位置に要素を追加する >>> 
1109|*【引数】
1110|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1111|*  ・elem_type*  pos;      追加する位置(elem_type は要素の構造体型)
1112|*  ・elem_type*  ins;      追加する要素(elem_type は要素の構造体型)
1113|*【補足】
1114|*・pos とその直前の要素の間に ins を追加します。
1115|*・リストの末尾に追加するときは、pos=NULL にします。
1116|*・内部で追加する直前の要素を線形検索しています。
1117|*【型】
1118|*・void  ListX_Plus_insert( ListX_Plus*, elem_type* pos, elem_type* ins );
1119|**************************************************************************/
1120|#define  ListX_Plus_insert( this, pos, ins ) \
1121|  ListX_insert_imp( (ListX*)&(this)->first, pos, ins, (this)->next )
1122|
1123|
1124|
1125| 
1126|/*************************************************************************
1127|*  19-8. <<< [ListX_Plus_insertNext] 指定要素の次に要素を追加する >>> 
1128|*【引数】
1129|*  ・ListX_Plus*      this;    単方向リスト構造・追加リスト用・コンテナ
1130|*  ・ListX_PlusElem*  pos;     追加する直前の要素
1131|*  ・ListX_PlusElem*  ins;     追加する要素
1132|*【補足】
1133|*・pos とその直後の要素の間に ins を追加します。
1134|*・ListX_Plus_insert に比べ、線形走査しない分だけ高速です。
1135|*【型】
1136|*・void  ListX_Plus_insertNext( ListX_Plus* this, ListX_PlusElem* pos,
1137|*    ListX_PlusElem* ins );
1138|**************************************************************************/
1139|#define  ListX_Plus_insertNext( this, pos, ins ) \
1140|( \
1141|  Offset_ref( (this)->next, ins, void* ) = Offset_ref( (this)->next, pos, void* ), \
1142|  Offset_ref( (this)->next, pos, void* ) = (ins) \
1143|)
1144|
1145| 
1146|/*************************************************************************
1147|*  19-9. <<< [ListX_Plus_remove] リストから指定要素を外す >>> 
1148|*【引数】
1149|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1150|*  ・elem_type*  elem;     外す要素(elem_type は要素の構造体型)
1151|*【補足】
1152|*・内部で除外する直前の要素を線形検索しています。
1153|*【型】
1154|*・void  ListX_Plus_remove( ListX_Plus*, elem_type* elem );
1155|**************************************************************************/
1156|#define  ListX_Plus_remove( this, elem ) \
1157|  ListX_remove_imp( (ListX*)&(this)->first, elem, (this)->next )
1158|
1159|
1160| 
1161|/*************************************************************************
1162|*  19-10. <<< [ListX_Plus_reverse] リストの順番を逆にする >>> 
1163|*【引数】
1164|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1165|**************************************************************************/
1166|#define  ListX_Plus_reverse( this, type ) \
1167|  ListX_reverse_imp( (ListX*)&(this)->first, (this)->next );
1168|
1169| 
1170|/*************************************************************************
1171|*  19-11. <<< [ListX_Plus_getFirst] 先頭の要素を参照する >>> 
1172|*【引数】
1173|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1174|*  ・elem_type;            要素の構造体型
1175|*  ・elem_type*  返り値;   要素のアドレス
1176|*【型】
1177|*・elem_type*  ListX_Plus_getFirst( ListX_Plus*, elem_type );
1178|**************************************************************************/
1179|#define  ListX_Plus_getFirst( this, elem_type ) \
1180|  ( (elem_type*)(this)->first )
1181|
1182|
1183| 
1184|/*************************************************************************
1185|*  19-12. <<< [ListX_Plus_getNext] リストの次の要素を参照する >>> 
1186|*【引数】
1187|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1188|*  ・elem_type*   elem;    基準となる要素
1189|*  ・elem_type;            要素の型
1190|*  ・elem_type*  返り値;   次の要素のアドレス
1191|*【型】
1192|*・elem_type*  ListX_Plus_getNext( ListX_Plus*, elem_type* elem, elem_type );
1193|**************************************************************************/
1194|#define  ListX_Plus_getNext( this, elem, elem_type ) \
1195|  Offset_ref( (this)->next, (elem), elem_type* )
1196|
1197|
1198| 
1199|/*************************************************************************
1200|*  19-13. <<< [ListX_Plus_get] 指定番目の要素を参照する >>> 
1201|*【引数】
1202|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1203|*  ・int  i;               要素番号(先頭=0)
1204|*  ・elem_type;            要素の構造体型
1205|*  ・elem_type*  返り値;   要素のアドレス
1206|*【型】
1207|*・elem_type*  ListX_Plus_get( ListX_Plus*, int i, elem_type );
1208|**************************************************************************/
1209|#define  ListX_Plus_get( this, i, elem_type ) \
1210|  (elem_type*)ListX_get_imp( (ListX*)(this)->first, i, (this)->next )
1211|
1212|
1213|
1214| 
1215|/*************************************************************************
1216|*  19-14. <<< [ListX_Plus_getN] 要素数を返す >>> 
1217|*【引数】
1218|*  ・ListX_Plus*  this;    単方向リスト構造・追加リスト用・コンテナ
1219|*  ・elem_type;            要素の構造体型
1220|*  ・int  返り値;          要素数
1221|*【型】
1222|*・int  ListX_Plus_getN( ListX_Plus*, elem_type );
1223|*【内部補足】
1224|*・elem_type 引数は使用していませんが、ListX_getN との互換性のために
1225|*  引数に入れています。
1226|**************************************************************************/
1227|#define  ListX_Plus_getN( this, elem_type ) \
1228|  ListX_getN_imp( (ListX*)(this), (this)->next )
1229|
1230|
1231| 
1232|/*************************************************************************
1233|*  19-15. <<< [ListX_Plus_forEach] リストを走査する >>> 
1234|*【補足】
1235|*・for 文の中で使用します。
1236|*    ListX*  con;    // コンテナ
1237|*    Elem*   pp;     // 走査中の要素のアドレス
1238|*    for ( ListX_Plus_forEach( &pp, con, Elem ) );
1239|**************************************************************************/
1240|#define  ListX_Plus_forEach( list, pp, elem_type ) \
1241|  *(pp) = (elem_type*)((list)->first);  \
1242|  *(pp) != NULL;  \
1243|  *(pp) = Offset_ref( (list)->next, *(pp), elem_type* )
1244|
1245| 
1246|/*-----------------------------------------------------------------------*/
1247|/*  20. <<<< ◆(ListX_PlusElem) 単方向リスト構造・追加リスト用・要素 >>>> */ 
1248|/*-----------------------------------------------------------------------*/
1249|
1250| 
1251|/*-----------------------------------------------------------------------*/
1252|/*  20-1. <<<< ◆(ListX_Dic) ハッシュテーブルを用いた辞書(ヒープ使用) >>>> */ 
1253|/*-----------------------------------------------------------------------*/
1254|
1255|#if defined(USES_INF) && defined(USES_ARRX) && defined(USES_STRX) && defined(USES_STDPLUS)
1256| 
1257|/***********************************************************************
1258|*  20-1-1. <<< [ListX_Dic_init] 初期化する >>> 
1259|*【引数】
1260|*  ・int  width;            ハッシュテーブルの幅(なるべく素数にします)
1261|*  ・elem_type;             辞書要素の型(ListX_Elem から仮想継承)
1262|*  ・Offset_Key*  key;      キー
1263|*  ・StrX_HashFunc  hash;   ハッシュ関数(StrX_getHash など)
1264|*【補足】
1265|*・辞書要素は、ListX_Elem から多重継承します。
1266|************************************************************************/
1267|#define  ListX_Dic_init( this, width, elem_type, key, hash ) \
1268|  ListX_Dic_init_imp( this, width, key, hash, Offset_init( elem_type, inherit_ListX_Elem ) )
1269|
1270| 
1271|/***********************************************************************
1272|*  20-1-2. <<< [ListX_Dic_finish] 後始末する >>> 
1273|************************************************************************/
1274|#define  ListX_Dic_finish( this, elem_type, Elem_finish ) \
1275|  ListX_Dic_finish_imp( this, Offset_init( elem_type, inherit_ListX_Elem ), \
1276|    Elem_finish )
1277|
1278|
1279| 
1280|/***********************************************************************
1281|*  20-1-3. <<< [ListX_Dic_toEmpty] 要素を空にする >>> 
1282|************************************************************************/
1283|#define  ListX_Dic_toEmpty( this, elem_type, Elem_finish ) \
1284|  ListX_Dic_toEmpty_imp( this, Offset_init( elem_type, inherit_ListX_Elem ), \
1285|    Elem_finish )
1286|
1287|
1288| 
1289|/***********************************************************************
1290|*  20-1-4. <<< [ListX_Dic_search] 検索する >>> 
1291|*【引数】
1292|*  ・char*  kword;         検索するキー文字列
1293|*  ・elem_type;            辞書要素の型
1294|*  ・elem_type*  返り値;   ヒットした辞書要素のアドレス(NULL=ヒットなし)
1295|************************************************************************/
1296|#define  ListX_Dic_search( this, kword, elem_type ) \
1297|  ( (elem_type*)ListX_Dic_search_imp( this, kword, \
1298|    Offset_init( elem_type, inherit_ListX_Elem ) ) )
1299|
1300|
1301| 
1302|/***********************************************************************
1303|*  20-1-5. <<< [ListX_Dic_searchNext] 次にヒットする辞書要素を検索する >>> 
1304|*【引数】
1305|*  ・elem_type*  prev;     前回ヒットした辞書要素
1306|*  ・elem_type;            辞書要素の型
1307|*  ・elem_type*  返り値;   ヒットした辞書要素のアドレス(NULL=ヒットなし)
1308|************************************************************************/
1309|#define  ListX_Dic_searchNext( this, prev, elem_type ) \
1310|  ( (elem_type*)ListX_Dic_searchNext_imp( this, prev, \
1311|    Offset_init( elem_type, inherit_ListX_Elem ) ) )
1312|
1313|
1314| 
1315|/**************************************************************************
1316|*  20-1-6. <<< [ListX_Dic_alloc] 指定したキーワードの辞書項目の領域を確保する >>> 
1317|*【引数】
1318|*  ・char*  kword;         キーワード
1319|*  ・elem_type;            辞書要素の型
1320|*  ・elem_type*  返り値;   確保した領域のアドレス、(NULL=既にある)
1321|*【補足】
1322|*・辞書要素中のキーワード文字列のための文字列領域の確保は本マクロで行いません。
1323|*・キーワード文字列の領域を malloc したときは、ListX_Dic_finish 等で指定する
1324|*  後始末関数にキーワードの文字列領域を free してください。
1325|***************************************************************************/
1326|#define  ListX_Dic_alloc( this, kword, elem_type ) \
1327|  ( (elem_type*)ListX_Dic_alloc_imp( this, kword, \
1328|     Offset_init( elem_type, inherit_ListX_Elem ), sizeof(elem_type) ) )
1329|
1330|
1331| 
1332|#endif  /* ListX_Dic */ 
1333| 
1334|#endif /* __LISTX_H */ 
1335| 
1336|