Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
set.hpp 3.41 KiB
/*
 * std.hpp
 *
 * Created on: Apr 1, 2013
 * Author: Jan Travnicek
 */

#ifndef __SET_HPP_
#define __SET_HPP_

namespace std {

template< class T >
std::ostream& operator<<(std::ostream& out, const std::set<T>& list) {
	out << "{";

	bool first = true;
	for(const T& item : list) {
		if(!first) out << ", ";
		first = false;
		out << item;
	}

	out << "}";
	return out;
}

template<class T>
struct compare<set<T>> {
	int operator()(const set<T>& first, const set<T>& second) const {
		if(first.size() < second.size()) return -1;
		if(first.size() > second.size()) return 1;

		compare<T> comp;
		for(auto iterF = first.begin(), iterS = second.begin(); iterF != first.end(); ++iterF, ++iterS) {
			int res = comp(*iterF, *iterS);
			if(res != 0) return res;
		}
		return 0;
	}
};

template<class T>
bool empty_intersection(const set<T>& x, const set<T>& y) {
	auto i = x.begin();
	auto j = y.begin();
	while (i != x.end() && j != y.end()) {
		if (*i == *j)
			return false;
		else if (*i < *j)
			++i;
		else
			++j;
	}
	return true;
}

template <class Iterator>
class set_move_iterator {
	Iterator current;

public:
	typedef Iterator iterator_type;
	typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
	typedef typename iterator_traits<Iterator>::value_type        value_type;
	typedef Iterator pointer;
	typedef value_type&& reference;

	explicit set_move_iterator() {
	}

	explicit set_move_iterator (Iterator it) : current(it) {
	}

	set_move_iterator (const set_move_iterator<Iterator>& it) : current(it.current) {
	}

	set_move_iterator& operator= (const set_move_iterator<Iterator>& it) {
		current = it.current;
	}

	iterator_type base() const {
		return current;
	}

	pointer operator->() const {
		return current;
	}

	reference operator*() const {
		return std::move(const_cast<value_type&>(*current));
	}

	set_move_iterator& operator++() {
		++current;
		return *this;
	}

	set_move_iterator& operator--() {
		--current;
		return *this;
	}

	set_move_iterator operator++(int) {
		set_move_iterator temp = *this;
		++current;
		return temp;
	}

	set_move_iterator operator--(int) {
		set_move_iterator temp = *this;
		--current;
		return temp;
	}

	bool operator== (const set_move_iterator<Iterator>& other) {
		return this->current == other.current;
	}

	bool operator!= (const set_move_iterator<Iterator>& other) {
		return ! ( *this == other );
	}

};

template<class Iterator>
set_move_iterator<Iterator> make_set_move_iterator (Iterator it) {
	return set_move_iterator<Iterator>(it);
}

template<class T>
class moveable_set_ref {
	set<T>& theSet;
public:
	moveable_set_ref(set<T>& param) : theSet(param) {}

	set_move_iterator<typename set<T>::iterator> begin() {
		return make_set_move_iterator(theSet.begin());
	}
	set_move_iterator<typename set<T>::iterator> end() {
		return make_set_move_iterator(theSet.end());
	}
};

template<class T>
moveable_set_ref<T> make_moveable_set (std::set<T>& set) {
	return moveable_set_ref<T>(set);
}

template<class T>
class moveable_set {
	set<T> theSet;
public:
	moveable_set(set<T> param) : theSet(std::move(param)) {}

	set_move_iterator<typename set<T>::iterator> begin() {
		return make_set_move_iterator(theSet.begin());
	}

	set_move_iterator<typename set<T>::iterator> end() {
		return make_set_move_iterator(theSet.end());
	}
};

template<class T>
moveable_set<T> make_moveable_set (std::set<T>&& set) {
	return moveable_set<T>(std::move(set));
}

} /* namespace std */

#endif /* __SET_HPP_ */