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