TNB Library
TnbList.h
[詳解]
1#pragma once
15#include "TnbPointerHandle.h"
16#include "TnbCollection.h"
17
18
19
20//TNB Library
21namespace TNB
22{
23
24
25
59template<typename TYP, typename ATT = DWORD>
60class CListT : public ICollectionMidT<TYP>
61{
62 DEFSUPER(ICollectionMidT<TYP>);
63
64 #ifndef _TnbDOXYGEN //Document作成用シンボル
66 struct TOne
67 {
68 TOne* pNextOne;
69 ATT attribute;
70 TYP value;
72 TOne(TYP t) : value(t) , attribute(ATT()) , pNextOne(NULL)
73 {
74 }
79 void Delete(void)
80 {
81 if ( pNextOne != NULL )
82 {
83 pNextOne->Delete();
84 delete pNextOne;
85 pNextOne = NULL;
86 }
87 }
88 };
89
95 struct TTop : public TOne, CCopyImpossible
96 {
97 CSyncSection m_syncObj;
98 size_t size;
99 TOne* pLastOne;
101 TTop(void) : TOne(TYP()) , size(0) , pLastOne(NULL) {}
103 ~TTop(void)
104 {
105 TOne::Delete();
106 }
113 TOne* GetPointer(INDEX index) const
114 {
115 const TOne* P = this;
116 for ( INDEX i = index + 1; i > 0; i-- )
117 {
118 if ( P->pNextOne == NULL )
119 {
120 P = NULL;
121 break;
122 }
123 P = P->pNextOne;
124 }
125 return const_cast<TOne*>(P);
126 }
127
132 TOne* GetLastPointer(void)
133 {
134 #ifndef _DEBUG
135 if ( pLastOne != NULL ){ return pLastOne; }
136 #endif
137 TOne* P = this;
138 while ( true )
139 {
140 if ( P->pNextOne == NULL )
141 {
142 break;
143 }
144 P = P->pNextOne;
145 }
146 ASSERTLIB(pLastOne == NULL || pLastOne == P);
147 pLastOne = P;
148 return P;
149 }
150 };
151 #endif
152
153 CPointerHandleT<TTop> m_hpTop;
154 CSyncSection m_syncFunc;
155
157 void m_Separate(void)
158 {
159 m_hpTop->m_syncObj.Lock();
160 if ( m_hpTop.GetReferCount() > 1 )
161 {
162 //新たにメモリ確保
163 TTop* P = new TTop;
164 TOne* pNew = P;
165 //複製
166 TOne* pOld = m_hpTop->pNextOne;
167 loop ( i, GetSize() )
168 {
169 ASSERTLIB(pOld != NULL);
170 pNew->pNextOne = new TOne(pOld->value);
171 pNew->pNextOne->attribute = pOld->attribute;
172 P->size++;
173 P->pLastOne = pNew->pNextOne;
174 //
175 pOld = pOld->pNextOne;
176 pNew = pNew->pNextOne;
177 }
178 //新しくバッファアドレスを指定
179 m_hpTop->m_syncObj.Unlock();
180 m_hpTop = P;
181 }
182 else
183 {
184 m_hpTop->m_syncObj.Unlock();
185 }
186 }
187
188protected:
189
196 virtual const TYP* m_GetConstPointer(INDEX index) const
197 {
198 const TOne* P = m_hpTop->GetPointer(index);
199 return (P == NULL) ? NULL : &(P->value);
200 }
201
208 virtual TYP* m_GetPointer(INDEX index)
209 {
210 m_Separate();
211 TOne* P = m_hpTop->GetPointer(index);
212 return (P == NULL) ? NULL : &(P->value);
213 }
214
215public:
216
223 iterator insert(iterator ite, const TYP& t = TYP())
224 {
225 INDEX index = ite.GetIndex();
226 Insert(index, t);
227 return begin() + index;
228 }
229
234 void push_front(const TYP& t)
235 {
236 Insert(0, t);
237 }
238
239
240 //------------------------
241
242
244 CListT(void) : _super(), m_hpTop(new TTop)
245 {
246 }
247
252 CListT(const CListT& other) : _super(), m_hpTop(other.m_hpTop)
253 {
254 }
255
257 virtual ~CListT(void)
258 {
259 m_hpTop.Null();
260 }
261
267 CListT& operator=(const CListT& other)
268 {
269 m_hpTop = other.m_hpTop;
270 return *this;
271 }
272
281 {
282 EXCLUSIVE2(list, *this);
283 TOne* P = list.GetPointer(0);
284 loop ( i, list.m_hpTop->GetSize() )
285 {
286 ASSERTLIB( P != NULL );
287 VERIFYLIB( Add(P->value, P->attribute) != INVALID_INDEX );
288 P = P->pNextOne;
289 }
290 return *this;
291 }
292
301 virtual bool Lock(DWORD dwTime = INFINITE) const
302 {
303 return m_syncFunc.Lock();
304 }
305
307 virtual void Unlock(void) const
308 {
309 m_syncFunc.Unlock();
310 }
311
316 virtual size_t GetSize(void) const
317 {
318 return m_hpTop->size;
319 }
320
328 virtual INDEX Add(const TYP& t)
329 {
330 return Add(t, ATT());
331 }
332
341 virtual bool Remove(INDEX index)
342 {
343 m_Separate();
344 m_hpTop->m_syncObj.Lock();
345 TOne* P = m_hpTop->GetPointer(index - 1);
346 if ( P == NULL )
347 {
348 m_hpTop->m_syncObj.Unlock();
349 return false;
350 }
351 TOne* pTmp = P->pNextOne;
352 if ( pTmp == NULL )
353 {
354 m_hpTop->m_syncObj.Unlock();
355 return false;
356 }
357 P->pNextOne = pTmp->pNextOne;
358 delete pTmp;
359 m_hpTop->size--;
360 m_hpTop->pLastOne = NULL;
361 m_hpTop->m_syncObj.Unlock();
362 return true;
363 }
364
374 virtual bool Set(INDEX index, const TYP& t)
375 {
376 return Set(index, t, ATT());
377 }
378
386 virtual bool SetEx(INDEX index, const TYP& t)
387 {
388 return SetEx(index, t, ATT());
389 }
390
395 virtual bool RemoveAll(void)
396 {
397 m_hpTop = new TTop;
398 return true;
399 }
400
408 virtual void Swap(INDEX index1, INDEX index2)
409 {
410 if ( index1 == index2 )
411 {
412 return;
413 }
414 EXCLUSIVE(this);
415 m_Separate();
416 TOne* P1 = m_hpTop->GetPointer(index1 - 1);
417 TOne* P2 = m_hpTop->GetPointer(index2 - 1);
418 if ( P1 == NULL || P2 == NULL ){ throw CIndexOutOfBoundsException(); }
419 TOne* P1n = P1->pNextOne;
420 TOne* P2n = P2->pNextOne;
421 if ( P1n == NULL || P2n == NULL ){ throw CIndexOutOfBoundsException(); }
422 TOne** P1nn = &(P1n->pNextOne);
423 TOne** P2nn = &(P2n->pNextOne);
424 //
425 P1->pNextOne = P2n;
426 P2->pNextOne = P1n;
427 TOne* P = *P1nn;
428 *P1nn = *P2nn;
429 *P2nn = P;
430 m_hpTop->pLastOne = NULL;
431 }
432
441 INDEX Add(const TYP& t, const ATT& attribute)
442 {
443 m_Separate();
444 m_hpTop->m_syncObj.Lock();
445 INDEX r = m_hpTop->size;
446 TOne* P = m_hpTop->GetLastPointer();
447 ASSERTLIB(P != NULL);
448 P->pNextOne = new TOne(t);
449 P->pNextOne->attribute = attribute;
450 m_hpTop->size++;
451 m_hpTop->pLastOne = P->pNextOne;
452 m_hpTop->m_syncObj.Unlock();
453 return r;
454 }
455
462 INDEX AddEx(const TYP& t, const ATT& attribute)
463 {
464 EXCLUSIVE(this);
465 return Add(t, attribute);
466 }
467
478 bool Set(INDEX index, const TYP& t, const ATT& attribute)
479 {
480 m_Separate();
481 TOne* P = m_hpTop->GetPointer(index);
482 if ( P == NULL )
483 {
484 return false;
485 }
486 P->value = t;
487 P->attribute = attribute;
488 return true;
489 }
490
499 bool SetEx(INDEX index, const TYP& t, const ATT& attribute)
500 {
501 EXCLUSIVE(this);
502 return Set(index, t, attribute);
503 }
504
511 const ATT& GetAttribute(INDEX index) const
512 {
513 EXCLUSIVE(this);
514 TOne* P = m_hpTop->GetPointer(index);
515 if ( P != NULL )
516 {
517 return P->attribute;
518 }
519 ASSERT1(false, "CListT::GetAttribute", "範囲外のIndex(%d)が指定されました。", index);
521 }
522
532 bool Insert(INDEX index, const TYP& t, const ATT& attribute = ATT())
533 {
534 EXCLUSIVE(this);
535 m_Separate();
536 if ( index == GetSize() )
537 {
538 return Add(t) != INVALID_INDEX;
539 }
540 m_hpTop->m_syncObj.Lock();
541 TOne* P = m_hpTop->GetPointer(index - 1);
542 if ( P == NULL )
543 {
544 m_hpTop->m_syncObj.Unlock();
545 return false;
546 }
547 TOne* pNew = new TOne(t);
548 pNew->attribute = attribute;
549 pNew->pNextOne = P->pNextOne;
550 P->pNextOne = pNew;
551 m_hpTop->size++;
552 m_hpTop->m_syncObj.Unlock();
553 return true;
554 }
555
564 virtual bool SetSize(size_t size)
565 {
566 if ( size == INVALID_SIZE )
567 {
568 return false;
569 }
570 EXCLUSIVE(this);
571 m_hpTop->m_syncObj.Lock();
572 if ( size < m_hpTop->size )
573 {
574 //今より小さく
575 m_Separate();
576 TOne* P = m_hpTop->GetPointer(size - 1);
577 P->Delete();
578 m_hpTop->size = size;
579 m_hpTop->m_syncObj.Unlock();
580 }
581 else if ( size > m_hpTop->size )
582 {
583 //今より大きく
584 INT_PTR l = size - m_hpTop->size;
585 m_Separate();
586 m_hpTop->m_syncObj.Unlock();
587 while ( l-- )
588 {
589 Add(TYP());
590 }
591 }
592 return true;
593 }
594
604 virtual size_t Cull(const IChecker& checker, bool boIsReverse = false)
605 {
606 EXCLUSIVE(this);
607 size_t r = 0;
608 size_t i = 0;
609 while ( i < GetSize() )
610 {
611 if ( ! checker.IsValid(At(i)) ^ boIsReverse )
612 {
613 if ( ! Remove(i) ){ return INVALID_SIZE; }
614 r++;
615 }
616 else
617 {
618 i++;
619 }
620 }
621 return r;
622 }//memo;Listは頭から削除していったほうが高速のため、特別に実装。
623
624 #ifndef _WIN32_WCE
634 size_t CullOnAttribute(typename const IConstCollectionT<ATT>::IChecker& checker, bool boIsReverse = false)
635 {
636 EXCLUSIVE(this);
637 size_t r = 0;
638 if ( ! IsEmpty() )
639 {
640 for ( INDEX i = GetSize() - 1; i >= 0; i-- )
641 {
642 if ( ! checker.IsValid(GetAttribute(i)) ^ boIsReverse )
643 {
644 if ( ! Remove(i) )
645 {
646 return INVALID_SIZE;
647 }
648 r++;
649 }
650 }
651 }
652 return r;
653 }
654 #endif // _WIN32_WCE
655
662 virtual void Serialize(ISerializer& _sr) const
663 {
664 size_t l = GetSize();
665 _sr << l << l;
666 loop ( i, l )
667 {
668 _sr << At(i);
669 _sr << GetAttribute(i);
670 }
671 }
672
679 virtual void Deserialize(const IDeserializer& ds)
680 {
681 size_t l1, l2;
682 ds >> l1 >> l2;
683 if ( l1 != l2 )
684 {
686 }
687 RemoveAll();
688 TYP t;
689 ATT attribute;
690 loop ( i, l1 )
691 {
692 ds >> t;
693 ds >> attribute;
694 Add(t, attribute);
695 }
696 }
697};
698
699
700
707
708
709
710
711}; // TNB
情報群管理関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ポインタハンドル関係のヘッダ
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
INDEX範囲外例外
Definition: TnbException.h:81
パラメータ不正例外
Definition: TnbException.h:159
リスト型情報管理テンプレート
Definition: TnbList.h:61
iterator insert(iterator ite, const TYP &t=TYP())
[反復] 挿入
Definition: TnbList.h:223
bool Insert(INDEX index, const TYP &t, const ATT &attribute=ATT())
[追加] 要素一つ挿入.
Definition: TnbList.h:532
size_t CullOnAttribute(typename const IConstCollectionT< ATT >::IChecker &checker, bool boIsReverse=false)
[削除] 間引き.
Definition: TnbList.h:634
virtual void Swap(INDEX index1, INDEX index2)
[設定] 要素の入れ替え
Definition: TnbList.h:408
INDEX Add(const TYP &t, const ATT &attribute)
[追加] 要素一つ追加
Definition: TnbList.h:441
virtual size_t GetSize(void) const
[取得] 要素数取得
Definition: TnbList.h:316
bool Set(INDEX index, const TYP &t, const ATT &attribute)
[設定] 要素の設定
Definition: TnbList.h:478
virtual size_t Cull(const IChecker &checker, bool boIsReverse=false)
[削除] 間引き.
Definition: TnbList.h:604
virtual void Deserialize(const IDeserializer &ds)
[処理] デシリアライズ
Definition: TnbList.h:679
void push_front(const TYP &t)
[反復] 先頭に挿入
Definition: TnbList.h:234
virtual ~CListT(void)
デストラクタ
Definition: TnbList.h:257
virtual bool Remove(INDEX index)
[削除] 要素一つ削除
Definition: TnbList.h:341
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbList.h:301
CListT(void)
コンストラクタ
Definition: TnbList.h:244
virtual bool SetSize(size_t size)
[操作] サイズ指定
Definition: TnbList.h:564
CListT & operator+=(const CListT &list)
[追加] 追加オペレータ.
Definition: TnbList.h:280
virtual bool RemoveAll(void)
[削除] 全要素削除
Definition: TnbList.h:395
INDEX AddEx(const TYP &t, const ATT &attribute)
[追加] 要素一つ追加
Definition: TnbList.h:462
CListT & operator=(const CListT &other)
[代入] コピーオペレータ
Definition: TnbList.h:267
CListT(const CListT &other)
コピーコンストラクタ
Definition: TnbList.h:252
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加
Definition: TnbList.h:328
virtual void Serialize(ISerializer &_sr) const
[処理] シリアライズ
Definition: TnbList.h:662
bool SetEx(INDEX index, const TYP &t, const ATT &attribute)
[設定] 要素の設定
Definition: TnbList.h:499
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbList.h:307
virtual const TYP * m_GetConstPointer(INDEX index) const
[取得] 要素アドレス取得
Definition: TnbList.h:196
const ATT & GetAttribute(INDEX index) const
[取得] 要素の属性値、取得
Definition: TnbList.h:511
virtual bool SetEx(INDEX index, const TYP &t)
[設定] 要素の設定.
Definition: TnbList.h:386
virtual bool Set(INDEX index, const TYP &t)
[設定] 要素の設定.
Definition: TnbList.h:374
virtual TYP * m_GetPointer(INDEX index)
[取得] 要素アドレス取得
Definition: TnbList.h:208
int GetReferCount(void) const
[取得] 参照数取得.
void Null(void)
[設定] 開放.
Section排他管理クラス
Definition: TnbSync.h:125
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:148
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:155
情報群管理操作インターフェース拡張テンプレート
virtual const TYP & At(INDEX index) const
[取得] 要素の参照取得.
ランダムアクセスイテレータ.
TNB::CListT< BYTE > CByteList
BYTE配列管理クラス
Definition: TnbList.h:706
#define EXCLUSIVE2(CLS1, CLS2)
簡易排他ツイン制御マクロ.
Definition: TnbSync.h:820
#define EXCLUSIVE(CLS)
簡易排他制御マクロ.
Definition: TnbSync.h:788
TNB Library
Definition: TnbDoxyTitle.txt:2
const_iterator begin(void) const
[反復] 先頭const_iterator.
情報群管理インターフェースのチェッカーインターフェース.
virtual bool IsValid(const TYP &T) const =0
[確認] チェック
bool IsEmpty(void) const
[確認] 要素の有無確認.
デシリアライザーインターフェースクラス.
シリアライザーインターフェースクラス.