Browse Source

Some preperation to remove the Allocator

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
f36849b8ef
5 changed files with 129 additions and 43 deletions
  1. 17 5
      AnKi/Util/Allocator.h
  2. 0 37
      AnKi/Util/Allocator.inl.h
  3. 0 1
      AnKi/Util/CpuMemoryPools.h
  4. 3 0
      AnKi/Util/Forward.h
  5. 109 0
      AnKi/Util/Functions.h

+ 17 - 5
AnKi/Util/Allocator.h

@@ -294,13 +294,23 @@ public:
 	/// @note This is AnKi specific.
 	/// @note The output is a parameter to work with template deduction.
 	template<typename TValue, typename TSize>
-	void newArray(size_type n, WeakArray<TValue, TSize>& out);
+	void newArray(size_type n, WeakArray<TValue, TSize>& out)
+	{
+		TValue* arr = newArray<TValue>(n);
+		ANKI_ASSERT(n < std::numeric_limits<TSize>::max());
+		out.setArray(arr, TSize(n));
+	}
 
 	/// Allocate a new array of objects and call their constructor.
 	/// @note This is AnKi specific.
 	/// @note The output is a parameter to work with template deduction.
 	template<typename TValue, typename TSize>
-	void newArray(size_type n, const TValue& v, WeakArray<TValue, TSize>& out);
+	void newArray(size_type n, const TValue& v, WeakArray<TValue, TSize>& out)
+	{
+		TValue* arr = newArray<TValue>(n, v);
+		ANKI_ASSERT(n < std::numeric_limits<TSize>::max());
+		out.setArray(arr, TSize(n));
+	}
 
 	/// Call the destructor and deallocate an object
 	/// @note This is AnKi specific
@@ -341,7 +351,11 @@ public:
 	/// Call the destructor and deallocate an array of objects
 	/// @note This is AnKi specific
 	template<typename TValue, typename TSize>
-	void deleteArray(WeakArray<TValue, TSize>& arr);
+	void deleteArray(WeakArray<TValue, TSize>& arr)
+	{
+		deleteArray(arr.getBegin(), arr.getSize());
+		arr.setArray(nullptr, 0);
+	}
 
 private:
 	TPool* m_pool = nullptr;
@@ -426,5 +440,3 @@ using StackAllocator = GenericPoolAllocator<T, StackMemoryPool>;
 /// @}
 
 } // end namespace anki
-
-#include <AnKi/Util/Allocator.inl.h>

+ 0 - 37
AnKi/Util/Allocator.inl.h

@@ -1,37 +0,0 @@
-// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Util/Allocator.h>
-#include <AnKi/Util/WeakArray.h>
-
-namespace anki {
-
-template<typename T, typename TPool>
-template<typename TValue, typename TSize>
-void GenericPoolAllocator<T, TPool>::deleteArray(WeakArray<TValue, TSize>& arr)
-{
-	deleteArray(arr.getBegin(), arr.getSize());
-	arr.setArray(nullptr, 0);
-}
-
-template<typename T, typename TPool>
-template<typename TValue, typename TSize>
-void GenericPoolAllocator<T, TPool>::newArray(size_type n, WeakArray<TValue, TSize>& out)
-{
-	TValue* arr = newArray<TValue>(n);
-	ANKI_ASSERT(n < std::numeric_limits<TSize>::max());
-	out.setArray(arr, TSize(n));
-}
-
-template<typename T, typename TPool>
-template<typename TValue, typename TSize>
-void GenericPoolAllocator<T, TPool>::newArray(size_type n, const TValue& v, WeakArray<TValue, TSize>& out)
-{
-	TValue* arr = newArray<TValue>(n, v);
-	ANKI_ASSERT(n < std::numeric_limits<TSize>::max());
-	out.setArray(arr, TSize(n));
-}
-
-} // end namespace anki

+ 0 - 1
AnKi/Util/CpuMemoryPools.h

@@ -8,7 +8,6 @@
 #include <AnKi/Util/StdTypes.h>
 #include <AnKi/Util/Atomic.h>
 #include <AnKi/Util/Assert.h>
-#include <AnKi/Util/Array.h>
 #include <AnKi/Util/Thread.h>
 #include <AnKi/Util/StackAllocatorBuilder.h>
 #include <utility> // For forward

+ 3 - 0
AnKi/Util/Forward.h

