Daniele Bartolini před 11 roky
rodič
revize
11c147379f

+ 50 - 0
engine/core/Functional.h

@@ -0,0 +1,50 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+namespace crown
+{
+
+template<typename T>
+struct less
+{
+	bool operator()(const T& a, const T& b) const
+	{
+		return a < b;
+	};
+};
+
+template <typename T>
+struct greater
+{
+	bool operator()(const T& a, const T& b) const
+	{
+		return a > b;
+	};
+};
+
+} // namespace crown

+ 19 - 0
engine/core/containers/ContainerTypes.h

@@ -28,6 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Types.h"
 #include "MemoryTypes.h"
+#include "Functional.h"
 
 namespace crown
 {
@@ -160,4 +161,22 @@ struct Map
 	Vector<Node> m_data;
 };
 
+/// Sorted map from key to POD items.
+/// Items are not automatically sorted, you need to call sort_map::sort().
+/// @ingroup Containers.
+template <typename TKey, typename TValue, class Compare = less<TKey> >
+struct SortMap
+{
+	SortMap(Allocator& a);
+
+	struct Entry
+	{
+		TKey key;
+		TValue value;
+	};
+
+	bool m_is_sorted;
+	Array<Entry> m_data;
+};
+
 } // namespace crown

+ 191 - 0
engine/core/containers/SortMap.h

@@ -0,0 +1,191 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Array.h"
+#include <algorithm>
+
+namespace crown
+{
+
+/// Functions to manipulate SortMap.
+///
+/// @ingroup Containers
+namespace sort_map
+{
+	/// Returns whether the @a key exists in the map.
+	template <typename TKey, typename TValue, typename Compare> bool has(const SortMap<TKey, TValue, Compare>& m, const TKey& key);
+
+	/// Returns the value for the given @a key or @a deffault if
+	/// the key does not exist in the map.
+	template <typename TKey, typename TValue, typename Compare> const TValue& get(const SortMap<TKey, TValue, Compare>& m, const TKey& key, const TValue& deffault);
+
+	/// Sorts the keys in the map.
+	template <typename TKey, typename TValue, typename Compare> void sort(SortMap<TKey, TValue, Compare>& m);
+
+	template <typename TKey, typename TValue, typename Compare> void set(SortMap<TKey, TValue, Compare>& m, const TKey& key, const TValue& val);
+
+	/// Removes the @a key from the map if it exists.
+	template <typename TKey, typename TValue, typename Compare> void remove(SortMap<TKey, TValue, Compare>& m, const TKey& key);
+
+	/// Removes all the items in the map.
+	template <typename TKey, typename TValue, typename Compare> void clear(SortMap<TKey, TValue, Compare>& m);
+
+	/// Returns a pointer to the first item in the map, can be used to
+	/// efficiently iterate over the elements.
+	template <typename TKey, typename TValue, typename Compare> const typename SortMap<TKey, TValue, Compare>::Entry* begin(const SortMap<TKey, TValue, Compare>& m);
+	template <typename TKey, typename TValue, typename Compare> const typename SortMap<TKey, TValue, Compare>::Entry* end(const SortMap<TKey, TValue, Compare>& m);
+
+} // namespace sort_map
+
+namespace sort_map_internal
+{
+	const uint32_t END_OF_LIST = 0xFFFFFFFFu;
+
+	struct FindResult
+	{
+		uint32_t item_i;
+	};
+
+	template <typename TKey, typename TValue, typename Compare>
+	struct CompareEntry
+	{
+		bool operator()(const typename SortMap<TKey, TValue, Compare>::Entry& a,
+			const typename SortMap<TKey, TValue, Compare>::Entry& b) const
+		{
+			return comp(a.key, b.key);
+		}
+
+		bool operator()(const typename SortMap<TKey, TValue, Compare>::Entry& a,
+			const TKey& key) const
+		{
+			return comp(a.key, key);
+		}
+
+		Compare comp;
+	};
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline FindResult find(const SortMap<TKey, TValue, Compare>& m, const TKey& key)
+	{
+		CE_ASSERT(m.m_is_sorted, "Map not sorted");
+
+		FindResult result;
+		result.item_i = END_OF_LIST;
+
+		const typename SortMap<TKey, TValue, Compare>::Entry* first =
+			std::lower_bound(array::begin(m.m_data), array::end(m.m_data), key,
+			sort_map_internal::CompareEntry<TKey, TValue, Compare>());
+
+		if (first != array::end(m.m_data) && !(key < first->key))
+		 	result.item_i = first - array::begin(m.m_data);
+
+		return result;
+	}
+} // namespace sort_map_internal
+
+namespace sort_map
+{
+	template <typename TKey, typename TValue, typename Compare>
+	inline bool has(const SortMap<TKey, TValue, Compare>& m, const TKey& key)
+	{
+		return sort_map_internal::find(m, key).item_i != sort_map_internal::END_OF_LIST;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	const TValue& get(const SortMap<TKey, TValue, Compare>& m, const TKey& key, const TValue& deffault)
+	{
+		sort_map_internal::FindResult result = sort_map_internal::find(m, key);
+
+		if (result.item_i == sort_map_internal::END_OF_LIST)
+			return deffault;
+
+		return m.m_data[result.item_i].value;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline void sort(SortMap<TKey, TValue, Compare>& m)
+	{
+		std::sort(array::begin(m.m_data), array::end(m.m_data),
+			sort_map_internal::CompareEntry<TKey, TValue, Compare>());
+		m.m_is_sorted = true;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline void set(SortMap<TKey, TValue, Compare>& m, const TKey& key, const TValue& val)
+	{
+		typename SortMap<TKey, TValue, Compare>::Entry e;
+		e.key = key;
+		e.value = val;
+		array::push_back(m.m_data, e);
+		m.m_is_sorted = false;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline void remove(SortMap<TKey, TValue, Compare>& m, const TKey& key)
+	{
+		sort_map_internal::FindResult result = sort_map_internal::find(m, key);
+
+		if (result.item_i == sort_map_internal::END_OF_LIST)
+			return;
+
+		if (array::size(m.m_data))
+		{
+			m.m_data[result.item_i] = m.m_data[array::size(m.m_data) - 1];
+			array::pop_back(m.m_data);
+		}
+
+		m.m_is_sorted = false;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline void clear(SortMap<TKey, TValue, Compare>& m)
+	{
+		array::clear(m.m_data);
+		m.m_is_sorted = false;
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline const typename SortMap<TKey, TValue, Compare>::Entry* begin(const SortMap<TKey, TValue, Compare>& m)
+	{
+		return array::begin(m.m_data);
+	}
+
+	template <typename TKey, typename TValue, typename Compare>
+	inline const typename SortMap<TKey, TValue, Compare>::Entry* end(const SortMap<TKey, TValue, Compare>& m)
+	{
+		return array::end(m.m_data);
+	}
+} // namespace sort_map
+
+template <typename TKey, typename TValue, typename Compare>
+inline SortMap<TKey, TValue, Compare>::SortMap(Allocator& a)
+	: m_is_sorted(false), m_data(a)
+{
+}
+
+} // namespace crown