0024271: Provide Boolean operations for NCollection_Map

NCollection_Map - add two maps content Exchange operation without data copying
Add Exchange method to NCollection_DataMap, NCollection_DoubleMap, NCollection_IndexedDataMap, NCollection_IndexedMap
Add NCollection_Map::IsEqual() method
Corrections for gcc - use this->myAllocator
This commit is contained in:
kgv
2013-10-24 12:12:42 +04:00
committed by bugmaster
parent 14b04bd216
commit ab2db9a59e
9 changed files with 439 additions and 6 deletions
@@ -17,7 +17,6 @@
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef NCollection_BaseCollection_HeaderFile
#define NCollection_BaseCollection_HeaderFile
@@ -115,6 +114,13 @@ template<class TheItemType> class NCollection_BaseCollection
return myIterAllocator;
}
//! Exchange allocators of two collections
void exchangeAllocators (NCollection_BaseCollection& theOther)
{
std::swap (myAllocator, theOther.myAllocator);
std::swap (myIterAllocator, theOther.myIterAllocator);
}
protected:
// --------- PROTECTED FIELDS -----------
Handle(NCollection_BaseAllocator) myAllocator;
+11
View File
@@ -199,6 +199,17 @@ class NCollection_BaseMap
Standard_EXPORT Standard_Integer NextPrimeForMap
(const Standard_Integer N) const;
//! Exchange content of two maps without data copying
void exchangeMapsData (NCollection_BaseMap& theOther)
{
std::swap (myData1, theOther.myData1);
std::swap (myData2, theOther.myData2);
//std::swap (isDouble, theOther.isDouble);
std::swap (mySaturated, theOther.mySaturated);
std::swap (myNbBuckets, theOther.myNbBuckets);
std::swap (mySize, theOther.mySize);
}
protected:
// --------- PROTECTED FIELDS -----------
NCollection_ListNode ** myData1;
+8
View File
@@ -152,6 +152,14 @@ template < class TheKeyType,
Standard_TypeMismatch::Raise ("NCollection_DataMap::Assign impossible");
}
//! Exchange the content of two maps without re-allocations.
//! Notice that allocators will be swapped as well!
void Exchange (NCollection_DataMap& theOther)
{
this->exchangeAllocators (theOther);
this->exchangeMapsData (theOther);
}
//! = another map
NCollection_DataMap& operator= (const NCollection_DataMap& theOther)
{
+8 -1
View File
@@ -17,7 +17,6 @@
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef NCollection_DoubleMap_HeaderFile
#define NCollection_DoubleMap_HeaderFile
@@ -162,6 +161,14 @@ template < class TheKey1Type,
Standard_TypeMismatch::Raise ("NCollection_DoubleMap::Assign impossible");
}
//! Exchange the content of two maps without re-allocations.
//! Notice that allocators will be swapped as well!
void Exchange (NCollection_DoubleMap& theOther)
{
this->exchangeAllocators (theOther);
this->exchangeMapsData (theOther);
}
//! = another map
NCollection_DoubleMap& operator=(const NCollection_DoubleMap& theOther)
{
@@ -165,6 +165,14 @@ template < class TheKeyType,
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->exchangeAllocators (theOther);
this->exchangeMapsData (theOther);
}
//! = another map
NCollection_IndexedDataMap& operator=
(const NCollection_IndexedDataMap& theOther)
+8 -1
View File
@@ -17,7 +17,6 @@
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef NCollection_IndexedMap_HeaderFile
#define NCollection_IndexedMap_HeaderFile
@@ -157,6 +156,14 @@ template < class TheKeyType,
Add(anIter.Value());
}
//! Exchange the content of two maps without re-allocations.
//! Notice that allocators will be swapped as well!
void Exchange (NCollection_IndexedMap& theOther)
{
this->exchangeAllocators (theOther);
this->exchangeMapsData (theOther);
}
//! = another map
NCollection_IndexedMap& operator= (const NCollection_IndexedMap& theOther)
{
+279 -1
View File
@@ -17,12 +17,12 @@
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef NCollection_Map_HeaderFile
#define NCollection_Map_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_TListNode.hxx>
#include <NCollection_DefaultHasher.hxx>
@@ -156,6 +156,14 @@ template < class TheKeyType,
Add (anIter.Value());
}
//! Exchange the content of two maps without re-allocations.
//! Notice that allocators will be swapped as well!
void Exchange (NCollection_Map& theOther)
{
this->exchangeAllocators (theOther);
this->exchangeMapsData (theOther);
}
//! = another map
NCollection_Map& operator= (const NCollection_Map& theOther)
{
@@ -313,6 +321,276 @@ template < class TheKeyType,
virtual Standard_Integer Size(void) const
{ return Extent(); }
public:
//!@name Boolean operations with maps as sets of keys
//!@{
//! @return true if two maps contains exactly the same keys
Standard_Boolean IsEqual (const NCollection_Map& theOther) const
{
return Extent() == theOther.Extent()
&& Contains (theOther);
}
//! @return true if this map contains ALL keys of another map.
Standard_Boolean Contains (const NCollection_Map& theOther) const
{
if (this == &theOther
|| theOther.IsEmpty())
{
return Standard_True;
}
else if (Extent() < theOther.Extent())
{
return Standard_False;
}
for (Iterator anIter (theOther); anIter.More(); anIter.Next())
{
if (!Contains (anIter.Key()))
{
return Standard_False;
}
}
return Standard_True;
}
//! Sets this Map to be the result of union (aka addition, fuse, merge, boolean OR) operation between two given Maps
//! The new Map contains the values that are contained either in the first map or in the second map or in both.
//! All previous content of this Map is cleared.
//! This map (result of the boolean operation) can also be passed as one of operands.
void Union (const NCollection_Map& theLeft,
const NCollection_Map& theRight)
{
if (&theLeft == &theRight)
{
Assign (theLeft);
return;
}
if (this != &theLeft
&& this != &theRight)
{
Clear();
}
if (this != &theLeft)
{
for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
{
Add (anIter.Key());
}
}
if (this != &theRight)
{
for (Iterator anIter (theRight); anIter.More(); anIter.Next())
{
Add (anIter.Key());
}
}
}
//! Apply to this Map the boolean operation union (aka addition, fuse, merge, boolean OR) with another (given) Map.
//! The result contains the values that were previously contained in this map or contained in the given (operand) map.
//! This algorithm is similar to method Union().
//! Returns True if contents of this map is changed.
Standard_Boolean Unite (const NCollection_Map& theOther)
{
if (this == &theOther)
{
return Standard_False;
}
const Standard_Integer anOldExtent = Extent();
Union (*this, theOther);
return anOldExtent != Extent();
}
//! Sets this Map to be the result of intersection (aka multiplication, common, boolean AND) operation between two given Maps.
//! The new Map contains only the values that are contained in both map operands.
//! All previous content of this Map is cleared.
//! This same map (result of the boolean operation) can also be used as one of operands.
void Intersection (const NCollection_Map& theLeft,
const NCollection_Map& theRight)
{
if (&theLeft == &theRight)
{
Assign (theLeft);
return;
}
if (this == &theLeft)
{
NCollection_Map aCopy (1, this->myAllocator);
Exchange (aCopy);
Intersection (aCopy, theRight);
return;
}
else if (this == &theRight)
{
NCollection_Map aCopy (1, this->myAllocator);
Exchange (aCopy);
Intersection (theLeft, aCopy);
return;
}
Clear();
if (theLeft.Extent() < theRight.Extent())
{
for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
{
if (theRight.Contains (anIter.Key()))
{
Add (anIter.Key());
}
}
}
else
{
for (Iterator anIter (theRight); anIter.More(); anIter.Next())
{
if (theLeft.Contains (anIter.Key()))
{
Add (anIter.Key());
}
}
}
}
//! Apply to this Map the intersection operation (aka multiplication, common, boolean AND) with another (given) Map.
//! The result contains only the values that are contained in both this and the given maps.
//! This algorithm is similar to method Intersection().
//! Returns True if contents of this map is changed.
Standard_Boolean Intersect (const NCollection_Map& theOther)
{
if (this == &theOther
|| IsEmpty())
{
return Standard_False;
}
const Standard_Integer anOldExtent = Extent();
Intersection (*this, theOther);
return anOldExtent != Extent();
}
//! Sets this Map to be the result of subtraction (aka set-theoretic difference, relative complement,
//! exclude, cut, boolean NOT) operation between two given Maps.
//! The new Map contains only the values that are contained in the first map operands and not contained in the second one.
//! All previous content of this Map is cleared.
void Subtraction (const NCollection_Map& theLeft,
const NCollection_Map& theRight)
{
if (this == &theLeft)
{
Subtract (theRight);
return;
}
else if (this == &theRight)
{
NCollection_Map aCopy (1, this->myAllocator);
Exchange (aCopy);
Subtraction (theLeft, aCopy);
return;
}
Assign (theLeft);
Subtract (theRight);
}
//! Apply to this Map the subtraction (aka set-theoretic difference, relative complement,
//! exclude, cut, boolean NOT) operation with another (given) Map.
//! The result contains only the values that were previously contained in this map and not contained in this map.
//! This algorithm is similar to method Subtract() with two operands.
//! Returns True if contents of this map is changed.
Standard_Boolean Subtract (const NCollection_Map& theOther)
{
if (this == &theOther)
{
if (IsEmpty())
{
return Standard_False;
}
Clear();
return Standard_True;
}
const Standard_Integer anOldExtent = Extent();
for (Iterator anIter (theOther); anIter.More(); anIter.Next())
{
Remove (anIter.Key());
}
return anOldExtent != Extent();
}
//! Sets this Map to be the result of symmetric difference (aka exclusive disjunction, boolean XOR) operation between two given Maps.
//! The new Map contains the values that are contained only in the first or the second operand maps but not in both.
//! All previous content of this Map is cleared. This map (result of the boolean operation) can also be used as one of operands.
void Difference (const NCollection_Map& theLeft,
const NCollection_Map& theRight)
{
if (&theLeft == &theRight)
{
Clear();
return;
}
else if (this == &theLeft)
{
NCollection_Map aCopy (1, this->myAllocator);
Exchange (aCopy);
Difference (aCopy, theRight);
return;
}
else if (this == &theRight)
{
NCollection_Map aCopy (1, this->myAllocator);
Exchange (aCopy);
Difference (theLeft, aCopy);
return;
}
Clear();
for (Iterator anIter (theLeft); anIter.More(); anIter.Next())
{
if (!theRight.Contains (anIter.Key()))
{
Add (anIter.Key());
}
}
for (Iterator anIter (theRight); anIter.More(); anIter.Next())
{
if (!theLeft.Contains (anIter.Key()))
{
Add (anIter.Key());
}
}
}
//! Apply to this Map the symmetric difference (aka exclusive disjunction, boolean XOR) operation with another (given) Map.
//! The result contains the values that are contained only in this or the operand map, but not in both.
//! This algorithm is similar to method Difference().
//! Returns True if contents of this map is changed.
Standard_Boolean Differ (const NCollection_Map& theOther)
{
if (this == &theOther)
{
if (IsEmpty())
{
return Standard_False;
}
Clear();
return Standard_True;
}
const Standard_Integer anOldExtent = Extent();
Difference (*this, theOther);
return anOldExtent != Extent();
}
//!@}
private:
// ----------- PRIVATE METHODS -----------