@@ -41,6 +41,9 @@ class ThreadHive;
 template<typename T, PtrSize kPreallocatedStorage = ANKI_SAFE_ALIGNMENT>
 class Function;
 
+template<typename, PtrSize>
+class Array;
+
 template<typename T, typename TSize = U32>
 class WeakArray;
 

+ 109 - 0
AnKi/Util/Functions.h

@@ -9,6 +9,7 @@
 #pragma once
 
 #include <AnKi/Util/StdTypes.h>
+#include <AnKi/Util/Forward.h>
 #include <AnKi/Util/Assert.h>
 #include <cmath>
 #include <utility>
@@ -362,6 +363,114 @@ inline U32 floatBitsToUint(F32 f)
 	memcpy(&out, &f, sizeof(out));
 	return out;
 }
+
+/// Call one of the costructors of an object.
+template<typename T, typename... TArgs>
+void callConstructor(T& p, TArgs&&... args)
+{
+	::new(&p) T(std::forward<TArgs>(args)...);
+}
+
+/// Call the destructor of an object.
+template<typename T>
+void callDestructor(T& p)
+{
+	static_assert(sizeof(T) > 0, "Incomplete type");
+	p.~T();
+}
+
+/// Allocate a new object and call it's constructor
+template<typename T, typename TMemPool, typename... TArgs>
+[[nodiscard]] T* newInstance(TMemPool& pool, TArgs&&... args)
+{
+	T* ptr = pool.allocate(sizeof(T), alignof(T));
+	if(ANKI_LIKELY(ptr))
+	{
+		callConstructor(ptr, std::forward<TArgs>(args)...);
+	}
+
+	return ptr;
+}
+
+/// Allocate a new array of objects and call their constructor
+template<typename T, typename TMemPool>
+[[nodiscard]] T* newArray(TMemPool& pool, PtrSize n)
+{
+	T* ptr = pool.allocate(n * sizeof(T), alignof(T));
+	if(ANKI_LIKELY(ptr))
+	{
+		for(PtrSize i = 0; i < n; i++)
+		{
+			callConstructor(&ptr[i]);
+		}
+	}
+
+	return ptr;
+}
+
+/// Allocate a new array of objects and call their constructor
+template<typename T, typename TMemPool>
+[[nodiscard]] T* newArray(TMemPool& pool, PtrSize n, const T& copy)
+{
+	T* ptr = pool.allocate(n * sizeof(T), alignof(T));
+	if(ANKI_LIKELY(ptr))
+	{
+		for(PtrSize i = 0; i < n; i++)
+		{
+			callConstructor(&ptr[i], copy);
+		}
+	}
+
+	return ptr;
+}
+
+/// Allocate a new array of objects and call their constructor.
+/// @note The output is a parameter (instead of a return value) to work with template deduction.
+template<typename T, typename TMemPool, typename TSize>
+void newArray(TMemPool& pool, PtrSize n, WeakArray<T, TSize>& out)
+{
+	T* arr = newArray<T>(pool, n);
+	ANKI_ASSERT(n < getMaxNumericLimit<TSize>());
+	out.setArray(arr, TSize(n));
+}
+
+/// Call the destructor and deallocate an object.
+template<typename T, typename TMemPool>
+void deleteInstance(TMemPool& pool, T* ptr)
+{
+	if(ANKI_LIKELY(ptr != nullptr))
+	{
+		callDestructor(&ptr);
+		pool.free(ptr);
+	}
+}
+
+/// Call the destructor and deallocate an array of objects.
+template<typename T, typename TMemPool>
+void deleteArray(TMemPool& pool, T* arr, PtrSize n)
+{
+	if(ANKI_LIKELY(arr != nullptr))
+	{
+		for(PtrSize i = 0; i < n; i++)
+		{
+			callDestructor(arr[i]);
+		}
+
+		pool.free(arr);
+	}
+	else
+	{
+		ANKI_ASSERT(n == 0);
+	}
+}
+
+/// Call the destructor and deallocate an array of objects.
+template<typename T, typename TMemPool, typename TSize>
+void deleteArray(TMemPool& pool, WeakArray<T, TSize>& arr)
+{
+	deleteArray(pool, arr.getBegin(), arr.getSize());
+	arr.setArray(nullptr, 0);
+}
 /// @}
 
 } // end namespace anki