Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:19

0001 // Copyright (c) 2023 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef NCollection_IndexedIterator_HeaderFile
0015 #define NCollection_IndexedIterator_HeaderFile
0016 
0017 #include <Standard_Assert.hxx>
0018 #include <iterator>
0019 
0020 //! Helper class that allows to use NCollection iterators as STL iterators.
0021 //! NCollection iterator can be extended to STL iterator of any category by
0022 //! adding necessary methods: STL forward iterator requires IsEqual method,
0023 //! STL bidirectional iterator requires Previous method, and STL random access
0024 //! iterator requires Offset and Differ methods. See NCollection_Vector as
0025 //! example of declaring custom STL iterators.
0026 template<class Category, class BaseIndexedMap, class ItemType, bool IsConstant>
0027 class NCollection_IndexedIterator
0028 {
0029 public:
0030 
0031   // Since C++20 inheritance from std::iterator is deprecated, so define predefined types manually:
0032   using iterator_category = Category;
0033   using value_type = ItemType;
0034   using difference_type = ptrdiff_t;
0035   using pointer = typename std::conditional<IsConstant, const ItemType*, ItemType*>::type;
0036   using reference = typename std::conditional<IsConstant, const ItemType&, ItemType&>::type;
0037 
0038   //! Default constructor
0039   NCollection_IndexedIterator() : myIndex(0), myIndexedMap(nullptr)
0040   {}
0041 
0042   //! Constructor from NCollection_Indexed*Map
0043   NCollection_IndexedIterator(const BaseIndexedMap& theMap) :
0044     myIndex(0), myIndexedMap((&const_cast<BaseIndexedMap&>(theMap)))
0045   {}
0046 
0047   //! Constructor from NCollection_Indexed*Map
0048   NCollection_IndexedIterator(const size_t theIndex, const BaseIndexedMap& theMap) :
0049     myIndex(theIndex), myIndexedMap(&const_cast<BaseIndexedMap&>(theMap))
0050   {}
0051 
0052   //! Cast from non-const variant to const one
0053   NCollection_IndexedIterator(const NCollection_IndexedIterator<Category, BaseIndexedMap, ItemType, false>& theOther) :
0054     myIndex(theOther.myIndex), myIndexedMap(theOther.myIndexedMap)
0055   {}
0056 
0057   //! Assignment of non-const iterator to const one
0058   NCollection_IndexedIterator& operator= (const NCollection_IndexedIterator<Category, BaseIndexedMap, ItemType, false>& theOther)
0059   {
0060     myIndex = theOther.myIndex;
0061     myIndexedMap = theOther.myIndexedMap;
0062     return *this;
0063   }
0064 
0065 protected: //! @name methods related to forward STL iterator
0066 
0067   // Note: Here we use SFINAE (Substitution failure is not an error) to choose
0068   // an appropriate method based on template arguments (at instantiation time).
0069 
0070   template<bool Condition>
0071   typename std::enable_if<!Condition, ItemType&>::type Reference() const
0072   {
0073     return myIndexedMap->at(myIndex);
0074   }
0075 
0076   template<bool Condition>
0077   typename std::enable_if<Condition, const ItemType&>::type Reference() const
0078   {
0079     return myIndexedMap->at(myIndex);
0080   }
0081 
0082 public: //! @name methods related to forward STL iterator
0083 
0084   //! Test for equality
0085   bool operator== (const NCollection_IndexedIterator& theOther) const
0086   {
0087     return myIndexedMap == theOther.myIndexedMap &&
0088       myIndex == theOther.myIndex;
0089   }
0090 
0091   template<bool theOtherIsConstant>
0092   bool operator== (const NCollection_IndexedIterator<Category, BaseIndexedMap, ItemType, theOtherIsConstant>& theOther) const
0093   {
0094     return myIndexedMap == theOther.myIndexedMap &&
0095       myIndex == theOther.myIndex;
0096   }
0097 
0098   template<bool theOtherIsConstant>
0099   bool operator!= (const NCollection_IndexedIterator<Category, BaseIndexedMap, ItemType, theOtherIsConstant>& theOther) const
0100   {
0101     return myIndexedMap != theOther.myIndexedMap ||
0102       myIndex != theOther.myIndex;
0103   }
0104 
0105   //! Test for inequality
0106   bool operator!= (const NCollection_IndexedIterator& theOther) const
0107   {
0108     return !(*this == theOther);
0109   }
0110 
0111   //! Get reference to current item
0112   typename NCollection_IndexedIterator::reference operator*() const
0113   {
0114     return Reference<IsConstant>();
0115   }
0116 
0117   //! Dereferencing operator
0118   typename NCollection_IndexedIterator::pointer operator->() const
0119   {
0120     return &Reference<IsConstant>();
0121   }
0122 
0123   //! Prefix increment
0124   NCollection_IndexedIterator& operator++()
0125   {
0126     myIndex++;
0127     return *this;
0128   }
0129 
0130   //! Postfix increment
0131   NCollection_IndexedIterator operator++(int)
0132   {
0133     const NCollection_IndexedIterator theOld(*this);
0134     ++(*this);
0135     return theOld;
0136   }
0137 
0138 public: //! @name methods related to bidirectional STL iterator
0139 
0140   //! Prefix decrement
0141   NCollection_IndexedIterator& operator--()
0142   {
0143     Standard_STATIC_ASSERT((opencascade::std::is_same<std::bidirectional_iterator_tag, Category>::value ||
0144                             opencascade::std::is_same<std::random_access_iterator_tag, Category>::value));
0145     myIndex--;
0146     return *this;
0147   }
0148 
0149   //! Postfix decrement
0150   NCollection_IndexedIterator operator--(int)
0151   {
0152     NCollection_IndexedIterator theOld(*this);
0153     --(*this);
0154     return theOld;
0155   }
0156 
0157 public: //! @name methods related to random access STL iterator
0158 
0159   //! Move forward
0160   NCollection_IndexedIterator& operator+= (typename NCollection_IndexedIterator::difference_type theOffset)
0161   {
0162     Standard_STATIC_ASSERT((opencascade::std::is_same<std::random_access_iterator_tag, Category>::value));
0163     myIndex += theOffset;
0164     return *this;
0165   }
0166 
0167   //! Addition
0168   NCollection_IndexedIterator operator+ (typename NCollection_IndexedIterator::difference_type theOffset) const
0169   {
0170     NCollection_IndexedIterator aTemp(*this);
0171     return aTemp += theOffset;
0172   }
0173 
0174   //! Move backward
0175   NCollection_IndexedIterator& operator-= (typename NCollection_IndexedIterator::difference_type theOffset)
0176   {
0177     return *this += -theOffset;
0178   }
0179 
0180   //! Decrease
0181   NCollection_IndexedIterator operator- (typename NCollection_IndexedIterator::difference_type theOffset) const
0182   {
0183     NCollection_IndexedIterator aTemp(*this);
0184     return aTemp += -theOffset;
0185   }
0186 
0187   //! Difference
0188   typename NCollection_IndexedIterator::difference_type operator- (const NCollection_IndexedIterator& theOther) const
0189   {
0190     Standard_STATIC_ASSERT((opencascade::std::is_same<std::random_access_iterator_tag, Category>::value));
0191     return myIndex - theOther.myIndex;
0192   }
0193 
0194   //! Get item at offset from current
0195   typename NCollection_IndexedIterator::reference operator[] (typename NCollection_IndexedIterator::difference_type theOffset) const
0196   {
0197     return *(*this + theOffset);
0198   }
0199 
0200   //! Comparison
0201   bool operator< (const NCollection_IndexedIterator& theOther) const
0202   {
0203     return (*this - theOther) < 0;
0204   }
0205 
0206   //! Comparison
0207   bool operator> (const NCollection_IndexedIterator& theOther) const
0208   {
0209     return theOther < *this;
0210   }
0211 
0212   //! Comparison
0213   bool operator<= (const NCollection_IndexedIterator& theOther) const
0214   {
0215     return !(theOther < *this);
0216   }
0217 
0218   //! Comparison
0219   bool operator>= (const NCollection_IndexedIterator& theOther) const
0220   {
0221     return !(*this < theOther);
0222   }
0223 
0224   friend class NCollection_IndexedIterator<Category, BaseIndexedMap, ItemType, !IsConstant>;
0225 
0226 private:
0227   //! NCollection iterator
0228   size_t myIndex;
0229   BaseIndexedMap* myIndexedMap;
0230 };
0231 
0232 #endif // NCollection_IndexedIterator_HeaderFile