11 typedef __POSITION
* POSITION
;
22 #if (_AFX_PACKING >= 8)
26 static inline CAtlPlex
* Create(
27 _Inout_ CAtlPlex
*& Entry
,
28 _In_
size_t MaxElements
,
29 _In_
size_t ElementSize
34 ATLASSERT(MaxElements
> 0);
35 ATLASSERT(ElementSize
> 0);
37 size_t BufferSize
= sizeof(CAtlPlex
) + (MaxElements
* ElementSize
);
39 void *Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
40 if (Buffer
== NULL
) return NULL
;
42 Block
= static_cast< CAtlPlex
* >(Buffer
);
43 Block
->m_Next
= Entry
;
63 HeapFree(GetProcessHeap(), 0, Block
);
71 class CElementTraitsBase
74 typedef const T
& INARGTYPE
;
75 typedef T
& OUTARGTYPE
;
77 static void CopyElements(
78 _Out_writes_all_(NumElements
) T
* Dest
,
79 _In_reads_(NumElements
) const T
* Source
,
80 _In_
size_t NumElements
)
82 for (size_t i
= 0; i
< NumElements
; i
++)
88 static void RelocateElements(
89 _Out_writes_all_(NumElements
) T
* Dest
,
90 _In_reads_(NumElements
) T
* Source
,
91 _In_
size_t NumElements
)
93 memmove_s(Dest
, NumElements
* sizeof(T
), Source
, NumElements
* sizeof(T
));
98 class CDefaultCompareTraits
101 static bool CompareElements(
105 return (Val1
== Val2
);
108 static int CompareElementsOrdered(
116 else if (Val1
> Val2
)
126 class CDefaultElementTraits
:
127 public CElementTraitsBase
<T
>,
128 public CDefaultCompareTraits
<T
>
134 class CElementTraits
:
135 public CDefaultElementTraits
<T
>
139 template<typename E
, class ETraits
= CElementTraits
<E
> >
143 typedef typename
ETraits::INARGTYPE INARGTYPE
;
146 class CNode
: public __POSITION
154 CNode(INARGTYPE Element
) :
159 /* The CNode class does not support construction by copy */
161 CNode(_In_
const CNode
&);
162 CNode
& operator=(_In_
const CNode
&);
171 size_t m_NumElements
;
173 /* The CAtlList class does not support construction by copy */
175 CAtlList(_In_
const CAtlList
&);
176 CAtlList
& operator=(_In_
const CAtlList
&);
179 CAtlList(_In_ UINT nBlockSize
= 10);
182 size_t GetCount() const;
183 bool IsEmpty() const;
185 POSITION
GetHeadPosition() const;
186 POSITION
GetTailPosition() const;
188 E
& GetNext(_Inout_ POSITION
& pos
);
189 const E
& GetNext(_Inout_ POSITION
& pos
) const;
190 E
& GetPrev(_Inout_ POSITION
& pos
);
191 const E
& GetPrev(_Inout_ POSITION
& pos
) const;
193 E
& GetAt(_In_ POSITION pos
);
194 const E
& GetAt(_In_ POSITION pos
) const;
196 POSITION
AddHead(INARGTYPE element
);
197 POSITION
AddTail(INARGTYPE element
);
202 void RemoveAt(_In_ POSITION pos
);
206 _In_opt_ POSITION posStartAfter
= NULL
) const;
207 POSITION
FindIndex(_In_
size_t iElement
) const;
212 _In_opt_ CNode
* pPrev
,
213 _In_opt_ CNode
* pNext
227 // CAtlist public methods
230 template<typename E
, class ETraits
>
231 CAtlList
< E
, ETraits
>::CAtlList(_In_ UINT nBlockSize
) :
233 m_BlockSize(nBlockSize
),
239 ATLASSERT(nBlockSize
> 0);
242 template<typename E
, class ETraits
>
243 CAtlList
<E
, ETraits
>::~CAtlList(void)
248 template<typename E
, class ETraits
>
249 inline size_t CAtlList
< E
, ETraits
>::GetCount() const
251 return m_NumElements
;
254 template<typename E
, class ETraits
>
255 inline bool CAtlList
< E
, ETraits
>::IsEmpty() const
257 return (m_NumElements
== 0);
260 template<typename E
, class ETraits
>
261 inline POSITION CAtlList
<E
, ETraits
>::GetHeadPosition() const
263 return (POSITION
)m_HeadNode
;
266 template<typename E
, class ETraits
>
267 inline POSITION CAtlList
<E
, ETraits
>::GetTailPosition() const
269 return (POSITION
)m_TailNode
;
272 template<typename E
, class ETraits
>
273 inline E
& CAtlList
< E
, ETraits
>::GetNext(_Inout_ POSITION
& pos
)
275 CNode
* Node
= (CNode
*)pos
;
276 pos
= (POSITION
)Node
->m_Next
;
277 return Node
->m_Element
;
280 template<typename E
, class ETraits
>
281 inline const E
& CAtlList
< E
, ETraits
>::GetNext(_Inout_ POSITION
& pos
) const
283 CNode
* Node
= (CNode
*)pos
;
284 pos
= (POSITION
)Node
->m_Next
;
285 return Node
->m_Element
;
288 template<typename E
, class ETraits
>
289 inline E
& CAtlList
< E
, ETraits
>::GetPrev(_Inout_ POSITION
& pos
)
291 CNode
* Node
= (CNode
*)pos
;
292 pos
= (POSITION
)Node
->m_Prev
;
293 return Node
->m_Element
;
296 template<typename E
, class ETraits
>
297 inline const E
& CAtlList
< E
, ETraits
>::GetPrev(_Inout_ POSITION
& pos
) const
299 CNode
* Node
= (CNode
*)pos
;
300 pos
= (POSITION
)Node
->m_Prev
;
301 return Node
->m_Element
;
304 template<typename E
, class ETraits
>
305 inline E
& CAtlList
< E
, ETraits
>::GetAt(_In_ POSITION pos
)
307 CNode
* Node
= (CNode
*)pos
;
308 return Node
->m_Element
;
311 template<typename E
, class ETraits
>
312 inline const E
& CAtlList
< E
, ETraits
>::GetAt(_In_ POSITION pos
) const
314 CNode
* Node
= (CNode
*)pos
;
315 return Node
->m_Element
;
318 template<typename E
, class ETraits
>
319 POSITION CAtlList
<E
, ETraits
>::AddHead(INARGTYPE element
)
321 CNode
* Node
= CreateNode(element
, NULL
, m_HeadNode
);
324 m_HeadNode
->m_Prev
= Node
;
332 return (POSITION
)Node
;
335 template<typename E
, class ETraits
>
336 POSITION CAtlList
<E
, ETraits
>::AddTail(INARGTYPE element
)
338 CNode
* Node
= CreateNode(element
, m_TailNode
, NULL
);
341 m_TailNode
->m_Next
= Node
;
349 return (POSITION
)Node
;
352 template<typename E
, class ETraits
>
353 E CAtlList
<E
, ETraits
>::RemoveHead()
355 CNode
* Node
= m_HeadNode
;
356 E
Element(Node
->m_Element
);
358 m_HeadNode
= Node
->m_Next
;
361 m_HeadNode
->m_Prev
= NULL
;
372 template<typename E
, class ETraits
>
373 E CAtlList
<E
, ETraits
>::RemoveTail()
375 CNode
* Node
= m_TailNode
;
376 E
Element(Node
->m_Element
);
378 m_TailNode
= Node
->m_Prev
;
381 m_TailNode
->m_Next
= NULL
;
392 template<typename E
, class ETraits
>
393 void CAtlList
<E
, ETraits
>::RemoveAll()
395 while (m_NumElements
> 0)
397 CNode
* Node
= m_HeadNode
;
398 m_HeadNode
= m_HeadNode
->m_Next
;
413 template<typename E
, class ETraits
>
414 void CAtlList
<E
, ETraits
>::RemoveAt(_In_ POSITION pos
)
416 ATLASSERT(pos
!= NULL
);
418 CNode
* OldNode
= (CNode
*)pos
;
419 if (OldNode
== m_HeadNode
)
421 m_HeadNode
= OldNode
->m_Next
;
425 OldNode
->m_Prev
->m_Next
= OldNode
->m_Next
;
427 if (OldNode
== m_TailNode
)
429 m_TailNode
= OldNode
->m_Prev
;
433 OldNode
->m_Next
->m_Prev
= OldNode
->m_Prev
;
438 template<typename E
, class ETraits
>
439 POSITION CAtlList
< E
, ETraits
>::Find(
441 _In_opt_ POSITION posStartAfter
) const
443 CNode
* Node
= (CNode
*)posStartAfter
;
453 for (; Node
!= NULL
; Node
= Node
->m_Next
)
455 if (ETraits::CompareElements(Node
->m_Element
, element
))
456 return (POSITION
)Node
;
462 template<typename E
, class ETraits
>
463 POSITION CAtlList
< E
, ETraits
>::FindIndex(_In_
size_t iElement
) const
465 if (iElement
>= m_NumElements
)
468 if (m_HeadNode
== NULL
)
471 CNode
* Node
= m_HeadNode
;
472 for (size_t i
= 0; i
< iElement
; i
++)
477 return (POSITION
)Node
;
482 // CAtlist private methods
485 template<typename E
, class ETraits
>
486 typename CAtlList
<E
, ETraits
>::CNode
* CAtlList
<E
, ETraits
>::CreateNode(
488 _In_opt_ CNode
* Prev
,
494 CNode
* NewNode
= m_FreeNode
;
495 CNode
* NextFree
= m_FreeNode
->m_Next
;
497 NewNode
= new CNode(element
);
499 m_FreeNode
= NextFree
;
500 NewNode
->m_Prev
= Prev
;
501 NewNode
->m_Next
= Next
;
507 template<typename E
, class ETraits
>
508 void CAtlList
<E
, ETraits
>::FreeNode(
513 pNode
->m_Next
= m_FreeNode
;
517 if (m_NumElements
== 0)
523 template<typename E
, class ETraits
>
524 typename CAtlList
<E
, ETraits
>::CNode
* CAtlList
< E
, ETraits
>::GetFreeNode()
531 CAtlPlex
* Block
= CAtlPlex::Create(m_Blocks
, m_BlockSize
, sizeof(CNode
));
534 AtlThrowImp(E_OUTOFMEMORY
);
537 CNode
* Node
= (CNode
*)Block
->GetData();
538 Node
+= (m_BlockSize
- 1);
539 for (int i
= m_BlockSize
- 1; i
>= 0; i
--)
541 Node
->m_Next
= m_FreeNode
;