// tell emacs we are using -*- C++ -*- // #ifndef SET_H #define SET_H #include "../lib/list.h" #include template class set { public: // constructors set(); set(set & old); // operations set insert(T item); set setunion(const set & right); set intersect(const set & right); set difference(const set & right); int member(T item) const; set & operator = (const set & right); int size(); void makeEmpty(); // friends friend istream & operator >> <> (istream & stream, set & right); friend ostream & operator << <> (ostream & stream, const set & right); protected: list contents; }; // basic constructor template set::set () { } // the copy constructor template set::set (set & old): contents(old.contents) { } template void set::makeEmpty () { contents.deleteAllValues(); } // insert an item into the set. template set set::insert(T item) { // only add item if it is not already there. if (!member(item)) { contents.add(item); } return *this; } // Create a new set that is the union of two given sets. template set set::setunion(const set & right) { // copy the current set set result(*this); // the cast to (list&) removes the "const"-ness of right // We are promising that we will not use the iterator to modify // right.contents. listIterator itr((list&)(right.contents)); for (itr.init(); !itr; ++itr) { result.insert(itr()); } return result; } // Create a new set that is the intersection of two given sets template set set::intersect(const set & right) { // Create an empty result. set result; listIterator itr(contents); for (itr.init(); !itr; ++itr) { if (right.member(itr())) { result.insert(itr()); } } return result; } // Create a new set that contains all elements of *this that are not // in right. template set set::difference(const set & right) { // Create an empty result. set result; listIterator itr(contents); for (itr.init(); !itr; ++itr) { if (!right.member(itr())) { result.insert(itr()); } } return result; } template int set::member (T item) const { return contents.includes(item); } template int set::size () { return contents.length(); } // The assignment operator. We must do a deep copy of the contents // field. template set & set::operator = (const set & right) { // list assignment does the deep copy for us. contents = right.contents; } // I/O operations template istream & operator >> (istream & stream, set & right) { right.makeEmpty(); char c; stream >> c; assert(c == '{'); while (1) { stream >> c; if (c == '}') break; T temp; stream >> temp; right.insert(temp); } return stream; } template ostream & operator << (ostream & stream, const set & right) { stream << "{"; // the cast to (list&) removes the "const"-ness of right // We are promising that we will not use the iterator to modify // right.contents. listIterator itr((list&)(right.contents)); itr.init(); while (!itr) { stream << itr(); ++itr; // if there is another element, print a space first. if (!itr) stream << " "; } stream << "}"; return stream; } #endif