/* along with this program. If not, see <http:
#ifndef _set_h
#define _set_h
#include <iostream>
#include "map.h"
#include "vector.h"
template <typename ValueType>
class Set {
public:
Set();
virtual ~Set();
int size() const;
bool isEmpty() const;
void add(const ValueType & value);
void insert(const ValueType & value);
void remove(const ValueType & value);
bool contains(const ValueType & value) const;
bool isSubsetOf(const Set & set2) const;
void clear();
bool operator==(const Set & set2) const;
bool operator!=(const Set & set2) const;
Set operator+(const Set & set2) const;
Set operator+(const ValueType & element) const;
Set operator*(const Set & set2) const;
Set operator-(const Set & set2) const;
Set operator-(const ValueType & element) const;
Set & operator+=(const Set & set2);
Set & operator+=(const ValueType & value);
Set & operator*=(const Set & set2);
Set & operator-=(const Set & set2);
Set & operator-=(const ValueType & value);
ValueType first() const;
std::string toString();
void mapAll(void (*fn)(ValueType)) const;
void mapAll(void (*fn)(const ValueType &)) const;
template <typename FunctorType>
void mapAll(FunctorType fn) const;
private:
Map<ValueType,bool> map;
bool removeFlag;
public:
template <typename CompareType>
explicit Set(CompareType cmp) : map(Map<ValueType,bool>(cmp)) {
}
Set & operator,(const ValueType & value) {
if (this->removeFlag) {
this->remove(value);
} else {
this->add(value);
}
return *this;
}
class iterator : public std::iterator<std::input_iterator_tag,ValueType> {
private:
typename Map<ValueType,bool>::iterator mapit;
public:
iterator() {
}
iterator(typename Map<ValueType,bool>::iterator it) : mapit(it) {
}
iterator(const iterator & it) {
mapit = it.mapit;
}
iterator & operator++() {
++mapit;
return *this;
}
iterator operator++(int) {
iterator copy(*this);
operator++();
return copy;
}
bool operator==(const iterator & rhs) {
return mapit == rhs.mapit;
}
bool operator!=(const iterator & rhs) {
return !(*this == rhs);
}
ValueType operator*() {
return *mapit;
}
ValueType *operator->() {
return mapit;
}
};
iterator begin() const {
return iterator(map.begin());
}
iterator end() const {
return iterator(map.end());
}
};
extern void error(std::string msg);
template <typename ValueType>
Set<ValueType>::Set() {
}
template <typename ValueType>
Set<ValueType>::~Set() {
}
template <typename ValueType>
int Set<ValueType>::size() const {
return map.size();
}
template <typename ValueType>
bool Set<ValueType>::isEmpty() const {
return map.isEmpty();
}
template <typename ValueType>
void Set<ValueType>::add(const ValueType & value) {
map.put(value, true);
}
template <typename ValueType>
void Set<ValueType>::insert(const ValueType & value) {
map.put(value, true);
}
template <typename ValueType>
void Set<ValueType>::remove(const ValueType & value) {
map.remove(value);
}
template <typename ValueType>
bool Set<ValueType>::contains(const ValueType & value) const {
return map.containsKey(value);
}
template <typename ValueType>
void Set<ValueType>::clear() {
map.clear();
}
template <typename ValueType>
bool Set<ValueType>::isSubsetOf(const Set & set2) const {
iterator it = begin();
iterator end = this->end();
while (it != end) {
if (!set2.map.containsKey(*it)) return false;
++it;
}
return true;
}
template <typename ValueType>
bool Set<ValueType>::operator==(const Set & set2) const {
if (size() != set2.map.size()) return false;
iterator it1 = begin();
iterator it2 = set2.map.begin();
iterator end = this->end();
while (it1 != end) {
if (map.compareKeys(*it1, *it2) != 0) return false;
++it1;
++it2;
}
return true;
}
template <typename ValueType>
bool Set<ValueType>::operator!=(const Set & set2) const {
return !(*this == set2);
}
template <typename ValueType>
Set<ValueType> Set<ValueType>::operator+(const Set & set2) const {
Set<ValueType> set = *this;
foreach (ValueType value in set2) {
set.add(value);
}
return set;
}
template <typename ValueType>
Set<ValueType> Set<ValueType>::operator+(const ValueType & element) const {
Set<ValueType> set = *this;
set.add(element);
return set;
}
template <typename ValueType>
Set<ValueType> Set<ValueType>::operator*(const Set & set2) const {
Set<ValueType> set = *this;
set.clear();
foreach (ValueType value in *this) {
if (set2.contains(value)) set.add(value);
}
return set;
}
template <typename ValueType>
Set<ValueType> Set<ValueType>::operator-(const Set & set2) const {
Set<ValueType> set = *this;
foreach (ValueType value in set2) {
set.remove(value);
}
return set;
}
template <typename ValueType>
Set<ValueType> Set<ValueType>::operator-(const ValueType & element) const {
Set<ValueType> set = *this;
set.remove(element);
return set;
}
template <typename ValueType>
Set<ValueType> & Set<ValueType>::operator+=(const Set & set2) {
foreach (ValueType value in set2) {
this->add(value);
}
return *this;
}
template <typename ValueType>
Set<ValueType> & Set<ValueType>::operator+=(const ValueType & value) {
this->add(value);
this->removeFlag = false;
return *this;
}
template <typename ValueType>
Set<ValueType> & Set<ValueType>::operator*=(const Set & set2) {
Vector<ValueType> toRemove;
foreach (ValueType value in *this) {
if (!set2.map.containsKey(value)) toRemove.add(value);
}
foreach (ValueType value in toRemove) {
this->remove(value);
}
return *this;
}
template <typename ValueType>
Set<ValueType> & Set<ValueType>::operator-=(const Set & set2) {
Vector<ValueType> toRemove;
foreach (ValueType value in *this) {
if (set2.map.containsKey(value)) toRemove.add(value);
}
foreach (ValueType value in toRemove) {
this->remove(value);
}
return *this;
}
template <typename ValueType>
Set<ValueType> & Set<ValueType>::operator-=(const ValueType & value) {
this->remove(value);
this->removeFlag = true;
return *this;
}
template <typename ValueType>
ValueType Set<ValueType>::first() const {
if (isEmpty()) error("first: set is empty");
return *begin();
}
template <typename ValueType>
std::string Set<ValueType>::toString() {
ostringstream os;
os << *this;
return os.str();
}
template <typename ValueType>
void Set<ValueType>::mapAll(void (*fn)(ValueType)) const {
map.mapAll(fn);
}
template <typename ValueType>
void Set<ValueType>::mapAll(void (*fn)(const ValueType &)) const {
map.mapAll(fn);
}
template <typename ValueType>
template <typename FunctorType>
void Set<ValueType>::mapAll(FunctorType fn) const {
map.mapAll(fn);
}
template <typename ValueType>
std::ostream & operator<<(std::ostream & os, const Set<ValueType> & set) {
os << "{";
bool started = false;
foreach (ValueType value in set) {
if (started) os << ", ";
writeGenericValue(os, value, true);
started = true;
}
os << "}";
return os;
}
template <typename ValueType>
std::istream & operator>>(std::istream & is, Set<ValueType> & set) {
char ch;
is >> ch;
if (ch != '{') error("operator >>: Missing {");
set.clear();
is >> ch;
if (ch != '}') {
is.unget();
while (true) {
ValueType value;
readGenericValue(is, value);
set += value;
is >> ch;
if (ch == '}') break;
if (ch != ',') {
error(std::string("operator >>: Unexpected character ") + ch);
}
}
}
return is;
}
#endif