blob: f9e75f1466b72af93fce610e29f8f747dad0a711 [file] [log] [blame]
#ifndef _SV_ORDERED_SET_HH_
#define _SV_ORDERED_SET_HH_ 1
#include <algorithm>
namespace sv {
////////////////////////////////////////////////////////////////////////////////////////////////////
/// A set implemented atop a sorted vector.
template< typename Key,
typename Compare = std::less<Key>,
typename Alloc = std::allocator<Key> >
class set {
typedef std::vector<Key, Alloc> internal_type;
// Types
public:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef Alloc allocator_type;
typedef typename Alloc::reference reference;
typedef typename Alloc::const_reference const_reference;
typedef typename Alloc::pointer pointer;
typedef typename Alloc::const_pointer const_pointer;
typedef typename internal_type::const_iterator const_iterator;
typedef typename internal_type::iterator iterator;
typedef typename internal_type::reverse_iterator reverse_iterator;
typedef typename internal_type::const_reverse_iterator const_reverse_iterator;
typedef typename internal_type::size_type size_type;
typedef typename internal_type::difference_type difference_type;
private:
internal_type container_;
void sort_unique() {
std::sort(container_.begin(), container_.end());
iterator i = std::unique(container_.begin(), container_.end());
container_.erase(i, container_.end());
}
public:
/// Empty constructor.
set()
: container_() { }
/// Constructor taking a range.
template< typename Iterator >
set(const Iterator& begin, const Iterator& end)
: container_(begin, end) {
sort_unique();
}
/// Copy-constructor.
set(const set& rhs)
: container_(rhs.container_)
{}
/// Affectation of a sorted vector to another one.
set & operator=(const set& rhs) {
if (&rhs != this) {
this->container_ = rhs.container_;
}
return *this;
}
/// Returns the beginning of the sorted vector.
const_iterator begin() const {
return container_.begin();
}
/// Returns the end of the sorted vector.
const_iterator end() const {
return container_.end();
}
/// Returns the beginning of the sorted vector.
iterator begin() {
return container_.begin();
}
/// Returns the end of the sorted vector.
iterator end() {
return container_.end();
}
/// Returns the beginning of the sorted vector.
const_reverse_iterator rrbegin() const {
return container_.rbegin();
}
/// Returns the end of the sorted vector.
const_reverse_iterator rend() const {
return container_.rend();
}
/// Returns the beginning of the sorted vector.
reverse_iterator rbegin() {
return container_.rbegin();
}
/// Returns the end of the sorted vector.
reverse_iterator rend() {
return container_.rend();
}
bool empty() const {
return container_.empty();
}
size_type size() const {
return container_.size();
}
size_type max_size() const {
return container_.max_size();
}
/// Insert a value into the sorted vector.
std::pair<iterator,bool>
insert(const value_type& x) {
bool insertion = false;
iterator i = std::lower_bound(container_.begin(), container_.end(), x);
if (i == container_.end() || x < *i) {
i = container_.insert(i, x);
insertion = true;
}
return std::make_pair(i, insertion);
}
/// Insert a range.
template < typename Iterator >
void insert(Iterator _begin, Iterator _end) {
while (_begin != _end)
container_.push_back(*_begin++);
sort_unique();
}
void erase ( iterator position ) {
container_.erase(position);
}
size_type erase(const key_type& x) {
iterator i = find(x);
if (i != end()) {
erase(i);
return 1;
}
return 0;
}
void erase ( iterator first, iterator last ) {
container_.erase(first, last);
}
/// Swap the content of two sorted_vector.
void swap(set& s) {
container_.swap(s.container_);
}
void clear() {
container_.clear();
}
/// Find the key k.
const_iterator find(const key_type& k) const {
const_iterator i = std::lower_bound(container_.begin(), container_.end(), k);
if (*i == k) return i;
return container_.end();
}
iterator find(const key_type& k) {
iterator i = std::lower_bound(container_.begin(), container_.end(), k);
if (*i == k) return i;
return container_.end();
}
bool count(const key_type& k) const {
return find(k) != end();
}
iterator lower_bound(const key_type& x) const {
return std::lower_bound(container_.begin(), container_.end(), x);
}
iterator upper_bound(const key_type& x) const {
return std::upper_bound(container_.begin(), container_.end(), x);
}
std::pair<iterator,iterator> equal_range(const key_type& x) const {
return std::make_pair(lower_bound(x),upper_bound(x));
}
/// Tells if this sorted vector is equal to another one.
bool operator==(const set& rhs) const {
return container_ == rhs.container_;
}
bool operator<(const set& rhs) const {
if (rhs.size() < size()) return false;
if (size() < rhs.size()) return true;
const_iterator ii = begin();
const_iterator ee = end();
const_iterator rhs_ii = rhs.begin();
const_iterator rhs_ee = rhs.end();
while (ii != ee) {
if (*rhs_ii < *ii) return false;
if (*ii < *rhs_ii) return true;
++ii;
++rhs_ii;
}
// Equal
return false;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
} // end of namespace sv
#endif // _SV_ORDERED_SET_HH_