/*! \file piset.h
* \brief Set container
*
* This file declare PISet
*/
/*
PIP - Platform Independent Primitives
Set container
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
*/
#ifndef PISET_H
#define PISET_H
#include "pimap.h"
/*! \brief Set of any type
* \details This class used to store collection of unique elements
* of any type. You can only add values to set with \a operator<< or
* with function \a insert(). You can discover if value already in
* set with \a operator[] or with function \a find(). These function
* has logarithmic complexity.
*/
template
class PISet: public PIMap {
typedef PIMap _CSet;
public:
//! Contructs an empty set
PISet() {}
//! Contructs set with one element "value"
explicit PISet(const T & value) { _CSet::insert(value, 0); }
//! Contructs set with elements "v0" and "v1"
PISet(const T & v0, const T & v1) {
_CSet::insert(v0, 0);
_CSet::insert(v1, 0);
}
//! Contructs set with elements "v0", "v1" and "v2"
PISet(const T & v0, const T & v1, const T & v2) {
_CSet::insert(v0, 0);
_CSet::insert(v1, 0);
_CSet::insert(v2, 0);
}
//! Contructs set with elements "v0", "v1", "v2" and "v3"
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {
_CSet::insert(v0, 0);
_CSet::insert(v1, 0);
_CSet::insert(v2, 0);
_CSet::insert(v3, 0);
}
//! Contructs set from vector of elements
explicit PISet(const PIVector & values) {
if (values.isEmpty()) return;
for (int i = 0; i < values.size_s(); ++i) {
_CSet::insert(values[i], 0);
}
}
//! Contructs set from deque of elements
explicit PISet(const PIDeque & values) {
if (values.isEmpty()) return;
for (int i = 0; i < values.size_s(); ++i) {
_CSet::insert(values[i], 0);
}
}
typedef T key_type;
PISet & operator<<(const T & t) {
_CSet::insert(t, 0);
return *this;
}
PISet & operator<<(T && t) {
_CSet::insert(std::move(t), 0);
return *this;
}
PISet & operator<<(const PISet & other) {
(*(_CSet *)this) << *((_CSet *)&other);
return *this;
}
//! Returns if element "t" exists in this set
bool operator[](const T & t) const { return _CSet::contains(t); }
//! Returns if element "t" exists in this set
PISet & remove(const T & t) {
_CSet::remove(t);
return *this;
}
//! Unite set with "v"
PISet & unite(const PISet & v) {
for (typename PIMap::const_iterator i = v.begin(); i != v.end(); ++i)
_CSet::insert(i.key(), 0);
return *this;
}
//! Subtract set with "v"
PISet & subtract(const PISet & v) {
for (typename PIMap::const_iterator i = v.begin(); i != v.end(); ++i)
_CSet::remove(i.key());
return *this;
}
//! Intersect set with "v"
PISet & intersect(const PISet & v) {
for (typename _CSet::iterator i = _CSet::begin(); i != _CSet::end(); ++i)
if (!v.contains(i.key())) {
_CSet::remove(i.key());
--i;
}
return *this;
}
//! Unite set with "v"
PISet & operator+=(const PISet & v) { return unite(v); }
//! Unite set with "v"
PISet & operator|=(const PISet & v) { return unite(v); }
//! Subtract set with "v"
PISet & operator-=(const PISet & v) { return subtract(v); }
//! Intersect set with "v"
PISet & operator&=(const PISet & v) { return intersect(v); }
//! Returns content of set as PIVector
PIVector toVector() const {
PIVector ret;
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
ret << i.key();
return ret;
}
//! Returns content of set as PIDeque
PIDeque toDeque() const {
PIDeque ret;
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
ret << i.key();
return ret;
}
};
//! \relatesalso PISet \brief Returns unite of two sets
template
PISet operator+(const PISet & v0, const PISet & v1) {
PISet ret(v0);
ret.unite(v1);
return ret;
}
//! \relatesalso PISet \brief Returns subtraction of two sets
template
PISet operator-(const PISet & v0, const PISet & v1) {
PISet ret(v0);
ret.subtract(v1);
return ret;
}
//! \relatesalso PISet \brief Returns unite of two sets
template
PISet operator|(const PISet & v0, const PISet & v1) {
PISet ret(v0);
ret.unite(v1);
return ret;
}
//! \relatesalso PISet \brief Returns intersetion of two sets
template
PISet operator&(const PISet & v0, const PISet & v1) {
PISet ret(v0);
ret.intersect(v1);
return ret;
}
template
inline PICout operator<<(PICout s, const PISet & v) {
s.space();
s.saveAndSetControls(0);
s << "{";
bool first = true;
for (typename PIMap::const_iterator i = v.begin(); i != v.end(); ++i) {
if (!first) s << ", ";
first = false;
s << i.key();
}
s << "}";
s.restoreControls();
return s;
}
#endif // PISET_H