25 #include "ndCoreStdafx.h"
28 #include "ndClassAlloc.h"
29 #include "ndContainersAlloc.h"
31 template<
class T,
class allocator = ndContainersAlloc<T> >
45 m_prev->m_next =
this;
49 m_next->m_prev =
this;
61 m_prev->m_next =
this;
65 m_next->m_prev =
this;
77 m_prev->m_next = m_next;
81 m_next->m_prev = m_prev;
87 void AddLast(
ndNode*
const node)
93 void AddFirst(
ndNode*
const node)
119 friend class ndList<T, allocator>;
135 operator ndInt32()
const
137 return m_ptr !=
nullptr;
140 bool operator== (
const Iterator &target)
const
142 return (m_ptr == target.m_ptr) && (m_list == target.m_list);
147 m_ptr = m_list->GetFirst();
152 m_ptr = m_list->GetLast();
155 void Set (
ndNode*
const node)
163 m_ptr = m_ptr->m_next();
166 void operator++ (ndInt32)
169 m_ptr = m_ptr->GetNext();
175 m_ptr = m_ptr->GetPrev();
178 void operator-- (ndInt32)
181 m_ptr = m_ptr->GetPrev();
184 T &operator* ()
const
186 return m_ptr->GetInfo();
206 operator ndInt32()
const;
207 ndInt32 GetCount()
const;
212 ndNode* Append (
const T &element);
215 ndNode* Addtop (
const T &element);
217 void RotateToEnd (
ndNode*
const node);
218 void RotateToBegin (
ndNode*
const node);
219 void InsertAfter (
ndNode*
const root,
ndNode*
const node);
220 void InsertBefore (
ndNode*
const root,
ndNode*
const node);
222 ndNode* Find (
const T &element)
const;
223 ndNode* GetNodeFromInfo (T &m_info)
const;
224 void Remove (
ndNode*
const node);
225 void Remove (
const T &element);
229 void Unlink (
ndNode*
const node);
230 bool SanityCheck ()
const;
232 static void FlushFreeList()
234 allocator::FlushFreeList(
sizeof (
ndNode));
248 template<
class T,
class allocator>
257 template<
class T,
class allocator>
263 template<
class T,
class allocator>
269 template<
class T,
class allocator>
272 return m_first !=
nullptr;
275 template<
class T,
class allocator>
281 template<
class T,
class allocator>
287 template<
class T,
class allocator>
290 ndAssert (node->m_next ==
nullptr);
291 ndAssert (node->m_prev ==
nullptr);
293 if (m_first ==
nullptr)
300 m_last->AddLast (node);
303 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
304 ndAssert (SanityCheck ());
309 template<
class T,
class allocator>
313 if (m_first ==
nullptr)
315 m_first =
new ndNode(
nullptr,
nullptr);
320 m_last =
new ndNode(m_last,
nullptr);
322 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
323 ndAssert (SanityCheck ());
328 template<
class T,
class allocator>
332 if (m_first ==
nullptr)
334 m_first =
new ndNode(element,
nullptr,
nullptr);
339 m_last =
new ndNode(element, m_last,
nullptr);
341 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
342 ndAssert (SanityCheck ());
348 template<
class T,
class allocator>
351 ndAssert (node->m_next ==
nullptr);
352 ndAssert (node->m_prev ==
nullptr);
354 if (m_last ==
nullptr)
361 m_first->AddFirst(node);
364 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
365 ndAssert (SanityCheck ());
370 template<
class T,
class allocator>
374 if (m_last ==
nullptr)
376 m_last =
new ndNode(
nullptr,
nullptr);
381 m_first =
new ndNode(
nullptr, m_first);
383 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
384 ndAssert (SanityCheck ());
389 template<
class T,
class allocator>
393 if (m_last ==
nullptr)
395 m_last =
new ndNode(element,
nullptr,
nullptr);
400 m_first =
new ndNode(element,
nullptr, m_first);
402 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
403 ndAssert (SanityCheck ());
408 template<
class T,
class allocator>
414 if (root->m_next != node)
418 m_first = node->m_next;
422 m_last = node->m_prev;
427 node->m_next = root->m_next;
430 root->m_next->m_prev = node;
434 if (node->m_next ==
nullptr)
440 ndAssert (!m_last->m_next);
442 ndAssert (!m_first->m_prev);
443 ndAssert (SanityCheck ());
448 template<
class T,
class allocator>
454 if (root->m_prev != node)
458 m_last = node->m_prev;
460 if (node == m_first) {
461 m_first = node->m_next;
466 node->m_prev = root->m_prev;
469 root->m_prev->m_next = node;
473 if (node->m_prev ==
nullptr) {
478 ndAssert (!m_first->m_prev);
480 ndAssert (!m_last->m_next);
481 ndAssert (SanityCheck ());
486 template<
class T,
class allocator>
491 if (m_last != m_first)
495 m_first = m_first->GetNext();
498 m_last->AddLast(node);
503 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
504 ndAssert (SanityCheck ());
508 template<
class T,
class allocator>
513 if (m_last != m_first)
517 m_last = m_last->GetPrev();
520 m_first->AddFirst(node);
525 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
526 ndAssert (SanityCheck ());
530 template<
class T,
class allocator>
534 for (node = m_first; node; node = node->GetNext())
536 if (element == node->m_info)
544 template<
class T,
class allocator>
547 ndNode*
const node = (ndNode *) &info;
548 ndInt64 offset = ((
char*) &node->m_info) - ((
char *) node);
549 ndNode*
const retnode = (ndNode *) (((
char *) node) - offset);
551 ndAssert (&retnode->GetInfo () == &info);
555 template<
class T,
class allocator>
558 ndNode *
const node = Find (element);
565 template<
class T,
class allocator>
571 ndAssert (m_count >= 0);
575 m_first = m_first->GetNext();
579 m_last = m_last->GetPrev();
583 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
584 ndAssert (SanityCheck ());
588 template<
class T,
class allocator>
591 m_count += list.m_count;
594 list.m_first->m_prev = m_last;
598 m_last->m_next = list.m_first;
600 m_last = list.m_last;
603 m_first = list.m_first;
607 list.m_last =
nullptr;
608 list.m_first =
nullptr;
609 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
610 ndAssert (SanityCheck ());
614 template<
class T,
class allocator>
621 template<
class T,
class allocator>
624 for (ndNode *node = m_first; node; node = m_first)
627 m_first = node->GetNext();
631 ndAssert (m_count == 0);
636 template<
class T,
class allocator>
641 for (ndNode * node = m_first; node; node = node->GetNext())
644 if (node->GetPrev()) {
645 ndAssert (node->GetPrev() != node->GetNext());
646 if (node->GetPrev()->GetNext() != node)
654 ndAssert (node->GetPrev() != node->GetNext());
655 if (node->GetNext()->GetPrev() != node)
662 if (tCount != m_count)