Sfoglia il codice sorgente

core: copy ctor and copy assignment for HashMap and HashSet

Daniele Bartolini 6 anni fa
parent
commit
2ccb809ddf

+ 58 - 0
src/core/containers/hash_map.h

@@ -317,6 +317,38 @@ HashMap<TKey, TValue, Hash, KeyEqual>::HashMap(Allocator& a)
 {
 }
 
+template <typename TKey, typename TValue, typename Hash, typename KeyEqual>
+HashMap<TKey, TValue, Hash, KeyEqual>::HashMap(const HashMap<TKey, TValue, Hash, KeyEqual>& other)
+	: _allocator(other._allocator)
+	, _capacity(0)
+	, _size(0)
+	, _mask(0)
+	, _index(NULL)
+	, _data(NULL)
+	, _buffer(NULL)
+{
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
+
+	_allocator->deallocate(_buffer);
+	if (other._capacity > 0)
+	{
+		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
+		_buffer = (char*)_allocator->allocate(size);
+		_index = (Index*)memory::align_top(_buffer, alignof(Index));
+		_data = (Entry*)memory::align_top(_index + _capacity, alignof(Entry));
+
+		memcpy(_index, other._index, sizeof(Index)*other._capacity);
+		for (u32 i = 0; i < other._capacity; ++i)
+		{
+			const u32 index = other._index[i].index;
+			if (index != hash_map_internal::FREE && !hash_map_internal::is_deleted(index))
+				new (&_data[i]) Entry(other._data[i]);
+		}
+	}
+}
+
 template <typename TKey, typename TValue, typename Hash, typename KeyEqual>
 HashMap<TKey, TValue, Hash, KeyEqual>::~HashMap()
 {
@@ -329,4 +361,30 @@ HashMap<TKey, TValue, Hash, KeyEqual>::~HashMap()
 	_allocator->deallocate(_buffer);
 }
 
+template <typename TKey, typename TValue, typename Hash, typename KeyEqual>
+HashMap<TKey, TValue, Hash, KeyEqual>& HashMap<TKey, TValue, Hash, KeyEqual>::operator=(const HashMap<TKey, TValue, Hash, KeyEqual>& other)
+{
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
+
+	_allocator->deallocate(_buffer);
+	if (other._capacity > 0)
+	{
+		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
+		_buffer = (char*)_allocator->allocate(size);
+		_index = (Index*)memory::align_top(_buffer, alignof(Index));
+		_data = (Entry*)memory::align_top(_index + _capacity, alignof(Entry));
+
+		memcpy(_index, other._index, sizeof(Index)*other._capacity);
+		for (u32 i = 0; i < other._capacity; ++i)
+		{
+			const u32 index = other._index[i].index;
+			if (index != hash_map_internal::FREE && !hash_map_internal::is_deleted(index))
+				new (&_data[i]) Entry(other._data[i]);
+		}
+	}
+	return *this;
+}
+
 } // namespace crown

+ 58 - 0
src/core/containers/hash_set.h

@@ -273,6 +273,38 @@ HashSet<TKey, Hash, KeyEqual>::HashSet(Allocator& a)
 {
 }
 
+template <typename TKey, typename Hash, typename KeyEqual>
+HashSet<TKey, Hash, KeyEqual>::HashSet(const HashSet& other)
+	: _allocator(other._allocator)
+	, _capacity(0)
+	, _size(0)
+	, _mask(0)
+	, _index(NULL)
+	, _data(NULL)
+	, _buffer(NULL)
+{
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
+
+	_allocator->deallocate(_buffer);
+	if (other._capacity > 0)
+	{
+		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
+		_buffer = (char*)_allocator->allocate(size);
+		_index = (Index*)memory::align_top(_buffer, alignof(Index));
+		_data = (TKey*)memory::align_top(_index + _capacity, alignof(TKey));
+
+		memcpy(_index, other._index, sizeof(Index)*other._capacity);
+		for (u32 i = 0; i < other._capacity; ++i)
+		{
+			const u32 index = other._index[i].index;
+			if (index != hash_set_internal::FREE && !hash_set_internal::is_deleted(index))
+				new (&_data[i]) TKey(other._data[i]);
+		}
+	}
+}
+
 template <typename TKey, typename Hash, typename KeyEqual>
 HashSet<TKey, Hash, KeyEqual>::~HashSet()
 {
@@ -285,4 +317,30 @@ HashSet<TKey, Hash, KeyEqual>::~HashSet()
 	_allocator->deallocate(_buffer);
 }
 
+template <typename TKey, typename Hash, typename KeyEqual>
+HashSet<TKey, Hash, KeyEqual>& HashSet<TKey, Hash, KeyEqual>::operator=(const HashSet<TKey, Hash, KeyEqual>& other)
+{
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
+
+	_allocator->deallocate(_buffer);
+	if (other._capacity > 0)
+	{
+		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
+		_buffer = (char*)_allocator->allocate(size);
+		_index = (Index*)memory::align_top(_buffer, alignof(Index));
+		_data = (TKey*)memory::align_top(_index + _capacity, alignof(TKey));
+
+		memcpy(_index, other._index, sizeof(Index)*other._capacity);
+		for (u32 i = 0; i < other._capacity; ++i)
+		{
+			const u32 index = other._index[i].index;
+			if (index != hash_set_internal::FREE && !hash_set_internal::is_deleted(index))
+				new (&_data[i]) TKey(other._data[i]);
+		}
+	}
+	return *this;
+}
+
 } // namespace crown

+ 4 - 0
src/core/containers/types.h

@@ -141,7 +141,9 @@ struct HashMap
 	char* _buffer;
 
 	HashMap(Allocator& a);
+	HashMap(const HashMap& other);
 	~HashMap();
+	HashMap<TKey, TValue, Hash, KeyEqual>& operator=(const HashMap<TKey, TValue, Hash, KeyEqual>& other);
 };
 
 /// Hash set.
@@ -167,7 +169,9 @@ struct HashSet
 	char* _buffer;
 
 	HashSet(Allocator& a);
+	HashSet(const HashSet& other);
 	~HashSet();
+	HashSet<TKey, Hash, KeyEqual>& operator=(const HashSet<TKey, Hash, KeyEqual>& other);
 };
 
 /// Vector of sorted items.