#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Hash/HSet.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVL_HSET_HEADER #define RAVL_HSET_HEADER 1 /////////////////////////////////////////////////////////////// //! file="Ravl/Core/Container/Hash/HSet.hh" //! lib=RavlCore //! userlevel=Normal //! author="Charles Galambos" //! date="2/9/1996" //! docentry="Ravl.Core.Hash Tables" //! rcsid="$Id: HSet.hh,v 1.6 2002/07/29 14:27:09 craftit Exp $" #include "Ravl/RCHash.hh" #include "Ravl/HashIter.hh" #include "Ravl/Random.hh" #include "Ravl/Empty.hh" namespace RavlN { template class HSetIterC; //: Set of objects. // This is based on the templated hash tables. // Object must provide the Hash function needed by HashC. // see "amma/Hash.hh"

// BIG OBJECT template class HSetC { public: inline HSetC() : set(true) { RavlAssert(set.IsValid()); } //: Default constructor. inline HSetC(istream &in); //: stream constructor. inline HSetC(const HSetC &Oth); //: Copy constructor. HSetC Copy() const; //: Make a Shallow copy of the set. inline bool IsMember(const T &It) const { return set.IsElm(It); } //: Is 'It' a member of the set ? inline bool Contains(const T &It) const { return set.IsElm(It); } //: Is 'It' a member of the set ? inline bool operator[](const T &It) const { return set.IsElm(It); } //: Is 'It' a member of the set ? inline bool Insert(const T &It) { return !set.Insert(It,EmptyC()); } //: Insert an element into the set. // Ret = False, member already present. // True, new member added. inline bool Remove(const T &It) { return set.Del(It); } //: Remove an item from the set. // Ret = True, item removed. // False, item not in set. inline void Empty() { set.Empty(); } //: Remove everthing from the set. inline UIntT Size() const { return set.Size(); } //: Number of elements in set. inline HSetC &operator+=(const T &dat); //: Add a member to the set. inline HSetC &operator-=(const T &dat); //: Remove a member from the set. inline HSetC &operator+=(const HSetC &dat); //: Add a set to this set. inline HSetC &operator-=(const HSetC &dat); //: Remove a set from this one. const T &Random() const; //: Select a random member of the set. // NOTE: It is the user's responsibility to ensure the // set it not empty when this function is called. const T &First() const; //: Return the first member of the set. // The exact member this returns is undefined, // but it is not random.

// NOTE: It is the user's responsibility to ensure the // set it not empty when this function is called. inline bool IsEmpty() const { return set.IsEmpty(); } //: Test if the set is empty. inline HSetC Union(const HSetC &Oth) const; //: Get Union of another set with this one. inline bool UnionIP(const HSetC &Oth); //: Get Union of another set with this one. // Returns true when resulting set in non-empty. HSetC Intersect(const HSetC &Oth) const; //: Get intersection of another set with this one. bool IntersectIP(const HSetC &Oth); //: Intersect this set with another (In Place) // Returns true when resulting set in non-empty. HSetC Disjunction(const HSetC &Oth) const; //: Return the items in either set but not in both. bool DisjunctionIP(const HSetC &Oth); //: Return the items in either set but not in both. (In Place). // Returns true when resulting set in non-empty. bool IsSubset(const HSetC &oth) const; //: is oth a subset of this ? inline bool Contains(const HSetC &ss) const { return IsSubset(ss); } //: is ss a subset of this one. bool operator==(const HSetC &oth) const; //: Is equal, ie contains all the same members ? inline bool operator!=(const HSetC &oth) const { return !operator==(oth); } //: Is not equal, ie contains different members ? inline void AddFrom(HSetC &oth) { set.AddFrom(oth.set); } //: Add contents of another set into this one. // leave other empty. // More comming soon.... (Or on request. ) private: RCHashC set; friend class HSetIterC; }; /////////////////////////////// //: Set Iterator. // SMALL OBJECT

// This creates a reference to the set, so the set will not be // deleted while an iterator references it.

