/** ** \file misc/set.hxx ** \brief misc::set: wrapper around std::set. **/ #pragma once #include #include #include #include namespace misc { template template requires Iterator inline set::set(Iter first, Iter last) { this->insert(first, last); } /* Useful to convert a std::vector or other Compare in misc::set. */ template template requires ConstIterableType inline set::set(const Container v) { for (const Key& x : v) this->insert(x); } template inline bool set::has(const Key& k) const { return set_type::find(k) != this->end(); } /* \brief Return the addition of \a data into \a this. \a data must not yet be part of \a this. */ template inline set set::operator+(const Key& data) const { precondition(!(data % *this)); set res(*this); res.insert(data); return res; } /* \brief Insert \a data in \a this. \a data must not yet be part of \a this. */ template inline set& set::operator+=(const Key& data) { precondition(!(data % *this)); this->insert(data); return *this; } /* \brief Return the removal of \a data into \a this. \a data must be part of \a this. */ template inline set set::operator-(const Key& data) const { precondition(data % *this); set res(*this); res.erase(data); return res; } /* \brief Remove \a data from \a this. \a data must be part of \a this. */ template inline set& set::operator-=(const Key& data) { precondition(data % *this); this->erase(data); return *this; } // Union with another set \a s. // FIXME: Deprecate this use, it ought to be direct sum. template inline set set::operator+( const set& s) const { return set_union(*this, s); } // In place union with another set \a s. template inline set& set::operator+=( const set& s) { return *this = *this + s; } // Subtraction with another set \a s. template inline set set::operator-( const set& s) const { return set_difference(*this, s); } // In place subtraction with another set \a s. template inline set& set::operator-=( const set& s) { *this = *this - s; return *this; } // Union with another set \a s. template inline set set::operator|( const set& s) const { return *this + s; } // In place union with another set \a s. template inline set& set::operator|=( const set& s) { return *this += s; } // Intersection with another set \a s. template inline set set::operator&( const set& s) const { return set_intersection(*this, s); } // In place intersection with another set \a s. template inline set& set::operator&=( const set& s) { return *this = *this & s; } template inline set set_difference(const set& s1, const set& s2) { set res; // Specifying the key_comp to use is required: without it, the // first set is properly ordered using its own key_comp, but // neither the second set nor the resulting set are ordering // using it. Even if s1, s2, and res do use the same Compare! std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(res, res.begin()), s1.key_comp()); return res; } template inline set set_intersection(const set& s1, const set& s2) { set res; std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(res, res.begin()), s1.key_comp()); return res; } template inline set set_union(const set& s1, const set& s2) { set res; std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(res, res.begin()), s1.key_comp()); return res; } template inline std::ostream& operator<<(std::ostream& ostr, const set& s) { for (auto i = s.begin(); i != s.end();) { ostr << *i; if (++i != s.end()) ostr << ", "; } return ostr; } template inline bool operator%(const Key& k, const set& s) { return s.has(k); } } // namespace misc