Listx.h

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