#ifndef YAP_PACKAGES_CLPBN_HORUS_TINYSET_H_ #define YAP_PACKAGES_CLPBN_HORUS_TINYSET_H_ #include #include #include namespace Horus { template > class TinySet { public: typedef typename std::vector::iterator iterator; typedef typename std::vector::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& 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::size_type i) const; T& operator[] (typename std::vector::size_type i); T front() const; T& front(); T back() const; T& back(); const std::vector& elements() const; bool empty() const; typename std::vector::size_type size() const; void clear(); void reserve (typename std::vector::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::size_type i; for (i = 0; i < s.size(); i++) { out << ((i != 0) ? "," : "") << s.vec_[i]; } out << "}" ; return out; } std::vector vec_; Compare cmp_; }; template inline TinySet::TinySet (const std::vector& elements, const C& cmp) : vec_(elements), cmp_(cmp) { std::sort (begin(), end(), cmp_); iterator it = unique_cmp (begin(), end()); vec_.resize (it - begin()); } template inline typename TinySet::iterator TinySet::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 inline void TinySet::insert_sorted (const T& t) { vec_.push_back (t); assert (consistent()); } template inline void TinySet::remove (const T& t) { iterator it = std::lower_bound (begin(), end(), t, cmp_); if (it != end()) { vec_.erase (it); } } template inline typename TinySet::const_iterator TinySet::find (const T& t) const { const_iterator it = std::lower_bound (begin(), end(), t, cmp_); return it == end() || cmp_(t, *it) ? end() : it; } template inline typename TinySet::iterator TinySet::find (const T& t) { iterator it = std::lower_bound (begin(), end(), t, cmp_); return it == end() || cmp_(t, *it) ? end() : it; } /* set union */ template inline TinySet TinySet::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 inline TinySet TinySet::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 inline TinySet TinySet::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 inline TinySet& TinySet::operator|= (const TinySet& s) { return *this = (*this | s); } template inline TinySet& TinySet::operator&= (const TinySet& s) { return *this = (*this & s); } template inline TinySet& TinySet::operator-= (const TinySet& s) { return *this = (*this - s); } template inline bool TinySet::contains (const T& t) const { return std::binary_search ( vec_.begin(), vec_.end(), t, cmp_); } template inline bool TinySet::contains (const TinySet& s) const { return std::includes ( vec_.begin(), vec_.end(), s.vec_.begin(), s.vec_.end(), cmp_); } template inline bool TinySet::in (const TinySet& s) const { return std::includes ( s.vec_.begin(), s.vec_.end(), vec_.begin(), vec_.end(), cmp_); } template inline bool TinySet::intersects (const TinySet& s) const { return (*this & s).size() > 0; } template inline const T& TinySet::operator[] (typename std::vector::size_type i) const { return vec_[i]; } template inline T& TinySet::operator[] (typename std::vector::size_type i) { return vec_[i]; } template inline T TinySet::front() const { return vec_.front(); } template inline T& TinySet::front() { return vec_.front(); } template inline T TinySet::back() const { return vec_.back(); } template inline T& TinySet::back() { return vec_.back(); } template inline const std::vector& TinySet::elements() const { return vec_; } template inline bool TinySet::empty() const { return vec_.empty(); } template inline typename std::vector::size_type TinySet::size() const { return vec_.size(); } template inline void TinySet::clear() { vec_.clear(); } template inline void TinySet::reserve (typename std::vector::size_type size) { vec_.reserve (size); } template typename TinySet::iterator TinySet::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 inline bool TinySet::consistent() const { typename std::vector::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_