Changeset 463 for trunk/Common


Ignore:
Timestamp:
May 25, 2015, 10:37:24 PM (7 years ago)
Author:
roman
Message:

Update with improved collection classes, esp. with range-for support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Common/alax.info/roatlcollections.h

    r78 r463  
    11////////////////////////////////////////////////////////////
    2 // Copyright (C) Roman Ryltsov, 2006-2012
     2// Copyright (C) Roman Ryltsov, 2006-2015
    33// Created by Roman Ryltsov roman@alax.info
    4 //
    5 // $Id$
    64//
    75// A permission to use the source code is granted as long as reference to
     
    1311
    1412////////////////////////////////////////////////////////////
     13// CRoIterativeTraitsBase
     14
     15class CRoIterativeTraitsBase
     16{
     17public:
     18
     19        ////////////////////////////////////////////////////////
     20        // CAddressT
     21
     22        template <typename CValue>
     23        class CAddressT
     24        {
     25        public:
     26                CValue m_Value;
     27
     28        public:
     29        // CAddressT
     30                const CValue* operator & () const
     31                {
     32                        return reinterpret_cast<const CValue*>(this);
     33                }
     34                CValue* operator & ()
     35                {
     36                        return reinterpret_cast<CValue*>(this);
     37                }
     38        };
     39
     40public:
     41// CRoIterativeTraitsBase
     42};
     43
     44////////////////////////////////////////////////////////////
    1545// CRoIterativeArrayTraitsT
    1646
    17 template <typename _Array>
    18 class CRoIterativeArrayTraitsT
     47template <typename CArray>
     48class CRoIterativeArrayTraitsT :
     49        public CRoIterativeTraitsBase
    1950{
    2051protected:
     
    2960        {
    3061        public:
    31                 const _Array* m_pArray;
     62                const CArray* m_pArray;
    3263                KEY m_nIndex;
    3364
    3465        public:
    3566        // CIterator
    36                 CIterator(const _Array* pArray) throw() :
     67                CIterator(const CArray* pArray) throw() :
    3768                        m_pArray(pArray),
    3869                        m_nIndex(0)
     
    6091        {
    6192        public:
    62                 const _Array* m_pArray;
     93                const CArray* m_pArray;
    6394                KEY m_nIndex;
    6495
    6596        public:
    6697        // CReverseIterator
    67                 CReverseIterator(const _Array* pArray) throw() :
     98                CReverseIterator(const CArray* pArray) throw() :
    6899                        m_pArray(pArray),
    69100                        m_nIndex(pArray->GetCount() - 1)
     
    85116        };
    86117
     118        ////////////////////////////////////////////////////////
     119        // CRangeIterator
     120
     121        class CRangeIterator
     122        {
     123        public:
     124                const CArray& m_Array;
     125                SIZE_T m_nIndex;
     126
     127        public:
     128        // CRangeIterator
     129                ATL_FORCEINLINE CRangeIterator(const CArray* pArray, SIZE_T nIndex) :
     130                        m_Array(*pArray),
     131                        m_nIndex(nIndex)
     132                {
     133                        _A(pArray);
     134                }
     135                ATL_FORCEINLINE BOOL operator == (const CRangeIterator& Value) const
     136                {
     137                        _A(&m_Array == &Value.m_Array);
     138                        return m_nIndex == Value.m_nIndex;
     139                }
     140                ATL_FORCEINLINE BOOL operator != (const CRangeIterator& Value) const
     141                {
     142                        return !(*this == Value);
     143                }
     144                ATL_FORCEINLINE CRangeIterator& operator ++ ()
     145                {
     146                        ++m_nIndex;
     147                        return *this;
     148                }
     149                ATL_FORCEINLINE operator const typename CArray::CCollectionElement* () const
     150                {
     151                        const typename CArray::CCollectionElement& Element = m_Array.GetAt(m_nIndex);
     152                        CAddressT<typename CArray::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CArray::CCollectionElement>&>(Element);
     153                        return &ElementAddress;
     154                }
     155                ATL_FORCEINLINE operator typename CArray::CCollectionElement* ()
     156                {
     157                        typename CArray::CCollectionElement& Element = const_cast<CArray&>(m_Array).GetAt(m_nIndex);
     158                        CAddressT<typename CArray::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CArray::CCollectionElement>&>(Element);
     159                        return &ElementAddress;
     160                }
     161                ATL_FORCEINLINE static CRangeIterator begin(const CArray* pArray)
     162                {
     163                        return CRangeIterator(pArray, 0);
     164                }
     165                ATL_FORCEINLINE static CRangeIterator end(const CArray* pArray)
     166                {
     167                        return CRangeIterator(pArray, pArray->GetCount());
     168                }
     169        };
     170
    87171public:
    88172// CRoIterativeArrayTraitsT
     
    92176// CRoIterativeListTraitsT
    93177
    94 template <typename _List>
    95 class CRoIterativeListTraitsT
     178template <typename CList>
     179class CRoIterativeListTraitsT :
     180        public CRoIterativeTraitsBase
    96181{
    97182protected:
     
    106191        {
    107192        public:
    108                 const _List* m_pList;
     193                const CList* m_pList;
    109194                KEY m_Position;
    110195
    111196        public:
    112197        // CIterator
    113                 CIterator(const _List* pList) throw() :
     198                CIterator(const CList* pList) throw() :
    114199                        m_pList(pList),
    115200                        m_Position(pList->GetHeadPosition())
     
    136221        {
    137222        public:
    138                 const _List* m_pList;
     223                const CList* m_pList;
    139224                KEY m_Position;
    140225
    141226        public:
    142227        // CReverseIterator
    143                 CReverseIterator(const _List* pList) throw() :
     228                CReverseIterator(const CList* pList) throw() :
    144229                        m_pList(pList),
    145230                        m_Position(pList->GetTailPosition())
     
    159244                }
    160245        };
     246
     247        ////////////////////////////////////////////////////////
     248        // CRangeIterator
     249
     250        class CRangeIterator
     251        {
     252        public:
     253                const CList& m_List;
     254                POSITION m_Position;
     255
     256        public:
     257        // CRangeIterator
     258                ATL_FORCEINLINE CRangeIterator(const CList* pList, POSITION Position) :
     259                        m_List(*pList),
     260                        m_Position(Position)
     261                {
     262                        _A(pList);
     263                }
     264                ATL_FORCEINLINE BOOL operator == (const CRangeIterator& Value) const
     265                {
     266                        _A(&m_List == &Value.m_List);
     267                        return m_Position == Value.m_Position;
     268                }
     269                ATL_FORCEINLINE BOOL operator != (const CRangeIterator& Value) const
     270                {
     271                        return !(*this == Value);
     272                }
     273                ATL_FORCEINLINE CRangeIterator& operator ++ ()
     274                {
     275                        m_List.GetNext(m_Position);
     276                        return *this;
     277                }
     278                ATL_FORCEINLINE operator const typename CList::CCollectionElement* () const
     279                {
     280                        _A(m_Position);
     281                        const typename CList::CCollectionElement& Element = m_List.GetAt(m_Position);
     282                        CAddressT<typename CList::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CList::CCollectionElement>&>(Element);
     283                        return &ElementAddress;
     284                }
     285                ATL_FORCEINLINE operator typename CList::CCollectionElement* ()
     286                {
     287                        _A(m_Position);
     288                        typename CList::CCollectionElement& Element = const_cast<CList&>(m_List).GetAt(m_Position);
     289                        CAddressT<typename CList::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CList::CCollectionElement>&>(Element);
     290                        return &ElementAddress;
     291                }
     292                ATL_FORCEINLINE static CRangeIterator begin(const CList* pList)
     293                {
     294                        return CRangeIterator(pList, pList->GetHeadPosition());
     295                }
     296                ATL_FORCEINLINE static CRangeIterator end(const CList* pList)
     297                {
     298                        return CRangeIterator(pList, NULL);
     299                }
     300        };
     301
     302public:
     303// CRoIterativeListTraitsT
    161304};
    162305
     
    164307// CRoIterativeCollectionT
    165308
    166 template <typename T, template <typename _Collection> class _IterativeTraitsT, typename _Element, typename _ElementTraits = CElementTraits<_Element> >
     309template <typename T, template <typename _Collection> class CIterativeTraits, typename _Element, typename _ElementTraits = CElementTraits<_Element> >
    167310class CRoIterativeCollectionT :
    168         protected _IterativeTraitsT<T>
     311        protected CIterativeTraits<T>
    169312{
    170313protected:
    171         typedef typename _IterativeTraitsT<T>::KEY KEY;
     314        typedef typename CIterativeTraits<T>::KEY KEY;
    172315
    173316public:
     
    277420                        return RemoveThatT<CReverseIterator>(pCompareElement);
    278421                }
     422                BOOL RemoveFirst(typename _ElementTraits::INARGTYPE Element)
     423                {
     424                        T* pT = static_cast<T*>(this);
     425                        KEY Key;
     426                        if(!pT->FindFirst(Element, &Key))
     427                                return FALSE;
     428                        pT->RemoveAt(Key);
     429                        return TRUE;
     430                }
     431                BOOL RemoveLast(typename _ElementTraits::INARGTYPE Element)
     432                {
     433                        T* pT = static_cast<T*>(this);
     434                        KEY Key;
     435                        if(!pT->FindLast(Element, &Key))
     436                                return FALSE;
     437                        pT->RemoveAt(Key);
     438                        return TRUE;
     439                }
    279440        //}
    280441        template <typename _Iterator>
     
    390551        }
    391552        // TODO: ForEachThat
     553
     554// Range Iterator
     555        ATL_FORCEINLINE typename CIterativeTraits<T>::CRangeIterator begin() const
     556        {
     557                return CRangeIterator::begin(static_cast<const T*>(this));
     558        }
     559        ATL_FORCEINLINE typename CIterativeTraits<T>::CRangeIterator end() const
     560        {
     561                return CRangeIterator::end(static_cast<const T*>(this));
     562        }
    392563};
    393564
     
    400571        public CRoIterativeCollectionT<CRoArrayT<_Element, _ElementTraits>, CRoIterativeArrayTraitsT, _Element, _ElementTraits>
    401572{
     573public:
    402574        typedef CAtlArray<_Element, _ElementTraits> CBaseArray;
     575        typedef _Element CCollectionElement;
    403576
    404577private:
     
    473646{
    474647public:
     648        typedef CRoListT<_Element, _ElementTraits> CRoList;
     649        typedef _Element CCollectionElement;
     650
     651public:
    475652// CRoListT
    476653        BOOL FindPositionIndex(POSITION Position, SIZE_T* pnIndex = NULL) const throw()
     
    711888template<typename _KeyElement, typename _Element, class _KeyElementTraits = CElementTraits<_KeyElement>, class _ElementTraits = CElementTraits<_Element> >
    712889class CRoMapT :
    713         public CAtlMap<_KeyElement, _Element, _KeyElementTraits, _ElementTraits>
     890        public CAtlMap<_KeyElement, _Element, _KeyElementTraits, _ElementTraits>,
     891        public CRoIterativeTraitsBase
    714892{
    715893public:
     894        typedef CAtlMap<_KeyElement, _Element, _KeyElementTraits, _ElementTraits> CBaseMap;
     895        typedef CRoMapT<_KeyElement, _Element, _KeyElementTraits, _ElementTraits> CMap;
     896        typedef _Element CCollectionElement;
     897
     898        ////////////////////////////////////////////////////////
     899        // CPositionRangeIterator
     900
     901        class CPositionRangeIterator
     902        {
     903        public:
     904                const CMap& m_Map;
     905                POSITION m_Position;
     906
     907        public:
     908        // CPositionRangeIterator
     909                ATL_FORCEINLINE CPositionRangeIterator(const CMap* pMap, POSITION Position) :
     910                        m_Map(*pMap),
     911                        m_Position(Position)
     912                {
     913                        _A(pMap);
     914                }
     915                ATL_FORCEINLINE BOOL operator == (const CPositionRangeIterator& Position) const
     916                {
     917                        _A(&m_Map == &Position.m_Map);
     918                        return m_Position == Position.m_Position;
     919                }
     920                ATL_FORCEINLINE BOOL operator != (const CPositionRangeIterator& Position) const
     921                {
     922                        return !(*this == Position);
     923                }
     924                ATL_FORCEINLINE CPositionRangeIterator& operator ++ ()
     925                {
     926                        m_Map.GetNext(m_Position);
     927                        return *this;
     928                }
     929                ATL_FORCEINLINE operator const POSITION* () const
     930                {
     931                        return &m_Position;
     932                }
     933                ATL_FORCEINLINE operator typename POSITION* ()
     934                {
     935                        return &m_Position;
     936                }
     937                ATL_FORCEINLINE static CPositionRangeIterator begin(const CMap* pMap)
     938                {
     939                        return CPositionRangeIterator(pMap, pMap->GetStartPosition());
     940                }
     941                ATL_FORCEINLINE static CPositionRangeIterator end(const CMap* pMap)
     942                {
     943                        return CPositionRangeIterator(pMap, NULL);
     944                }
     945        };
     946
     947        ////////////////////////////////////////////////////////
     948        // CPositions
     949
     950        class CPositions
     951        {
     952        public:
     953                const CMap* m_pMap;
     954
     955        public:
     956        // CPositions
     957                ATL_FORCEINLINE CPositions(const CMap* pMap) :
     958                        m_pMap(pMap)
     959                {
     960                        _A(pMap);
     961                }
     962
     963        // Range Iterator
     964                ATL_FORCEINLINE CPositionRangeIterator begin() const
     965                {
     966                        return CPositionRangeIterator::begin(m_pMap);
     967                }
     968                ATL_FORCEINLINE CPositionRangeIterator end() const
     969                {
     970                        return CPositionRangeIterator::end(m_pMap);
     971                }
     972        };
     973
     974        ////////////////////////////////////////////////////////
     975        // CValueRangeIterator
     976
     977        class CValueRangeIterator
     978        {
     979        public:
     980                const CMap& m_Map;
     981                POSITION m_Position;
     982
     983        public:
     984        // CValueRangeIterator
     985                ATL_FORCEINLINE CValueRangeIterator(const CMap* pMap, POSITION Position) :
     986                        m_Map(*pMap),
     987                        m_Position(Position)
     988                {
     989                        _A(pMap);
     990                }
     991                ATL_FORCEINLINE BOOL operator == (const CValueRangeIterator& Value) const
     992                {
     993                        _A(&m_Map == &Value.m_Map);
     994                        return m_Position == Value.m_Position;
     995                }
     996                ATL_FORCEINLINE BOOL operator != (const CValueRangeIterator& Value) const
     997                {
     998                        return !(*this == Value);
     999                }
     1000                ATL_FORCEINLINE CValueRangeIterator& operator ++ ()
     1001                {
     1002                        m_Map.GetNext(m_Position);
     1003                        return *this;
     1004                }
     1005                ATL_FORCEINLINE operator const typename CMap::CCollectionElement* () const
     1006                {
     1007                        _A(m_Position);
     1008                        const typename CMap::CCollectionElement& Element = m_Map.GetValueAt(m_Position);
     1009                        CAddressT<typename CMap::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CMap::CCollectionElement>&>(Element);
     1010                        return &ElementAddress;
     1011                }
     1012                ATL_FORCEINLINE operator typename CMap::CCollectionElement* ()
     1013                {
     1014                        _A(m_Position);
     1015                        typename CMap::CCollectionElement& Element = const_cast<CMap&>(m_Map).GetValueAt(m_Position);
     1016                        CAddressT<typename CMap::CCollectionElement>& ElementAddress = reinterpret_cast<CAddressT<typename CMap::CCollectionElement>&>(Element);
     1017                        return &ElementAddress;
     1018                }
     1019                ATL_FORCEINLINE static CValueRangeIterator begin(const CMap* pMap)
     1020                {
     1021                        return CValueRangeIterator(pMap, pMap->GetStartPosition());
     1022                }
     1023                ATL_FORCEINLINE static CValueRangeIterator end(const CMap* pMap)
     1024                {
     1025                        return CValueRangeIterator(pMap, NULL);
     1026                }
     1027        };
     1028
     1029        ////////////////////////////////////////////////////////
     1030        // CValues
     1031
     1032        class CValues
     1033        {
     1034        public:
     1035                const CMap* m_pMap;
     1036
     1037        public:
     1038        // CValues
     1039                ATL_FORCEINLINE CValues(const CMap* pMap) :
     1040                        m_pMap(pMap)
     1041                {
     1042                        _A(pMap);
     1043                }
     1044
     1045        // Range Iterator
     1046                ATL_FORCEINLINE CValueRangeIterator begin() const
     1047                {
     1048                        return CValueRangeIterator::begin(m_pMap);
     1049                }
     1050                ATL_FORCEINLINE CValueRangeIterator end() const
     1051                {
     1052                        return CValueRangeIterator::end(m_pMap);
     1053                }
     1054        };
     1055
     1056public:
    7161057// CRoMapT
     1058        CPositions GetPositions() const
     1059        {
     1060                return CPositions(this);
     1061        }
     1062        CValues GetValues() const
     1063        {
     1064                return CValues(this);
     1065        }
    7171066};
    7181067
Note: See TracChangeset for help on using the changeset viewer.