0029492: Coding Rules. NCollection_IndexedDataMap - add missing documentation to...
[occt.git] / src / NCollection / NCollection_IndexedDataMap.hxx
old mode 100755 (executable)
new mode 100644 (file)
index 8068fb7..b6c3684
@@ -1,22 +1,29 @@
-// File:        NCollection_IndexedDataMap.hxx
-// Created:     Thu Apr 24 15:02:53 2002
-// Author:      Alexander KARTOMIN (akm)
-//              <akm@opencascade.com>
+// Created on: 2002-04-24
+// 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_IndexedDataMap_HeaderFile
 #define NCollection_IndexedDataMap_HeaderFile
 
-#include <NCollection_BaseCollection.hxx>
 #include <NCollection_BaseMap.hxx>
 #include <NCollection_TListNode.hxx>
 #include <Standard_TypeMismatch.hxx>
 #include <Standard_NoSuchObject.hxx>
-
+#include <NCollection_StlIterator.hxx>
 #include <NCollection_DefaultHasher.hxx>
 
-#if !defined No_Exception && !defined No_Standard_OutOfRange
 #include <Standard_OutOfRange.hxx>
-#endif
 
 /**
  * Purpose:     An indexed map is used  to store keys and to  bind
 template < class TheKeyType, 
            class TheItemType, 
            class Hasher = NCollection_DefaultHasher<TheKeyType> > 
-  class NCollection_IndexedDataMap 
-  : public NCollection_BaseCollection<TheItemType>,
-    public NCollection_BaseMap
+class NCollection_IndexedDataMap : public NCollection_BaseMap
 {
+public:
+  //! STL-compliant typedef for key type
+  typedef TheKeyType key_type;
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
+
+private:
   //!    Adaptation of the TListNode to the INDEXEDDatamap
- private:
   class IndexedDataMapNode : public NCollection_TListNode<TheItemType>
   {
   public:
     //! Constructor with 'Next'
     IndexedDataMapNode (const TheKeyType&      theKey1, 
-                        const Standard_Integer theKey2,
+                        const Standard_Integer theIndex,
                         const TheItemType&     theItem,
-                        NCollection_ListNode*  theNext1, 
-                        NCollection_ListNode*  theNext2) :
-                          NCollection_TListNode<TheItemType>(theItem,theNext1)
+                        NCollection_ListNode*  theNext1)
+    : NCollection_TListNode<TheItemType>(theItem,theNext1),
+      myKey1  (theKey1),
+      myIndex (theIndex)
     { 
-      myKey1 = theKey1;
-      myKey2 = theKey2;
-      myNext2 = (IndexedDataMapNode *) theNext2;
     }
     //! Key1
-    TheKeyType& Key1 (void)
-    { return myKey1; }
-    //! Key2
-    const Standard_Integer& Key2 (void)
-    { return myKey2; }
-    //! Next2
-    IndexedDataMapNode*& Next2 (void)
-    { return myNext2; }
-    
+    TheKeyType& Key1() { return myKey1; }
+    //! Index
+    Standard_Integer& Index() { return myIndex; }
+
     //! Static deleter to be passed to BaseList
     static void delNode (NCollection_ListNode * theNode, 
                          Handle(NCollection_BaseAllocator)& theAl)
@@ -79,165 +83,191 @@ template < class TheKeyType,
       theAl->Free(theNode);
     }
   private:
-    TheKeyType           myKey1;
-    Standard_Integer     myKey2;
-    IndexedDataMapNode * myNext2;
+    TheKeyType       myKey1;
+    Standard_Integer myIndex;
   };
 
  public:
   //!   Implementation of the Iterator interface.
-  class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
+  class Iterator
   {
   public:
     //! Empty constructor
-    Iterator (void) :
-      myMap(NULL),
-      myIndex(0) {}
+    Iterator()
+    : myMap (NULL),
+      myNode (NULL),
+      myIndex (0) {}
     //! Constructor
-    Iterator (const NCollection_IndexedDataMap& theMap) :
-      myMap((NCollection_IndexedDataMap *) &theMap),
-      myIndex(1) {}
+    Iterator (const NCollection_IndexedDataMap& theMap)
+    : myMap  ((NCollection_IndexedDataMap* )&theMap),
+      myNode (!theMap.IsEmpty() ? (IndexedDataMapNode* )myMap->myData2[0] : NULL),
+      myIndex (1) {}
     //! Query if the end of collection is reached by iterator
-    virtual Standard_Boolean More(void) const
-    { return (myIndex <= myMap->Extent()); }
+    Standard_Boolean More(void) const
+    { return (myMap != NULL) && (myIndex <= myMap->Extent()); }
     //! Make a step along the collection
-    virtual void Next(void)
-    { myIndex++; }
+    void Next(void)
+    {
+      myNode = (IndexedDataMapNode* )myMap->myData2[++myIndex - 1];
+    }
     //! Value access
-    virtual const TheItemType& Value(void) const
+    const TheItemType& Value(void) const
     {  
-#if !defined No_Exception && !defined No_Standard_NoSuchObject
-      if (!More())
-        Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::Iterator::Value");
-#endif
-      return myMap->FindFromIndex(myIndex);
+      Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Value");
+      return myNode->Value();
     }
     //! ChangeValue access
-    virtual TheItemType& ChangeValue(void) const
+    TheItemType& ChangeValue(void) const
     {  
-#if !defined No_Exception && !defined No_Standard_NoSuchObject
-      if (!More())
-        Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::Iterator::ChangeValue");
-#endif
-      return myMap->ChangeFromIndex(myIndex);
+      Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::ChangeValue");
+      return myNode->ChangeValue();
+    }
+    //! Key
+    const TheKeyType& Key() const
+    {
+      Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Key");
+      return myNode->Key1();
+    }
+    //! Performs comparison of two iterators.
+    Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myMap == theOther.myMap &&
+             myNode == theOther.myNode &&
+             myIndex == theOther.myIndex;
     }
-    
   private:
-    NCollection_IndexedDataMap * myMap;   //!< Pointer to the map being iterated
-    Standard_Integer             myIndex; //!< Current index
+    NCollection_IndexedDataMap* myMap;   //!< Pointer to the map being iterated
+    IndexedDataMapNode*         myNode;  //!< Current node
+    Standard_Integer            myIndex; //!< Current index
   };
   
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the map.
+  iterator begin() const { return Iterator (*this); }
+
+  //! Returns an iterator referring to the past-the-end element in the map.
+  iterator end() const { return Iterator(); }
+
+  //! Returns a const iterator pointing to the first element in the map.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the map.
+  const_iterator cend() const { return Iterator(); }
+  
  public:
   // ---------- PUBLIC METHODS ------------
 
+  //! Empty constructor.
+  NCollection_IndexedDataMap() : NCollection_BaseMap (1, Standard_False, Handle(NCollection_BaseAllocator)()) {}
+
   //! Constructor
-  NCollection_IndexedDataMap (const Standard_Integer NbBuckets=1,
-                     const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
-    :  NCollection_BaseCollection<TheItemType>(theAllocator),
-       NCollection_BaseMap (NbBuckets, Standard_False) {}
+  explicit NCollection_IndexedDataMap (const Standard_Integer theNbBuckets,
+                                       const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
+  : NCollection_BaseMap (theNbBuckets, Standard_False, theAllocator) {}
 
   //! Copy constructor
   NCollection_IndexedDataMap (const NCollection_IndexedDataMap& theOther) 
-    : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
-      NCollection_BaseMap (theOther.NbBuckets(), Standard_False) 
+    : NCollection_BaseMap (theOther.NbBuckets(), Standard_False, theOther.myAllocator) 
   { *this = theOther; }
 
-  //! Assign another collection
-  virtual void Assign(const NCollection_BaseCollection<TheItemType>& theOther)
-  { 
-    if (this == &theOther)
-      return;
-    Standard_TypeMismatch::Raise("NCollection_IndexedDataMap::Assign");
+  //! Exchange the content of two maps without re-allocations.
+  //! Notice that allocators will be swapped as well!
+  void Exchange (NCollection_IndexedDataMap& theOther)
+  {
+    this->exchangeMapsData (theOther);
   }
 
-  //! = another map
-  NCollection_IndexedDataMap& operator= 
-    (const NCollection_IndexedDataMap& theOther)
+  //! Assignment.
+  //! This method does not change the internal allocator.
+  NCollection_IndexedDataMap& Assign (const NCollection_IndexedDataMap& theOther)
   { 
     if (this == &theOther)
       return *this;
 
-    Clear(theOther.myAllocator);
+    Clear();
     ReSize (theOther.Extent()-1);
-    Standard_Integer i;
-    for (i=1; i<=theOther.Extent(); i++)
+    for (Standard_Integer anIndexIter = 1; anIndexIter <= theOther.Extent(); ++anIndexIter)
     {
-      TheKeyType aKey1 = theOther.FindKey(i);
-      TheItemType anItem = theOther.FindFromIndex(i);
-      Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
-      Standard_Integer iK2 = ::HashCode (i, NbBuckets());
-      IndexedDataMapNode * pNode = 
-        new (this->myAllocator) IndexedDataMapNode (aKey1, i, anItem,
-                                              myData1[iK1], myData2[iK2]);
-      myData1[iK1] = pNode;
-      myData2[iK2] = pNode;
+      const TheKeyType&  aKey1  = theOther.FindKey      (anIndexIter);
+      const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
+      const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
+      IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
+      myData1[iK1]             = pNode;
+      myData2[anIndexIter - 1] = pNode;
       Increment();
     }
     return *this;
   }
 
+  //! Assignment operator
+  NCollection_IndexedDataMap& operator= (const NCollection_IndexedDataMap& theOther)
+  {
+    return Assign (theOther);
+  }
+
   //! ReSize
   void ReSize (const Standard_Integer N)
   {
-    IndexedDataMapNode** ppNewData1 = NULL;
-    IndexedDataMapNode** ppNewData2 = NULL;
+    NCollection_ListNode** ppNewData1 = NULL;
+    NCollection_ListNode** ppNewData2 = NULL;
     Standard_Integer newBuck;
-    if (BeginResize (N, newBuck, 
-                     (NCollection_ListNode**&)ppNewData1, 
-                     (NCollection_ListNode**&)ppNewData2,
-                     this->myAllocator)) 
+    if (BeginResize (N, newBuck, ppNewData1, ppNewData2))
     {
       if (myData1) 
       {
-        IndexedDataMapNode *p, *q;
-        Standard_Integer i, iK1, iK2;
-        for (i = 0; i <= NbBuckets(); i++) 
+        memcpy (ppNewData2, myData2, sizeof(IndexedDataMapNode*) * Extent());
+        for (Standard_Integer aBucketIter = 0; aBucketIter <= NbBuckets(); ++aBucketIter)
         {
-          if (myData1[i]) 
+          if (myData1[aBucketIter])
           {
-            p = (IndexedDataMapNode *) myData1[i];
+            IndexedDataMapNode* p = (IndexedDataMapNode *) myData1[aBucketIter];
             while (p) 
             {
-              iK1 = Hasher::HashCode (p->Key1(), newBuck);
-              iK2 = ::HashCode (p->Key2(), newBuck);
-              q = (IndexedDataMapNode*) p->Next();
-              p->Next()  = ppNewData1[iK1];
-              p->Next2() = ppNewData2[iK2];
+              const Standard_Integer iK1 = Hasher::HashCode (p->Key1(), newBuck);
+              IndexedDataMapNode* q = (IndexedDataMapNode* )p->Next();
+              p->Next() = ppNewData1[iK1];
               ppNewData1[iK1] = p;
-              ppNewData2[iK2] = p;
               p = q;
             }
           }
         }
       }
-      EndResize(N,newBuck,
-                (NCollection_ListNode**&)ppNewData1,
-                (NCollection_ListNode**&)ppNewData2,
-                this->myAllocator);
+      EndResize (N, newBuck, ppNewData1, ppNewData2);
     }
   }
 
-  //! Add
+  //! Returns the Index of already bound Key or appends new Key with specified Item value.
+  //! @param theKey1 Key to search (and to bind, if it was not bound already)
+  //! @param theItem Item value to set for newly bound Key; ignored if Key was already bound
+  //! @return index of Key
   Standard_Integer Add (const TheKeyType& theKey1, const TheItemType& theItem)
   {
-    if (Resizable()) 
+    if (Resizable())
+    {
       ReSize(Extent());
-    Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
-    IndexedDataMapNode * pNode;
-    pNode = (IndexedDataMapNode *) myData1[iK1];
+    }
+
+    const Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
+    IndexedDataMapNode* pNode = (IndexedDataMapNode* )myData1[iK1];
     while (pNode)
     {
       if (Hasher::IsEqual (pNode->Key1(), theKey1))
-        return pNode->Key2();
+      {
+        return pNode->Index();
+      }
       pNode = (IndexedDataMapNode *) pNode->Next();
     }
-    Increment();
-    Standard_Integer iK2 = ::HashCode(Extent(),NbBuckets());
-    pNode = new (this->myAllocator) IndexedDataMapNode (theKey1, Extent(), theItem,
-                                                  myData1[iK1], myData2[iK2]);
-    myData1[iK1] = pNode;
-    myData2[iK2] = pNode;
-    return Extent();
+
+    const Standard_Integer aNewIndex = Increment();
+    pNode = new (this->myAllocator) IndexedDataMapNode (theKey1, aNewIndex, theItem, myData1[iK1]);
+    myData1[iK1]           = pNode;
+    myData2[aNewIndex - 1] = pNode;
+    return aNewIndex;
   }
 
   //! Contains
@@ -262,33 +292,34 @@ template < class TheKeyType,
                    const TheKeyType&      theKey1,
                    const TheItemType&     theItem)
   {
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-    if (theIndex < 1 || theIndex > Extent())
-      Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::Substitute");
-#endif
-    IndexedDataMapNode * p;
+    Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(),
+                                  "NCollection_IndexedDataMap::Substitute : "
+                                  "Index is out of range");
+
     // check if theKey1 is not already in the map
-    Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
-    p = (IndexedDataMapNode *) myData1[iK1];
-    while (p) 
+    const Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
+    IndexedDataMapNode* p = (IndexedDataMapNode *) myData1[iK1];
+    while (p)
     {
-      if (Hasher::IsEqual (p->Key1(), theKey1)) 
-        Standard_DomainError::Raise("NCollection_IndexedDataMap::Substitute");
+      if (Hasher::IsEqual (p->Key1(), theKey1))
+      {
+        if (p->Index() != theIndex)
+        {
+          throw Standard_DomainError ("NCollection_IndexedDataMap::Substitute : "
+                                      "Attempt to substitute existing key");
+        }
+        p->Key1() = theKey1;
+        p->ChangeValue() = theItem;
+        return;
+      }
       p = (IndexedDataMapNode *) p->Next();
     }
 
     // Find the node for the index I
-    Standard_Integer iK2 = ::HashCode (theIndex, NbBuckets());
-    p = (IndexedDataMapNode *) myData2[iK2];
-    while (p) 
-    {
-      if (p->Key2() == theIndex) 
-        break;
-      p = (IndexedDataMapNode*) p->Next2();
-    }
+    p = (IndexedDataMapNode* )myData2[theIndex - 1];
     
     // remove the old key
-    Standard_Integer iK = Hasher::HashCode (p->Key1(), NbBuckets());
+    const Standard_Integer iK = Hasher::HashCode (p->Key1(), NbBuckets());
     IndexedDataMapNode * q = (IndexedDataMapNode *) myData1[iK];
     if (q == p)
       myData1[iK] = (IndexedDataMapNode *) p->Next();
@@ -306,33 +337,38 @@ template < class TheKeyType,
     myData1[iK1] = p;
   }
 
+  //! Swaps two elements with the given indices.
+  void Swap (const Standard_Integer theIndex1,
+             const Standard_Integer theIndex2)
+  {
+    Standard_OutOfRange_Raise_if (theIndex1 < 1 || theIndex1 > Extent()
+                               || theIndex2 < 1 || theIndex2 > Extent(), "NCollection_IndexedDataMap::Swap");
+
+    if (theIndex1 == theIndex2)
+    {
+      return;
+    }
+
+    IndexedDataMapNode* aP1 = (IndexedDataMapNode* )myData2[theIndex1 - 1];
+    IndexedDataMapNode* aP2 = (IndexedDataMapNode* )myData2[theIndex2 - 1];
+    std::swap (aP1->Index(), aP2->Index());
+    myData2[theIndex2 - 1] = aP1;
+    myData2[theIndex1 - 1] = aP2;
+  }
+
   //! RemoveLast
   void RemoveLast (void)
   {
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-    if (Extent() == 0)
-      Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::RemoveLast");
-#endif
-    IndexedDataMapNode * p, * q;
+    const Standard_Integer aLastIndex = Extent();
+    Standard_OutOfRange_Raise_if (aLastIndex == 0, "NCollection_IndexedDataMap::RemoveLast");
+
     // Find the node for the last index and remove it
-    Standard_Integer iK2 = ::HashCode (Extent(), NbBuckets());
-    p = (IndexedDataMapNode *) myData2[iK2];
-    q = NULL;
-    while (p) 
-    {
-      if (p->Key2() == Extent()) 
-        break;
-      q = p;
-      p = (IndexedDataMapNode*) p->Next2();
-    }
-    if (q == NULL) 
-      myData2[iK2] = (IndexedDataMapNode *) p->Next2();
-    else 
-      q->Next2() = p->Next2();
+    IndexedDataMapNode* p = (IndexedDataMapNode* )myData2[aLastIndex - 1];
+    myData2[aLastIndex - 1] = NULL;
     
     // remove the key
-    Standard_Integer iK1 = Hasher::HashCode (p->Key1(), NbBuckets());
-    q = (IndexedDataMapNode *) myData1[iK1];
+    const Standard_Integer iK1 = Hasher::HashCode (p->Key1(), NbBuckets());
+    IndexedDataMapNode* q = (IndexedDataMapNode *) myData1[iK1];
     if (q == p)
       myData1[iK1] = (IndexedDataMapNode *) p->Next();
     else 
@@ -346,81 +382,70 @@ template < class TheKeyType,
     Decrement();
   }
 
-  //! FindKey
-  const TheKeyType& FindKey (const Standard_Integer theKey2) const
+  //! Remove the key of the given index.
+  //! Caution! The index of the last key can be changed.
+  void RemoveFromIndex(const Standard_Integer theIndex)
   {
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-    if (theKey2 < 1 || theKey2 > Extent())
-      Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::FindKey");
-#endif
-    IndexedDataMapNode * pNode2 =
-      (IndexedDataMapNode *) myData2[::HashCode(theKey2,NbBuckets())];
-    while (pNode2)
+    const Standard_Integer aLastInd = Extent();
+    Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > aLastInd, "NCollection_IndexedDataMap::Remove");
+    if (theIndex != aLastInd)
     {
-      if (pNode2->Key2() == theKey2)
-        return pNode2->Key1();
-      pNode2 = (IndexedDataMapNode*) pNode2->Next2();
+      Swap (theIndex, aLastInd);
     }
-    Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindKey");
-    return pNode2->Key1(); // This for compiler
+    RemoveLast();
   }
 
-  //! FindFromIndex
-  const TheItemType& FindFromIndex (const Standard_Integer theKey2) const
+  //! Remove the given key.
+  //! Caution! The index of the last key can be changed.
+  void RemoveKey(const TheKeyType& theKey1)
   {
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-    if (theKey2 < 1 || theKey2 > Extent())
-      Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::FindFromIndex");
-#endif
-    IndexedDataMapNode * pNode2 =
-      (IndexedDataMapNode *) myData2[::HashCode(theKey2,NbBuckets())];
-    while (pNode2)
-    {
-      if (pNode2->Key2() == theKey2)
-        return pNode2->Value();
-      pNode2 = (IndexedDataMapNode*) pNode2->Next2();
+    Standard_Integer anIndToRemove = FindIndex(theKey1);
+    if (anIndToRemove > 0) {
+      RemoveFromIndex(anIndToRemove);
     }
-    Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromIndex");
-    return pNode2->Value(); // This for compiler
+  }
+
+  //! FindKey
+  const TheKeyType& FindKey (const Standard_Integer theIndex) const
+  {
+    Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::FindKey");
+    IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
+    return aNode->Key1();
+  }
+
+  //! FindFromIndex
+  const TheItemType& FindFromIndex (const Standard_Integer theIndex) const
+  {
+    Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::FindFromIndex");
+    IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
+    return aNode->Value();
   }
 
   //! operator ()
-  const TheItemType& operator() (const Standard_Integer theKey2) const
-  { return FindFromIndex (theKey2); }
+  const TheItemType& operator() (const Standard_Integer theIndex) const { return FindFromIndex (theIndex); }
 
   //! ChangeFromIndex
-  TheItemType& ChangeFromIndex (const Standard_Integer theKey2)
+  TheItemType& ChangeFromIndex (const Standard_Integer theIndex)
   {
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-    if (theKey2 < 1 || theKey2 > Extent())
-      Standard_OutOfRange::Raise("NCollection_IndexedDataMap::ChangeFromIndex");
-#endif
-    IndexedDataMapNode * pNode2 =
-      (IndexedDataMapNode *) myData2[::HashCode(theKey2,NbBuckets())];
-    while (pNode2)
-    {
-      if (pNode2->Key2() == theKey2)
-        return pNode2->ChangeValue();
-      pNode2 = (IndexedDataMapNode*) pNode2->Next2();
-    }
-    Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromIndex");
-    return pNode2->ChangeValue(); // This for compiler
+    Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::ChangeFromIndex");
+    IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
+    return aNode->ChangeValue();
   }
 
   //! operator ()
-  TheItemType& operator() (const Standard_Integer theKey2)
-  { return ChangeFromIndex (theKey2); }
+  TheItemType& operator() (const Standard_Integer theIndex) { return ChangeFromIndex (theIndex); }
 
   //! FindIndex
   Standard_Integer FindIndex(const TheKeyType& theKey1) const
   {
     if (IsEmpty()) return 0;
-    IndexedDataMapNode * pNode1 = 
-      (IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
+    IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
     while (pNode1)
     {
-      if (Hasher::IsEqual (pNode1->Key1(), theKey1)) 
-        return pNode1->Key2();
+      if (Hasher::IsEqual (pNode1->Key1(), theKey1))
+      {
+        return pNode1->Index();
+      }
       pNode1 = (IndexedDataMapNode*) pNode1->Next();
     }
     return 0;
@@ -429,45 +454,90 @@ template < class TheKeyType,
   //! FindFromKey
   const TheItemType& FindFromKey(const TheKeyType& theKey1) const
   {
-#if !defined No_Exception && !defined No_Standard_NoSuchObject
-    if (IsEmpty())
-      Standard_NoSuchObject::Raise ("NCollection_IndexedDataMap::FindFromKey");
-#endif
-    IndexedDataMapNode * pNode1 = 
-      (IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
+    Standard_NoSuchObject_Raise_if (IsEmpty(), "NCollection_IndexedDataMap::FindFromKey");
+
+    IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
     while (pNode1)
     {
-      if (Hasher::IsEqual (pNode1->Key1(), theKey1)) 
+      if (Hasher::IsEqual (pNode1->Key1(), theKey1))
+      {
         return pNode1->Value();
+      }
       pNode1 = (IndexedDataMapNode*) pNode1->Next();
     }
-    Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromKey");
-    return pNode1->Value();
+    throw Standard_NoSuchObject("NCollection_IndexedDataMap::FindFromKey");
   }
 
   //! ChangeFromKey
   TheItemType& ChangeFromKey (const TheKeyType& theKey1)
   {
-#if !defined No_Exception && !defined No_Standard_NoSuchObject
-    if (IsEmpty())
-      Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::ChangeFromKey");
-#endif
-    IndexedDataMapNode * pNode1 = 
-      (IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
+    Standard_NoSuchObject_Raise_if (IsEmpty(), "NCollection_IndexedDataMap::ChangeFromKey");
+
+    IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
     while (pNode1)
     {
-      if (Hasher::IsEqual (pNode1->Key1(), theKey1)) 
+      if (Hasher::IsEqual (pNode1->Key1(), theKey1))
+      {
         return pNode1->ChangeValue();
+      }
       pNode1 = (IndexedDataMapNode*) pNode1->Next();
     }
-    Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::ChangeFromKey");
-    return pNode1->ChangeValue();
+    throw Standard_NoSuchObject("NCollection_IndexedDataMap::ChangeFromKey");
+  }
+
+  //! Seek returns pointer to Item by Key. Returns
+  //! NULL if Key was not found.
+  const TheItemType* Seek(const TheKeyType& theKey1) const
+  {
+    return const_cast< NCollection_IndexedDataMap * >( this )->ChangeSeek(theKey1);
+    //NCollection_IndexedDataMap *pMap=(NCollection_IndexedDataMap *)this;
+    //return pMap->ChangeSeek(theKey1);
+  }
+
+  //! ChangeSeek returns modifiable pointer to Item by Key. Returns
+  //! NULL if Key was not found.
+  TheItemType* ChangeSeek (const TheKeyType& theKey1)
+  {
+    if (!IsEmpty()) 
+    {
+      IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
+      while (pNode1)
+      {
+        if (Hasher::IsEqual (pNode1->Key1(), theKey1))
+        {
+          return &pNode1->ChangeValue();
+        }
+        pNode1 = (IndexedDataMapNode*) pNode1->Next();
+      }
+    }
+    return 0L;
+  }
+
+  //! Find value for key with copying.
+  //! @return true if key was found
+  Standard_Boolean FindFromKey (const TheKeyType& theKey1,
+                                TheItemType&      theValue) const
+  {
+    if (IsEmpty())
+    {
+      return Standard_False;
+    }
+    for (IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData1[Hasher::HashCode (theKey1, NbBuckets())];
+         aNode != NULL; aNode = (IndexedDataMapNode* )aNode->Next())
+    {
+      if (Hasher::IsEqual (aNode->Key1(), theKey1))
+      {
+        theValue = aNode->Value();
+        return Standard_True;
+      }
+    }
+    return Standard_False;
   }
 
   //! Clear data. If doReleaseMemory is false then the table of
   //! buckets is not released and will be reused.
   void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
-  { Destroy (IndexedDataMapNode::delNode, this->myAllocator, doReleaseMemory); }
+  { Destroy (IndexedDataMapNode::delNode, doReleaseMemory); }
 
   //! Clear data and reset allocator
   void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
@@ -478,21 +548,16 @@ template < class TheKeyType,
   }
 
   //! Destructor
-  ~NCollection_IndexedDataMap (void)
+  virtual ~NCollection_IndexedDataMap (void)
   { Clear(); }
 
   //! Size
-  virtual Standard_Integer Size(void) const
+  Standard_Integer Size(void) const
   { return Extent(); }
 
  private:
   // ----------- PRIVATE METHODS -----------
 
-  //! Creates Iterator for use on BaseCollection
-  virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& 
-    CreateIterator(void) const
-  { return *(new (this->IterAllocator()) Iterator(*this)); }
-
 };
 
 #endif