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|