Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 2005-2026 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_PackedMapAlgo_HeaderFile
#define NCollection_PackedMapAlgo_HeaderFile
#include <NCollection_PackedMap.hxx>
//! @brief Algorithms and utilities for NCollection_PackedMap operations.
//!
//! This namespace provides template functions for boolean operations
//! on packed maps: union, intersection, subtraction, and symmetric difference.
//! These algorithms are optimized for the packed bit representation.
namespace NCollection_PackedMapAlgo
{
//! Apply to theMap the boolean operation union (aka addition, fuse, merge, boolean OR)
//! with another (given) Map. The result contains the values that were previously
//! contained in theMap or contained in the given (operand) map.
//! @return True if content of theMap is changed
template <class IntType>
bool Unite(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (theOtherMap.IsEmpty() || &theMap == &theOtherMap)
return false;
else if (theMap.IsEmpty())
{
theMap.Assign(theOtherMap);
return true;
}
const int anOldExtent = theMap.Extent();
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theOtherMap); anIter.More();
anIter.Next())
{
theMap.Add(anIter.Key());
}
return anOldExtent != theMap.Extent();
}
//! Sets theMap 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 theMap is cleared. theMap (result of the boolean
//! operation) can also be passed as one of operands.
template <class IntType>
void Union(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theLeftMap,
const NCollection_PackedMap<IntType>& theRightMap)
{
if (theLeftMap.IsEmpty())
theMap.Assign(theRightMap);
else if (theRightMap.IsEmpty())
theMap.Assign(theLeftMap);
else if (&theMap == &theLeftMap)
Unite(theMap, theRightMap);
else if (&theMap == &theRightMap)
Unite(theMap, theLeftMap);
else
{
theMap.Clear();
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theLeftMap); anIter.More();
anIter.Next())
{
theMap.Add(anIter.Key());
}
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theRightMap); anIter.More();
anIter.Next())
{
theMap.Add(anIter.Key());
}
}
}
//! Apply to theMap the intersection operation (aka multiplication, common, boolean AND)
//! with another (given) Map. The result contains only the values that are contained in
//! both theMap and the given map.
//! @return True if content of theMap is changed
template <class IntType>
bool Intersect(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (theMap.IsEmpty())
return false;
else if (theOtherMap.IsEmpty())
{
theMap.Clear();
return true;
}
else if (&theMap == &theOtherMap)
return false;
const int anOldExtent = theMap.Extent();
NCollection_PackedMap<IntType> aCopy;
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theMap); anIter.More();
anIter.Next())
{
if (theOtherMap.Contains(anIter.Key()))
{
aCopy.Add(anIter.Key());
}
}
theMap = std::move(aCopy);
return anOldExtent != theMap.Extent();
}
//! Sets theMap 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 theMap is cleared.
//! theMap (result of the boolean operation) can also be used as one of operands.
template <class IntType>
void Intersection(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theLeftMap,
const NCollection_PackedMap<IntType>& theRightMap)
{
if (theLeftMap.IsEmpty() || theRightMap.IsEmpty())
theMap.Clear();
else if (&theMap == &theLeftMap)
Intersect(theMap, theRightMap);
else if (&theMap == &theRightMap)
Intersect(theMap, theLeftMap);
else
{
theMap.Clear();
const NCollection_PackedMap<IntType>* aSmaller = &theLeftMap;
const NCollection_PackedMap<IntType>* aLarger = &theRightMap;
if (theLeftMap.Extent() > theRightMap.Extent())
{
aSmaller = &theRightMap;
aLarger = &theLeftMap;
}
for (typename NCollection_PackedMap<IntType>::Iterator anIter(*aSmaller); anIter.More();
anIter.Next())
{
if (aLarger->Contains(anIter.Key()))
{
theMap.Add(anIter.Key());
}
}
}
}
//! Apply to theMap 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 theMap and not contained in theOtherMap.
//! @return True if content of theMap is changed
template <class IntType>
bool Subtract(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (&theMap == &theOtherMap)
{
if (theMap.IsEmpty())
{
return false;
}
theMap.Clear();
return true;
}
if (theMap.IsEmpty() || theOtherMap.IsEmpty())
return false;
const int anOldExtent = theMap.Extent();
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theOtherMap); anIter.More();
anIter.Next())
{
theMap.Remove(anIter.Key());
}
return anOldExtent != theMap.Extent();
}
//! Sets theMap 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 operand and not contained
//! in the second one. All previous content of theMap is cleared.
template <class IntType>
void Subtraction(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theLeftMap,
const NCollection_PackedMap<IntType>& theRightMap)
{
if (&theMap == &theLeftMap)
{
Subtract(theMap, theRightMap);
return;
}
else if (&theMap == &theRightMap)
{
NCollection_PackedMap<IntType> aCopy;
Subtraction(aCopy, theLeftMap, theRightMap);
theMap = std::move(aCopy);
return;
}
theMap.Assign(theLeftMap);
Subtract(theMap, theRightMap);
}
//! Apply to theMap the symmetric difference (aka exclusive disjunction, boolean XOR)
//! operation with another (given) Map. The result contains the values that are contained
//! only in theMap or the operand map, but not in both.
//! @return True if content of theMap is changed
template <class IntType>
bool Differ(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (&theMap == &theOtherMap)
{
if (theMap.IsEmpty())
{
return false;
}
theMap.Clear();
return true;
}
if (theOtherMap.IsEmpty())
return false;
else if (theMap.IsEmpty())
{
theMap.Assign(theOtherMap);
return true;
}
const int anOldExtent = theMap.Extent();
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theOtherMap); anIter.More();
anIter.Next())
{
const IntType aKey = anIter.Key();
if (theMap.Contains(aKey))
theMap.Remove(aKey);
else
theMap.Add(aKey);
}
return anOldExtent != theMap.Extent();
}
//! Sets theMap 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 theMap is cleared. theMap (result of the boolean operation)
//! can also be used as one of operands.
template <class IntType>
void Difference(NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theLeftMap,
const NCollection_PackedMap<IntType>& theRightMap)
{
if (&theLeftMap == &theRightMap)
{
theMap.Clear();
return;
}
else if (&theMap == &theLeftMap)
{
Differ(theMap, theRightMap);
return;
}
else if (&theMap == &theRightMap)
{
Differ(theMap, theLeftMap);
return;
}
theMap.Clear();
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theLeftMap); anIter.More();
anIter.Next())
{
if (!theRightMap.Contains(anIter.Key()))
{
theMap.Add(anIter.Key());
}
}
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theRightMap); anIter.More();
anIter.Next())
{
if (!theLeftMap.Contains(anIter.Key()))
{
theMap.Add(anIter.Key());
}
}
}
//! Returns True if theMap and theOtherMap have common elements.
template <class IntType>
bool HasIntersection(const NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (theMap.IsEmpty() || theOtherMap.IsEmpty())
return false;
if (&theMap == &theOtherMap)
return true;
const NCollection_PackedMap<IntType>* aSmaller = &theMap;
const NCollection_PackedMap<IntType>* aLarger = &theOtherMap;
if (theMap.Extent() > theOtherMap.Extent())
{
aSmaller = &theOtherMap;
aLarger = &theMap;
}
for (typename NCollection_PackedMap<IntType>::Iterator anIter(*aSmaller); anIter.More();
anIter.Next())
{
if (aLarger->Contains(anIter.Key()))
{
return true;
}
}
return false;
}
//! Checks if theMap contains all keys of theOtherMap.
//! Returns True if theMap is a superset of theOtherMap (theOtherMap is a subset of theMap).
template <class IntType>
bool Contains(const NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (&theMap == &theOtherMap || theOtherMap.IsEmpty())
{
return true;
}
else if (theMap.Extent() < theOtherMap.Extent())
{
return false;
}
for (typename NCollection_PackedMap<IntType>::Iterator anIter(theOtherMap); anIter.More();
anIter.Next())
{
if (!theMap.Contains(anIter.Key()))
{
return false;
}
}
return true;
}
//! Returns True if theMap is a subset of theOtherMap, i.e. all elements
//! contained in theMap are also contained in theOtherMap.
//! If theMap is empty, this method returns true for any operand map.
template <class IntType>
bool IsSubset(const NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
return Contains(theOtherMap, theMap);
}
//! Checks if two maps contain exactly the same keys.
//! Returns True if theMap and theOtherMap are equal.
template <class IntType>
bool IsEqual(const NCollection_PackedMap<IntType>& theMap,
const NCollection_PackedMap<IntType>& theOtherMap)
{
if (&theMap == &theOtherMap)
{
return true;
}
return theMap.Extent() == theOtherMap.Extent() && Contains(theMap, theOtherMap);
}
} // namespace NCollection_PackedMapAlgo
#endif // NCollection_PackedMapAlgo_HeaderFile