diff options
| author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 | 
|---|---|---|
| committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 | 
| commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
| tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Utilities/sorted_vector.h | |
Diffstat (limited to 'Runtime/Utilities/sorted_vector.h')
| -rw-r--r-- | Runtime/Utilities/sorted_vector.h | 358 | 
1 files changed, 358 insertions, 0 deletions
diff --git a/Runtime/Utilities/sorted_vector.h b/Runtime/Utilities/sorted_vector.h new file mode 100644 index 0000000..5f0576f --- /dev/null +++ b/Runtime/Utilities/sorted_vector.h @@ -0,0 +1,358 @@ +#ifndef SORTED_VECTOR_H +#define SORTED_VECTOR_H +#include <vector> +#include <algorithm> + +/// container optimization anschauen (compressed pair for valuecompare) + + +template<class T, class Compare, class Allocator> +class sorted_vector : private Compare +{ +	public: +	 +	typedef				std::vector<T, Allocator>			container; +	typedef typename	container::iterator					iterator; +	typedef typename	container::const_iterator			const_iterator; +	typedef typename	container::reverse_iterator			reverse_iterator; +	typedef typename	container::const_reverse_iterator	const_reverse_iterator; +	typedef typename	container::value_type				value_type; +	typedef typename	container::size_type				size_type; +	typedef typename	container::difference_type			difference_type; +	typedef 			Compare								value_compare; +	typedef typename	Allocator::reference				reference; +	typedef typename	Allocator::const_reference			const_reference; +	typedef				Allocator							allocator_type; + +	value_compare const& get_compare () const { return *static_cast<value_compare const*> (this); } + +		 +	sorted_vector (const Compare& comp, const Allocator& a) +		: c (a), value_compare (comp)	 {} +	 +	 +	bool      			empty() const		{ return c.empty(); } +	size_type			size()  const		{ return c.size(); } +	const value_type&	front() const 		{ return c.front(); } +	const value_type&	back() const		{ return c.front(); } +		 +	const_iterator begin ()const			{ return c.begin (); } +	const_iterator end ()const				{ return c.end (); } +	iterator begin ()						{ return c.begin (); } +	iterator end ()							{ return c.end (); } +	const_reverse_iterator rbegin ()const	{ return c.rbegin (); } +	const_reverse_iterator rend ()const		{ return c.rend (); } +	reverse_iterator rbegin ()				{ return c.rbegin (); } +	reverse_iterator rend ()				{ return c.rend (); } +	 +	value_compare value_comp() const		{ return get_compare ();} +/* +	template <class InputIterator> +	void insert_one (InputIterator first, InputIterator last) +	{ +		c.reserve (size () + std::distance (first, last)); +		for (;first != last;first++) +			insert_one (*i); +	} +	 +	template<typename KeyT, typename MappedT> +	MappedT& find_or_insert (const KeyT& k) +	{ +		iterator i = lower_bound (k); +		if (i == end () || get_compare () (k, *i)) +			return c.insert (i, std::make_pair<KeyT, MappedT> (k, MappedT ()))->second; +		else +			return i->second; +	} +*/ +	 +	template<typename KeyT, typename MappedT> +	void find_or_insert (MappedT*& mappedT, const KeyT& k) +	{ +		iterator i = lower_bound (k); +		if (i == end () || get_compare () (k, *i)) +			#if _MSC_VER >= 1700	// Microsoft Visual Studio 2012 workaround +			mappedT =  &c.insert (i, std::make_pair<KeyT, MappedT> (static_cast<KeyT&&>(const_cast<KeyT&>(k)), MappedT ()))->second; +			#else +			mappedT =  &c.insert (i, std::make_pair<KeyT, MappedT> (k, MappedT ()))->second; +			#endif +		else +			mappedT = &i->second; +	} + +	std::pair<iterator, bool> insert_one (const value_type& x) +	{ +		iterator i = lower_bound (x); +		// is not included in container +		if (i == end () || get_compare () (x, *i)) +			return std::make_pair (c.insert (i, x), true); +		else +			return std::make_pair (i, false); +	 +	} + +	void verify_duplicates_and_sorted () const +	{ +		#if DEBUGMODE +		// Check that there are no duplicates in the set +		if (empty()) +			return; + +		const_iterator previous = c.begin(); +		const_iterator i = c.begin(); +		i++; +		for (; i != c.end();++i) +		{ +			Assert(get_compare ()(*previous, *i)); +			previous = i; +		} +		#endif +	} +	 +	 +	template<class CompareType> +	size_type erase_one (const CompareType& x) +	{ +		iterator i = lower_bound (x); +		if (i == end () || get_compare () (x, *i)) +			return 0; +		else +		{	 +			c.erase (i); +			return 1; +		} +	} +	 +	void      			erase(iterator position)				{ c.erase (position);} +	void      			erase(iterator first, iterator last)	{ c.erase (first, last); } +	void 				swap(sorted_vector& x)					{ c.swap (x.c); } +	 +	void				clear ()								{ c.clear (); } +	 +	template<class T2> +	size_type			count_one (const T2& x)const			 +	{	 +		const_iterator i = lower_bound (x); +		if (i == end () || get_compare () (x, *i)) +			return 0; +		else +			return 1; +	}							 + +	template<class T2> +	iterator				find (const T2& x)						 +	{ +		iterator i = lower_bound (x); +		if (i == end () || get_compare () (x, *i)) +			return end (); +		else +			return i; +	} + +	template<class T2> +	const_iterator				find (const T2& x) const						 +	{ +		const_iterator i = lower_bound (x); +		if (i == end () || get_compare () (x, *i)) +			return end (); +		else +			return i; +	} +		 +	template<class T2> +	iterator lower_bound (const T2& x) +	{ +		return std::lower_bound (c.begin (), c.end (), x, get_compare ()); +	} + +	template<class T2> +	const_iterator lower_bound (const T2& x) const +	{ +		return std::lower_bound (c.begin (), c.end (), x, get_compare ()); +	} + +	template<class T2> +	iterator upper_bound (const T2& x) +	{ +		return std::lower_bound (c.begin (), c.end (), x, get_compare ()); +	} + +	template<class T2> +	const_iterator upper_bound (const T2& x) const +	{ +		return std::lower_bound (c.begin (), c.end (), x, get_compare ()); +	} + +	template<class T2> +	std::pair<iterator, iterator> equal_range (const T2& x) +	{ +		return std::equal_range (c.begin (), c.end (), x, get_compare ()); +	}	 + +	template<class T2> +	std::pair<const_iterator, const_iterator> equal_range (const T2& x) const +	{ +		return std::equal_range (c.begin (), c.end (), x, get_compare ()); +	}	 +	 +	void reserve (size_type n)	{ c.reserve (n); } + +	value_type& operator [] (int n) { return c[n]; } +	const value_type& operator [] (int n) const { return c[n]; } + +	public: + +	container		c; +}; + +template<class T, class Compare, class Allocator> +class unsorted_vector : private Compare +{ +	public: +	 +	typedef         	std::vector<T, Allocator>			container; +	typedef typename	container::iterator					iterator; +	typedef typename	container::const_iterator			const_iterator; +	typedef typename	container::reverse_iterator			reverse_iterator; +	typedef typename	container::const_reverse_iterator	const_reverse_iterator; + +	typedef typename	container::value_type				value_type; +	typedef typename	container::size_type				size_type; +	typedef typename	container::difference_type			difference_type; +	typedef 			Compare								value_compare;					 +	typedef typename	Allocator::reference				reference; +	typedef typename	Allocator::const_reference			const_reference; +	typedef				Allocator							allocator_type; + +	value_compare const& get_compare () const { return *static_cast<value_compare const*> (this); } + +	unsorted_vector (const Compare& comp, const Allocator& a) +		: c (a), value_compare (comp)  {} +	 +	 +	bool      			empty() const		{ return c.empty(); } +	size_type			size()  const		{ return c.size(); } +	const value_type&	front() const 		{ return c.front(); } +	const value_type&	back() const		{ return c.front(); } +		 +	const_iterator begin ()const			{ return c.begin (); } +	const_iterator end ()const				{ return c.end (); } +	iterator begin ()						{ return c.begin (); } +	iterator end ()							{ return c.end (); } +	const_reverse_iterator rbegin ()const	{ return c.rbegin (); } +	const_reverse_iterator rend ()const		{ return c.rend (); } +	reverse_iterator rbegin ()				{ return c.rbegin (); } +	reverse_iterator rend ()				{ return c.rend (); } +	 +	value_compare value_comp() const		{ return get_compare ();} +/* +	template <class InputIterator> +	void insert_one (InputIterator first, InputIterator last) +	{ +		c.reserve (size () + std::distance (first, last)); +		for (;first != last;first++) +			insert_one (*i); +	} +*/ +	template<typename KeyT, typename MappedT> +	void find_or_insert (MappedT*& mappedT, const KeyT& k) +	{ +		iterator i = find (k); +		if (i == end ()) +		{ +			c.push_back (std::make_pair<KeyT, MappedT> (k, MappedT ())); +			mappedT = &(c.end () - 1)->second; +		} +		else +			mappedT = &i->second; +	} +	/* +	template<class Key, class Value> +	Value& find_or_insert (const Key& k) +	{ +		iterator i = find (k); +		if (i == end ()) +		{ +			c.push_back (std::make_pair<Key, Value> (k, Value ())); +			return (c.end () - 1)->second; +		} +		else +			return i->second; +	} +	*/ +	std::pair<iterator, bool> insert_one (const value_type& x) +	{ +		iterator i = find (x); +		// is not included in container +		if (i == end ()) +		{ +			c.push_back (x); +			return std::make_pair (c.end () - 1, true); +		} +		else +			return std::make_pair (i, false); +	} +	 +	template<class CompareType> +	size_type erase_one (const CompareType& x) +	{ +		iterator i = find (x); +		if (i == end ()) +			return 0; +		else +		{	 +			erase (i); +			return 1; +		} +	} +	 +	void      			erase(iterator position)	{ *position = c.back (); c.pop_back (); } +	void 					swap(unsorted_vector& x)	{ c.swap (x.c); } +	 +	void					clear ()							{ c.clear (); } + +	template<class T2> +	size_type			count_one (const T2& x)const			 +	{	 +		const_iterator i = find (x); +		return i != end (); +	}							 + +	template<class T2> +	iterator				find (const T2& x) +	{ +		iterator b = c.begin (); +		iterator e = c.end (); +		for (;b != e;++b) +		{ +			if (get_compare () (*b, x)) +				return b; +		} +		return e;	 +	} + +	template<class T2> +	const_iterator			find (const T2& x) const +	{ +	{ +		const_iterator b = c.begin (); +		const_iterator e = c.end (); +		for (;b != e;++b) +		{ +			if (get_compare () (*b, x)) +				return b; +		} +		return e;	 +	} +	 +	}		 +	void 					reserve (size_type n)				{ c.reserve (n); } +	value_type& operator [] (int n) { return c[n]; } +	const value_type& operator [] (int n) const { return c[n]; } + +	public: + +	container		c; +}; + +#endif  | 
