902624f557
"In fact, the f(void) style has been called an "abomination" by Bjarne Stroustrup, the creator of C++, Dennis Ritchie, the co-creator of C, and Doug McIlroy, head of the research department where Unix was born."
410 lines
7.8 KiB
C++
410 lines
7.8 KiB
C++
#ifndef YAP_PACKAGES_CLPBN_HORUS_TINYSET_H_
|
|
#define YAP_PACKAGES_CLPBN_HORUS_TINYSET_H_
|
|
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <ostream>
|
|
|
|
|
|
namespace Horus {
|
|
|
|
template <typename T, typename Compare = std::less<T>>
|
|
class TinySet {
|
|
public:
|
|
typedef typename std::vector<T>::iterator iterator;
|
|
typedef typename std::vector<T>::const_iterator const_iterator;
|
|
|
|
TinySet (const TinySet& s)
|
|
: vec_(s.vec_), cmp_(s.cmp_) { }
|
|
|
|
TinySet (const Compare& cmp = Compare())
|
|
: vec_(), cmp_(cmp) { }
|
|
|
|
TinySet (const T& t, const Compare& cmp = Compare())
|
|
: vec_(1, t), cmp_(cmp) { }
|
|
|
|
TinySet (const std::vector<T>& elements, const Compare& cmp = Compare());
|
|
|
|
iterator insert (const T& t);
|
|
|
|
void insert_sorted (const T& t);
|
|
|
|
void remove (const T& t);
|
|
|
|
const_iterator find (const T& t) const;
|
|
|
|
iterator find (const T& t);
|
|
|
|
/* set union */
|
|
TinySet operator| (const TinySet& s) const;
|
|
|
|
/* set intersection */
|
|
TinySet operator& (const TinySet& s) const;
|
|
|
|
/* set difference */
|
|
TinySet operator- (const TinySet& s) const;
|
|
|
|
TinySet& operator|= (const TinySet& s);
|
|
|
|
TinySet& operator&= (const TinySet& s);
|
|
|
|
TinySet& operator-= (const TinySet& s);
|
|
|
|
bool contains (const T& t) const;
|
|
|
|
bool contains (const TinySet& s) const;
|
|
|
|
bool in (const TinySet& s) const;
|
|
|
|
bool intersects (const TinySet& s) const;
|
|
|
|
const T& operator[] (typename std::vector<T>::size_type i) const;
|
|
|
|
T& operator[] (typename std::vector<T>::size_type i);
|
|
|
|
T front() const;
|
|
|
|
T& front();
|
|
|
|
T back() const;
|
|
|
|
T& back();
|
|
|
|
const std::vector<T>& elements() const;
|
|
|
|
bool empty() const;
|
|
|
|
typename std::vector<T>::size_type size() const;
|
|
|
|
void clear();
|
|
|
|
void reserve (typename std::vector<T>::size_type size);
|
|
|
|
iterator begin() { return vec_.begin(); }
|
|
iterator end () { return vec_.end(); }
|
|
const_iterator begin() const { return vec_.begin(); }
|
|
const_iterator end () const { return vec_.end(); }
|
|
|
|
private:
|
|
iterator unique_cmp (iterator first, iterator last);
|
|
|
|
bool consistent() const;
|
|
|
|
friend bool operator== (const TinySet& s1, const TinySet& s2)
|
|
{
|
|
return s1.vec_ == s2.vec_;
|
|
}
|
|
|
|
friend bool operator!= (const TinySet& s1, const TinySet& s2)
|
|
{
|
|
return ! (s1.vec_ == s2.vec_);
|
|
}
|
|
|
|
friend std::ostream& operator<< (std::ostream& out, const TinySet& s)
|
|
{
|
|
out << "{" ;
|
|
typename std::vector<T>::size_type i;
|
|
for (i = 0; i < s.size(); i++) {
|
|
out << ((i != 0) ? "," : "") << s.vec_[i];
|
|
}
|
|
out << "}" ;
|
|
return out;
|
|
}
|
|
|
|
std::vector<T> vec_;
|
|
Compare cmp_;
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename C> inline
|
|
TinySet<T,C>::TinySet (const std::vector<T>& elements, const C& cmp)
|
|
: vec_(elements), cmp_(cmp)
|
|
{
|
|
std::sort (begin(), end(), cmp_);
|
|
iterator it = unique_cmp (begin(), end());
|
|
vec_.resize (it - begin());
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline typename TinySet<T,C>::iterator
|
|
TinySet<T,C>::insert (const T& t)
|
|
{
|
|
iterator it = std::lower_bound (begin(), end(), t, cmp_);
|
|
if (it == end() || cmp_(t, *it)) {
|
|
vec_.insert (it, t);
|
|
}
|
|
return it;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline void
|
|
TinySet<T,C>::insert_sorted (const T& t)
|
|
{
|
|
vec_.push_back (t);
|
|
assert (consistent());
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline void
|
|
TinySet<T,C>::remove (const T& t)
|
|
{
|
|
iterator it = std::lower_bound (begin(), end(), t, cmp_);
|
|
if (it != end()) {
|
|
vec_.erase (it);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline typename TinySet<T,C>::const_iterator
|
|
TinySet<T,C>::find (const T& t) const
|
|
{
|
|
const_iterator it = std::lower_bound (begin(), end(), t, cmp_);
|
|
return it == end() || cmp_(t, *it) ? end() : it;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline typename TinySet<T,C>::iterator
|
|
TinySet<T,C>::find (const T& t)
|
|
{
|
|
iterator it = std::lower_bound (begin(), end(), t, cmp_);
|
|
return it == end() || cmp_(t, *it) ? end() : it;
|
|
}
|
|
|
|
|
|
|
|
/* set union */
|
|
template <typename T, typename C> inline TinySet<T,C>
|
|
TinySet<T,C>::operator| (const TinySet& s) const
|
|
{
|
|
TinySet res;
|
|
std::set_union (
|
|
vec_.begin(), vec_.end(),
|
|
s.vec_.begin(), s.vec_.end(),
|
|
std::back_inserter (res.vec_),
|
|
cmp_);
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
/* set intersection */
|
|
template <typename T, typename C> inline TinySet<T,C>
|
|
TinySet<T,C>::operator& (const TinySet& s) const
|
|
{
|
|
TinySet res;
|
|
std::set_intersection (
|
|
vec_.begin(), vec_.end(),
|
|
s.vec_.begin(), s.vec_.end(),
|
|
std::back_inserter (res.vec_),
|
|
cmp_);
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
/* set difference */
|
|
template <typename T, typename C> inline TinySet<T,C>
|
|
TinySet<T,C>::operator- (const TinySet& s) const
|
|
{
|
|
TinySet res;
|
|
std::set_difference (
|
|
vec_.begin(), vec_.end(),
|
|
s.vec_.begin(), s.vec_.end(),
|
|
std::back_inserter (res.vec_),
|
|
cmp_);
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline TinySet<T,C>&
|
|
TinySet<T,C>::operator|= (const TinySet& s)
|
|
{
|
|
return *this = (*this | s);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline TinySet<T,C>&
|
|
TinySet<T,C>::operator&= (const TinySet& s)
|
|
{
|
|
return *this = (*this & s);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline TinySet<T,C>&
|
|
TinySet<T,C>::operator-= (const TinySet& s)
|
|
{
|
|
return *this = (*this - s);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::contains (const T& t) const
|
|
{
|
|
return std::binary_search (
|
|
vec_.begin(), vec_.end(), t, cmp_);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::contains (const TinySet& s) const
|
|
{
|
|
return std::includes (
|
|
vec_.begin(), vec_.end(),
|
|
s.vec_.begin(), s.vec_.end(),
|
|
cmp_);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::in (const TinySet& s) const
|
|
{
|
|
return std::includes (
|
|
s.vec_.begin(), s.vec_.end(),
|
|
vec_.begin(), vec_.end(),
|
|
cmp_);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::intersects (const TinySet& s) const
|
|
{
|
|
return (*this & s).size() > 0;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline const T&
|
|
TinySet<T,C>::operator[] (typename std::vector<T>::size_type i) const
|
|
{
|
|
return vec_[i];
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline T&
|
|
TinySet<T,C>::operator[] (typename std::vector<T>::size_type i)
|
|
{
|
|
return vec_[i];
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline T
|
|
TinySet<T,C>::front() const
|
|
{
|
|
return vec_.front();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline T&
|
|
TinySet<T,C>::front()
|
|
{
|
|
return vec_.front();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline T
|
|
TinySet<T,C>::back() const
|
|
{
|
|
return vec_.back();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline T&
|
|
TinySet<T,C>::back()
|
|
{
|
|
return vec_.back();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline const std::vector<T>&
|
|
TinySet<T,C>::elements() const
|
|
{
|
|
return vec_;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::empty() const
|
|
{
|
|
return vec_.empty();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline typename std::vector<T>::size_type
|
|
TinySet<T,C>::size() const
|
|
{
|
|
return vec_.size();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline void
|
|
TinySet<T,C>::clear()
|
|
{
|
|
vec_.clear();
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline void
|
|
TinySet<T,C>::reserve (typename std::vector<T>::size_type size)
|
|
{
|
|
vec_.reserve (size);
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> typename TinySet<T,C>::iterator
|
|
TinySet<T,C>::unique_cmp (iterator first, iterator last)
|
|
{
|
|
if (first == last) {
|
|
return last;
|
|
}
|
|
iterator result = first;
|
|
while (++first != last) {
|
|
if (cmp_(*result, *first)) {
|
|
*(++result) = *first;
|
|
}
|
|
}
|
|
return ++result;
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename C> inline bool
|
|
TinySet<T,C>::consistent() const
|
|
{
|
|
typename std::vector<T>::size_type i;
|
|
for (i = 0; i < vec_.size() - 1; i++) {
|
|
if ( ! cmp_(vec_[i], vec_[i + 1])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace Horus
|
|
|
|
#endif // YAP_PACKAGES_CLPBN_HORUS_TINYSET_H_
|
|
|