source: trunk/Common/alax.info/roatlcollections.h @ 155

Last change on this file since 155 was 78, checked in by roman, 10 years ago
  • Property svn:keywords set to Id
File size: 25.3 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2006-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: roatlcollections.h 78 2012-07-24 09:49:20Z roman $
6//
7// A permission to use the source code is granted as long as reference to
8// source website http://alax.info is retained.
9
10#pragma once
11
12#include <atlcoll.h>
13
14////////////////////////////////////////////////////////////
15// CRoIterativeArrayTraitsT
16
17template <typename _Array>
18class CRoIterativeArrayTraitsT
19{
20protected:
21        typedef SIZE_T KEY;
22
23public:
24
25        ////////////////////////////////////////////////////////
26        // CIterator
27
28        class CIterator
29        {
30        public:
31                const _Array* m_pArray;
32                KEY m_nIndex;
33
34        public:
35        // CIterator
36                CIterator(const _Array* pArray) throw() :
37                        m_pArray(pArray),
38                        m_nIndex(0)
39                {
40                        _A(pArray);
41                }
42                BOOL IsValid() const throw()
43                {
44                        return m_nIndex < m_pArray->GetCount();
45                }
46                VOID Next() throw()
47                {
48                        m_nIndex++;
49                }
50                operator KEY () const throw()
51                {
52                        return m_nIndex;
53                }
54        };
55
56        ////////////////////////////////////////////////////////
57        // CReverseIterator
58
59        class CReverseIterator
60        {
61        public:
62                const _Array* m_pArray;
63                KEY m_nIndex;
64
65        public:
66        // CReverseIterator
67                CReverseIterator(const _Array* pArray) throw() :
68                        m_pArray(pArray),
69                        m_nIndex(pArray->GetCount() - 1)
70                {
71                        _A(pArray);
72                }
73                BOOL IsValid() const throw()
74                {
75                        return (SSIZE_T) m_nIndex >= 0;
76                }
77                VOID Next() throw()
78                {
79                        m_nIndex--;
80                }
81                operator KEY () const throw()
82                {
83                        return m_nIndex;
84                }
85        };
86
87public:
88// CRoIterativeArrayTraitsT
89};
90
91////////////////////////////////////////////////////////////
92// CRoIterativeListTraitsT
93
94template <typename _List>
95class CRoIterativeListTraitsT
96{
97protected:
98        typedef POSITION KEY;
99
100public:
101
102        ////////////////////////////////////////////////////////
103        // CIterator
104
105        class CIterator
106        {
107        public:
108                const _List* m_pList;
109                KEY m_Position;
110
111        public:
112        // CIterator
113                CIterator(const _List* pList) throw() :
114                        m_pList(pList),
115                        m_Position(pList->GetHeadPosition())
116                {
117                }
118                BOOL IsValid() const throw()
119                {
120                        return m_Position != NULL;
121                }
122                VOID Next() throw()
123                {
124                        m_pList->GetNext(m_Position);
125                }
126                operator KEY () const throw()
127                {
128                        return m_Position;
129                }
130        };
131
132        ////////////////////////////////////////////////////////
133        // CReverseIterator
134
135        class CReverseIterator
136        {
137        public:
138                const _List* m_pList;
139                KEY m_Position;
140
141        public:
142        // CReverseIterator
143                CReverseIterator(const _List* pList) throw() :
144                        m_pList(pList),
145                        m_Position(pList->GetTailPosition())
146                {
147                }
148                BOOL IsValid() const throw()
149                {
150                        return m_Position != NULL;
151                }
152                VOID Next() throw()
153                {
154                        m_pList->GetPrev(m_Position);
155                }
156                operator KEY () const throw()
157                {
158                        return m_Position;
159                }
160        };
161};
162
163////////////////////////////////////////////////////////////
164// CRoIterativeCollectionT
165
166template <typename T, template <typename _Collection> class _IterativeTraitsT, typename _Element, typename _ElementTraits = CElementTraits<_Element> >
167class CRoIterativeCollectionT :
168        protected _IterativeTraitsT<T>
169{
170protected:
171        typedef typename _IterativeTraitsT<T>::KEY KEY;
172
173public:
174// CRoIterativeCollectionT
175        template <typename _Iterator, typename _Parameter>
176        SIZE_T GetCountThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter) const throw()
177        {
178                _A(pCompareElement);
179                const T* pT = static_cast<const T*>(this);
180                SIZE_T nCount = 0;
181                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
182                        if((*pCompareElement)(pT->GetAt(Iterator), Parameter))
183                                nCount++;
184                return nCount;
185        }
186        template <typename _Parameter>
187        SIZE_T GetCountThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter) const throw()
188        {
189                return GetCountThatT<CIterator, _Parameter>(pCompareElement, Parameter);
190        }
191        template <typename _Iterator>
192        SIZE_T GetCountThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element)) const throw()
193        {
194                _A(pCompareElement);
195                const T* pT = static_cast<const T*>(this);
196                SIZE_T nCount = 0;
197                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
198                        if((*pCompareElement)(pT->GetAt(Iterator)))
199                                nCount++;
200                return nCount;
201        }
202        SIZE_T GetCountThat(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element)) const throw()
203        {
204                return GetCountThatT<CIterator>(pCompareElement);
205        }
206        //__if_exists(T::Add)
207        //{
208                template <typename _Iterator, typename _Parameter>
209                SIZE_T GetThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter, T& Collection) const throw()
210                {
211                        _A(pCompareElement);
212                        _A(Collection.IsEmpty());
213                        const T* pT = static_cast<const T*>(this);
214                        Collection.SetCount(0, (INT) pT->GetCount());
215                        SIZE_T nCount = 0;
216                        for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
217                        {
218                                const _Element& Element = pT->GetAt(Iterator);
219                                if((*pCompareElement)(Element, Parameter))
220                                        _W(Collection.Add(Element) >= 0);
221                        }
222                        return Collection.GetCount();
223                }
224                template <typename _Parameter>
225                SIZE_T GetThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter, T& Collection) const throw()
226                {
227                        return GetThatT<CIterator, _Parameter>(pCompareElement, Parameter, Collection);
228                }
229                template <typename _Iterator>
230                SIZE_T GetThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element), T& Collection) const
231                {
232                        _A(pCompareElement);
233                        _A(Collection.IsEmpty());
234                        const T* pT = static_cast<const T*>(this);
235                        Collection.SetCount(0, (INT) pT->GetCount());
236                        for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
237                        {
238                                const _Element& Element = pT->GetAt(Iterator);
239                                if((*pCompareElement)(Element))
240                                        _W(Collection.Add(Element) >= 0);
241                        }
242                        return Collection.GetCount();
243                }
244                SIZE_T GetThat(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element), T& Collection) const
245                {
246                        return GetThatT<CIterator>(pCompareElement, Collection);
247                }
248        //}
249        //__if_exists(T::RemoveAt)
250        //{
251                template <typename _Iterator, typename _Parameter>
252                SIZE_T RemoveThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter) throw()
253                {
254                        _A(pCompareElement);
255                        T* pT = static_cast<T*>(this);
256                        SIZE_T nCount = 0;
257                        for(_Iterator Iterator(pT); Iterator.IsValid(); )
258                        {
259                                const KEY CurrentKey = Iterator;
260                                Iterator.Next();
261                                if(!(*pCompareElement)(pT->GetAt(CurrentKey), Parameter))
262                                        continue;
263                                // ASSU: Removed item does not invalidate further items on the loop
264                                pT->RemoveAt(CurrentKey);
265                                nCount++;
266                        }
267                        return nCount;
268                }
269                template <typename _Parameter>
270                SIZE_T RemoveThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, typename CElementTraits<_Parameter>::INARGTYPE Parameter), typename CElementTraits<_Parameter>::INARGTYPE Parameter) throw()
271                {
272                        // ASSU: Elements removed by CReverseIterator leave items to go intact and valid for further iterations
273                        return RemoveThatT<CReverseIterator, _Parameter>(pCompareElement, Parameter);
274                }
275                SIZE_T RemoveThat(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element)) throw()
276                {
277                        return RemoveThatT<CReverseIterator>(pCompareElement);
278                }
279        //}
280        template <typename _Iterator>
281        BOOL FindT(typename _ElementTraits::INARGTYPE Element, KEY* pKey = NULL) const throw()
282        {
283                const T* pT = static_cast<const T*>(this);
284                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
285                        if(_ElementTraits::CompareElements(pT->GetAt(Iterator), Element))
286                        {
287                                if(pKey)
288                                        *pKey = Iterator;
289                                return TRUE;
290                        }
291                return FALSE;
292        }
293        template <typename _Iterator>
294        BOOL FindThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element), KEY* pKey = NULL) const throw()
295        {
296                _A(pCompareElement);
297                const T* pT = static_cast<const T*>(this);
298                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
299                        if((*pCompareElement)(pT->GetAt(Iterator)))
300                        {
301                                if(pKey)
302                                        *pKey = Iterator;
303                                return TRUE;
304                        }
305                return FALSE;
306        }
307        template <typename _Iterator, typename _Parameter>
308        BOOL FindThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter), _Parameter Parameter, KEY* pKey = NULL) const throw()
309        {
310                _A(pCompareElement);
311                const T* pT = static_cast<const T*>(this);
312                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
313                        if((*pCompareElement)(pT->GetAt(Iterator), Parameter))
314                        {
315                                if(pKey)
316                                        *pKey = Iterator;
317                                return TRUE;
318                        }
319                return FALSE;
320        }
321        template <typename _Iterator, typename _Parameter>
322        BOOL FindThatT(BOOL (T::*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter), _Parameter Parameter, KEY* pKey = NULL) const throw()
323        {
324                _A(pCompareElement);
325                const T* pT = static_cast<const T*>(this);
326                for(_Iterator Iterator(pT); Iterator.IsValid(); Iterator.Next())
327                        if((pT->*pCompareElement)(pT->GetAt(Iterator), Parameter))
328                        {
329                                if(pKey)
330                                        *pKey = Iterator;
331                                return TRUE;
332                        }
333                return FALSE;
334        }
335        BOOL FindFirst(typename _ElementTraits::INARGTYPE Element, KEY* pKey = NULL) const throw()
336        {
337                return FindT<CIterator>(Element, pKey);
338        }
339        BOOL FindLast(typename _ElementTraits::INARGTYPE Element, KEY* pKey = NULL) const throw()
340        {
341                return FindT<CReverseIterator>(Element, pKey);
342        }
343        BOOL FindFirstThat(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element), KEY* pKey = NULL) const throw()
344        {
345                return FindThatT<CIterator>(pCompareElement, pKey);
346        }
347        BOOL FindLastThat(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element), KEY* pKey = NULL) const throw()
348        {
349                return FindThatT<CReverseIterator>(pCompareElement, pKey);
350        }
351        template <typename _Parameter>
352        BOOL FindFirstThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter), _Parameter Parameter, KEY* pKey = NULL) const throw()
353        {
354                return FindThatT<CIterator, _Parameter>(pCompareElement, Parameter, pKey);
355        }
356        template <typename _Parameter>
357        BOOL FindLastThatT(BOOL (*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter), _Parameter Parameter, KEY* pKey = NULL) const throw()
358        {
359                return FindThatT<CReverseIterator, _Parameter>(pCompareElement, Parameter, pKey);
360        }
361        template <typename _Parameter>
362        BOOL FindFirstThatT(BOOL (T::*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter) const, _Parameter Parameter, KEY* pKey = NULL) const throw()
363        {
364                return FindThatT<CIterator, _Parameter>(pCompareElement, Parameter, pKey);
365        }
366        template <typename _Parameter>
367        BOOL FindLastThatT(BOOL (T::*pCompareElement)(typename _ElementTraits::INARGTYPE Element, _Parameter Parameter) const, _Parameter Parameter, KEY* pKey = NULL) const throw()
368        {
369                return FindThatT<CReverseIterator, _Parameter>(pCompareElement, Parameter, pKey);
370        }
371        SIZE_T ForEach(BOOL (*pProcessElement)(typename _ElementTraits::INARGTYPE Element)) const
372        {
373                _A(pProcessElement);
374                T* pT = static_cast<T*>(this);
375                SIZE_T nCount = 0;
376                for(CIterator Iterator(pT); Iterator.IsValid(); Iterator.Next(), nCount++)
377                        if(!(*pProcessElement)(pT->GetAt(Iterator)))
378                                break;
379                return nCount;
380        }
381        SIZE_T ForEach(BOOL (*pProcessElement)(_Element& Element))
382        {
383                _A(pProcessElement);
384                T* pT = static_cast<T*>(this);
385                SIZE_T nCount = 0;
386                for(CIterator Iterator(pT); Iterator.IsValid(); Iterator.Next(), nCount++)
387                        if(!(*pProcessElement)(pT->GetAt(Iterator)))
388                                break;
389                return nCount;
390        }
391        // TODO: ForEachThat
392};
393
394////////////////////////////////////////////////////////////
395// CRoArrayT
396
397template <typename _Element, typename _ElementTraits = CElementTraits<_Element> >
398class CRoArrayT :
399        public CAtlArray<_Element, _ElementTraits>,
400        public CRoIterativeCollectionT<CRoArrayT<_Element, _ElementTraits>, CRoIterativeArrayTraitsT, _Element, _ElementTraits>
401{
402        typedef CAtlArray<_Element, _ElementTraits> CBaseArray;
403
404private:
405
406        class CBasePrivateMembers
407        {
408        public:
409                _Element* m_pData;
410                SIZE_T m_nSize;
411                SIZE_T m_nMaxSize;
412                INT m_nGrowBy;
413
414        public:
415        // CBasePrivateMembers
416        };
417
418public:
419// CRoArrayT
420        #pragma region Hacks
421        SIZE_T GetCapacity() const throw()
422        {
423                _A(sizeof (CBaseArray) == sizeof (CBasePrivateMembers));
424                const CBasePrivateMembers* pMembers = reinterpret_cast<const CBasePrivateMembers*>(static_cast<const CBaseArray*>(this));
425                _A(pMembers->m_nSize == GetCount());
426                return pMembers->m_nMaxSize; 
427        }
428        BOOL SetCapacity(SIZE_T nCapacity)
429        {
430                __D(nCapacity >= GetCount(), E_UNNAMED);
431                _A(sizeof (CBaseArray) == sizeof (CBasePrivateMembers));
432                CBasePrivateMembers* pMembers = reinterpret_cast<CBasePrivateMembers*>(static_cast<CBaseArray*>(this));
433                _Element* pElements;
434                if(nCapacity)
435                {
436                        pElements = static_cast<_Element*>(calloc(nCapacity, sizeof (_Element)));
437                        if(!pElements)
438                                return FALSE;
439                } else
440                        pElements = NULL;
441                _ElementTraits::RelocateElements(pElements, pMembers->m_pData, pMembers->m_nSize);
442                free(pMembers->m_pData);
443                pMembers->m_pData = pElements;
444                pMembers->m_nMaxSize = nCapacity;
445                return TRUE;
446        }
447        VOID ImmediateSetCount(SIZE_T nCount)
448        {
449                _A(sizeof (CBaseArray) == sizeof (CBasePrivateMembers));
450                CBasePrivateMembers* pMembers = reinterpret_cast<CBasePrivateMembers*>(static_cast<CBaseArray*>(this));
451                _A(pMembers->m_nSize == GetCount());
452                __D(nCount <= pMembers->m_nMaxSize, HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
453                pMembers->m_nSize = nCount;
454        }
455        #pragma endregion
456        SIZE_T AddNotFound(INARGTYPE Element)
457        {
458                SIZE_T nIndex;
459                if(!FindFirst(Element, &nIndex))
460                        nIndex = Add(Element);
461                _A(nIndex >= 0);
462                return nIndex;
463        }
464};
465
466////////////////////////////////////////////////////////////
467// CRoListT
468
469template <typename _Element, typename _ElementTraits = CElementTraits<_Element> >
470class CRoListT :
471        public CAtlList<_Element, _ElementTraits>,
472        public CRoIterativeCollectionT<CRoListT<_Element, _ElementTraits>, CRoIterativeListTraitsT, _Element, _ElementTraits>
473{
474public:
475// CRoListT
476        BOOL FindPositionIndex(POSITION Position, SIZE_T* pnIndex = NULL) const throw()
477        {
478                SIZE_T nIndex = 0;
479                for(CIterator Iterator(this); Iterator.IsValid(); Iterator.Next(), nIndex++)
480                        if(Iterator == Position)
481                        {
482                                if(pnIndex)
483                                        *pnIndex = nIndex;
484                                return TRUE;
485                        }
486                return FALSE;
487        }
488};
489
490////////////////////////////////////////////////////////////
491// CRoAssignableListT
492
493template <typename _Base>
494class CRoAssignableListT :
495        public _Base
496{
497public:
498// CRoAssignableListT
499        CRoAssignableListT() throw()
500        {
501        }
502        CRoAssignableListT(const CRoAssignableListT& Value)
503        {
504                *this = Value;
505        }
506        CRoAssignableListT& operator = (const CRoAssignableListT& Value)
507        {
508                RemoveAll();
509                AddTailList(&Value);
510                return *this;
511        }
512};
513
514////////////////////////////////////////////////////////////
515// CRoAssignableArrayT
516
517template <typename _Base>
518class CRoAssignableArrayT :
519        public _Base
520{
521public:
522// CRoAssignableArrayT
523        CRoAssignableArrayT() throw()
524        {
525        }
526        CRoAssignableArrayT(const CRoAssignableArrayT& Value)
527        {
528                *this = Value;
529        }
530        CRoAssignableArrayT& operator = (const CRoAssignableArrayT& Value)
531        {
532                RemoveAll();
533                Append(Value);
534                return *this;
535        }
536};
537
538////////////////////////////////////////////////////////////
539// CRoFixedArrayT
540
541template <typename _Element, SIZE_T t_nFixedCapacity, typename _ElementTraits = CElementTraits<_Element> >
542class CRoFixedArrayT :
543        public CRoIterativeCollectionT<CRoFixedArrayT<_Element, t_nFixedCapacity, _ElementTraits>, CRoIterativeArrayTraitsT, _Element, _ElementTraits>
544{
545public:
546        typedef typename _ElementTraits::INARGTYPE INARGTYPE;
547        typedef typename _ElementTraits::OUTARGTYPE OUTARGTYPE;
548
549protected:
550        typedef CRoFixedArrayT<_Element, t_nFixedCapacity, _ElementTraits> CRoFixedArray;
551
552private:
553        CTempBuffer<_Element, sizeof (_Element) * t_nFixedCapacity> m_pElements;
554        SIZE_T m_nCapacity;
555        SIZE_T m_nCount;
556
557#pragma push_macro("new")
558#undef new
559        static void CallConstructors(_Element* pElements, SIZE_T nCount)
560        {
561                SIZE_T nIndex = 0;
562                _ATLTRY
563                {
564                        for(; nIndex < nCount; nIndex++)
565                                ::new (pElements + nIndex) _Element;
566                }
567                _ATLCATCHALL()
568                {
569                        for(; nIndex > 0; nIndex--)
570                                pElements[nIndex - 1].~_Element();
571                        _ATLRETHROW;
572                }
573        }
574#pragma pop_macro("new")
575        static void CallDestructors(_Element* pElements, SIZE_T nCount) throw()
576        {
577                for(SIZE_T nIndex = 0; nIndex < nCount; nIndex++)
578                        pElements[nIndex].~_Element();
579        }
580
581public:
582// CRoFixedArrayT
583        static SIZE_T GetFixedCapacity() throw()
584        {
585                return t_nFixedCapacity;
586        }
587        CRoFixedArrayT() throw() :
588                m_pElements(GetFixedCapacity()),
589                m_nCapacity(GetFixedCapacity()),
590                m_nCount(0)
591        {
592        }
593        CRoFixedArrayT(SIZE_T nCapacity) :
594                m_pElements(nCapacity),
595                m_nCapacity(nCapacity),
596                m_nCount(0)
597        {
598        }
599        ~CRoFixedArrayT() throw()
600        {
601                if(m_nCount)
602                        CallDestructors(m_pElements, m_nCount);
603        }
604        SIZE_T GetCount() const throw()
605        {
606                return m_nCount;
607        }
608        BOOL IsEmpty() const throw()
609        {
610                return !m_nCount;
611        }
612        BOOL SetCount(SIZE_T nCount, INT nGrowBy = 0)
613        {
614                nGrowBy;
615                if(nCount == 0)
616                {
617                        // shrink to nothing
618                        if(m_nCount)
619                                CallDestructors(m_pElements, m_nCount);
620                        m_nCount = 0;
621                        return TRUE;
622                }
623                __D(nCount <= m_nCapacity, E_OUTOFMEMORY);
624                if(nCount > m_nCount)
625                        CallConstructors(m_pElements + m_nCount, nCount - m_nCount);
626                else if(m_nCount > nCount)
627                        CallDestructors(m_pElements + nCount, m_nCount - nCount);
628                m_nCount = nCount;
629                return TRUE;
630        }
631        const _Element* GetData() const throw()
632        {
633                return m_pElements;
634        }
635        _Element* GetData() throw()
636        {
637                return m_pElements;
638        }
639        const _Element& GetAt(SIZE_T nIndex) const throw()
640        {
641                _A(nIndex < m_nCount);
642                return m_pElements[nIndex];
643        }
644        _Element& GetAt(SIZE_T nIndex) throw()
645        {
646                _A(nIndex < m_nCount);
647                return m_pElements[nIndex];
648        }
649        //VOID SetAt(SIZE_T nIndex, INARGTYPE Element)
650#pragma push_macro("new")
651#undef new
652        SIZE_T Add()
653        {
654                __D(m_nCount < m_nCapacity, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW));
655                const SIZE_T nIndex = m_nCount;
656                ::new (m_pElements + nIndex) _Element;
657                m_nCount++;
658                return nIndex;
659        }
660        SIZE_T Add(INARGTYPE Element)
661        {
662                __D(m_nCount < m_nCapacity, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW));
663                const SIZE_T nIndex = m_nCount;
664                ::new (m_pElements + nIndex) _Element(Element);
665                m_nCount++;
666                return nIndex;
667        }
668#pragma pop_macro("new")
669        SIZE_T AddNotFound(INARGTYPE Element)
670        {
671                SIZE_T nIndex;
672                if(!FindFirst(Element, &nIndex))
673                        nIndex = Add(Element);
674                _A(nIndex >= 0);
675                return nIndex;
676        }
677        //VOID InsertAt(SIZE_T nIndex, INARGTYPE Element, SIZE_T nCount = 1)
678        template <typename _Array>
679        VOID Append(const _Array& Array)
680        {
681                // SUGG: Process at once without iterations
682                for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
683                        _W(Add(Array[nIndex]) >= 0);
684        }
685        VOID RemoveAt(SIZE_T nIndex, SIZE_T nCount = 1)
686        {
687                _A((nIndex + nCount) <= m_nCount);
688                const SIZE_T nMoveCount = m_nCount - (nIndex + nCount);
689                CallDestructors(m_pElements + nIndex, nCount);
690                if(nMoveCount > 0)
691                        _ElementTraits::RelocateElements(m_pElements + nIndex, m_pElements + nIndex + nCount, nMoveCount);
692                m_nCount -= nCount;
693        }
694        VOID RemoveAll() throw()
695        {
696                SetCount(0);
697        }
698        const _Element& operator [] (SIZE_T nIndex) const throw()
699        {
700                return GetAt(nIndex);
701        }
702        _Element& operator [] (SIZE_T nIndex) throw()
703        {
704                return GetAt(nIndex);
705        }
706};
707
708////////////////////////////////////////////////////////////
709// CRoMapT
710
711template<typename _KeyElement, typename _Element, class _KeyElementTraits = CElementTraits<_KeyElement>, class _ElementTraits = CElementTraits<_Element> >
712class CRoMapT :
713        public CAtlMap<_KeyElement, _Element, _KeyElementTraits, _ElementTraits>
714{
715public:
716// CRoMapT
717};
718
719////////////////////////////////////////////////////////////
720// CRoMapT
721
722template<typename _KeyElement, typename _Element, SIZE_T t_nFixedCapacity, class _KeyElementTraits = CElementTraits<_KeyElement>, class _ElementTraits = CElementTraits<_Element> >
723class CRoFixedMapT
724{
725        typedef CRoFixedArrayT<_KeyElement, t_nFixedCapacity, _KeyElementTraits> CKeyElementArray;
726        typedef CRoFixedArrayT<_Element, t_nFixedCapacity, _ElementTraits> CElementArray;
727
728public:
729        typedef typename _KeyElementTraits::INARGTYPE KINARGTYPE;
730        typedef typename _KeyElementTraits::OUTARGTYPE KOUTARGTYPE;
731        typedef typename _ElementTraits::INARGTYPE VINARGTYPE;
732        typedef typename _ElementTraits::OUTARGTYPE VOUTARGTYPE;
733
734private:
735        CKeyElementArray m_KeyElementArray;
736        CElementArray m_ElementArray;
737
738        static POSITION PositionFromIndex(SIZE_T nIndex) throw()
739        {
740                return (POSITION) (nIndex + 1);
741        }
742        static SIZE_T IndexFromPosition(POSITION Position) throw()
743        {
744                _A(Position);
745                return (SIZE_T) Position - 1;
746        }
747
748public:
749// CRoFixedMapT
750        static SIZE_T GetFixedCapacity() throw()
751        {
752                return t_nFixedCapacity;
753        }
754        CRoFixedMapT() throw()
755        {
756        }
757        SIZE_T GetCount() const throw()
758        {
759                _A(m_KeyElementArray.GetCount() == m_ElementArray.GetCount());
760                return m_KeyElementArray.GetCount();
761        }
762        BOOL IsEmpty() const throw()
763        {
764                _A(m_KeyElementArray.GetCount() == m_ElementArray.GetCount());
765                return m_KeyElementArray.IsEmpty();
766        }
767        BOOL Lookup(KINARGTYPE Key, VOUTARGTYPE Value) const
768        {
769                for(SIZE_T nIndex = 0; nIndex < m_KeyElementArray.GetCount(); nIndex++)
770                        if(_KeyElementTraits::CompareElements(m_KeyElementArray[nIndex], Key))
771                        {
772                                Value = m_ElementArray[nIndex];
773                                return TRUE;
774                        }
775                return FALSE;
776        }
777        POSITION Lookup(KINARGTYPE Key) const throw()
778        {
779                for(SIZE_T nIndex = 0; nIndex < m_KeyElementArray.GetCount(); nIndex++)
780                        if(_KeyElementTraits::CompareElements(m_KeyElementArray[nIndex], Key))
781                                return PositionFromIndex(nIndex);
782                return NULL;
783        }
784        //const CPair* Lookup(KINARGTYPE key) const throw()
785        //CPair* Lookup(KINARGTYPE key) throw()
786        _Element& operator[] (KINARGTYPE Key)
787        {
788                const POSITION Position = Lookup(Key);
789                if(Position)
790                        return GetValueAt(Position);
791                const SIZE_T nIndex = m_KeyElementArray.Add(Key);
792                _A((SSIZE_T) nIndex >= 0);
793                _W(m_ElementArray.Add() == nIndex);
794                _A(m_KeyElementArray.GetCount() == m_ElementArray.GetCount());
795                return m_ElementArray[nIndex];
796        }
797        POSITION SetAt(KINARGTYPE Key, VINARGTYPE Value)
798        {
799                POSITION Position = Lookup(Key);
800                if(!Position)
801                {
802                        const SIZE_T nIndex = m_KeyElementArray.Add(Key);
803                        _A((SSIZE_T) nIndex >= 0);
804                        _W(m_ElementArray.Add(Value) == nIndex);
805                        _A(m_KeyElementArray.GetCount() == m_ElementArray.GetCount());
806                        Position = PositionFromIndex(nIndex);
807                } else
808                        GetValueAt(Position) = Value;
809                return Position;
810        }
811        //VOID SetValueAt(POSITION Position, VINARGTYPE Value)
812        BOOL RemoveKey(KINARGTYPE Key) throw()
813        {
814                const POSITION Position = Lookup(Key);
815                if(!Position)
816                        return FALSE;
817                RemoveAtPos(Position);
818                return TRUE;
819        }
820        VOID RemoveAll() throw()
821        {
822                m_KeyElementArray.RemoveAll();
823                m_ElementArray.RemoveAll();
824        }
825        VOID RemoveAtPos(POSITION Position) throw()
826        {
827                const SIZE_T nIndex = IndexFromPosition(Position);
828                m_KeyElementArray.RemoveAt(nIndex);
829                m_ElementArray.RemoveAt(nIndex);
830        }
831        POSITION GetStartPosition() const throw()
832        {
833                if(!IsEmpty())
834                        return PositionFromIndex(0);
835                return NULL;
836        }
837        //VOID GetNextAssoc(POSITION& Position, KOUTARGTYPE Key, VOUTARGTYPE Value) const
838        POSITION GetNext(POSITION& Position) const throw()
839        {
840                _A(Position);
841                reinterpret_cast<BYTE*&>(Position)++;
842                if(IndexFromPosition(Position) >= m_KeyElementArray.GetCount())
843                        Position = NULL;
844                return Position;
845        }
846        //CPair* GetNext(POSITION& Position) throw()
847        //const _KeyElement& GetNextKey(POSITION& Position) const
848        //const _Element& GetNextValue(POSITION& Position) const
849        //_Element& GetNextValue(POSITION& Position)
850        //VOID GetAt(POSITION Position, KOUTARGTYPE Key, VOUTARGTYPE Value) const
851        //CPair* GetAt(POSITION Position) throw()
852        //const CPair* GetAt(POSITION Position) const throw()
853        const _KeyElement& GetKeyAt(POSITION Position) const
854        {
855                _A(Position);
856                const SIZE_T nIndex = IndexFromPosition(Position);
857                return m_KeyElementArray[nIndex];
858        }
859        const _Element& GetValueAt(POSITION Position) const
860        {
861                _A(Position);
862                const SIZE_T nIndex = IndexFromPosition(Position);
863                return m_ElementArray[nIndex];
864        }
865        _Element& GetValueAt(POSITION Position)
866        {
867                _A(Position);
868                const SIZE_T nIndex = IndexFromPosition(Position);
869                return m_ElementArray[nIndex];
870        }
871};
872
873////////////////////////////////////////////////////////////
874// CRoAssignableMapT
875
876template <typename _Base>
877class CRoAssignableMapT :
878        public _Base
879{
880public:
881// CRoAssignableMapT
882        CRoAssignableMapT() throw()
883        {
884        }
885        CRoAssignableMapT(const CRoAssignableMapT& Value)
886        {
887                *this = Value;
888        }
889        CRoAssignableMapT& operator = (const CRoAssignableMapT& Value)
890        {
891                RemoveAll();
892                for(POSITION Position = Value.GetStartPosition(); Position; Value.GetNext(Position))
893                        _W(SetAt(Value.GetKeyAt(Position), Value.GetValueAt(Position)));
894                return *this;
895        }
896};
897
Note: See TracBrowser for help on using the repository browser.