-// 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)
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),
+ myIndex (0) {}
+
//! Constructor
- Iterator (const NCollection_IndexedDataMap& theMap) :
- myMap((NCollection_IndexedDataMap *) &theMap),
- myIndex(1) {}
+ Iterator (const NCollection_IndexedDataMap& theMap)
+ : myMap ((NCollection_IndexedDataMap*)&theMap),
+ 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)
+ { ++myIndex; }
+
//! 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
+ Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Value");
return myMap->FindFromIndex(myIndex);
}
+
//! 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
+ Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::ChangeValue");
return myMap->ChangeFromIndex(myIndex);
}
-
+
+ //! Key
+ const TheKeyType& Key() const
+ {
+ Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Key");
+ return myMap->FindKey(myIndex);
+ }
+
+ //! Performs comparison of two iterators.
+ Standard_Boolean IsEqual (const Iterator& theOther) const
+ {
+ return myMap == theOther.myMap &&
+ myIndex == theOther.myIndex;
+ }
+
private:
- NCollection_IndexedDataMap * myMap; //!< Pointer to the map being iterated
- Standard_Integer myIndex; //!< Current index
+ NCollection_IndexedDataMap* myMap; //!< Pointer to 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);
- ReSize (theOther.Extent()-1);
- Standard_Integer i;
- for (i=1; i<=theOther.Extent(); i++)
+ Clear();
+ Standard_Integer anExt = theOther.Extent();
+ if (anExt)
{
- 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;
- Increment();
+ ReSize (anExt-1); //mySize is same after resize
+ for (Standard_Integer anIndexIter = 1; anIndexIter <= anExt; ++anIndexIter)
+ {
+ 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
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();
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
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;
//! 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)
}
//! 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