Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/opencascade/NCollection_SparseArrayBase.hxx was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Created on: 2007-01-23
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2007-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef NCollection_SparseArrayBase_HeaderFile
0017 #define NCollection_SparseArrayBase_HeaderFile
0018 
0019 #include <Standard.hxx>
0020 #include <Standard_OutOfRange.hxx>
0021 
0022 typedef size_t Standard_Size;
0023 
0024 /**
0025  * Base class for NCollection_SparseArray;
0026  * provides non-template implementation of general mechanics
0027  * of block allocation, items creation / deletion etc.
0028  */
0029 
0030 class NCollection_SparseArrayBase
0031 {
0032 public:
0033   //!@name Type-independent public interface
0034   //!@{
0035 
0036   //! Clears all the data
0037   Standard_EXPORT void Clear();
0038 
0039   //! Returns number of currently contained items
0040   Standard_Size Size() const { return mySize; }
0041 
0042   //! Check whether the value at given index is set
0043   Standard_EXPORT Standard_Boolean HasValue(const Standard_Size theIndex) const;
0044 
0045   //! Deletes the item from the array;
0046   //! returns True if that item was defined
0047   Standard_EXPORT Standard_Boolean UnsetValue(const Standard_Size theIndex);
0048 
0049   //!@}
0050 
0051 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
0052 public: // work-around against obsolete SUN WorkShop 5.3 compiler
0053 #else
0054 private:
0055 #endif
0056 
0057   /**
0058    * The block of data contains array of items, counter
0059    * and bit field, allocated as single piece of memory addressed
0060    * from the blocks array (myData).
0061    *
0062    * The Block structure provides a logical view on the block,
0063    * and provides methods to work with bit map.
0064    *
0065    * Note that NCollection_SparseArrayBase class takes responsibility
0066    * for correct allocation/deallocation of all the data.
0067    */
0068 
0069   class Block
0070   {
0071   public:
0072     typedef unsigned char Cell; //!< type of items used to hold bits
0073 
0074     //! Number of bits in each cell
0075     static Standard_Size BitsPerCell() { return sizeof(Cell) * 8; }
0076 
0077   public:
0078     //! Initializes the block by pointer to block data
0079     Block(const Standard_Address theAddr,
0080           const Standard_Size    theNbItems,
0081           const Standard_Size    theItemSize)
0082         : Count((Standard_Size*)theAddr),
0083           Array((char*)theAddr + sizeof(Standard_Size)),
0084           Bits((Cell*)((char*)theAddr + sizeof(Standard_Size) + theNbItems * theItemSize))
0085     {
0086     }
0087 
0088     //! Compute required size for block data, in bytes
0089     static Standard_Size Size(const Standard_Size theNbItems, const Standard_Size theItemSize)
0090     {
0091       return sizeof(Standard_Size)
0092              + sizeof(Cell) * ((theNbItems + BitsPerCell() - 1) / BitsPerCell())
0093              + theNbItems * theItemSize;
0094     }
0095 
0096     //! Returns address of array from address of block
0097     static char* ToArray(const Standard_Address theAddress,
0098                          const Standard_Size /*theNbItems*/,
0099                          const Standard_Size /*theItemSize*/)
0100     {
0101       return (char*)theAddress + sizeof(Standard_Size);
0102     }
0103 
0104   public:
0105     //! Set bit for i-th item; returns non-null if that bit has
0106     //! not been set previously
0107     Cell Set(Standard_Size i)
0108     {
0109       Cell* abyte = Bits + i / BitsPerCell();
0110       Cell  amask = (Cell)('\1' << (i % BitsPerCell()));
0111       Cell  anold = (Cell)(*abyte & amask);
0112       *abyte      = (Cell)(*abyte | amask);
0113       return !anold;
0114     }
0115 
0116     //! Check bit for i-th item; returns non-null if that bit is set
0117     Cell IsSet(Standard_Size i)
0118     {
0119       Cell* abyte = Bits + i / BitsPerCell();
0120       Cell  amask = (Cell)('\1' << (i % BitsPerCell()));
0121       return (Cell)(*abyte & amask);
0122     }
0123 
0124     //! Unset bit for i-th item; returns non-null if that bit
0125     //! has been set previously
0126     Cell Unset(Standard_Size i)
0127     {
0128       Cell* abyte = Bits + i / BitsPerCell();
0129       Cell  amask = (Cell)('\1' << (i % BitsPerCell()));
0130       Cell  anold = (Cell)(*abyte & amask);
0131       *abyte      = (Cell)(*abyte & ~amask);
0132       return anold;
0133     }
0134 
0135   public:
0136     Standard_Size*   Count; //!< items counter
0137     Standard_Address Array; //!< pointer to the data items array
0138     Cell*            Bits;  //!< bit map for defined/undefined flags
0139   };
0140 
0141 public:
0142   /**
0143    * Iterator
0144    */
0145 
0146   class Iterator
0147   {
0148   public:
0149     // Public interface
0150 
0151     //! Restart iterations on the same array
0152     void Restart() { init(myArr); }
0153 
0154     //! Returns True if current item is available
0155     Standard_Boolean More() const { return myHasMore; }
0156 
0157     //! Advances to the next item
0158     Standard_EXPORT void Next();
0159 
0160     //! Returns current index
0161     Standard_Size Index() const { return myIBlock * myArr->myBlockSize + myInd; }
0162 
0163   protected:
0164     // Methods for descendant
0165 
0166     //! Empty constructor
0167     Standard_EXPORT Iterator(const NCollection_SparseArrayBase* theArray = 0);
0168 
0169     //! Initialize by the specified array
0170     Standard_EXPORT void init(const NCollection_SparseArrayBase* theArray);
0171 
0172     //! Returns address of the current item
0173     Standard_Address value() const { return myArr->getItem(myBlock, myInd); }
0174 
0175   private:
0176     const NCollection_SparseArrayBase* myArr;
0177     Standard_Boolean                   myHasMore;
0178     Standard_Size                      myIBlock;
0179     Standard_Size                      myInd;
0180     Block                              myBlock;
0181   };
0182   friend class Iterator;
0183 
0184 private:
0185   // Copy constructor and assignment operator are private thus not accessible
0186   NCollection_SparseArrayBase(const NCollection_SparseArrayBase&);
0187   void operator=(const NCollection_SparseArrayBase&);
0188 
0189 protected:
0190   // Object life
0191 
0192   //! Constructor; initialized by size of item and of block (in items)
0193   NCollection_SparseArrayBase(Standard_Size theItemSize, Standard_Size theBlockSize)
0194       : myItemSize(theItemSize),
0195         myBlockSize(theBlockSize),
0196         myNbBlocks(0),
0197         mySize(0),
0198         myData(0)
0199   {
0200   }
0201 
0202   //! Destructor
0203   virtual ~NCollection_SparseArrayBase() { Clear(); }
0204 
0205 protected:
0206   // Data access interface for descendants
0207 
0208   //! Creates Block structure for block pointed by theAddr
0209   Block getBlock(const Standard_Address theAddr) const
0210   {
0211     return Block(theAddr, myBlockSize, myItemSize);
0212   }
0213 
0214   //! Find address of the item in the block by index (in the block)
0215   Standard_Address getItem(const Block& theBlock, Standard_Size theInd) const
0216   {
0217     return ((char*)theBlock.Array) + myItemSize * theInd;
0218   }
0219 
0220   //! Direct const access to the item
0221   Standard_Address getValue(const Standard_Size theIndex) const
0222   {
0223     Standard_OutOfRange_Raise_if(
0224       !HasValue(theIndex),
0225       "NCollection_SparseArray::Value()") return Block::ToArray(myData[theIndex / myBlockSize],
0226                                                                 myBlockSize,
0227                                                                 myItemSize)
0228       + myItemSize * (theIndex % myBlockSize);
0229   }
0230 
0231   //! Set a value to the specified item; returns address of the set item
0232   Standard_EXPORT Standard_Address setValue(const Standard_Size    theIndex,
0233                                             const Standard_Address theValue);
0234 
0235   //! Copy contents of theOther to this;
0236   //! assumes that this and theOther have exactly the same type of arguments
0237   Standard_EXPORT void assign(const NCollection_SparseArrayBase& theOther);
0238 
0239   //! Exchange contents of theOther and this;
0240   //! assumes that this and theOther have exactly the same type of arguments
0241   Standard_EXPORT void exchange(NCollection_SparseArrayBase& theOther);
0242 
0243 protected:
0244   // Methods to be provided by descendant
0245 
0246   //! Create new item at the specified address with default constructor
0247   //  virtual void createItem (Standard_Address theAddress) = 0;
0248 
0249   //! Create new item at the specified address with copy constructor
0250   //! from existing item
0251   virtual void createItem(Standard_Address theAddress, Standard_Address theOther) = 0;
0252 
0253   //! Call destructor to the item
0254   virtual void destroyItem(Standard_Address theAddress) = 0;
0255 
0256   //! Call assignment operator to the item
0257   virtual void copyItem(Standard_Address theAddress, Standard_Address theOther) = 0;
0258 
0259 private:
0260   // Implementation of memory allocation/deallocation and access mechanics
0261 
0262   //! Allocate space for at least iBlock+1 blocks
0263   void allocData(const Standard_Size iBlock);
0264 
0265   //! Free specified block
0266   void freeBlock(const Standard_Size iBlock);
0267 
0268 protected:
0269   Standard_Size     myItemSize;  //!< size of item
0270   Standard_Size     myBlockSize; //!< block size (in items)
0271   Standard_Size     myNbBlocks;  //!< allocated size of blocks table
0272   Standard_Size     mySize;      //!< number of currently defined items
0273   Standard_Address* myData;      //!< array of pointers to data blocks
0274 };
0275 
0276 #endif