// Created on: 2002-04-15 // Created by: Alexander Kartomin (akm) // Copyright (c) 2002-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef NCollection_Array1_HeaderFile #define NCollection_Array1_HeaderFile #include #include #include // *********************************************** Template for Array1 class /** * Purpose: The class Array1 represents unidimensional arrays * of fixed size known at run time. * The range of the index is user defined. * An array1 can be constructed with a "C array". * This functionality is useful to call methods expecting * an Array1. It allows to carry the bounds inside the arrays. * * Examples: Item tab[100]; // An example with a C array * Array1OfItem ttab (tab[0],1,100); * * Array1OfItem tttab (ttab(10),10,20); // a slice of ttab * * If you want to reindex an array from 1 to Length do : * * Array1 tab1(tab(tab.Lower()),1,tab.Length()); * * Warning: Programs client of such a class must be independant * of the range of the first element. Then, a C++ for * loop must be written like this * * for (i = A.Lower(); i <= A.Upper(); i++) * * Changes: In comparison to TCollection the flag isAllocated was * renamed into myDeletable (alike in the Array2). For naming * compatibility the method IsAllocated remained in class along * with IsDeletable. */ template class NCollection_Array1 { public: //! STL-compliant typedef for value type typedef TheItemType value_type; public: //! Implementation of the Iterator interface. class Iterator { public: //! Empty constructor - for later Init Iterator (void) : myPtrCur (NULL), myPtrEnd (NULL) { // } //! Constructor with initialization Iterator (const NCollection_Array1& theArray, Standard_Boolean theToEnd = Standard_False) : myPtrEnd (const_cast (&theArray.Last() + 1)) { myPtrCur = theToEnd ? myPtrEnd : const_cast (&theArray.First()); } //! Initialisation void Init (const NCollection_Array1& theArray) { myPtrCur = const_cast (&theArray.First()); myPtrEnd = const_cast (&theArray.Last() + 1); } //! Assignment Iterator& operator= (const Iterator& theOther) { myPtrCur = theOther.myPtrCur; myPtrEnd = theOther.myPtrEnd; return *this; } //! Check end Standard_Boolean More (void) const { return myPtrCur < myPtrEnd; } //! Increment operator void Next (void) { ++myPtrCur; } //! Decrement operator void Previous() { --myPtrCur; } //! Offset operator. void Offset (ptrdiff_t theOffset) { myPtrCur += theOffset; } //! Difference operator. ptrdiff_t Differ (const Iterator& theOther) const { return myPtrCur - theOther.myPtrCur; } //! Constant value access const TheItemType& Value (void) const { return *myPtrCur; } //! Variable value access TheItemType& ChangeValue (void) const { return *myPtrCur; } //! Performs comparison of two iterators Standard_Boolean IsEqual (const Iterator& theOther) const { return myPtrCur == theOther.myPtrCur; } private: TheItemType* myPtrCur; //!< Pointer to the current element in the array TheItemType* myPtrEnd; //!< Pointer to the past-the-end element in the array }; // End of the nested class Iterator //! Shorthand for a regular iterator type. typedef NCollection_StlIterator iterator; //! Shorthand for a constant iterator type. typedef NCollection_StlIterator const_iterator; //! Returns an iterator pointing to the first element in the array. iterator begin() const { return Iterator (*this, false); } //! Returns an iterator referring to the past-the-end element in the array. iterator end() const { return Iterator (*this, true); } //! Returns a const iterator pointing to the first element in the array. const_iterator cbegin() const { return Iterator (*this, false); } //! Returns a const iterator referring to the past-the-end element in the array. const_iterator cend() const { return Iterator (*this, true); } public: // ---------- PUBLIC METHODS ------------ //! Constructor NCollection_Array1(const Standard_Integer theLower, const Standard_Integer theUpper) : myLowerBound (theLower), myUpperBound (theUpper), myDeletable (Standard_True) { TheItemType* pBegin = new TheItemType[Length()]; myData = pBegin - theLower; } //! Copy constructor NCollection_Array1 (const NCollection_Array1& theOther) : myLowerBound (theOther.Lower()), myUpperBound (theOther.Upper()), myDeletable (Standard_True) { TheItemType* pBegin = new TheItemType[Length()]; myData = pBegin - myLowerBound; *this = theOther; } //! C array-based constructor NCollection_Array1 (const TheItemType& theBegin, const Standard_Integer theLower, const Standard_Integer theUpper) : myLowerBound (theLower), myUpperBound (theUpper), myDeletable (Standard_False) { myData = (TheItemType *) &theBegin - theLower; } //! Initialise the items with theValue void Init (const TheItemType& theValue) { TheItemType *pCur = &myData[myLowerBound], *pEnd=&myData[myUpperBound]; for(; pCur <= pEnd; pCur++) *pCur = (TheItemType&) theValue; } //! Size query Standard_Integer Size (void) const { return Length(); } //! Length query (the same) Standard_Integer Length (void) const { return (myUpperBound-myLowerBound+1); } //! Lower bound Standard_Integer Lower (void) const { return myLowerBound; } //! Upper bound Standard_Integer Upper (void) const { return myUpperBound; } //! myDeletable flag Standard_Boolean IsDeletable (void) const { return myDeletable; } //! IsAllocated flag - for naming compatibility Standard_Boolean IsAllocated (void) const { return myDeletable; } //! Assignment NCollection_Array1& Assign (const NCollection_Array1& theOther) { if (&theOther == this) return *this; TheItemType * pMyItem = &myData[myLowerBound]; TheItemType * const pEndItem = &(theOther.myData)[theOther.myUpperBound]; TheItemType * pItem = &(theOther.myData)[theOther.myLowerBound]; while (pItem <= pEndItem) * pMyItem ++ = * pItem ++; return *this; } //! Assignment operator NCollection_Array1& operator= (const NCollection_Array1& theOther) { return Assign (theOther); } //! @return first element const TheItemType& First() const { return myData[myLowerBound]; } //! @return first element TheItemType& ChangeFirst() { return myData[myLowerBound]; } //! @return last element const TheItemType& Last() const { return myData[myUpperBound]; } //! @return last element TheItemType& ChangeLast() { return myData[myUpperBound]; } //! Constant value access const TheItemType& Value (const Standard_Integer theIndex) const { return myData[theIndex]; } //! operator() - alias to Value const TheItemType& operator() (const Standard_Integer theIndex) const { return Value (theIndex); } //! Variable value access TheItemType& ChangeValue (const Standard_Integer theIndex) { return myData[theIndex]; } //! operator() - alias to ChangeValue TheItemType& operator() (const Standard_Integer theIndex) { return ChangeValue (theIndex); } //! Set value void SetValue (const Standard_Integer theIndex, const TheItemType& theItem) { myData[theIndex] = theItem; } //! Destructor - releases the memory ~NCollection_Array1 (void) { if (myDeletable) delete [] &(myData[myLowerBound]); } protected: // ---------- PROTECTED FIELDS ----------- Standard_Integer myLowerBound; Standard_Integer myUpperBound; Standard_Boolean myDeletable; //!< Flag showing who allocated the array TheItemType* myData; //!< Pointer to '0'th array item }; #endif