BeckyPlugin library  2.4
class library for Becky! plugin
CrossLink.h
1 #ifndef _CROSS_H
2 #define _CROSS_H
3 //==================================================================================
4 // Chain cros link template class
5 // Programmed by you-chi@fsinet.or.jp
6 // Copyright (C) 2001-2003 by you-chi@fsinet.or.jp
7 // All rights reserved.
8 //==================================================================================
9 //
10 
11 class SAddressBook;
12 namespace CLink
13 {
14 
16  template<class T> class SCrossLink
17  {
18  protected:
23 
24  T Data;
25 
26  public:
30  SCrossLink(T& _Item, SCrossLink<T> *_Parent = NULL)
31  {
32  Parent = _Parent;
33  Child = NULL;
34  Next = NULL;
35  Prev = NULL;
36  Data = _Item;
37  }
38 
41  {
42  // 破棄手順は子供→兄弟の順番
43  if (Child != NULL)
44  {
45  delete Child;
46  }
47  if (Next != NULL)
48  {
49  delete Next;
50  }
51  }
54  const T& operator *()
55  {
56  return Data;
57  }
61  {
62  return Parent;
63  }
67  {
68  return Child;
69  }
73  {
74  return Prev;
75  }
79  {
80  return Next;
81  }
82 
86  SCrossLink<T> *Add(T& _Item)
87  {
88  if (Child != NULL)
89  {
90  return Child->Connect(_Item);
91  }
92  else
93  {
94  return Chain(_Item);
95  }
96  }
97 
99  void Delete()
100  {
101  // 兄弟リンクからの削除
102  if (Prev != NULL)
103  {
104  Prev->Next = Next;
105  }
106  if (Next != NULL)
107  {
108  Next->Prev = Prev;
109  }
110 
111  // 親子リンクからの削除(親子関係は1:多の関係)
112  if (Parent != NULL)
113  {
114  if (Parent->Child == this)
115  {
116  // 親の直下の子供の場合にだけ変更する必要がある。
117  // 親子関係の更新は、リスト構造によって変更する必要があるのかも・・・
118  Parent->Child = Child; // ( Next == NULL ) ? Child : Next;
119  }
120  }
121  Parent = NULL;
122  Prev = Next = NULL;
123 
124  // ※子供がいる場合には削除してしまいますので注意が必要です。
125  delete this;
126  }
127 
131  SCrossLink<T> *Chain(T& _Item)
132  {
133  SCrossLink<T> *target = this;
134 
135  while (target->Child != NULL)
136  {
137  target = target->Child;
138  }
139 
140  return target->Child = new SCrossLink<T>(_Item, target);
141  }
142 
147  {
148  SCrossLink<T> *elder = new SCrossLink<T>(_Item, this);
149  if (Child != NULL)
150  {
151  Child->Parent = elder;
152  }
153  return Child = elder;
154  }
155 
160  {
161  SCrossLink<T> *target = this;
162 
163  while (target->Next != NULL)
164  {
165  target = target->Next;
166  }
167 
168  SCrossLink<T> *item = new SCrossLink<T>(_Item, Parent);
169  target->Next = item;
170  item->Prev = target;
171 
172  return item;
173  }
174 
179  {
180  SCrossLink<T> *item = new SCrossLink<T>(_Item, Parent);
181 
182  if (Prev != NULL)
183  {
184  Prev->Next = item;
185  }
186  item->Prev = Prev;
187  Prev = item;
188  item->Next = this;
189 
190  return item;
191  }
192 
194  typedef bool(*FSCrossLinkTracer)(void *_User, SCrossLink<T> *_Object);
195 
201  bool TraceChain(bool _Nesting, void *_User, FSCrossLinkTracer _EachTrace)
202  {
203  SCrossLink<T> *node = this;
204  if (node != 0)
205  {
206  if (_EachTrace(_User, node) == false)
207  {
208  return false;
209  }
210  if ((_Nesting == true) && (node->Child != NULL))
211  {
212  if (node->Child->TraceChain(_Nesting, _User, _EachTrace) == false)
213  {
214  return false;
215  }
216  }
217  if ((_Nesting == true) && (node->Next != NULL))
218  {
219  if (node->Next->TraceConnect(_Nesting, _User, _EachTrace) == false)
220  {
221  return false;
222  }
223  }
224  }
225  return true;
226  }
227 
232  bool BackTraceChain(void *_User, FSCrossLinkTracer _EachTrace)
233  {
234  SCrossLink<T> *node = this;
235  while (node != 0)
236  {
237  if (_EachTrace(_User, node) == false)
238  {
239  return false;
240  }
241 
242  node = node->Parent;
243  }
244  return true;
245  }
246 
252  bool TraceConnect(bool _Nesting, void *_User, FSCrossLinkTracer _EachTrace)
253  {
254  SCrossLink<T> *node = this;
255  while (node != 0)
256  {
257  if (_EachTrace(_User, node) == false)
258  {
259  return false;
260  }
261  if ((_Nesting == true) && (node->Child != NULL))
262  {
263  if (node->Child->TraceChain(_Nesting, _User, _EachTrace) == false)
264  {
265  return false;
266  }
267  }
268 
269  node = node->Next;
270  }
271  return true;
272  }
273 
278  bool BackTraceConnect(void *_User, FSCrossLinkTracer _EachTrace)
279  {
280  SCrossLink<T> *node = this;
281  while (node != 0)
282  {
283  if (_EachTrace(_User, node) == false)
284  {
285  return false;
286  }
287  if (node->Prev != NULL)
288  {
289  if (node->Prev->BackTraceChain(_User, _EachTrace) == false)
290  {
291  return false;
292  }
293  }
294 
295  node = node->Prev;
296  }
297  return true;
298  }
299 
300 #if 0
301  // 兄弟の先頭を取得する
302  SCrossLink<T> *GetElder()
303  {
304  SCrossLink<T> *node = this;
305  while (node->Prev != 0)
306  {
307  node = node->Prev;
308  }
309  return node;
310  }
311 #endif
312 
313  }; // template<class T> class SCrossLink
314 
315 
316 }; // namespace CLink;
317 
318 #endif // _CROSS_H
アドレスブッククラス.
Definition: Addrbook.h:62