// You should NOT modify the set while using an iterator on it. // The actions of such a code are unpredictable. template class HSetIterC { public: HSetIterC() {} //: Default constructor. HSetIterC(const HSetIterC &oth); //: Copy Constructor. HSetIterC(const HSetC &oth); //: Constructor. inline bool IsElm() const { return iter.IsElm(); } //: At valid element ? inline operator bool() const { return iter.IsElm(); } //: At valid element ? inline bool First() { return iter.First(); } //: Goto first element. inline bool Next() { return iter.Next(); } //: Goto next element. inline bool operator++(int) { return iter.Next(); } //: Goto next element. inline const T &Data() const { return iter.Key(); } //: Access data element. inline const T &operator*() const { return iter.Key(); } //: Access data element. inline const T *operator->() const { return &iter.Key(); } //: Access data element. inline bool IsInSet(const HSetC &oth) const { return (oth.set == set); } //: Is iterator going through set 'oth' ? private: RCHashC set; // Make a handle to set. HashIterC iter; }; /////////////////////////////////////////////// template HSetIterC::HSetIterC(const HSetIterC &oth) : set(oth.set), iter(oth.iter) {} template HSetIterC::HSetIterC(const HSetC &oth) : set(oth.set), iter((const_cast &>(oth)).set.Data()) {} template HSetC HSetC::Copy() const { HSetC ret; for(HSetIterC it(const_cast &>(*this)); it.IsElm();it.Next()) ret.Insert(it.Data()); return ret; } ////////////////////////////////////////////////////// template inline HSetC::HSetC(istream &in) : set(in) { RavlAssert(set.IsValid()); } template inline HSetC::HSetC(const HSetC &Oth) : set(Oth.set) { RavlAssert(set.IsValid()); } template inline HSetC &HSetC::operator+=(const T &dat) { Insert(dat); return *this; } template inline HSetC &HSetC::operator-=(const T &dat) { Remove(dat); return *this; } template inline HSetC &HSetC::operator+=(const HSetC &dat) { set.Data().Add(dat.set.Data(),false); return *this; } template inline HSetC &HSetC::operator-=(const HSetC &dat) { for(HSetIterC it(dat);it.IsElm();it.Next()) Remove(it.Data()); return *this; } template const T &HSetC::Random() const { // Maybe not the fastest method, but it'll do for now. IntT sel = RandomInt() % Size(); HashIterC it(set.Data()); for(;sel > 0 && it.IsElm();sel--,it.Next()) ; RavlAssert(it.IsElm()); return it.Key(); } template const T &HSetC::First() const { HashIterC it(set.Data()); RavlAssert(it.IsElm()); return it.Key(); } template inline HSetC HSetC::Union(const HSetC &oth) const { HSetC ret = Copy(); ret += oth; return ret; } template inline bool HSetC::UnionIP(const HSetC &oth) { (*this) += oth; return !IsEmpty(); } template HSetC HSetC::Intersect(const HSetC &oth) const { HSetC ret; // Iterate through the smaller set. if(Size() < oth.Size()) { for(HSetIterC it(const_cast &>(*this));it.IsElm();it.Next()) { if(oth.IsMember(it.Data())) ret.Insert(it.Data()); } } else { for(HSetIterC it(const_cast &>(oth));it.IsElm();it.Next()) { if(IsMember(it.Data())) ret.Insert(it.Data()); } } return ret; } template bool HSetC::IntersectIP(const HSetC &Oth) { for(HSetIterC Iter(*this);Iter.IsElm();Iter.Next()) if(!Oth.IsMember(Iter.Data())) Remove(Iter.Data()); return !IsEmpty(); } template HSetC HSetC::Disjunction(const HSetC &Oth) const { HSetC ret; for(HSetIterC Iter(Oth);Iter;Iter++) { if(!IsMember(Iter.Data())) ret.Insert(Iter.Data()); } for(HSetIterC Iter2(*this);Iter2;Iter2++) { if(!Oth.IsMember(Iter2.Data())) ret.Insert(Iter2.Data()); } return ret; } template bool HSetC::DisjunctionIP(const HSetC &Oth) { for(HSetIterC Iter(Oth);Iter.IsElm();Iter.Next()) { if(IsMember(Iter.Data())) Remove(Iter.Data()); // Remove common members. else Insert(Iter.Data()); // Add those in both. } return !IsEmpty(); } template bool HSetC::IsSubset(const HSetC &oth) const { if(Size() < oth.Size()) return false; // Can't be its bigger ! for(HSetIterC it(const_cast &>(oth));it.IsElm();it.Next()) if(!IsMember(it.Data())) return false; return true; } //: Is equal, ie contains all the same members ? template bool HSetC::operator==(const HSetC &oth) const { if(this == &oth) return true; // They're the same set !! if(Size() != oth.Size()) // Must be the same size to start with. return false; for(HSetIterC it(const_cast &>(oth));it.IsElm();it.Next()) if(!IsMember(it.Data())) return false; return true; // Member can't be duplicated, so must be the same. } template ostream &operator<<(ostream &out,const HSetC &obj) { out << obj.Size() << "\n"; for(HSetIterC it(const_cast &>(obj));it.IsElm();it.Next()) out << it.Data() << "\n"; return out; } template istream &operator>>(istream &in,HSetC &obj) { UIntT size; in >> size; T tmp; obj = HSetC(); for(UIntT i = 0;i < size;i++) { in >> tmp; obj.Insert(tmp); } return in; } class BinOStreamC; class BinIStreamC; template BinOStreamC &operator<<(BinOStreamC &out,const HSetC &obj) { out << obj.Size(); for(HSetIterC it(const_cast &>(obj));it.IsElm();it.Next()) out << it.Data(); return out; } template BinIStreamC &operator>>(BinIStreamC &in,HSetC &obj) { UIntT size; in >> size; T tmp; obj = HSetC(); for(UIntT i = 0;i < size;i++) { in >> tmp; obj.Insert(tmp); } return in; } } #endif