/*! \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 PIP_EXPORT PISet: public PIMap { typedef PIMap _CSet; public: //! Contructs an empty set PISet() {} virtual ~PISet() {;} //! Contructs set with one element "value" 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 PISet(const PIVector & values) { if (values.isEmpty()) return; //_CSet::pim_content.resize(values.size_s()); //_CSet::pim_index.resize(values.size_s()); for (int i = 0; i < values.size_s(); ++i) { //_CSet::pim_index[i].index = i; //_CSet::pim_index[i].key = values[i]; _CSet::insert(values[i], 0); } //_CSet::_sort(); } //! Contructs set from deque of elements PISet(const PIDeque & values) { if (values.isEmpty()) return; //_CSet::pim_content.resize(values.size_s()); //_CSet::pim_index.resize(values.size_s()); for (int i = 0; i < values.size_s(); ++i) { //_CSet::pim_index[i].index = i; //_CSet::pim_index[i].key = values[i]; _CSet::insert(values[i], 0); } //_CSet::_sort(); } typedef T key_type; PISet & operator <<(const T & t) {_CSet::insert(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->first, 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->first); 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).first; 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).first; 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.setControl(0, true); s << "{"; bool first = true; for (typename PIMap::const_iterator i = v.begin(); i != v.end(); ++i) { if (!first) s << ", "; first = false; s << i->first; } s << "}"; s.restoreControl(); return s; } #endif // PISET_H