Browse Source

Remove the allocator from most Util classes

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
9250dd27ab
100 changed files with 1242 additions and 1185 deletions
  1. 5 5
      AnKi/Core/App.cpp
  2. 1 1
      AnKi/Core/App.h
  3. 7 7
      AnKi/Core/CoreTracer.cpp
  4. 1 1
      AnKi/Core/StatsUi.cpp
  5. 1 1
      AnKi/Gr/Gl/CommandBuffer.cpp
  6. 2 2
      AnKi/Gr/Gl/Shader.cpp
  7. 6 6
      AnKi/Gr/Gl/ShaderImpl.cpp
  8. 1 1
      AnKi/Gr/Gl/ShaderProgramImpl.cpp
  9. 21 21
      AnKi/Gr/RenderGraph.cpp
  10. 3 3
      AnKi/Gr/RenderGraph.h
  11. 5 5
      AnKi/Gr/Vulkan/CommandBufferImpl.cpp
  12. 5 5
      AnKi/Gr/Vulkan/DescriptorSet.cpp
  13. 18 18
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  14. 2 2
      AnKi/Gr/Vulkan/PipelineCache.cpp
  15. 1 1
      AnKi/Gr/Vulkan/ShaderImpl.cpp
  16. 2 2
      AnKi/Gr/Vulkan/ShaderProgramImpl.cpp
  17. 1 1
      AnKi/Gr/Vulkan/SwapchainFactory.cpp
  18. 60 60
      AnKi/Importer/GltfImporter.cpp
  19. 20 20
      AnKi/Importer/GltfImporter.h
  20. 17 17
      AnKi/Importer/GltfImporterAnimation.cpp
  21. 22 22
      AnKi/Importer/GltfImporterMaterial.cpp
  22. 17 17
      AnKi/Importer/GltfImporterMesh.cpp
  23. 19 19
      AnKi/Importer/ImageImporter.cpp
  24. 1 1
      AnKi/Math/Axisang.h
  25. 1 1
      AnKi/Math/Euler.h
  26. 2 2
      AnKi/Math/Mat.h
  27. 2 2
      AnKi/Math/Transform.h
  28. 6 6
      AnKi/Math/Vec.h
  29. 1 1
      AnKi/Physics/PhysicsTrigger.cpp
  30. 1 1
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  31. 1 1
      AnKi/Renderer/ProbeReflections.cpp
  32. 5 5
      AnKi/Renderer/ShadowMapping.cpp
  33. 2 2
      AnKi/Renderer/ShadowMapping.h
  34. 2 2
      AnKi/Resource/CpuMeshResource.cpp
  35. 2 2
      AnKi/Resource/ImageLoader.cpp
  36. 1 1
      AnKi/Resource/ImageResource.cpp
  37. 1 1
      AnKi/Resource/MaterialResource.cpp
  38. 2 2
      AnKi/Resource/MeshBinaryLoader.cpp
  39. 1 1
      AnKi/Resource/MeshBinaryLoader.h
  40. 2 2
      AnKi/Resource/MeshResource.cpp
  41. 3 3
      AnKi/Resource/ResourceFilesystem.cpp
  42. 2 2
      AnKi/Resource/ResourceFilesystem.h
  43. 3 3
      AnKi/Resource/ResourceObject.cpp
  44. 1 1
      AnKi/Resource/ResourceObject.h
  45. 1 1
      AnKi/Resource/ScriptResource.cpp
  46. 1 1
      AnKi/Resource/ShaderProgramResource.cpp
  47. 10 10
      AnKi/Resource/ShaderProgramResourceSystem.cpp
  48. 1 1
      AnKi/Resource/SkeletonResource.cpp
  49. 1 1
      AnKi/Scene/Events/EventManager.cpp
  50. 1 1
      AnKi/Scene/Events/ScriptEvent.cpp
  51. 2 2
      AnKi/Scene/ModelNode.cpp
  52. 4 4
      AnKi/Scene/Octree.cpp
  53. 3 3
      AnKi/Scene/Octree.h
  54. 1 1
      AnKi/ShaderCompiler/Common.h
  55. 12 12
      AnKi/ShaderCompiler/Glslang.cpp
  56. 2 2
      AnKi/ShaderCompiler/Glslang.h
  57. 6 6
      AnKi/ShaderCompiler/MaliOfflineCompiler.cpp
  58. 1 1
      AnKi/ShaderCompiler/MaliOfflineCompiler.h
  59. 34 34
      AnKi/ShaderCompiler/ShaderProgramCompiler.cpp
  60. 6 6
      AnKi/ShaderCompiler/ShaderProgramDump.cpp
  61. 1 1
      AnKi/ShaderCompiler/ShaderProgramDump.h
  62. 26 26
      AnKi/ShaderCompiler/ShaderProgramParser.cpp
  63. 29 29
      AnKi/ShaderCompiler/ShaderProgramParser.h
  64. 30 30
      AnKi/ShaderCompiler/ShaderProgramReflection.cpp
  65. 2 1
      AnKi/Util/Assert.cpp
  66. 5 5
      AnKi/Util/BitSet.h
  67. 28 0
      AnKi/Util/CpuMemoryPools.h
  68. 73 74
      AnKi/Util/DynamicArray.h
  69. 28 29
      AnKi/Util/DynamicArray.inl.h
  70. 3 3
      AnKi/Util/File.cpp
  71. 2 2
      AnKi/Util/File.h
  72. 3 3
      AnKi/Util/Filesystem.cpp
  73. 14 14
      AnKi/Util/Filesystem.h
  74. 9 9
      AnKi/Util/FilesystemPosix.cpp
  75. 4 4
      AnKi/Util/FilesystemWindows.cpp
  76. 10 8
      AnKi/Util/Forward.h
  77. 15 15
      AnKi/Util/Function.h
  78. 7 7
      AnKi/Util/Functions.h
  79. 6 5
      AnKi/Util/INotify.h
  80. 52 51
      AnKi/Util/List.h
  81. 3 3
      AnKi/Util/List.inl.h
  82. 3 3
      AnKi/Util/Process.cpp
  83. 3 3
      AnKi/Util/Process.h
  84. 1 1
      AnKi/Util/SegregatedListsAllocatorBuilder.h
  85. 1 1
      AnKi/Util/SegregatedListsAllocatorBuilder.inl.h
  86. 1 1
      AnKi/Util/Serializer.cpp
  87. 7 7
      AnKi/Util/Serializer.h
  88. 14 15
      AnKi/Util/Serializer.inl.h
  89. 0 148
      AnKi/Util/String.cpp
  90. 244 97
      AnKi/Util/String.h
  91. 0 155
      AnKi/Util/StringList.cpp
  92. 49 31
      AnKi/Util/StringList.h
  93. 164 0
      AnKi/Util/StringList.inl.h
  94. 4 4
      AnKi/Util/System.cpp
  95. 4 4
      AnKi/Util/System.h
  96. 7 8
      AnKi/Util/ThreadHive.cpp
  97. 7 9
      AnKi/Util/ThreadHive.h
  98. 6 6
      AnKi/Util/Tracer.cpp
  99. 3 3
      AnKi/Util/Tracer.h
  100. 9 5
      AnKi/Util/WeakArray.h

+ 5 - 5
AnKi/Core/App.cpp

@@ -294,10 +294,10 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 #if !ANKI_OS_ANDROID
 	// Add the location of the executable where the shaders are supposed to be
-	StringAuto executableFname(m_heapAlloc);
+	StringRaii executableFname(m_heapAlloc);
 	ANKI_CHECK(getApplicationPath(executableFname));
 	ANKI_CORE_LOGI("Executable path is: %s", executableFname.cstr());
-	StringAuto shadersPath(m_heapAlloc);
+	StringRaii shadersPath(m_heapAlloc);
 	getParentFilepath(executableFname, shadersPath);
 	shadersPath.append(":");
 	shadersPath.append(m_config->getRsrcDataPaths());
@@ -378,7 +378,7 @@ Error App::initDirs()
 {
 	// Settings path
 #if !ANKI_OS_ANDROID
-	StringAuto home(m_heapAlloc);
+	StringRaii home(m_heapAlloc);
 	ANKI_CHECK(getHomeDirectory(home));
 
 	m_settingsDir.sprintf(m_heapAlloc, "%s/.anki", &home[0]);
@@ -444,7 +444,7 @@ Error App::mainLoop()
 			m_scene->doVisibilityTests(rqueue);
 
 			// Inject stats UI
-			DynamicArrayAuto<UiQueueElement> newUiElementArr(m_heapAlloc);
+			DynamicArrayRaii<UiQueueElement> newUiElementArr(m_heapAlloc);
 			injectUiElements(newUiElementArr, rqueue);
 
 			// Render
@@ -544,7 +544,7 @@ Error App::mainLoop()
 	return Error::kNone;
 }
 
-void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, RenderQueue& rqueue)
+void App::injectUiElements(DynamicArrayRaii<UiQueueElement>& newUiElementArr, RenderQueue& rqueue)
 {
 	const U32 originalCount = rqueue.m_uis.getSize();
 	if(m_config->getCoreDisplayStats() > 0 || m_consoleEnabled)

+ 1 - 1
AnKi/Core/App.h

@@ -205,7 +205,7 @@ private:
 	void cleanup();
 
 	/// Inject a new UI element in the render queue for displaying various stuff.
-	void injectUiElements(DynamicArrayAuto<UiQueueElement>& elements, RenderQueue& rqueue);
+	void injectUiElements(DynamicArrayRaii<UiQueueElement>& elements, RenderQueue& rqueue);
 
 	void setSignalHandlers();
 };

+ 7 - 7
AnKi/Core/CoreTracer.cpp

@@ -33,8 +33,8 @@ static void getSpreadsheetColumnName(U32 column, Array<char, 3>& arr)
 class CoreTracer::ThreadWorkItem : public IntrusiveListEnabled<ThreadWorkItem>
 {
 public:
-	DynamicArrayAuto<TracerEvent> m_events;
-	DynamicArrayAuto<TracerCounter> m_counters;
+	DynamicArrayRaii<TracerEvent> m_events;
+	DynamicArrayRaii<TracerCounter> m_counters;
 	ThreadId m_tid;
 	U64 m_frame;
 
@@ -48,7 +48,7 @@ public:
 class CoreTracer::PerFrameCounters : public IntrusiveListEnabled<PerFrameCounters>
 {
 public:
-	DynamicArrayAuto<TracerCounter> m_counters;
+	DynamicArrayRaii<TracerCounter> m_counters;
 	U64 m_frame;
 
 	PerFrameCounters(GenericMemoryPoolAllocator<U8>& alloc)
@@ -117,14 +117,14 @@ Error CoreTracer::init(GenericMemoryPoolAllocator<U8> alloc, CString directory)
 	});
 
 	std::tm tm = getLocalTime();
-	StringAuto fname(m_alloc);
+	StringRaii fname(m_alloc);
 	fname.sprintf("%s/%d%02d%02d-%02d%02d_", directory.cstr(), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
 				  tm.tm_min);
 
-	ANKI_CHECK(m_traceJsonFile.open(StringAuto(alloc).sprintf("%strace.json", fname.cstr()), FileOpenFlag::kWrite));
+	ANKI_CHECK(m_traceJsonFile.open(StringRaii(alloc).sprintf("%strace.json", fname.cstr()), FileOpenFlag::kWrite));
 	ANKI_CHECK(m_traceJsonFile.writeText("[\n"));
 
-	ANKI_CHECK(m_countersCsvFile.open(StringAuto(alloc).sprintf("%scounters.csv", fname.cstr()), FileOpenFlag::kWrite));
+	ANKI_CHECK(m_countersCsvFile.open(StringRaii(alloc).sprintf("%scounters.csv", fname.cstr()), FileOpenFlag::kWrite));
 
 	return Error::kNone;
 }
@@ -211,7 +211,7 @@ void CoreTracer::gatherCounters(ThreadWorkItem& item)
 	});
 
 	// Merge same
-	DynamicArrayAuto<TracerCounter> mergedCounters(m_alloc);
+	DynamicArrayRaii<TracerCounter> mergedCounters(m_alloc);
 	for(U32 i = 0; i < item.m_counters.getSize(); ++i)
 	{
 		if(mergedCounters.getSize() == 0 || mergedCounters.getBack().m_name != item.m_counters[i].m_name)

+ 1 - 1
AnKi/Core/StatsUi.cpp

@@ -36,7 +36,7 @@ void StatsUi::labelBytes(PtrSize val, CString name) const
 
 	b = val;
 
-	StringAuto timestamp(getAllocator());
+	StringRaii timestamp(getAllocator());
 	if(gb)
 	{
 		timestamp.sprintf("%s: %zu,%04zu,%04zu,%04zu", name.cstr(), gb, mb, kb, b);

+ 1 - 1
AnKi/Gr/Gl/CommandBuffer.cpp

@@ -1523,7 +1523,7 @@ void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
 	class PushConstants final : public GlCommand
 	{
 	public:
-		DynamicArrayAuto<Vec4> m_data;
+		DynamicArrayRaii<Vec4> m_data;
 
 		PushConstants(const void* data, U32 dataSize, const CommandBufferAllocator<F32>& alloc)
 			: m_data(alloc)

+ 2 - 2
AnKi/Gr/Gl/Shader.cpp

@@ -16,8 +16,8 @@ Shader* Shader::newInstance(GrManager* manager, const ShaderInitInfo& init)
 	{
 	public:
 		ShaderPtr m_shader;
-		StringAuto m_source;
-		DynamicArrayAuto<ShaderSpecializationConstValue> m_constValues;
+		StringRaii m_source;
+		DynamicArrayRaii<ShaderSpecializationConstValue> m_constValues;
 
 		ShaderCreateCommand(Shader* shader, ConstWeakArray<U8> bin,
 							ConstWeakArray<ShaderSpecializationConstValue> constValues,

+ 6 - 6
AnKi/Gr/Gl/ShaderImpl.cpp

@@ -43,11 +43,11 @@ Error ShaderImpl::init(CString source, ConstWeakArray<ShaderSpecializationConstV
 	m_glType = gltype[U(m_shaderType)];
 
 	// Create a new shader with spec consts if needed
-	StringAuto newSrc(getAllocator());
+	StringRaii newSrc(getAllocator());
 	if(constValues.getSize())
 	{
 		// Create const str
-		StringListAuto constStrLines(getAllocator());
+		StringListRaii constStrLines(getAllocator());
 		U count = 0;
 		for(const ShaderSpecializationConstValue& constVal : constValues)
 		{
@@ -63,11 +63,11 @@ Error ShaderImpl::init(CString source, ConstWeakArray<ShaderSpecializationConstV
 
 			++count;
 		}
-		StringAuto constStr(getAllocator());
+		StringRaii constStr(getAllocator());
 		constStrLines.join("\n", constStr);
 
 		// Break the old source
-		StringListAuto lines(getAllocator());
+		StringListRaii lines(getAllocator());
 		lines.splitString(source, '\n');
 		ANKI_ASSERT(lines.getFront().find("#version") == 0);
 		lines.popFront();
@@ -117,7 +117,7 @@ Error ShaderImpl::init(CString source, ConstWeakArray<ShaderSpecializationConstV
 			ANKI_ASSERT(0);
 		}
 
-		StringAuto fname(getAllocator());
+		StringRaii fname(getAllocator());
 		CString cacheDir = getManager().getCacheDirectory();
 		fname.sprintf("%s/%05u.%s", &cacheDir[0], static_cast<U32>(m_glName), ext);
 
@@ -132,7 +132,7 @@ Error ShaderImpl::init(CString source, ConstWeakArray<ShaderSpecializationConstV
 	if(status == GL_FALSE)
 	{
 		auto alloc = getAllocator();
-		StringAuto compilerLog(alloc);
+		StringRaii compilerLog(alloc);
 		GLint compilerLogLen = 0;
 		GLint charsWritten = 0;
 

+ 1 - 1
AnKi/Gr/Gl/ShaderProgramImpl.cpp

@@ -77,7 +77,7 @@ Error ShaderProgramImpl::link(GLuint vert, GLuint frag)
 	{
 		GLint infoLen = 0;
 		GLint charsWritten = 0;
-		DynamicArrayAuto<char> infoLogTxt(getAllocator());
+		DynamicArrayRaii<char> infoLogTxt(getAllocator());
 
 		glGetProgramiv(m_glName, GL_INFO_LOG_LENGTH, &infoLen);
 

+ 21 - 21
AnKi/Gr/RenderGraph.cpp

@@ -1456,14 +1456,14 @@ void RenderGraph::getStatistics(RenderGraphStatistics& statistics) const
 }
 
 #if ANKI_DBG_RENDER_GRAPH
-StringAuto RenderGraph::textureUsageToStr(StackAllocator<U8>& alloc, TextureUsageBit usage)
+StringRaii RenderGraph::textureUsageToStr(StackAllocator<U8>& alloc, TextureUsageBit usage)
 {
 	if(!usage)
 	{
-		return StringAuto(alloc, "None");
+		return StringRaii(alloc, "None");
 	}
 
-	StringListAuto slist(alloc);
+	StringListRaii slist(alloc);
 
 #	define ANKI_TEX_USAGE(u) \
 		if(!!(usage & TextureUsageBit::u)) \
@@ -1498,14 +1498,14 @@ StringAuto RenderGraph::textureUsageToStr(StackAllocator<U8>& alloc, TextureUsag
 #	undef ANKI_TEX_USAGE
 
 	ANKI_ASSERT(!slist.isEmpty());
-	StringAuto str(alloc);
+	StringRaii str(alloc);
 	slist.join(" | ", str);
 	return str;
 }
 
-StringAuto RenderGraph::bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageBit usage)
+StringRaii RenderGraph::bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageBit usage)
 {
-	StringListAuto slist(alloc);
+	StringListRaii slist(alloc);
 
 #	define ANKI_BUFF_USAGE(u) \
 		if(!!(usage & BufferUsageBit::u)) \
@@ -1550,14 +1550,14 @@ StringAuto RenderGraph::bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageB
 #	undef ANKI_BUFF_USAGE
 
 	ANKI_ASSERT(!slist.isEmpty());
-	StringAuto str(alloc);
+	StringRaii str(alloc);
 	slist.join(" | ", str);
 	return str;
 }
 
-StringAuto RenderGraph::asUsageToStr(StackAllocator<U8>& alloc, AccelerationStructureUsageBit usage)
+StringRaii RenderGraph::asUsageToStr(StackAllocator<U8>& alloc, AccelerationStructureUsageBit usage)
 {
-	StringListAuto slist(alloc);
+	StringListRaii slist(alloc);
 
 #	define ANKI_AS_USAGE(u) \
 		if(!!(usage & AccelerationStructureUsageBit::u)) \
@@ -1580,7 +1580,7 @@ StringAuto RenderGraph::asUsageToStr(StackAllocator<U8>& alloc, AccelerationStru
 #	undef ANKI_AS_USAGE
 
 	ANKI_ASSERT(!slist.isEmpty());
-	StringAuto str(alloc);
+	StringRaii str(alloc);
 	slist.join(" | ", str);
 	return str;
 }
@@ -1592,7 +1592,7 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 
 	static constexpr Array<const char*, 5> COLORS = {"red", "green", "blue", "magenta", "cyan"};
 	auto alloc = ctx.m_alloc;
-	StringListAuto slist(alloc);
+	StringListRaii slist(alloc);
 
 	slist.pushBackSprintf("digraph {\n");
 	slist.pushBackSprintf("\t//splines = ortho;\nconcentrate = true;\n");
@@ -1641,27 +1641,27 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 
 	// Barriers
 	// slist.pushBackSprintf("subgraph cluster_1 {\n");
-	StringAuto prevBubble(ctx.m_alloc);
+	StringRaii prevBubble(ctx.m_alloc);
 	prevBubble.create("START");
 	for(U32 batchIdx = 0; batchIdx < ctx.m_batches.getSize(); ++batchIdx)
 	{
 		const Batch& batch = ctx.m_batches[batchIdx];
 
-		StringAuto batchName(ctx.m_alloc);
+		StringRaii batchName(ctx.m_alloc);
 		batchName.sprintf("batch%u", batchIdx);
 
 		for(U32 barrierIdx = 0; barrierIdx < batch.m_textureBarriersBefore.getSize(); ++barrierIdx)
 		{
 			const TextureBarrier& barrier = batch.m_textureBarriersBefore[barrierIdx];
 
-			StringAuto barrierLabel(ctx.m_alloc);
+			StringRaii barrierLabel(ctx.m_alloc);
 			barrierLabel.sprintf("<b>%s</b> (mip,dp,f,l)=(%u,%u,%u,%u)<br/>%s <b>to</b> %s",
 								 &descr.m_renderTargets[barrier.m_idx].m_name[0], barrier.m_surface.m_level,
 								 barrier.m_surface.m_depth, barrier.m_surface.m_face, barrier.m_surface.m_layer,
 								 textureUsageToStr(alloc, barrier.m_usageBefore).cstr(),
 								 textureUsageToStr(alloc, barrier.m_usageAfter).cstr());
 
-			StringAuto barrierName(ctx.m_alloc);
+			StringRaii barrierName(ctx.m_alloc);
 			barrierName.sprintf("%s tex barrier%u", batchName.cstr(), barrierIdx);
 
 			slist.pushBackSprintf("\t\"%s\"[color=%s,style=bold,shape=box,label=< %s >];\n", barrierName.cstr(),
@@ -1675,12 +1675,12 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 		{
 			const BufferBarrier& barrier = batch.m_bufferBarriersBefore[barrierIdx];
 
-			StringAuto barrierLabel(ctx.m_alloc);
+			StringRaii barrierLabel(ctx.m_alloc);
 			barrierLabel.sprintf("<b>%s</b><br/>%s <b>to</b> %s", &descr.m_buffers[barrier.m_idx].m_name[0],
 								 bufferUsageToStr(alloc, barrier.m_usageBefore).cstr(),
 								 bufferUsageToStr(alloc, barrier.m_usageAfter).cstr());
 
-			StringAuto barrierName(ctx.m_alloc);
+			StringRaii barrierName(ctx.m_alloc);
 			barrierName.sprintf("%s buff barrier%u", batchName.cstr(), barrierIdx);
 
 			slist.pushBackSprintf("\t\"%s\"[color=%s,style=bold,shape=box,label=< %s >];\n", barrierName.cstr(),
@@ -1694,12 +1694,12 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 		{
 			const ASBarrier& barrier = batch.m_asBarriersBefore[barrierIdx];
 
-			StringAuto barrierLabel(ctx.m_alloc);
+			StringRaii barrierLabel(ctx.m_alloc);
 			barrierLabel.sprintf("<b>%s</b><br/>%s <b>to</b> %s", descr.m_as[barrier.m_idx].m_name.getBegin(),
 								 asUsageToStr(alloc, barrier.m_usageBefore).cstr(),
 								 asUsageToStr(alloc, barrier.m_usageAfter).cstr());
 
-			StringAuto barrierName(ctx.m_alloc);
+			StringRaii barrierName(ctx.m_alloc);
 			barrierName.sprintf("%s AS barrier%u", batchName.cstr(), barrierIdx);
 
 			slist.pushBackSprintf("\t\"%s\"[color=%s,style=bold,shape=box,label=< %s >];\n", barrierName.cstr(),
@@ -1712,7 +1712,7 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 		for(U32 passIdx : batch.m_passIndices)
 		{
 			const RenderPassDescriptionBase& pass = *descr.m_passes[passIdx];
-			StringAuto passName(alloc);
+			StringRaii passName(alloc);
 			passName.sprintf("%s pass", pass.m_name.cstr());
 			slist.pushBackSprintf("\t\"%s\"[color=%s,style=bold];\n", passName.cstr(),
 								  COLORS[batchIdx % COLORS.getSize()]);
@@ -1726,7 +1726,7 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 	slist.pushBackSprintf("}");
 
 	File file;
-	ANKI_CHECK(file.open(StringAuto(alloc).sprintf("%s/rgraph_%05u.dot", &path[0], m_version).toCString(),
+	ANKI_CHECK(file.open(StringRaii(alloc).sprintf("%s/rgraph_%05u.dot", &path[0], m_version).toCString(),
 						 FileOpenFlag::kWrite));
 	for(const String& s : slist)
 	{

+ 3 - 3
AnKi/Gr/RenderGraph.h

@@ -745,9 +745,9 @@ private:
 	/// @name Dump the dependency graph into a file.
 	/// @{
 	Error dumpDependencyDotFile(const RenderGraphDescription& descr, const BakeContext& ctx, CString path) const;
-	static StringAuto textureUsageToStr(StackAllocator<U8>& alloc, TextureUsageBit usage);
-	static StringAuto bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageBit usage);
-	static StringAuto asUsageToStr(StackAllocator<U8>& alloc, AccelerationStructureUsageBit usage);
+	static StringRaii textureUsageToStr(StackAllocator<U8>& alloc, TextureUsageBit usage);
+	static StringRaii bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageBit usage);
+	static StringRaii asUsageToStr(StackAllocator<U8>& alloc, AccelerationStructureUsageBit usage);
 	/// @}
 
 	TexturePtr getTexture(RenderTargetHandle handle) const;

+ 5 - 5
AnKi/Gr/Vulkan/CommandBufferImpl.cpp

@@ -461,11 +461,11 @@ void CommandBufferImpl::flushBarriers()
 	// Batch
 	//
 
-	DynamicArrayAuto<VkImageMemoryBarrier> finalImgBarriers(m_alloc);
+	DynamicArrayRaii<VkImageMemoryBarrier> finalImgBarriers(m_alloc);
 	U32 finalImgBarrierCount = 0;
 	if(m_imgBarrierCount > 0)
 	{
-		DynamicArrayAuto<VkImageMemoryBarrier> squashedBarriers(m_alloc);
+		DynamicArrayRaii<VkImageMemoryBarrier> squashedBarriers(m_alloc);
 		U32 squashedBarrierCount = 0;
 
 		squashedBarriers.create(m_imgBarrierCount);
@@ -894,9 +894,9 @@ void CommandBufferImpl::setPipelineBarrierInternal(
 {
 	commandCommon();
 
-	DynamicArrayAuto<VkImageMemoryBarrier> imageBarriers(m_alloc);
-	DynamicArrayAuto<VkBufferMemoryBarrier> bufferBarriers(m_alloc);
-	DynamicArrayAuto<VkMemoryBarrier> genericBarriers(m_alloc);
+	DynamicArrayRaii<VkImageMemoryBarrier> imageBarriers(m_alloc);
+	DynamicArrayRaii<VkBufferMemoryBarrier> bufferBarriers(m_alloc);
+	DynamicArrayRaii<VkMemoryBarrier> genericBarriers(m_alloc);
 	VkPipelineStageFlags srcStageMask = 0;
 	VkPipelineStageFlags dstStageMask = 0;
 

+ 5 - 5
AnKi/Gr/Vulkan/DescriptorSet.cpp

@@ -523,11 +523,11 @@ void DescriptorSetFactory::DSAllocator::writeSet(
 	const Array<AnyBindingExtended, kMaxBindingsPerDescriptorSet>& bindings, const DS& set,
 	StackAllocator<U8>& tmpAlloc)
 {
-	DynamicArrayAuto<VkWriteDescriptorSet> writeInfos(tmpAlloc);
-	DynamicArrayAuto<VkDescriptorImageInfo> texInfos(tmpAlloc);
-	DynamicArrayAuto<VkDescriptorBufferInfo> buffInfos(tmpAlloc);
-	DynamicArrayAuto<VkWriteDescriptorSetAccelerationStructureKHR> asInfos(tmpAlloc);
-	DynamicArrayAuto<VkBufferView> bufferViews(tmpAlloc);
+	DynamicArrayRaii<VkWriteDescriptorSet> writeInfos(tmpAlloc);
+	DynamicArrayRaii<VkDescriptorImageInfo> texInfos(tmpAlloc);
+	DynamicArrayRaii<VkDescriptorBufferInfo> buffInfos(tmpAlloc);
+	DynamicArrayRaii<VkWriteDescriptorSetAccelerationStructureKHR> asInfos(tmpAlloc);
+	DynamicArrayRaii<VkBufferView> bufferViews(tmpAlloc);
 
 	// First pass: Populate the VkDescriptorImageInfo and VkDescriptorBufferInfo
 	for(U bindingIdx = m_layoutEntry->m_minBinding; bindingIdx <= m_layoutEntry->m_maxBinding; ++bindingIdx)

+ 18 - 18
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -227,14 +227,14 @@ Error GrManagerImpl::initInstance()
 	ci.pApplicationInfo = &app;
 
 	// Instance layers
-	DynamicArrayAuto<const char*> layersToEnable(getAllocator());
+	DynamicArrayRaii<const char*> layersToEnable(getAllocator());
 	{
 		U32 layerCount;
 		vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
 
 		if(layerCount)
 		{
-			DynamicArrayAuto<VkLayerProperties> layerProps(getAllocator(), layerCount);
+			DynamicArrayRaii<VkLayerProperties> layerProps(getAllocator(), layerCount);
 			vkEnumerateInstanceLayerProperties(&layerCount, &layerProps[0]);
 
 			ANKI_VK_LOGV("Found the following instance layers:");
@@ -265,8 +265,8 @@ Error GrManagerImpl::initInstance()
 	}
 
 	// Validation features
-	DynamicArrayAuto<VkValidationFeatureEnableEXT> enabledValidationFeatures(getAllocator());
-	DynamicArrayAuto<VkValidationFeatureDisableEXT> disabledValidationFeatures(getAllocator());
+	DynamicArrayRaii<VkValidationFeatureEnableEXT> enabledValidationFeatures(getAllocator());
+	DynamicArrayRaii<VkValidationFeatureDisableEXT> disabledValidationFeatures(getAllocator());
 	if(m_config->getGrDebugPrintf())
 	{
 		enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
@@ -292,8 +292,8 @@ Error GrManagerImpl::initInstance()
 	}
 
 	// Extensions
-	DynamicArrayAuto<const char*> instExtensions(getAllocator());
-	DynamicArrayAuto<VkExtensionProperties> instExtensionInf(getAllocator());
+	DynamicArrayRaii<const char*> instExtensions(getAllocator());
+	DynamicArrayRaii<VkExtensionProperties> instExtensionInf(getAllocator());
 	U32 extCount = 0;
 	vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
 	if(extCount)
@@ -429,7 +429,7 @@ Error GrManagerImpl::initInstance()
 
 	// Find the correct physical device
 	{
-		DynamicArrayAuto<VkPhysicalDevice> physicalDevices(m_alloc, count);
+		DynamicArrayRaii<VkPhysicalDevice> physicalDevices(m_alloc, count);
 		ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &physicalDevices[0]));
 
 		VkPhysicalDevice firstChoice = VK_NULL_HANDLE;
@@ -554,7 +554,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
 	ANKI_VK_LOGI("Number of queue families: %u", count);
 
-	DynamicArrayAuto<VkQueueFamilyProperties> queueInfos(getAllocator());
+	DynamicArrayRaii<VkQueueFamilyProperties> queueInfos(getAllocator());
 	queueInfos.create(count);
 	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
 
@@ -624,8 +624,8 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	U32 extCount = 0;
 	vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, nullptr);
 
-	DynamicArrayAuto<VkExtensionProperties> extensionInfos(getAllocator()); // Keep it alive in the stack
-	DynamicArrayAuto<const char*> extensionsToEnable(getAllocator());
+	DynamicArrayRaii<VkExtensionProperties> extensionInfos(getAllocator()); // Keep it alive in the stack
+	DynamicArrayRaii<const char*> extensionsToEnable(getAllocator());
 	if(extCount)
 	{
 		extensionInfos.create(extCount);
@@ -1482,7 +1482,7 @@ VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBi
 
 	// Get all names of affected objects
 	GrManagerImpl* self = static_cast<GrManagerImpl*>(pUserData);
-	StringAuto objectNames(self->m_alloc);
+	StringRaii objectNames(self->m_alloc);
 	if(pCallbackData->objectCount)
 	{
 		for(U32 i = 0; i < pCallbackData->objectCount; ++i)
@@ -1537,7 +1537,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 		if(!m_shaderStatsFile.isOpen())
 		{
 			ANKI_CHECK(m_shaderStatsFile.open(
-				StringAuto(getAllocator()).sprintf("%s/../ppline_stats.csv", m_cacheDir.cstr()).toCString(),
+				StringRaii(getAllocator()).sprintf("%s/../ppline_stats.csv", m_cacheDir.cstr()).toCString(),
 				FileOpenFlag::kWrite));
 
 			ANKI_CHECK(m_shaderStatsFile.writeText("ppline name,hash,"
@@ -1551,7 +1551,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 
 		ANKI_CHECK(m_shaderStatsFile.writeTextf("%s,0x%" PRIx64 ",", name.cstr(), hash));
 
-		StringAuto str(getAllocator());
+		StringRaii str(getAllocator());
 
 		for(ShaderType type = ShaderType::kFirst; type < ShaderType::kCount; ++type)
 		{
@@ -1566,7 +1566,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 			ANKI_VK_CHECK(m_pfnGetShaderInfoAMD(m_device, ppline, VkShaderStageFlagBits(convertShaderTypeBit(stage)),
 												VK_SHADER_INFO_TYPE_STATISTICS_AMD, &size, &stats));
 
-			str.append(StringAuto(getAllocator())
+			str.append(StringRaii(getAllocator())
 						   .sprintf("Stage %u: VGRPS %02u, SGRPS %02u ", U32(type), stats.resourceUsage.numUsedVgprs,
 									stats.resourceUsage.numUsedSgprs));
 
@@ -1583,14 +1583,14 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 
 	if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties))
 	{
-		StringListAuto log(m_alloc);
+		StringListRaii log(m_alloc);
 
 		VkPipelineInfoKHR pplineInf = {};
 		pplineInf.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
 		pplineInf.pipeline = ppline;
 		U32 executableCount = 0;
 		ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
-		DynamicArrayAuto<VkPipelineExecutablePropertiesKHR> executableProps(m_alloc, executableCount);
+		DynamicArrayRaii<VkPipelineExecutablePropertiesKHR> executableProps(m_alloc, executableCount);
 		for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
 		{
 			prop = {};
@@ -1612,7 +1612,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 			exeInf.pipeline = ppline;
 			U32 statCount = 0;
 			vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, nullptr);
-			DynamicArrayAuto<VkPipelineExecutableStatisticKHR> stats(m_alloc, statCount);
+			DynamicArrayRaii<VkPipelineExecutableStatisticKHR> stats(m_alloc, statCount);
 			for(VkPipelineExecutableStatisticKHR& s : stats)
 			{
 				s = {};
@@ -1651,7 +1651,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 			}
 		}
 
-		StringAuto finalLog(m_alloc);
+		StringRaii finalLog(m_alloc);
 		log.join("", finalLog);
 		ANKI_VK_LOGV("%s", finalLog.cstr());
 	}

+ 2 - 2
AnKi/Gr/Vulkan/PipelineCache.cpp

@@ -18,7 +18,7 @@ Error PipelineCache::init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir,
 	m_dumpFilename.sprintf(alloc, "%s/VkPipelineCache", &cacheDir[0]);
 
 	// Try read the pipeline cache file.
-	DynamicArrayAuto<U8, PtrSize> diskDump(alloc);
+	DynamicArrayRaii<U8, PtrSize> diskDump(alloc);
 	if(fileExists(m_dumpFilename.toCString()))
 	{
 		File file;
@@ -94,7 +94,7 @@ Error PipelineCache::destroyInternal(VkDevice dev, VkPhysicalDevice pdev, GrAllo
 		if(size > 0)
 		{
 			// Read cache
-			DynamicArrayAuto<U8, PtrSize> cacheData(alloc);
+			DynamicArrayRaii<U8, PtrSize> cacheData(alloc);
 			cacheData.create(size);
 			ANKI_VK_CHECK(vkGetPipelineCacheData(dev, m_cacheHandle, &size, &cacheData[0]));
 

+ 1 - 1
AnKi/Gr/Vulkan/ShaderImpl.cpp

@@ -56,7 +56,7 @@ Error ShaderImpl::init(const ShaderInitInfo& inf)
 
 #if ANKI_DUMP_SHADERS
 	{
-		StringAuto fnameSpirv(getAllocator());
+		StringRaii fnameSpirv(getAllocator());
 		fnameSpirv.sprintf("%s/%s_t%u_%05u.spv", getManager().getCacheDirectory().cstr(), getName().cstr(),
 						   U(m_shaderType), getUuid());
 

+ 2 - 2
AnKi/Gr/Vulkan/ShaderProgramImpl.cpp

@@ -264,7 +264,7 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 	if(!!(m_stages & ShaderTypeBit::kAllRayTracing))
 	{
 		// Create shaders
-		DynamicArrayAuto<VkPipelineShaderStageCreateInfo> stages(getAllocator(), m_shaders.getSize());
+		DynamicArrayRaii<VkPipelineShaderStageCreateInfo> stages(getAllocator(), m_shaders.getSize());
 		for(U32 i = 0; i < stages.getSize(); ++i)
 		{
 			const ShaderImpl& impl = static_cast<const ShaderImpl&>(*m_shaders[i]);
@@ -289,7 +289,7 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 		U32 groupCount = inf.m_rayTracingShaders.m_rayGenShaders.getSize()
 						 + inf.m_rayTracingShaders.m_missShaders.getSize()
 						 + inf.m_rayTracingShaders.m_hitGroups.getSize();
-		DynamicArrayAuto<VkRayTracingShaderGroupCreateInfoKHR> groups(getAllocator(), groupCount, defaultGroup);
+		DynamicArrayRaii<VkRayTracingShaderGroupCreateInfoKHR> groups(getAllocator(), groupCount, defaultGroup);
 
 		// 1st group is the ray gen
 		groupCount = 0;

+ 1 - 1
AnKi/Gr/Vulkan/SwapchainFactory.cpp

@@ -70,7 +70,7 @@ Error MicroSwapchain::initInternal()
 		ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(m_factory->m_gr->getPhysicalDevice(),
 														   m_factory->m_gr->getSurface(), &formatCount, nullptr));
 
-		DynamicArrayAuto<VkSurfaceFormatKHR> formats(getAllocator());
+		DynamicArrayRaii<VkSurfaceFormatKHR> formats(getAllocator());
 		formats.create(formatCount);
 		ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(m_factory->m_gr->getPhysicalDevice(),
 														   m_factory->m_gr->getSurface(), &formatCount, &formats[0]));

+ 60 - 60
AnKi/Importer/GltfImporter.cpp

@@ -136,7 +136,7 @@ static Error getNodeTransform(const cgltf_node& node, Transform& trf)
 	return Error::kNone;
 }
 
-static Bool stringsExist(const HashMapAuto<CString, StringAuto>& map, const std::initializer_list<CString>& list)
+static Bool stringsExist(const HashMapAuto<CString, StringRaii>& map, const std::initializer_list<CString>& list)
 {
 	for(CString item : list)
 	{
@@ -221,7 +221,7 @@ Error GltfImporter::writeAll()
 {
 	populateNodePtrToIdx();
 
-	StringAuto sceneFname(m_alloc);
+	StringRaii sceneFname(m_alloc);
 	sceneFname.sprintf("%sScene.lua", m_outDir.cstr());
 	ANKI_CHECK(m_sceneFile.open(sceneFname.toCString(), FileOpenFlag::kWrite));
 	ANKI_CHECK(m_sceneFile.writeTextf("-- Generated by: %s\n", m_comment.cstr()));
@@ -233,7 +233,7 @@ Error GltfImporter::writeAll()
 	{
 		for(cgltf_node* const* node = scene->nodes; node < scene->nodes + scene->nodes_count && !err; ++node)
 		{
-			err = visitNode(*(*node), Transform::getIdentity(), HashMapAuto<CString, StringAuto>(m_alloc));
+			err = visitNode(*(*node), Transform::getIdentity(), HashMapAuto<CString, StringRaii>(m_alloc));
 		}
 	}
 
@@ -264,7 +264,7 @@ Error GltfImporter::writeAll()
 	return err;
 }
 
-Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, StringAuto>& out)
+Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, StringRaii>& out)
 {
 	cgltf_size extrasSize;
 	cgltf_copy_extras_json(m_gltf, &extras, nullptr, &extrasSize);
@@ -273,7 +273,7 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, S
 		return Error::kNone;
 	}
 
-	DynamicArrayAuto<char, PtrSize> json(m_alloc);
+	DynamicArrayRaii<char, PtrSize> json(m_alloc);
 	json.create(extrasSize + 1);
 	cgltf_result res = cgltf_copy_extras_json(m_gltf, &extras, &json[0], &extrasSize);
 	if(res != cgltf_result_success)
@@ -294,14 +294,14 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, S
 		return Error::kNone;
 	}
 
-	DynamicArrayAuto<jsmntok_t> tokens(m_alloc);
+	DynamicArrayRaii<jsmntok_t> tokens(m_alloc);
 	tokens.create(U32(tokenCount));
 
 	// Get tokens
 	jsmn_init(&parser);
 	jsmn_parse(&parser, jsonTxt.cstr(), jsonTxt.getLength(), &tokens[0], tokens.getSize());
 
-	StringListAuto tokenStrings(m_alloc);
+	StringListRaii tokenStrings(m_alloc);
 	for(const jsmntok_t& token : tokens)
 	{
 		if(token.type != JSMN_STRING && token.type != JSMN_PRIMITIVE)
@@ -309,7 +309,7 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, S
 			continue;
 		}
 
-		StringAuto tokenStr(m_alloc);
+		StringRaii tokenStr(m_alloc);
 		tokenStr.create(&jsonTxt[token.start], &jsonTxt[token.end]);
 		tokenStrings.pushBack(tokenStr.toCString());
 	}
@@ -327,7 +327,7 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapAuto<CString, S
 		auto it2 = it;
 		++it2;
 
-		out.emplace(it->toCString(), StringAuto(m_alloc, it2->toCString()));
+		out.emplace(it->toCString(), StringRaii(m_alloc, it2->toCString()));
 		++it;
 		++it;
 	}
@@ -358,9 +358,9 @@ void GltfImporter::populateNodePtrToIdx()
 	}
 }
 
-StringAuto GltfImporter::getNodeName(const cgltf_node& node)
+StringRaii GltfImporter::getNodeName(const cgltf_node& node)
 {
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 
 	if(node.name)
 	{
@@ -376,9 +376,9 @@ StringAuto GltfImporter::getNodeName(const cgltf_node& node)
 	return out;
 }
 
-Error GltfImporter::parseArrayOfNumbers(CString str, DynamicArrayAuto<F64>& out, const U32* expectedArraySize)
+Error GltfImporter::parseArrayOfNumbers(CString str, DynamicArrayRaii<F64>& out, const U32* expectedArraySize)
 {
-	StringListAuto list(m_alloc);
+	StringListRaii list(m_alloc);
 	list.splitString(str, ' ');
 
 	out.create(U32(list.getSize()));
@@ -408,7 +408,7 @@ Error GltfImporter::parseArrayOfNumbers(CString str, DynamicArrayAuto<F64>& out,
 }
 
 Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf,
-							  const HashMapAuto<CString, StringAuto>& parentExtras)
+							  const HashMapAuto<CString, StringRaii>& parentExtras)
 {
 	// Check error from a thread
 	const Error threadErr = m_errorInThread.load();
@@ -418,7 +418,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 		return threadErr;
 	}
 
-	HashMapAuto<CString, StringAuto> outExtras(m_alloc);
+	HashMapAuto<CString, StringRaii> outExtras(m_alloc);
 	if(node.light)
 	{
 		ANKI_CHECK(writeLight(node, parentExtras));
@@ -440,17 +440,17 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 	else if(node.mesh)
 	{
 		// Handle special nodes
-		HashMapAuto<CString, StringAuto> extras(parentExtras);
+		HashMapAuto<CString, StringRaii> extras(parentExtras);
 		ANKI_CHECK(getExtras(node.mesh->extras, extras));
 		ANKI_CHECK(getExtras(node.extras, extras));
 
-		HashMapAuto<CString, StringAuto>::Iterator it;
+		HashMapAuto<CString, StringRaii>::Iterator it;
 
 		const Bool skipRt = (it = extras.find("no_rt")) != extras.getEnd() && (*it == "true" || *it == "1");
 
 		if((it = extras.find("particles")) != extras.getEnd())
 		{
-			const StringAuto& fname = *it;
+			const StringRaii& fname = *it;
 
 			Bool gpuParticles = false;
 			if((it = extras.find("gpu_particles")) != extras.getEnd() && *it == "true")
@@ -479,7 +479,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 
 			if((it = extras.find("skybox_solid_color")) != extras.getEnd())
 			{
-				StringListAuto tokens(m_alloc);
+				StringListRaii tokens(m_alloc);
 				tokens.splitString(*it, ' ');
 				if(tokens.getSize() != 3)
 				{
@@ -548,7 +548,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 				m_sceneFile.writeTextf("\nnode = scene:newStaticCollisionNode(\"%s\")\n", getNodeName(node).cstr()));
 
 			ANKI_CHECK(m_sceneFile.writeText("comp = scene:getSceneNodeBase():getBodyComponent()\n"));
-			const StringAuto meshFname = computeMeshResourceFilename(*node.mesh);
+			const StringRaii meshFname = computeMeshResourceFilename(*node.mesh);
 			ANKI_CHECK(m_sceneFile.writeTextf("comp:loadMeshResource(\"%s%s\")\n", m_rpath.cstr(), meshFname.cstr()));
 
 			Transform localTrf;
@@ -616,13 +616,13 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 		}
 		else if((it = extras.find("decal")) != extras.getEnd() && (*it == "true" || *it == "1"))
 		{
-			StringAuto diffuseAtlas(m_alloc);
+			StringRaii diffuseAtlas(m_alloc);
 			if((it = extras.find("decal_diffuse_atlas")) != extras.getEnd())
 			{
 				diffuseAtlas.create(it->toCString());
 			}
 
-			StringAuto diffuseSubtexture(m_alloc);
+			StringRaii diffuseSubtexture(m_alloc);
 			if((it = extras.find("decal_diffuse_sub_texture")) != extras.getEnd())
 			{
 				diffuseSubtexture.create(it->toCString());
@@ -634,13 +634,13 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 				ANKI_CHECK(it->toNumber(diffuseFactor));
 			}
 
-			StringAuto specularRougnessMetallicAtlas(m_alloc);
+			StringRaii specularRougnessMetallicAtlas(m_alloc);
 			if((it = extras.find("decal_specular_roughness_metallic_atlas")) != extras.getEnd())
 			{
 				specularRougnessMetallicAtlas.create(it->toCString());
 			}
 
-			StringAuto specularRougnessMetallicSubtexture(m_alloc);
+			StringRaii specularRougnessMetallicSubtexture(m_alloc);
 			if((it = extras.find("decal_specular_roughness_metallic_sub_texture")) != extras.getEnd())
 			{
 				specularRougnessMetallicSubtexture.create(it->toCString());
@@ -698,7 +698,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 			ctx->m_skin = node.skin;
 			ctx->m_rayTracing = !skipRt;
 
-			HashMapAuto<CString, StringAuto>::Iterator it2;
+			HashMapAuto<CString, StringRaii>::Iterator it2;
 			const Bool selfCollision = (it2 = extras.find("collision_mesh")) != extras.getEnd() && *it2 == "self";
 
 			U32 maxLod = 0;
@@ -781,7 +781,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 
 				ANKI_CHECK(m_sceneFile.writeText("comp = node2:getSceneNodeBase():getBodyComponent()\n"));
 
-				const StringAuto meshFname = computeMeshResourceFilename(*node.mesh, maxLod);
+				const StringRaii meshFname = computeMeshResourceFilename(*node.mesh, maxLod);
 
 				ANKI_CHECK(
 					m_sceneFile.writeTextf("comp:loadMeshResource(\"%s%s\")\n", m_rpath.cstr(), meshFname.cstr()));
@@ -835,14 +835,14 @@ Error GltfImporter::writeTransform(const Transform& trf)
 
 Error GltfImporter::writeModel(const cgltf_mesh& mesh)
 {
-	const StringAuto modelFname = computeModelResourceFilename(mesh);
+	const StringRaii modelFname = computeModelResourceFilename(mesh);
 	ANKI_IMPORTER_LOGV("Importing model %s", modelFname.cstr());
 
-	HashMapAuto<CString, StringAuto> extras(m_alloc);
+	HashMapAuto<CString, StringRaii> extras(m_alloc);
 	ANKI_CHECK(getExtras(mesh.extras, extras));
 
 	File file;
-	StringAuto modelFullFname(m_alloc);
+	StringRaii modelFullFname(m_alloc);
 	modelFullFname.sprintf("%s/%s", m_outDir.cstr(), modelFname.cstr());
 	ANKI_CHECK(file.open(modelFullFname, FileOpenFlag::kWrite));
 
@@ -861,23 +861,23 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh)
 		}
 
 		{
-			const StringAuto meshFname = computeMeshResourceFilename(mesh);
+			const StringRaii meshFname = computeMeshResourceFilename(mesh);
 			ANKI_CHECK(file.writeTextf("\t\t\t<mesh>%s%s</mesh>\n", m_rpath.cstr(), meshFname.cstr()));
 		}
 
 		if(m_lodCount > 1 && !skipMeshLod(mesh, 1))
 		{
-			const StringAuto meshFname = computeMeshResourceFilename(mesh, 1);
+			const StringRaii meshFname = computeMeshResourceFilename(mesh, 1);
 			ANKI_CHECK(file.writeTextf("\t\t\t<mesh1>%s%s</mesh1>\n", m_rpath.cstr(), meshFname.cstr()));
 		}
 
 		if(m_lodCount > 2 && !skipMeshLod(mesh, 2))
 		{
-			const StringAuto meshFname = computeMeshResourceFilename(mesh, 2);
+			const StringRaii meshFname = computeMeshResourceFilename(mesh, 2);
 			ANKI_CHECK(file.writeTextf("\t\t\t<mesh2>%s%s</mesh2>\n", m_rpath.cstr(), meshFname.cstr()));
 		}
 
-		HashMapAuto<CString, StringAuto> materialExtras(m_alloc);
+		HashMapAuto<CString, StringRaii> materialExtras(m_alloc);
 		ANKI_CHECK(getExtras(mesh.primitives[primIdx].material->extras, materialExtras));
 		auto mtlOverride = materialExtras.find("material_override");
 		if(mtlOverride != materialExtras.getEnd())
@@ -886,7 +886,7 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh)
 		}
 		else
 		{
-			const StringAuto mtlFname = computeMaterialResourceFilename(*mesh.primitives[primIdx].material);
+			const StringRaii mtlFname = computeMaterialResourceFilename(*mesh.primitives[primIdx].material);
 			ANKI_CHECK(file.writeTextf("\t\t\t<material>%s%s</material>\n", m_rpath.cstr(), mtlFname.cstr()));
 		}
 
@@ -902,12 +902,12 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh)
 
 Error GltfImporter::writeSkeleton(const cgltf_skin& skin)
 {
-	StringAuto fname(m_alloc);
+	StringRaii fname(m_alloc);
 	fname.sprintf("%s%s", m_outDir.cstr(), computeSkeletonResourceFilename(skin).cstr());
 	ANKI_IMPORTER_LOGV("Importing skeleton %s", fname.cstr());
 
 	// Get matrices
-	DynamicArrayAuto<Mat4> boneMats(m_alloc);
+	DynamicArrayRaii<Mat4> boneMats(m_alloc);
 	readAccessor(*skin.inverse_bind_matrices, boneMats);
 	if(boneMats.getSize() != skin.joints_count)
 	{
@@ -926,7 +926,7 @@ Error GltfImporter::writeSkeleton(const cgltf_skin& skin)
 	{
 		const cgltf_node& boneNode = *skin.joints[i];
 
-		StringAuto parent(m_alloc);
+		StringRaii parent(m_alloc);
 
 		// Name & parent
 		ANKI_CHECK(file.writeTextf("\t\t<bone name=\"%s\" ", getNodeName(boneNode).cstr()));
@@ -965,13 +965,13 @@ Error GltfImporter::writeSkeleton(const cgltf_skin& skin)
 	return Error::kNone;
 }
 
-Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString, StringAuto>& parentExtras)
+Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString, StringRaii>& parentExtras)
 {
 	const cgltf_light& light = *node.light;
-	StringAuto nodeName = getNodeName(node);
+	StringRaii nodeName = getNodeName(node);
 	ANKI_IMPORTER_LOGV("Importing light %s", nodeName.cstr());
 
-	HashMapAuto<CString, StringAuto> extras(parentExtras);
+	HashMapAuto<CString, StringRaii> extras(parentExtras);
 	ANKI_CHECK(getExtras(light.extras, extras));
 	ANKI_CHECK(getExtras(node.extras, extras));
 
@@ -1059,7 +1059,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString
 
 		if(lsSpriteSize != extras.getEnd())
 		{
-			DynamicArrayAuto<F64> numbers(m_alloc);
+			DynamicArrayRaii<F64> numbers(m_alloc);
 			const U32 count = 2;
 			ANKI_CHECK(parseArrayOfNumbers(lsSpriteSize->toCString(), numbers, &count));
 
@@ -1068,7 +1068,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString
 
 		if(lsColor != extras.getEnd())
 		{
-			DynamicArrayAuto<F64> numbers(m_alloc);
+			DynamicArrayRaii<F64> numbers(m_alloc);
 			const U32 count = 4;
 			ANKI_CHECK(parseArrayOfNumbers(lsColor->toCString(), numbers, &count));
 
@@ -1085,7 +1085,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString
 
 		if(lightEventIntensity != extras.getEnd())
 		{
-			DynamicArrayAuto<F64> numbers(m_alloc);
+			DynamicArrayRaii<F64> numbers(m_alloc);
 			const U32 count = 4;
 			ANKI_CHECK(parseArrayOfNumbers(lightEventIntensity->toCString(), numbers, &count));
 			ANKI_CHECK(m_sceneFile.writeTextf("event:setIntensityMultiplier(Vec4.new(%f, %f, %f, %f))\n", numbers[0],
@@ -1094,7 +1094,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString
 
 		if(lightEventFrequency != extras.getEnd())
 		{
-			DynamicArrayAuto<F64> numbers(m_alloc);
+			DynamicArrayRaii<F64> numbers(m_alloc);
 			const U32 count = 2;
 			ANKI_CHECK(parseArrayOfNumbers(lightEventFrequency->toCString(), numbers, &count));
 			ANKI_CHECK(m_sceneFile.writeTextf("event:setFrequency(%f, %f)\n", numbers[0], numbers[1]));
@@ -1105,7 +1105,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapAuto<CString
 }
 
 Error GltfImporter::writeCamera(const cgltf_node& node,
-								[[maybe_unused]] const HashMapAuto<CString, StringAuto>& parentExtras)
+								[[maybe_unused]] const HashMapAuto<CString, StringRaii>& parentExtras)
 {
 	if(node.camera->type != cgltf_camera_type_perspective)
 	{
@@ -1128,14 +1128,14 @@ Error GltfImporter::writeCamera(const cgltf_node& node,
 	return Error::kNone;
 }
 
-Error GltfImporter::writeModelNode(const cgltf_node& node, const HashMapAuto<CString, StringAuto>& parentExtras)
+Error GltfImporter::writeModelNode(const cgltf_node& node, const HashMapAuto<CString, StringRaii>& parentExtras)
 {
 	ANKI_IMPORTER_LOGV("Importing model node %s", getNodeName(node).cstr());
 
-	HashMapAuto<CString, StringAuto> extras(parentExtras);
+	HashMapAuto<CString, StringRaii> extras(parentExtras);
 	ANKI_CHECK(getExtras(node.extras, extras));
 
-	const StringAuto modelFname = computeModelResourceFilename(*node.mesh);
+	const StringRaii modelFname = computeModelResourceFilename(*node.mesh);
 
 	ANKI_CHECK(m_sceneFile.writeTextf("\nnode = scene:newModelNode(\"%s\")\n", getNodeName(node).cstr()));
 	ANKI_CHECK(m_sceneFile.writeTextf("node:getSceneNodeBase():getModelComponent():loadModelResource(\"%s%s\")\n",
@@ -1150,9 +1150,9 @@ Error GltfImporter::writeModelNode(const cgltf_node& node, const HashMapAuto<CSt
 	return Error::kNone;
 }
 
-StringAuto GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) const
+StringRaii GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) const
 {
-	StringListAuto list(m_alloc);
+	StringListRaii list(m_alloc);
 
 	list.pushBack(mesh.name);
 
@@ -1162,55 +1162,55 @@ StringAuto GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) co
 		list.pushBackSprintf("_%s", mtlName);
 	}
 
-	StringAuto joined(m_alloc);
+	StringRaii joined(m_alloc);
 	list.join("", joined);
 
 	const U64 hash = computeHash(joined.getBegin(), joined.getLength());
 
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 	out.sprintf("%.64s_%" PRIx64 ".ankimdl", joined.cstr(), hash); // Limit the filename size
 
 	return out;
 }
 
-StringAuto GltfImporter::computeMeshResourceFilename(const cgltf_mesh& mesh, U32 lod) const
+StringRaii GltfImporter::computeMeshResourceFilename(const cgltf_mesh& mesh, U32 lod) const
 {
 	const U64 hash = computeHash(mesh.name, strlen(mesh.name));
 
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 
 	out.sprintf("%.64s_lod%u_%" PRIx64 ".ankimesh", mesh.name, lod, hash); // Limit the filename size
 
 	return out;
 }
 
-StringAuto GltfImporter::computeMaterialResourceFilename(const cgltf_material& mtl) const
+StringRaii GltfImporter::computeMaterialResourceFilename(const cgltf_material& mtl) const
 {
 	const U64 hash = computeHash(mtl.name, strlen(mtl.name));
 
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankimtl", mtl.name, hash); // Limit the filename size
 
 	return out;
 }
 
-StringAuto GltfImporter::computeAnimationResourceFilename(const cgltf_animation& anim) const
+StringRaii GltfImporter::computeAnimationResourceFilename(const cgltf_animation& anim) const
 {
 	const U64 hash = computeHash(anim.name, strlen(anim.name));
 
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankianim", anim.name, hash); // Limit the filename size
 
 	return out;
 }
 
-StringAuto GltfImporter::computeSkeletonResourceFilename(const cgltf_skin& skin) const
+StringRaii GltfImporter::computeSkeletonResourceFilename(const cgltf_skin& skin) const
 {
 	const U64 hash = computeHash(skin.name, strlen(skin.name));
 
-	StringAuto out(m_alloc);
+	StringRaii out(m_alloc);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankiskel", skin.name, hash); // Limit the filename size
 

+ 20 - 20
AnKi/Importer/GltfImporter.h

@@ -61,10 +61,10 @@ private:
 	// Data
 	GenericMemoryPoolAllocator<U8> m_alloc;
 
-	StringAuto m_inputFname = {m_alloc};
-	StringAuto m_outDir = {m_alloc};
-	StringAuto m_rpath = {m_alloc};
-	StringAuto m_texrpath = {m_alloc};
+	StringRaii m_inputFname = {m_alloc};
+	StringRaii m_outDir = {m_alloc};
+	StringRaii m_rpath = {m_alloc};
+	StringRaii m_texrpath = {m_alloc};
 
 	cgltf_data* m_gltf = nullptr;
 
@@ -83,32 +83,32 @@ private:
 	F32 m_lightIntensityScale = 1.0f;
 	Bool m_optimizeMeshes = false;
 	Bool m_optimizeAnimations = false;
-	StringAuto m_comment{m_alloc};
+	StringRaii m_comment{m_alloc};
 
 	/// Don't generate LODs for meshes with less vertices than this number.
 	U32 m_skipLodVertexCountThreshold = 256;
 
 	// Misc
-	Error getExtras(const cgltf_extras& extras, HashMapAuto<CString, StringAuto>& out);
-	Error parseArrayOfNumbers(CString str, DynamicArrayAuto<F64>& out, const U32* expectedArraySize = nullptr);
+	Error getExtras(const cgltf_extras& extras, HashMapAuto<CString, StringRaii>& out);
+	Error parseArrayOfNumbers(CString str, DynamicArrayRaii<F64>& out, const U32* expectedArraySize = nullptr);
 	void populateNodePtrToIdx();
 	void populateNodePtrToIdxInternal(const cgltf_node& node, U32& idx);
-	StringAuto getNodeName(const cgltf_node& node);
+	StringRaii getNodeName(const cgltf_node& node);
 
 	template<typename T, typename TFunc>
 	static void visitAccessor(const cgltf_accessor& accessor, TFunc func);
 
 	template<typename T>
-	static void readAccessor(const cgltf_accessor& accessor, DynamicArrayAuto<T>& out)
+	static void readAccessor(const cgltf_accessor& accessor, DynamicArrayRaii<T>& out)
 	{
 		visitAccessor<T>(accessor, [&](const T& val) {
 			out.emplaceBack(val);
 		});
 	}
 
-	StringAuto fixFilename(CString in) const
+	StringRaii fixFilename(CString in) const
 	{
-		StringAuto out(m_alloc, in);
+		StringRaii out(m_alloc, in);
 		out.replaceAll("|", "_");
 		out.replaceAll(" ", "_");
 		return out;
@@ -128,11 +128,11 @@ private:
 	static U32 getMeshTotalVertexCount(const cgltf_mesh& mesh);
 
 	// Compute filenames for various resources. Use a hash to solve the casing issue and remove unwanted special chars
-	StringAuto computeModelResourceFilename(const cgltf_mesh& mesh) const;
-	StringAuto computeMeshResourceFilename(const cgltf_mesh& mesh, U32 lod = 0) const;
-	StringAuto computeMaterialResourceFilename(const cgltf_material& mtl) const;
-	StringAuto computeAnimationResourceFilename(const cgltf_animation& anim) const;
-	StringAuto computeSkeletonResourceFilename(const cgltf_skin& skin) const;
+	StringRaii computeModelResourceFilename(const cgltf_mesh& mesh) const;
+	StringRaii computeMeshResourceFilename(const cgltf_mesh& mesh, U32 lod = 0) const;
+	StringRaii computeMaterialResourceFilename(const cgltf_material& mtl) const;
+	StringRaii computeAnimationResourceFilename(const cgltf_animation& anim) const;
+	StringRaii computeSkeletonResourceFilename(const cgltf_skin& skin) const;
 
 	// Resources
 	Error writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFactor);
@@ -144,10 +144,10 @@ private:
 	// Scene
 	Error writeTransform(const Transform& trf);
 	Error visitNode(const cgltf_node& node, const Transform& parentTrf,
-					const HashMapAuto<CString, StringAuto>& parentExtras);
-	Error writeLight(const cgltf_node& node, const HashMapAuto<CString, StringAuto>& parentExtras);
-	Error writeCamera(const cgltf_node& node, const HashMapAuto<CString, StringAuto>& parentExtras);
-	Error writeModelNode(const cgltf_node& node, const HashMapAuto<CString, StringAuto>& parentExtras);
+					const HashMapAuto<CString, StringRaii>& parentExtras);
+	Error writeLight(const cgltf_node& node, const HashMapAuto<CString, StringRaii>& parentExtras);
+	Error writeCamera(const cgltf_node& node, const HashMapAuto<CString, StringRaii>& parentExtras);
+	Error writeModelNode(const cgltf_node& node, const HashMapAuto<CString, StringRaii>& parentExtras);
 };
 /// @}
 

+ 17 - 17
AnKi/Importer/GltfImporterAnimation.cpp

@@ -19,10 +19,10 @@ public:
 class GltfAnimChannel
 {
 public:
-	StringAuto m_name;
-	DynamicArrayAuto<GltfAnimKey<Vec3>> m_positions;
-	DynamicArrayAuto<GltfAnimKey<Quat>> m_rotations;
-	DynamicArrayAuto<GltfAnimKey<F32>> m_scales;
+	StringRaii m_name;
+	DynamicArrayRaii<GltfAnimKey<Vec3>> m_positions;
+	DynamicArrayRaii<GltfAnimKey<Quat>> m_rotations;
+	DynamicArrayRaii<GltfAnimKey<F32>> m_scales;
 	const cgltf_node* m_targetNode;
 
 	GltfAnimChannel(GenericMemoryPoolAllocator<U8> alloc)
@@ -36,7 +36,7 @@ public:
 
 /// Optimize out same animation keys.
 template<typename T, typename TZeroFunc, typename TLerpFunc>
-static void optimizeChannel(DynamicArrayAuto<GltfAnimKey<T>>& arr, const T& identity, TZeroFunc isZeroFunc,
+static void optimizeChannel(DynamicArrayRaii<GltfAnimKey<T>>& arr, const T& identity, TZeroFunc isZeroFunc,
 							TLerpFunc lerpFunc)
 {
 	constexpr F32 kMinSkippedToTotalRatio = 0.1f;
@@ -49,7 +49,7 @@ static void optimizeChannel(DynamicArrayAuto<GltfAnimKey<T>>& arr, const T& iden
 			break;
 		}
 
-		DynamicArrayAuto<GltfAnimKey<T>> newArr(arr.getAllocator());
+		DynamicArrayRaii<GltfAnimKey<T>> newArr(arr.getAllocator());
 		for(U32 i = 0; i < arr.getSize() - 2; i += 2)
 		{
 			const GltfAnimKey<T>& left = arr[i];
@@ -106,8 +106,8 @@ static void optimizeChannel(DynamicArrayAuto<GltfAnimKey<T>>& arr, const T& iden
 
 Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 {
-	StringAuto fname(m_alloc);
-	StringAuto animFname = computeAnimationResourceFilename(anim);
+	StringRaii fname(m_alloc);
+	StringRaii animFname = computeAnimationResourceFilename(anim);
 	fname.sprintf("%s%s", m_outDir.cstr(), animFname.cstr());
 	fname = fixFilename(fname);
 	ANKI_IMPORTER_LOGV("Importing animation %s", fname.cstr());
@@ -118,7 +118,7 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 	for(U i = 0; i < anim.channels_count; ++i)
 	{
 		const cgltf_animation_channel& channel = anim.channels[i];
-		const StringAuto channelName = getNodeName(*channel.target_node);
+		const StringRaii channelName = getNodeName(*channel.target_node);
 
 		U idx;
 		switch(channel.target_path)
@@ -152,13 +152,13 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 	}
 
 	// Gather the keys
-	DynamicArrayAuto<GltfAnimChannel> tempChannels(m_alloc, channelCount, m_alloc);
+	DynamicArrayRaii<GltfAnimChannel> tempChannels(m_alloc, channelCount, m_alloc);
 	channelCount = 0;
 	for(auto it = channelMap.getBegin(); it != channelMap.getEnd(); ++it)
 	{
 		Array<const cgltf_animation_channel*, 3> arr = *it;
 		const cgltf_animation_channel& anyChannel = (arr[0]) ? *arr[0] : ((arr[1]) ? *arr[1] : *arr[2]);
-		const StringAuto channelName = getNodeName(*anyChannel.target_node);
+		const StringRaii channelName = getNodeName(*anyChannel.target_node);
 
 		tempChannels[channelCount].m_name = channelName;
 		tempChannels[channelCount].m_targetNode = anyChannel.target_node;
@@ -167,9 +167,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[0])
 		{
 			const cgltf_animation_channel& channel = *arr[0];
-			DynamicArrayAuto<F32> keys(m_alloc);
+			DynamicArrayRaii<F32> keys(m_alloc);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayAuto<Vec3> positions(m_alloc);
+			DynamicArrayRaii<Vec3> positions(m_alloc);
 			readAccessor(*channel.sampler->output, positions);
 			if(keys.getSize() != positions.getSize())
 			{
@@ -191,9 +191,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[1])
 		{
 			const cgltf_animation_channel& channel = *arr[1];
-			DynamicArrayAuto<F32> keys(m_alloc);
+			DynamicArrayRaii<F32> keys(m_alloc);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayAuto<Quat> rotations(m_alloc);
+			DynamicArrayRaii<Quat> rotations(m_alloc);
 			readAccessor(*channel.sampler->output, rotations);
 			if(keys.getSize() != rotations.getSize())
 			{
@@ -215,9 +215,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[2])
 		{
 			const cgltf_animation_channel& channel = *arr[2];
-			DynamicArrayAuto<F32> keys(m_alloc);
+			DynamicArrayRaii<F32> keys(m_alloc);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayAuto<Vec3> scales(m_alloc);
+			DynamicArrayRaii<Vec3> scales(m_alloc);
 			readAccessor(*channel.sampler->output, scales);
 			if(keys.getSize() != scales.getSize())
 			{

+ 22 - 22
AnKi/Importer/GltfImporterMaterial.cpp

@@ -100,7 +100,7 @@ static Error findConstantColorsInImage(CString fname, Vec4& constantColor, Gener
 
 Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracing)
 {
-	StringAuto fname(m_alloc);
+	StringRaii fname(m_alloc);
 	fname.sprintf("%s%s", m_outDir.cstr(), computeMaterialResourceFilename(mtl).cstr());
 	ANKI_IMPORTER_LOGV("Importing material %s", fname.cstr());
 
@@ -110,10 +110,10 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		return Error::kUserData;
 	}
 
-	HashMapAuto<CString, StringAuto> extras(m_alloc);
+	HashMapAuto<CString, StringRaii> extras(m_alloc);
 	ANKI_CHECK(getExtras(mtl.extras, extras));
 
-	StringAuto xml(m_alloc);
+	StringRaii xml(m_alloc);
 	xml.append(XmlDocument::kXmlHeader);
 	xml.append("\n");
 	xml.append(kMaterialTemplate);
@@ -128,10 +128,10 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const CString fname = getTextureUri(mtl.pbr_metallic_roughness.base_color_texture);
 
-		StringAuto uri(m_alloc);
+		StringRaii uri(m_alloc);
 		uri.sprintf("%s%s", m_texrpath.cstr(), fname.cstr());
 
-		xml.replaceAll("%diff%", StringAuto(m_alloc).sprintf("<input name=\"m_diffTex\" value=\"%s\"/>", uri.cstr()));
+		xml.replaceAll("%diff%", StringRaii(m_alloc).sprintf("<input name=\"m_diffTex\" value=\"%s\"/>", uri.cstr()));
 		xml.replaceAll("%diffTexMutator%", "1");
 
 		Vec4 constantColor;
@@ -144,7 +144,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const F32* diffCol = &mtl.pbr_metallic_roughness.base_color_factor[0];
 
-		xml.replaceAll("%diff%", StringAuto(m_alloc).sprintf("<input name=\"m_diffColor\" value=\"%f %f %f\"/>",
+		xml.replaceAll("%diff%", StringRaii(m_alloc).sprintf("<input name=\"m_diffColor\" value=\"%f %f %f\"/>",
 															 diffCol[0], diffCol[1], diffCol[2]));
 
 		xml.replaceAll("%diffTexMutator%", "0");
@@ -157,7 +157,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		auto it = extras.find("specular");
 		if(it != extras.getEnd())
 		{
-			StringListAuto tokens(m_alloc);
+			StringListRaii tokens(m_alloc);
 			tokens.splitString(it->toCString(), ' ');
 			if(tokens.getSize() != 3)
 			{
@@ -177,7 +177,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 			specular = Vec3(0.04f);
 		}
 
-		xml.replaceAll("%spec%", StringAuto(m_alloc).sprintf("<input name=\"m_specColor\" value=\"%f %f %f\"/>",
+		xml.replaceAll("%spec%", StringRaii(m_alloc).sprintf("<input name=\"m_specColor\" value=\"%f %f %f\"/>",
 															 specular.x(), specular.y(), specular.z()));
 
 		xml.replaceAll("%specTexMutator%", "0");
@@ -198,12 +198,12 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	// Roughness
 	if(mtl.pbr_metallic_roughness.metallic_roughness_texture.texture && constantRoughness < 0.0f)
 	{
-		StringAuto uri(m_alloc);
+		StringRaii uri(m_alloc);
 		uri.sprintf("%s%s", m_texrpath.cstr(),
 					getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
 
 		xml.replaceAll("%roughness%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_roughnessTex\" value=\"%s\"/>", uri.cstr()));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_roughnessTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%roughnessTexMutator%", "1");
 	}
@@ -214,7 +214,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 								  : mtl.pbr_metallic_roughness.roughness_factor;
 
 		xml.replaceAll("%roughness%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_roughness\" value=\"%f\"/>", roughness));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_roughness\" value=\"%f\"/>", roughness));
 
 		xml.replaceAll("%roughnessTexMutator%", "0");
 	}
@@ -222,12 +222,12 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	// Metallic
 	if(mtl.pbr_metallic_roughness.metallic_roughness_texture.texture && constantMetaliness < 0.0f)
 	{
-		StringAuto uri(m_alloc);
+		StringRaii uri(m_alloc);
 		uri.sprintf("%s%s", m_texrpath.cstr(),
 					getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
 
 		xml.replaceAll("%metallic%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_metallicTex\" value=\"%s\"/>", uri.cstr()));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_metallicTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%metalTexMutator%", "1");
 	}
@@ -238,7 +238,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 								  : mtl.pbr_metallic_roughness.metallic_factor;
 
 		xml.replaceAll("%metallic%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_metallic\" value=\"%f\"/>", metalines));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_metallic\" value=\"%f\"/>", metalines));
 
 		xml.replaceAll("%metalTexMutator%", "0");
 	}
@@ -250,11 +250,11 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		ANKI_CHECK(findConstantColorsInImage(getTextureUri(mtl.normal_texture).cstr(), constantColor, m_alloc));
 		if(constantColor.xyz() == -1.0f)
 		{
-			StringAuto uri(m_alloc);
+			StringRaii uri(m_alloc);
 			uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.normal_texture).cstr());
 
 			xml.replaceAll("%normal%",
-						   StringAuto(m_alloc).sprintf("<input name=\"m_normalTex\" value=\"%s\"/>", uri.cstr()));
+						   StringRaii(m_alloc).sprintf("<input name=\"m_normalTex\" value=\"%s\"/>", uri.cstr()));
 
 			xml.replaceAll("%normalTexMutator%", "1");
 		}
@@ -273,11 +273,11 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	// Emissive texture
 	if(mtl.emissive_texture.texture)
 	{
-		StringAuto uri(m_alloc);
+		StringRaii uri(m_alloc);
 		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.emissive_texture).cstr());
 
 		xml.replaceAll("%emission%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_emissiveTex\" value=\"%s\"/>", uri.cstr()));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_emissiveTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%emissiveTexMutator%", "1");
 	}
@@ -285,7 +285,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const F32* emissionCol = &mtl.emissive_factor[0];
 
-		xml.replaceAll("%emission%", StringAuto(m_alloc).sprintf("<input name=\"m_emission\" value=\"%f %f %f\"/>",
+		xml.replaceAll("%emission%", StringRaii(m_alloc).sprintf("<input name=\"m_emission\" value=\"%f %f %f\"/>",
 																 emissionCol[0], emissionCol[1], emissionCol[2]));
 
 		xml.replaceAll("%emissiveTexMutator%", "0");
@@ -305,17 +305,17 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		}
 
 		xml.replaceAll("%subsurface%",
-					   StringAuto(m_alloc).sprintf("<input name=\"m_subsurface\" value=\"%f\"/>", subsurface));
+					   StringRaii(m_alloc).sprintf("<input name=\"m_subsurface\" value=\"%f\"/>", subsurface));
 	}
 
 	// Height texture
 	auto it = extras.find("height_map");
 	if(it != extras.getEnd())
 	{
-		StringAuto uri(m_alloc);
+		StringRaii uri(m_alloc);
 		uri.sprintf("%s%s", m_texrpath.cstr(), it->cstr());
 
-		xml.replaceAll("%height%", StringAuto(m_alloc).sprintf("<input name=\"m_heightTex\" value=\"%s\" \"/>\n"
+		xml.replaceAll("%height%", StringRaii(m_alloc).sprintf("<input name=\"m_heightTex\" value=\"%s\" \"/>\n"
 															   "\t\t<input name=\"m_heightmapScale\" value=\"0.05\"/>",
 															   uri.cstr()));
 

+ 17 - 17
AnKi/Importer/GltfImporterMesh.cpp

@@ -130,8 +130,8 @@ static_assert(sizeof(TempVertex) == 5 * sizeof(Vec4), "Will be hashed");
 class SubMesh
 {
 public:
-	DynamicArrayAuto<TempVertex> m_verts;
-	DynamicArrayAuto<U32> m_indices;
+	DynamicArrayRaii<TempVertex> m_verts;
+	DynamicArrayRaii<U32> m_indices;
 
 	Vec3 m_aabbMin = Vec3(kMaxF32);
 	Vec3 m_aabbMax = Vec3(kMinF32);
@@ -150,15 +150,15 @@ static void reindexSubmesh(SubMesh& submesh, GenericMemoryPoolAllocator<U8> allo
 {
 	const U32 vertSize = sizeof(submesh.m_verts[0]);
 
-	DynamicArrayAuto<U32> remap(alloc);
+	DynamicArrayRaii<U32> remap(alloc);
 	remap.create(submesh.m_verts.getSize(), 0);
 
 	const U32 vertCount = U32(meshopt_generateVertexRemap(&remap[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 														  &submesh.m_verts[0], submesh.m_verts.getSize(), vertSize));
 
-	DynamicArrayAuto<U32> newIdxArray(alloc);
+	DynamicArrayRaii<U32> newIdxArray(alloc);
 	newIdxArray.create(submesh.m_indices.getSize(), 0);
-	DynamicArrayAuto<TempVertex> newVertArray(alloc);
+	DynamicArrayRaii<TempVertex> newVertArray(alloc);
 	newVertArray.create(vertCount);
 
 	meshopt_remapIndexBuffer(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(), &remap[0]);
@@ -175,7 +175,7 @@ static void optimizeSubmesh(SubMesh& submesh, GenericMemoryPoolAllocator<U8> all
 
 	// Vert cache
 	{
-		DynamicArrayAuto<U32> newIdxArray(alloc);
+		DynamicArrayRaii<U32> newIdxArray(alloc);
 		newIdxArray.create(submesh.m_indices.getSize(), 0);
 
 		meshopt_optimizeVertexCache(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
@@ -186,7 +186,7 @@ static void optimizeSubmesh(SubMesh& submesh, GenericMemoryPoolAllocator<U8> all
 
 	// Overdraw
 	{
-		DynamicArrayAuto<U32> newIdxArray(alloc);
+		DynamicArrayRaii<U32> newIdxArray(alloc);
 		newIdxArray.create(submesh.m_indices.getSize(), 0);
 
 		meshopt_optimizeOverdraw(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
@@ -197,7 +197,7 @@ static void optimizeSubmesh(SubMesh& submesh, GenericMemoryPoolAllocator<U8> all
 
 	// Vert fetch
 	{
-		DynamicArrayAuto<TempVertex> newVertArray(alloc);
+		DynamicArrayRaii<TempVertex> newVertArray(alloc);
 		newVertArray.create(submesh.m_verts.getSize());
 
 		const U32 newVertCount = U32(meshopt_optimizeVertexFetch(&newVertArray[0],
@@ -226,14 +226,14 @@ static void decimateSubmesh(F32 factor, SubMesh& submesh, GenericMemoryPoolAlloc
 	}
 
 	// Decimate
-	DynamicArrayAuto<U32> newIndices(alloc, submesh.m_indices.getSize());
+	DynamicArrayRaii<U32> newIndices(alloc, submesh.m_indices.getSize());
 	newIndices.resize(U32(meshopt_simplify(&newIndices[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 										   &submesh.m_verts[0].m_position.x(), submesh.m_verts.getSize(),
 										   sizeof(TempVertex), targetIndexCount, 1e-2f)));
 
 	// Re-pack
-	DynamicArrayAuto<U32> reindexedIndices(alloc);
-	DynamicArrayAuto<TempVertex> newVerts(alloc);
+	DynamicArrayRaii<U32> reindexedIndices(alloc);
+	DynamicArrayRaii<TempVertex> newVerts(alloc);
 	HashMapAuto<U32, U32> vertexStored(alloc);
 	for(U32 idx = 0; idx < newIndices.getSize(); ++idx)
 	{
@@ -276,7 +276,7 @@ U32 GltfImporter::getMeshTotalVertexCount(const cgltf_mesh& mesh)
 
 Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFactor)
 {
-	StringAuto fname(m_alloc);
+	StringRaii fname(m_alloc);
 	fname.sprintf("%s%s", m_outDir.cstr(), computeMeshResourceFilename(mesh, lod).cstr());
 	ANKI_IMPORTER_LOGV("Importing mesh (%s, decimate factor %f): %s",
 					   (m_optimizeMeshes) ? "optimize" : "WON'T optimize", decimateFactor, fname.cstr());
@@ -473,7 +473,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFacto
 		// Compute tangent
 		//
 		{
-			DynamicArrayAuto<Vec3> bitangents(m_alloc);
+			DynamicArrayRaii<Vec3> bitangents(m_alloc);
 			bitangents.create(vertCount, Vec3(0.0f));
 
 			for(U32 i = 0; i < submesh.m_indices.getSize(); i += 3)
@@ -740,7 +740,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFacto
 	U32 vertCount = 0;
 	for(const SubMesh& submesh : submeshes)
 	{
-		DynamicArrayAuto<U16> indices(m_alloc);
+		DynamicArrayRaii<U16> indices(m_alloc);
 		indices.create(submesh.m_indices.getSize());
 		for(U32 i = 0; i < indices.getSize(); ++i)
 		{
@@ -763,7 +763,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFacto
 	// Write position vert buffer
 	for(const SubMesh& submesh : submeshes)
 	{
-		DynamicArrayAuto<Vec3> positions(m_alloc);
+		DynamicArrayRaii<Vec3> positions(m_alloc);
 		positions.create(submesh.m_verts.getSize());
 		for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 		{
@@ -777,7 +777,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFacto
 	// Write the 2nd vert buffer
 	for(const SubMesh& submesh : submeshes)
 	{
-		DynamicArrayAuto<MainVertex> verts(m_alloc);
+		DynamicArrayRaii<MainVertex> verts(m_alloc);
 		verts.create(submesh.m_verts.getSize());
 
 		for(U32 i = 0; i < verts.getSize(); ++i)
@@ -801,7 +801,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh, U32 lod, F32 decimateFacto
 	{
 		for(const SubMesh& submesh : submeshes)
 		{
-			DynamicArrayAuto<BoneInfoVertex> verts(m_alloc);
+			DynamicArrayRaii<BoneInfoVertex> verts(m_alloc);
 			verts.create(submesh.m_verts.getSize());
 
 			for(U32 i = 0; i < verts.getSize(); ++i)

+ 19 - 19
AnKi/Importer/ImageImporter.cpp

@@ -18,9 +18,9 @@ namespace {
 class SurfaceOrVolumeData
 {
 public:
-	DynamicArrayAuto<U8, PtrSize> m_pixels;
-	DynamicArrayAuto<U8, PtrSize> m_s3tcPixels;
-	DynamicArrayAuto<U8, PtrSize> m_astcPixels;
+	DynamicArrayRaii<U8, PtrSize> m_pixels;
+	DynamicArrayRaii<U8, PtrSize> m_s3tcPixels;
+	DynamicArrayRaii<U8, PtrSize> m_astcPixels;
 
 	SurfaceOrVolumeData(GenericMemoryPoolAllocator<U8> alloc)
 		: m_pixels(alloc)
@@ -34,7 +34,7 @@ class Mipmap
 {
 public:
 	/// One surface for each layer ore one per face or a single volume if it's a 3D texture.
-	DynamicArrayAuto<SurfaceOrVolumeData> m_surfacesOrVolume;
+	DynamicArrayRaii<SurfaceOrVolumeData> m_surfacesOrVolume;
 
 	Mipmap(GenericMemoryPoolAllocator<U8> alloc)
 		: m_surfacesOrVolume(alloc)
@@ -46,7 +46,7 @@ public:
 class ImageImporterContext
 {
 public:
-	DynamicArrayAuto<Mipmap> m_mipmaps;
+	DynamicArrayRaii<Mipmap> m_mipmaps;
 	U32 m_width = 0;
 	U32 m_height = 0;
 	U32 m_depth = 0;
@@ -136,7 +136,7 @@ public:
 class CleanupFile
 {
 public:
-	StringAuto m_fileToDelete;
+	StringRaii m_fileToDelete;
 
 	CleanupFile(GenericMemoryPoolAllocator<U8> alloc, CString filename)
 		: m_fileToDelete(alloc, filename)
@@ -272,7 +272,7 @@ static Error checkInputImages(const ImageImporterConfig& config, U32& width, U32
 }
 
 static Error resizeImage(CString inImageFilename, U32 outWidth, U32 outHeight, CString tempDirectory,
-						 GenericMemoryPoolAllocator<U8> alloc, StringAuto& tmpFilename)
+						 GenericMemoryPoolAllocator<U8> alloc, StringRaii& tmpFilename)
 {
 	U32 inWidth, inHeight, channelCount;
 	Bool hdr;
@@ -299,7 +299,7 @@ static Error resizeImage(CString inImageFilename, U32 outWidth, U32 outHeight, C
 
 	// Resize
 	I ok;
-	DynamicArrayAuto<U8> outPixels(alloc);
+	DynamicArrayRaii<U8> outPixels(alloc);
 	if(!hdr)
 	{
 		outPixels.resize(outWidth * outHeight * channelCount);
@@ -614,7 +614,7 @@ static Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 				== PtrSize((hdr || channelCount == 4) ? 16 : 8) * (inWidth / 4) * (inHeight / 4));
 
 	// Create a PNG image to feed to the compressor
-	StringAuto tmpFilename(alloc);
+	StringRaii tmpFilename(alloc);
 	tmpFilename.sprintf("%s/AnKiImageImporter_%u.%s", tempDirectory.cstr(), U32(std::rand()), (hdr) ? "exr" : "png");
 	ANKI_IMPORTER_LOGV("Will store: %s", tmpFilename.cstr());
 	Bool saveTmpImageOk = false;
@@ -638,7 +638,7 @@ static Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 	CleanupFile tmpCleanup(alloc, tmpFilename);
 
 	// Invoke the compressor process
-	StringAuto ddsFilename(alloc);
+	StringRaii ddsFilename(alloc);
 	ddsFilename.sprintf("%s/AnKiImageImporter_%u.dds", tempDirectory.cstr(), U32(std::rand()));
 	Process proc;
 	Array<CString, 5> args;
@@ -659,7 +659,7 @@ static Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 
 	if(!(status == ProcessStatus::kNotRunning && exitCode == 0))
 	{
-		StringAuto errStr(alloc);
+		StringRaii errStr(alloc);
 		if(exitCode != 0)
 		{
 			ANKI_CHECK(proc.readFromStdout(errStr));
@@ -726,7 +726,7 @@ static Error compressAstc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 	ANKI_ASSERT(outPixels.getSizeInBytes() == blockBytes * (inWidth / blockSize.x()) * (inHeight / blockSize.y()));
 
 	// Create a BMP image to feed to the astcebc
-	StringAuto tmpFilename(alloc);
+	StringRaii tmpFilename(alloc);
 	tmpFilename.sprintf("%s/AnKiImageImporter_%u.%s", tempDirectory.cstr(), U32(std::rand()), (hdr) ? "exr" : "png");
 	ANKI_IMPORTER_LOGV("Will store: %s", tmpFilename.cstr());
 	Bool saveTmpImageOk = false;
@@ -750,9 +750,9 @@ static Error compressAstc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 	CleanupFile pngCleanup(alloc, tmpFilename);
 
 	// Invoke the compressor process
-	StringAuto astcFilename(alloc);
+	StringRaii astcFilename(alloc);
 	astcFilename.sprintf("%s/AnKiImageImporter_%u.astc", tempDirectory.cstr(), U32(std::rand()));
-	StringAuto blockStr(alloc);
+	StringRaii blockStr(alloc);
 	blockStr.sprintf("%ux%u", blockSize.x(), blockSize.y());
 	Process proc;
 	Array<CString, 5> args;
@@ -774,7 +774,7 @@ static Error compressAstc(GenericMemoryPoolAllocator<U8> alloc, CString tempDire
 
 	if(!(status == ProcessStatus::kNotRunning && exitCode == 0))
 	{
-		StringAuto errStr(alloc);
+		StringRaii errStr(alloc);
 		if(exitCode != 0)
 		{
 			ANKI_CHECK(proc.readFromStdout(errStr));
@@ -942,9 +942,9 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 	ANKI_CHECK(checkInputImages(config, width, height, channelCount, isHdr));
 
 	// Resize
-	DynamicArrayAuto<StringAuto> newFilenames(alloc);
-	DynamicArrayAuto<CString> newFilenamesCString(alloc);
-	DynamicArrayAuto<CleanupFile> resizedImagesCleanup(alloc);
+	DynamicArrayRaii<StringRaii> newFilenames(alloc);
+	DynamicArrayRaii<CString> newFilenamesCString(alloc);
+	DynamicArrayRaii<CleanupFile> resizedImagesCleanup(alloc);
 	if(width < config.m_minMipmapDimension || height < config.m_minMipmapDimension)
 	{
 		const U32 newWidth = max(width, config.m_minMipmapDimension);
@@ -953,7 +953,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 		ANKI_IMPORTER_LOGV("Image is smaller than the min mipmap dimension. Will resize it to %ux%u", newWidth,
 						   newHeight);
 
-		newFilenames.resize(config.m_inputFilenames.getSize(), StringAuto(alloc));
+		newFilenames.resize(config.m_inputFilenames.getSize(), StringRaii(alloc));
 		newFilenamesCString.resize(config.m_inputFilenames.getSize());
 
 		for(U32 i = 0; i < config.m_inputFilenames.getSize(); ++i)

+ 1 - 1
AnKi/Math/Axisang.h

@@ -186,7 +186,7 @@ public:
 	/// @name Other
 	/// @{
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		str.sprintf("%f %f %f | %f", m_axis.x(), m_axis.y(), m_axis.z(), m_ang);
 	}

+ 1 - 1
AnKi/Math/Euler.h

@@ -146,7 +146,7 @@ public:
 	/// @name Other
 	/// @{
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		str.sprintf("%f %f %f", m_vec.m_x, m_vec.m_y, m_vec.m_z);
 	}

+ 2 - 2
AnKi/Math/Mat.h

@@ -1436,7 +1436,7 @@ public:
 	}
 
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		for(U j = 0; j < J; ++j)
 		{
@@ -1455,7 +1455,7 @@ public:
 				{
 					fmt = "%f ";
 				}
-				str.append(StringAuto(str.getAllocator()).sprintf(fmt, m_arr2[j][i]));
+				str.append(StringRaii(str.getMemoryPool()).sprintf(fmt, m_arr2[j][i]));
 			}
 		}
 	}

+ 2 - 2
AnKi/Math/Transform.h

@@ -224,9 +224,9 @@ public:
 		return *this;
 	}
 
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value) void toString(StringAuto& str) const
+	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value) void toString(StringRaii& str) const
 	{
-		StringAuto b(str.getAllocator());
+		StringRaii b(str.getMemoryPool());
 		m_origin.toString(b);
 		str.append(b);
 		str.append("\n");

+ 6 - 6
AnKi/Math/Vec.h

@@ -3280,31 +3280,31 @@ public:
 	}
 
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		for(U i = 0; i < N; ++i)
 		{
-			str.append(StringAuto(str.getAllocator()).sprintf((i < i - N) ? "%f " : "%f", m_arr[i]));
+			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - N) ? "%f " : "%f", m_arr[i]));
 		}
 	}
 
 	static constexpr Bool kClangWorkaround = std::is_integral<T>::value && std::is_unsigned<T>::value;
 	ANKI_ENABLE_METHOD(kClangWorkaround)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		for(U i = 0; i < N; ++i)
 		{
-			str.append(StringAuto(str.getAllocator()).sprintf((i < i - N) ? "%u " : "%u", m_arr[i]));
+			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - N) ? "%u " : "%u", m_arr[i]));
 		}
 	}
 
 	static constexpr Bool kClangWorkaround2 = std::is_integral<T>::value && std::is_signed<T>::value;
 	ANKI_ENABLE_METHOD(kClangWorkaround2)
-	void toString(StringAuto& str) const
+	void toString(StringRaii& str) const
 	{
 		for(U i = 0; i < N; ++i)
 		{
-			str.append(StringAuto(str.getAllocator()).sprintf((i < i - N) ? "%d " : "%d", m_arr[i]));
+			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - N) ? "%d " : "%d", m_arr[i]));
 		}
 	}
 	/// @}

+ 1 - 1
AnKi/Physics/PhysicsTrigger.cpp

@@ -68,7 +68,7 @@ void PhysicsTrigger::processContacts()
 	}
 
 	// Gather the new pairs
-	DynamicArrayAuto<PhysicsTriggerFilteredPair*> newPairs(getWorld().getTempAllocator());
+	DynamicArrayRaii<PhysicsTriggerFilteredPair*> newPairs(getWorld().getTempAllocator());
 	newPairs.resizeStorage(m_ghostShape->getOverlappingPairs().size());
 	for(U32 i = 0; i < U32(m_ghostShape->getOverlappingPairs().size()); ++i)
 	{

+ 1 - 1
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -134,7 +134,7 @@ Error IndirectDiffuseProbes::initGBuffer()
 		{
 			texinit.m_format = kGBufferColorRenderTargetFormats[i];
 			m_gbuffer.m_colorRtDescrs[i] = texinit;
-			m_gbuffer.m_colorRtDescrs[i].setName(StringAuto(getAllocator()).sprintf("GI GBuff Col #%u", i).toCString());
+			m_gbuffer.m_colorRtDescrs[i].setName(StringRaii(getAllocator()).sprintf("GI GBuff Col #%u", i).toCString());
 			m_gbuffer.m_colorRtDescrs[i].bake();
 		}
 

+ 1 - 1
AnKi/Renderer/ProbeReflections.cpp

@@ -78,7 +78,7 @@ Error ProbeReflections::initGBuffer()
 			texinit.m_format = kGBufferColorRenderTargetFormats[i];
 			m_gbuffer.m_colorRtDescrs[i] = texinit;
 			m_gbuffer.m_colorRtDescrs[i].setName(
-				StringAuto(getAllocator()).sprintf("CubeRefl GBuff Col #%u", i).toCString());
+				StringRaii(getAllocator()).sprintf("CubeRefl GBuff Col #%u", i).toCString());
 			m_gbuffer.m_colorRtDescrs[i].bake();
 		}
 

+ 5 - 5
AnKi/Renderer/ShadowMapping.cpp

@@ -491,9 +491,9 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 
 	// Vars
 	const Vec4 cameraOrigin = ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz0();
-	DynamicArrayAuto<Scratch::LightToRenderToScratchInfo> lightsToRender(ctx.m_tempAllocator);
+	DynamicArrayRaii<Scratch::LightToRenderToScratchInfo> lightsToRender(ctx.m_tempAllocator);
 	U32 drawcallCount = 0;
-	DynamicArrayAuto<Atlas::ResolveWorkItem> atlasWorkItems(ctx.m_tempAllocator);
+	DynamicArrayRaii<Atlas::ResolveWorkItem> atlasWorkItems(ctx.m_tempAllocator);
 
 	// First thing, allocate an empty tile for empty faces of point lights
 	UVec4 emptyTileViewport;
@@ -752,7 +752,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 	// Split the work that will happen in the scratch buffer
 	if(lightsToRender.getSize())
 	{
-		DynamicArrayAuto<Scratch::WorkItem> workItems(ctx.m_tempAllocator);
+		DynamicArrayRaii<Scratch::WorkItem> workItems(ctx.m_tempAllocator);
 		Scratch::LightToRenderToScratchInfo* lightToRender = lightsToRender.getBegin();
 		U32 lightToRenderDrawcallCount = lightToRender->m_drawcallCount;
 		const Scratch::LightToRenderToScratchInfo* lightToRenderEnd = lightsToRender.getEnd();
@@ -826,8 +826,8 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 
 void ShadowMapping::newScratchAndAtlasResloveRenderWorkItems(
 	const UVec4& atlasViewport, const UVec4& scratchVewport, Bool blurAtlas, RenderQueue* lightRenderQueue,
-	U32 renderQueueElementsLod, DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
-	DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem, U32& drawcallCount) const
+	U32 renderQueueElementsLod, DynamicArrayRaii<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
+	DynamicArrayRaii<Atlas::ResolveWorkItem>& atlasResolveWorkItem, U32& drawcallCount) const
 {
 	// Scratch work item
 	{

+ 2 - 2
AnKi/Renderer/ShadowMapping.h

@@ -119,8 +119,8 @@ private:
 	/// Add new work to render to scratch buffer and atlas buffer.
 	void newScratchAndAtlasResloveRenderWorkItems(
 		const UVec4& atlasViewport, const UVec4& scratchVewport, Bool blurAtlas, RenderQueue* lightRenderQueue,
-		U32 renderQueueElementsLod, DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
-		DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem, U32& drawcallCount) const;
+		U32 renderQueueElementsLod, DynamicArrayRaii<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
+		DynamicArrayRaii<Atlas::ResolveWorkItem>& atlasResolveWorkItem, U32& drawcallCount) const;
 
 	/// Iterate lights and create work items.
 	void processLights(RenderingContext& ctx, U32& threadCountForScratchPass);

+ 2 - 2
AnKi/Resource/CpuMeshResource.cpp

@@ -27,8 +27,8 @@ Error CpuMeshResource::load(const ResourceFilename& filename, [[maybe_unused]] B
 
 	ANKI_CHECK(loader.load(filename));
 
-	DynamicArrayAuto<Vec3> tempPositions(getAllocator());
-	DynamicArrayAuto<U32> tempIndices(getAllocator());
+	DynamicArrayRaii<Vec3> tempPositions(getAllocator());
+	DynamicArrayRaii<U32> tempIndices(getAllocator());
 
 	ANKI_CHECK(loader.storeIndicesAndPosition(tempIndices, tempPositions));
 

+ 2 - 2
AnKi/Resource/ImageLoader.cpp

@@ -640,7 +640,7 @@ Error ImageLoader::loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& hei
 						   GenericMemoryPoolAllocator<U8>& alloc)
 {
 	// Read the file
-	DynamicArrayAuto<U8, PtrSize> fileData(alloc);
+	DynamicArrayRaii<U8, PtrSize> fileData(alloc);
 	const PtrSize fileSize = fs.getSize();
 	fileData.create(fileSize);
 	ANKI_CHECK(fs.read(&fileData[0], fileSize));
@@ -708,7 +708,7 @@ Error ImageLoader::load(const CString& filename, U32 maxImageSize)
 Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U32 maxImageSize)
 {
 	// get the extension
-	StringAuto ext(m_alloc);
+	StringRaii ext(m_alloc);
 	getFilepathExtension(filename, ext);
 
 	if(ext.isEmpty())

+ 1 - 1
AnKi/Resource/ImageResource.cpp

@@ -68,7 +68,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	}
 	ImageLoader& loader = ctx->m_loader;
 
-	StringAuto filenameExt(getTempAllocator());
+	StringRaii filenameExt(getTempAllocator());
 	getFilepathFilename(filename, filenameExt);
 
 	TextureInitInfo init(filenameExt);

+ 1 - 1
AnKi/Resource/MaterialResource.cpp

@@ -217,7 +217,7 @@ Error MaterialResource::parseShaderProgram(XmlElement shaderProgramEl, Bool asyn
 		return Error::kNone;
 	}
 
-	StringAuto fname(getTempAllocator());
+	StringRaii fname(getTempAllocator());
 	fname.sprintf("ShaderBinaries/%s.ankiprogbin", shaderName.cstr());
 
 	Program& prog = *m_programs.emplaceBack(getAllocator());

+ 2 - 2
AnKi/Resource/MeshBinaryLoader.cpp

@@ -252,7 +252,7 @@ Error MeshBinaryLoader::storeVertexBuffer(U32 bufferIdx, void* ptr, PtrSize size
 	return Error::kNone;
 }
 
-Error MeshBinaryLoader::storeIndicesAndPosition(DynamicArrayAuto<U32>& indices, DynamicArrayAuto<Vec3>& positions)
+Error MeshBinaryLoader::storeIndicesAndPosition(DynamicArrayRaii<U32>& indices, DynamicArrayRaii<Vec3>& positions)
 {
 	ANKI_ASSERT(isLoaded());
 
@@ -261,7 +261,7 @@ Error MeshBinaryLoader::storeIndicesAndPosition(DynamicArrayAuto<U32>& indices,
 		indices.resize(m_header.m_totalIndexCount);
 
 		// Store to staging buff
-		DynamicArrayAuto<U8, PtrSize> staging(m_alloc);
+		DynamicArrayRaii<U8, PtrSize> staging(m_alloc);
 		staging.create(getIndexBufferSize());
 		ANKI_CHECK(storeIndexBuffer(&staging[0], staging.getSizeInBytes()));
 

+ 1 - 1
AnKi/Resource/MeshBinaryLoader.h

@@ -36,7 +36,7 @@ public:
 	Error storeVertexBuffer(U32 bufferIdx, void* ptr, PtrSize size);
 
 	/// Instead of calling storeIndexBuffer and storeVertexBuffer use this method to get those buffers into the CPU.
-	Error storeIndicesAndPosition(DynamicArrayAuto<U32>& indices, DynamicArrayAuto<Vec3>& positions);
+	Error storeIndicesAndPosition(DynamicArrayRaii<U32>& indices, DynamicArrayRaii<Vec3>& positions);
 
 	const MeshBinaryHeader& getHeader() const
 	{

+ 2 - 2
AnKi/Resource/MeshResource.cpp

@@ -82,7 +82,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	LoadContext* ctx;
 	LoadContext localCtx(MeshResourcePtr(this), getTempAllocator());
 
-	StringAuto basename(getTempAllocator());
+	StringRaii basename(getTempAllocator());
 	getFilepathFilename(filename, basename);
 
 	const Bool rayTracingEnabled = getManager().getGrManager().getDeviceCapabilities().m_rayTracingEnabled;
@@ -194,7 +194,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	//
 	if(rayTracingEnabled)
 	{
-		AccelerationStructureInitInfo inf(StringAuto(getTempAllocator()).sprintf("%s_%s", "Blas", basename.cstr()));
+		AccelerationStructureInitInfo inf(StringRaii(getTempAllocator()).sprintf("%s_%s", "Blas", basename.cstr()));
 		inf.m_type = AccelerationStructureType::kBottomLevel;
 
 		inf.m_bottomLevel.m_indexBuffer = m_vertexBuffer;

+ 3 - 3
AnKi/Resource/ResourceFilesystem.cpp

@@ -31,7 +31,7 @@ public:
 		return m_file.read(buff, size);
 	}
 
-	Error readAllText(StringAuto& out) override
+	Error readAllText(StringRaii& out) override
 	{
 		ANKI_TRACE_SCOPED_EVENT(RSRC_FILE_READ);
 		return m_file.readAllText(out);
@@ -143,7 +143,7 @@ public:
 		return Error::kNone;
 	}
 
-	Error readAllText(StringAuto& out) override
+	Error readAllText(StringRaii& out) override
 	{
 		ANKI_ASSERT(m_size);
 		out.create('?', m_size);
@@ -406,7 +406,7 @@ Error ResourceFilesystem::openFileInternal(const ResourceFilename& filename, Res
 			}
 			else
 			{
-				StringAuto newFname(m_alloc);
+				StringRaii newFname(m_alloc);
 				newFname.sprintf("%s/%s", &p.m_path[0], &filename[0]);
 
 				CResourceFile* file = m_alloc.newInstance<CResourceFile>(m_alloc);

+ 2 - 2
AnKi/Resource/ResourceFilesystem.h

@@ -40,7 +40,7 @@ public:
 	virtual Error read(void* buff, PtrSize size) = 0;
 
 	/// Read all the contents of a text file. If the file is not rewined it will probably fail
-	virtual Error readAllText(StringAuto& out) = 0;
+	virtual Error readAllText(StringRaii& out) = 0;
 
 	/// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's
 	virtual Error readU32(U32& u) = 0;
@@ -148,7 +148,7 @@ private:
 	String m_cacheDir;
 
 	/// Add a filesystem path or an archive. The path is read-only.
-	Error addNewPath(const CString& path, const StringListAuto& excludedStrings);
+	Error addNewPath(const CString& path, const StringListRaii& excludedStrings);
 
 	Error openFileInternal(const ResourceFilename& filename, ResourceFile*& rfile);
 };

+ 3 - 3
AnKi/Resource/ResourceObject.cpp

@@ -35,14 +35,14 @@ Error ResourceObject::openFile(const CString& filename, ResourceFilePtr& file)
 	return m_manager->getFilesystem().openFile(filename, file);
 }
 
-Error ResourceObject::openFileReadAllText(const CString& filename, StringAuto& text)
+Error ResourceObject::openFileReadAllText(const CString& filename, StringRaii& text)
 {
 	// Load file
 	ResourceFilePtr file;
 	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
 
 	// Read string
-	text = StringAuto(getTempAllocator());
+	text = StringRaii(getTempAllocator());
 	ANKI_CHECK(file->readAllText(text));
 
 	return Error::kNone;
@@ -50,7 +50,7 @@ Error ResourceObject::openFileReadAllText(const CString& filename, StringAuto& t
 
 Error ResourceObject::openFileParseXml(const CString& filename, XmlDocument& xml)
 {
-	StringAuto txt(getTempAllocator());
+	StringRaii txt(getTempAllocator());
 	ANKI_CHECK(openFileReadAllText(filename, txt));
 
 	ANKI_CHECK(xml.parse(txt.toCString(), getTempAllocator()));

+ 1 - 1
AnKi/Resource/ResourceObject.h

@@ -83,7 +83,7 @@ public:
 
 	ANKI_INTERNAL Error openFile(const ResourceFilename& filename, ResourceFilePtr& file);
 
-	ANKI_INTERNAL Error openFileReadAllText(const ResourceFilename& filename, StringAuto& file);
+	ANKI_INTERNAL Error openFileReadAllText(const ResourceFilename& filename, StringRaii& file);
 
 	ANKI_INTERNAL Error openFileParseXml(const ResourceFilename& filename, XmlDocument& xml);
 

+ 1 - 1
AnKi/Resource/ScriptResource.cpp

@@ -18,7 +18,7 @@ Error ScriptResource::load(const ResourceFilename& filename, [[maybe_unused]] Bo
 	ResourceFilePtr file;
 	ANKI_CHECK(openFile(filename, file));
 
-	StringAuto src(getAllocator());
+	StringRaii src(getAllocator());
 	ANKI_CHECK(file->readAllText(src));
 	m_source.create(getAllocator(), src);
 

+ 1 - 1
AnKi/Resource/ShaderProgramResource.cpp

@@ -372,7 +372,7 @@ ShaderProgramResource::createNewVariant(const ShaderProgramResourceVariantInitIn
 	if(!!(m_shaderStages & (ShaderTypeBit::kAllGraphics | ShaderTypeBit::kCompute)))
 	{
 		// Create the program name
-		StringAuto progName(getTempAllocator());
+		StringRaii progName(getTempAllocator());
 		getFilepathFilename(getFilename(), progName);
 		char* cprogName = const_cast<char*>(progName.cstr());
 		if(progName.getLength() > kMaxGrObjectNameLength)

+ 10 - 10
AnKi/Resource/ShaderProgramResourceSystem.cpp

@@ -20,7 +20,7 @@ U64 ShaderProgramRaytracingLibrary::generateShaderGroupGroupHash(CString resourc
 																 GenericMemoryPoolAllocator<U8> alloc)
 {
 	ANKI_ASSERT(resourceFilename.getLength() > 0);
-	StringAuto basename(alloc);
+	StringRaii basename(alloc);
 	getFilepathFilename(resourceFilename, basename);
 	const U64 hash = appendHash(basename.cstr(), basename.getLength(), mutationHash);
 	return hash;
@@ -77,9 +77,9 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(ResourceFilesystem&
 	public:
 		GenericMemoryPoolAllocator<U8> m_alloc;
 		GrManager* m_gr;
-		StringAuto m_name{m_alloc};
-		DynamicArrayAuto<Shader> m_shaders{m_alloc};
-		DynamicArrayAuto<ShaderGroup> m_shaderGroups{m_alloc};
+		StringRaii m_name{m_alloc};
+		DynamicArrayRaii<Shader> m_shaders{m_alloc};
+		DynamicArrayRaii<ShaderGroup> m_shaderGroups{m_alloc};
 		ShaderTypeBit m_presentStages = ShaderTypeBit::kNone;
 		U32 m_rayTypeCount = 0;
 		BitSet<64> m_rayTypeMask = {false};
@@ -156,11 +156,11 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(ResourceFilesystem&
 		}
 	};
 
-	DynamicArrayAuto<Lib> libs(alloc);
+	DynamicArrayRaii<Lib> libs(alloc);
 
 	ANKI_CHECK(fs.iterateAllFilenames([&](CString filename) -> Error {
 		// Check file extension
-		StringAuto extension(alloc);
+		StringRaii extension(alloc);
 		getFilepathExtension(filename, extension);
 		const Char binExtension[] = "ankiprogbin";
 		if(extension.getLength() != sizeof(binExtension) - 1 || extension != binExtension)
@@ -194,7 +194,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(ResourceFilesystem&
 		}
 
 		// Create the program name
-		StringAuto progName(alloc);
+		StringRaii progName(alloc);
 		getFilepathFilename(filename, progName);
 
 		// Find or create the lib
@@ -396,9 +396,9 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(ResourceFilesystem&
 			outLib.m_libraryName.create(alloc, inLib.m_name);
 			outLib.m_rayTypeCount = inLib.m_rayTypeCount;
 
-			DynamicArrayAuto<RayTracingHitGroup> initInfoHitGroups(alloc);
-			DynamicArrayAuto<ShaderPtr> missShaders(alloc);
-			DynamicArrayAuto<ShaderPtr> rayGenShaders(alloc);
+			DynamicArrayRaii<RayTracingHitGroup> initInfoHitGroups(alloc);
+			DynamicArrayRaii<ShaderPtr> missShaders(alloc);
+			DynamicArrayRaii<ShaderPtr> rayGenShaders(alloc);
 
 			// Add the hitgroups to the init info
 			for(U32 shaderGroupIdx = 0; shaderGroupIdx < inLib.m_shaderGroups.getSize(); ++shaderGroupIdx)

+ 1 - 1
AnKi/Resource/SkeletonResource.cpp

@@ -39,7 +39,7 @@ Error SkeletonResource::load(const ResourceFilename& filename, [[maybe_unused]]
 
 	m_bones.create(getAllocator(), boneCount);
 
-	StringListAuto boneParents(getAllocator());
+	StringListRaii boneParents(getAllocator());
 
 	// Load every bone
 	boneCount = 0;

+ 1 - 1
AnKi/Scene/Events/EventManager.cpp

@@ -130,7 +130,7 @@ void EventManager::deleteEventsMarkedForDeletion(Bool fullCleanup)
 	if(fullCleanup)
 	{
 		// Gather in an array because we can't call setMarkedForDeletion while iterating m_events
-		DynamicArrayAuto<Event*> markedForDeletion(getFrameAllocator());
+		DynamicArrayRaii<Event*> markedForDeletion(getFrameAllocator());
 		for(Event& event : m_events)
 		{
 			for(SceneNode* node : event.m_associatedNodes)

+ 1 - 1
AnKi/Scene/Events/ScriptEvent.cpp

@@ -31,7 +31,7 @@ Error ScriptEvent::init(Second startTime, Second duration, CString script)
 	ANKI_CHECK(m_env.init(&getSceneGraph().getScriptManager()));
 
 	// Do the rest
-	StringAuto extension(getAllocator());
+	StringRaii extension(getAllocator());
 	getFilepathExtension(script, extension);
 
 	if(!extension.isEmpty() && extension == "lua")

+ 2 - 2
AnKi/Scene/ModelNode.cpp

@@ -332,9 +332,9 @@ void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData
 			SkeletonResourcePtr skeleton = skinc.getSkeleronResource();
 			const U32 boneCount = skinc.getBoneTransforms().getSize();
 
-			DynamicArrayAuto<Vec3> lines(ctx.m_frameAllocator);
+			DynamicArrayRaii<Vec3> lines(ctx.m_frameAllocator);
 			lines.resizeStorage(boneCount * 2);
-			DynamicArrayAuto<Vec3> chidlessLines(ctx.m_frameAllocator);
+			DynamicArrayRaii<Vec3> chidlessLines(ctx.m_frameAllocator);
 			for(U32 i = 0; i < boneCount; ++i)
 			{
 				const Bone& bone = skeleton->getBones()[i];

+ 4 - 4
AnKi/Scene/Octree.cpp

@@ -44,7 +44,7 @@ public:
 	U32 m_testId = kMaxU32;
 	OctreeNodeVisibilityTestCallback m_testCallback = nullptr;
 	void* m_testCallbackUserData = nullptr;
-	DynamicArrayAuto<void*>* m_out = nullptr;
+	DynamicArrayRaii<void*>* m_out = nullptr;
 };
 
 class Octree::GatherParallelTaskCtx
@@ -351,7 +351,7 @@ void Octree::removeInternal(OctreePlaceable& placeable)
 
 void Octree::gatherVisibleRecursive(const Plane frustumPlanes[6], U32 testId,
 									OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-									Leaf* leaf, DynamicArrayAuto<void*>& out)
+									Leaf* leaf, DynamicArrayRaii<void*>& out)
 {
 	ANKI_ASSERT(leaf);
 
@@ -459,7 +459,7 @@ void Octree::debugDrawRecursive(const Leaf& leaf, OctreeDebugDrawer& drawer) con
 
 void Octree::gatherVisibleParallel(const Plane frustumPlanes[6], U32 testId,
 								   OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-								   DynamicArrayAuto<void*>* out, ThreadHive& hive, ThreadHiveSemaphore* waitSemaphore,
+								   DynamicArrayRaii<void*>* out, ThreadHive& hive, ThreadHiveSemaphore* waitSemaphore,
 								   ThreadHiveSemaphore*& signalSemaphore)
 {
 	ANKI_ASSERT(out && frustumPlanes);
@@ -507,7 +507,7 @@ void Octree::gatherVisibleParallelTask([[maybe_unused]] U32 threadId, ThreadHive
 	GatherParallelCtx& ctx = *taskCtx.m_ctx;
 
 	Leaf* const leaf = taskCtx.m_leaf;
-	DynamicArrayAuto<void*>& out = *ctx.m_out;
+	DynamicArrayRaii<void*>& out = *ctx.m_out;
 	OctreeNodeVisibilityTestCallback testCallback = ctx.m_testCallback;
 	void* testCallbackUserData = ctx.m_testCallbackUserData;
 	const U32 testId = ctx.m_testId;

+ 3 - 3
AnKi/Scene/Octree.h

@@ -74,14 +74,14 @@ public:
 	/// @param out The output of the tests.
 	/// @note It's thread-safe against other gatherVisible calls.
 	void gatherVisible(const Plane frustumPlanes[6], U32 testId, OctreeNodeVisibilityTestCallback testCallback,
-					   void* testCallbackUserData, DynamicArrayAuto<void*>& out)
+					   void* testCallbackUserData, DynamicArrayRaii<void*>& out)
 	{
 		gatherVisibleRecursive(frustumPlanes, testId, testCallback, testCallbackUserData, m_rootLeaf, out);
 	}
 
 	/// Similar to gatherVisible but it spawns ThreadHive tasks.
 	void gatherVisibleParallel(const Plane frustumPlanes[6], U32 testId, OctreeNodeVisibilityTestCallback testCallback,
-							   void* testCallbackUserData, DynamicArrayAuto<void*>* out, ThreadHive& hive,
+							   void* testCallbackUserData, DynamicArrayRaii<void*>* out, ThreadHive& hive,
 							   ThreadHiveSemaphore* waitSemaphore, ThreadHiveSemaphore*& signalSemaphore);
 
 	/// Walk the tree.
@@ -263,7 +263,7 @@ private:
 
 	static void gatherVisibleRecursive(const Plane frustumPlanes[6], U32 testId,
 									   OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-									   Leaf* leaf, DynamicArrayAuto<void*>& out);
+									   Leaf* leaf, DynamicArrayRaii<void*>& out);
 
 	/// ThreadHive callback.
 	static void gatherVisibleTaskCallback(void* ud, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* sem);

+ 1 - 1
AnKi/ShaderCompiler/Common.h

@@ -28,7 +28,7 @@ using MutatorValue = I32; ///< The type of the mutator value
 class ShaderProgramFilesystemInterface
 {
 public:
-	virtual Error readAllText(CString filename, StringAuto& txt) = 0;
+	virtual Error readAllText(CString filename, StringRaii& txt) = 0;
 };
 
 /// This controls if the compilation will continue after the parsing stage.

+ 12 - 12
AnKi/ShaderCompiler/Glslang.cpp

@@ -202,13 +202,13 @@ static Error parseErrorLine(CString error, GenericMemoryPoolAllocator<U8> alloc,
 {
 	lineNumber = kMaxU32;
 
-	StringListAuto lines(alloc);
+	StringListRaii lines(alloc);
 	lines.splitString(error, '\n');
 	for(String& line : lines)
 	{
 		if(line.find("ERROR: ") == 0)
 		{
-			StringListAuto tokens(alloc);
+			StringListRaii tokens(alloc);
 			tokens.splitString(line, ':');
 
 			if(tokens.getSize() < 3 || (tokens.getBegin() + 2)->toNumber(lineNumber) != Error::kNone)
@@ -228,7 +228,7 @@ static Error parseErrorLine(CString error, GenericMemoryPoolAllocator<U8> alloc,
 }
 
 static void createErrorLog(CString glslangError, CString source, GenericMemoryPoolAllocator<U8> alloc,
-						   StringAuto& outError)
+						   StringRaii& outError)
 {
 	U32 errorLineNumberu = 0;
 	const Error err = parseErrorLine(glslangError, alloc, errorLineNumberu);
@@ -237,8 +237,8 @@ static void createErrorLog(CString glslangError, CString source, GenericMemoryPo
 
 	constexpr I32 lineCountAroundError = 4;
 
-	StringAuto prettySrc(alloc);
-	StringListAuto lines(alloc);
+	StringRaii prettySrc(alloc);
+	StringListRaii lines(alloc);
 
 	lines.splitString(source, '\n', true);
 
@@ -249,7 +249,7 @@ static void createErrorLog(CString glslangError, CString source, GenericMemoryPo
 
 		if(lineno >= errorLineNumber - lineCountAroundError && lineno <= errorLineNumber + lineCountAroundError)
 		{
-			prettySrc.append(StringAuto(alloc).sprintf("%s%s\n", (lineno == errorLineNumber) ? ">>  " : "    ",
+			prettySrc.append(StringRaii(alloc).sprintf("%s%s\n", (lineno == errorLineNumber) ? ">>  " : "    ",
 													   (it->isEmpty()) ? " " : (*it).cstr()));
 		}
 	}
@@ -257,7 +257,7 @@ static void createErrorLog(CString glslangError, CString source, GenericMemoryPo
 	outError.sprintf("%sIn:\n%s\n", glslangError.cstr(), prettySrc.cstr());
 }
 
-Error preprocessGlsl(CString in, StringAuto& out)
+Error preprocessGlsl(CString in, StringRaii& out)
 {
 	glslang::TShader shader(EShLangVertex);
 	Array<const char*, 1> csrc = {&in[0]};
@@ -278,7 +278,7 @@ Error preprocessGlsl(CString in, StringAuto& out)
 }
 
 Error compilerGlslToSpirv(CString src, ShaderType shaderType, GenericMemoryPoolAllocator<U8> tmpAlloc,
-						  DynamicArrayAuto<U8>& spirv, StringAuto& errorMessage)
+						  DynamicArrayRaii<U8>& spirv, StringRaii& errorMessage)
 {
 #if ANKI_GLSLANG_DUMP
 	// Dump it
@@ -286,10 +286,10 @@ Error compilerGlslToSpirv(CString src, ShaderType shaderType, GenericMemoryPoolA
 	{
 		File file;
 
-		StringAuto tmpDir(tmpAlloc);
+		StringRaii tmpDir(tmpAlloc);
 		ANKI_CHECK(getTempDirectory(tmpDir));
 
-		StringAuto fname(tmpAlloc);
+		StringRaii fname(tmpAlloc);
 		fname.sprintf("%s/%u.glsl", tmpDir.cstr(), dumpFileCount);
 		ANKI_SHADER_COMPILER_LOGW("GLSL dumping is enabled: %s", fname.cstr());
 		ANKI_CHECK(file.open(fname, FileOpenFlag::kWrite));
@@ -337,10 +337,10 @@ Error compilerGlslToSpirv(CString src, ShaderType shaderType, GenericMemoryPoolA
 	{
 		File file;
 
-		StringAuto tmpDir(tmpAlloc);
+		StringRaii tmpDir(tmpAlloc);
 		ANKI_CHECK(getTempDirectory(tmpDir));
 
-		StringAuto fname(tmpAlloc);
+		StringRaii fname(tmpAlloc);
 		fname.sprintf("%s/%u.spv", tmpDir.cstr(), dumpFileCount);
 		ANKI_SHADER_COMPILER_LOGW("GLSL dumping is enabled: %s", fname.cstr());
 		ANKI_CHECK(file.open(fname, FileOpenFlag::kWrite | FileOpenFlag::kBinary));

+ 2 - 2
AnKi/ShaderCompiler/Glslang.h

@@ -14,11 +14,11 @@ namespace anki {
 /// @{
 
 /// Run glslang's preprocessor.
-Error preprocessGlsl(CString in, StringAuto& out);
+Error preprocessGlsl(CString in, StringRaii& out);
 
 /// Compile glsl to SPIR-V.
 Error compilerGlslToSpirv(CString src, ShaderType shaderType, GenericMemoryPoolAllocator<U8> tmpAlloc,
-						  DynamicArrayAuto<U8>& spirv, StringAuto& errorMessage);
+						  DynamicArrayRaii<U8>& spirv, StringRaii& errorMessage);
 /// @}
 
 } // end namespace anki

+ 6 - 6
AnKi/ShaderCompiler/MaliOfflineCompiler.cpp

@@ -77,7 +77,7 @@ static CString hwUnitToStr(MaliOfflineCompilerHwUnit u)
 	return out;
 }
 
-void MaliOfflineCompilerOut::toString(StringAuto& str) const
+void MaliOfflineCompilerOut::toString(StringRaii& str) const
 {
 	str.destroy();
 	str.sprintf("Regs %u Spilling %u "
@@ -121,7 +121,7 @@ static Error runMaliOfflineCompilerInternal(CString maliocExecutable, CString sp
 	ANKI_CHECK(proc.wait(-1.0, &status, &exitCode));
 	if(exitCode != 0)
 	{
-		StringAuto stderre(tmpAlloc);
+		StringRaii stderre(tmpAlloc);
 		const Error err = proc.readFromStderr(stderre);
 		ANKI_SHADER_COMPILER_LOGE("Mali offline compiler failed with exit code %d. Stderr: %s", exitCode,
 								  (err || stderre.isEmpty()) ? "<no text>" : stderre.cstr());
@@ -129,7 +129,7 @@ static Error runMaliOfflineCompilerInternal(CString maliocExecutable, CString sp
 	}
 
 	// Get stdout
-	StringAuto stdouts(tmpAlloc);
+	StringRaii stdouts(tmpAlloc);
 	ANKI_CHECK(proc.readFromStdout(stdouts));
 	const std::string stdoutstl(stdouts.cstr());
 
@@ -295,7 +295,7 @@ static Error runMaliOfflineCompilerInternal(CString maliocExecutable, CString sp
 	if(false)
 	{
 		printf("%s\n", stdouts.cstr());
-		StringAuto str(tmpAlloc);
+		StringRaii str(tmpAlloc);
 		out.toString(str);
 		printf("%s\n", str.cstr());
 	}
@@ -309,9 +309,9 @@ Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv,
 	ANKI_ASSERT(spirv.getSize() > 0);
 
 	// Create temp file to dump the spirv
-	StringAuto tmpDir(tmpAlloc);
+	StringRaii tmpDir(tmpAlloc);
 	ANKI_CHECK(getTempDirectory(tmpDir));
-	StringAuto spirvFilename(tmpAlloc);
+	StringRaii spirvFilename(tmpAlloc);
 	spirvFilename.sprintf("%s/AnKiMaliocTmpSpirv_%" PRIu64 ".spv", tmpDir.cstr(), getRandom());
 
 	File spirvFile;

+ 1 - 1
AnKi/ShaderCompiler/MaliOfflineCompiler.h

@@ -41,7 +41,7 @@ public:
 	U32 m_spilling = 0;
 	F32 m_fp16ArithmeticPercentage = 0.0f;
 
-	void toString(StringAuto& str) const;
+	void toString(StringRaii& str) const;
 };
 
 /// Run the mali offline compiler and get some info back.

+ 34 - 34
AnKi/ShaderCompiler/ShaderProgramCompiler.cpp

@@ -131,7 +131,7 @@ void ShaderProgramBinaryWrapper::cleanup()
 }
 
 /// Spin the dials. Used to compute all mutator combinations.
-static Bool spinDials(DynamicArrayAuto<U32>& dials, ConstWeakArray<ShaderProgramParserMutator> mutators)
+static Bool spinDials(DynamicArrayRaii<U32>& dials, ConstWeakArray<ShaderProgramParserMutator> mutators)
 {
 	ANKI_ASSERT(dials.getSize() == mutators.getSize() && dials.getSize() > 0);
 	Bool done = true;
@@ -168,7 +168,7 @@ static Bool spinDials(DynamicArrayAuto<U32>& dials, ConstWeakArray<ShaderProgram
 
 static Error compileSpirv(ConstWeakArray<MutatorValue> mutation, const ShaderProgramParser& parser,
 						  GenericMemoryPoolAllocator<U8>& tmpAlloc,
-						  Array<DynamicArrayAuto<U8>, U32(ShaderType::kCount)>& spirv, StringAuto& errorLog)
+						  Array<DynamicArrayRaii<U8>, U32(ShaderType::kCount)>& spirv, StringRaii& errorLog)
 {
 	// Generate the source and the rest for the variant
 	ShaderProgramParserVariant parserVariant;
@@ -193,8 +193,8 @@ static Error compileSpirv(ConstWeakArray<MutatorValue> mutation, const ShaderPro
 
 static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const ShaderProgramParser& parser,
 								ShaderProgramBinaryVariant& variant,
-								DynamicArrayAuto<ShaderProgramBinaryCodeBlock>& codeBlocks,
-								DynamicArrayAuto<U64>& codeBlockHashes, GenericMemoryPoolAllocator<U8>& tmpAlloc,
+								DynamicArrayRaii<ShaderProgramBinaryCodeBlock>& codeBlocks,
+								DynamicArrayRaii<U64>& codeBlockHashes, GenericMemoryPoolAllocator<U8>& tmpAlloc,
 								GenericMemoryPoolAllocator<U8>& binaryAlloc,
 								ShaderProgramAsyncTaskInterface& taskManager, Mutex& mtx, Atomic<I32>& error)
 {
@@ -205,11 +205,11 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 	public:
 		GenericMemoryPoolAllocator<U8> m_tmpAlloc;
 		GenericMemoryPoolAllocator<U8> m_binaryAlloc;
-		DynamicArrayAuto<MutatorValue> m_mutation = {m_tmpAlloc};
+		DynamicArrayRaii<MutatorValue> m_mutation = {m_tmpAlloc};
 		const ShaderProgramParser* m_parser;
 		ShaderProgramBinaryVariant* m_variant;
-		DynamicArrayAuto<ShaderProgramBinaryCodeBlock>* m_codeBlocks;
-		DynamicArrayAuto<U64>* m_codeBlockHashes;
+		DynamicArrayRaii<ShaderProgramBinaryCodeBlock>* m_codeBlocks;
+		DynamicArrayRaii<U64>* m_codeBlockHashes;
 		Mutex* m_mtx;
 		Atomic<I32>* m_err;
 
@@ -242,7 +242,7 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 		}
 
 		// All good, compile the variant
-		Array<DynamicArrayAuto<U8>, U32(ShaderType::kCount)> spirvs = {{{tmpAlloc},
+		Array<DynamicArrayRaii<U8>, U32(ShaderType::kCount)> spirvs = {{{tmpAlloc},
 																		{tmpAlloc},
 																		{tmpAlloc},
 																		{tmpAlloc},
@@ -254,7 +254,7 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 																		{tmpAlloc},
 																		{tmpAlloc},
 																		{tmpAlloc}}};
-		StringAuto errorLog(tmpAlloc);
+		StringRaii errorLog(tmpAlloc);
 		const Error err = compileSpirv(ctx.m_mutation, *ctx.m_parser, tmpAlloc, spirvs, errorLog);
 
 		if(!err)
@@ -265,7 +265,7 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 
 			for(ShaderType shaderType : EnumIterable<ShaderType>())
 			{
-				DynamicArrayAuto<U8>& spirv = spirvs[shaderType];
+				DynamicArrayRaii<U8>& spirv = spirvs[shaderType];
 
 				if(spirv.isEmpty())
 				{
@@ -331,32 +331,32 @@ public:
 	/// @{
 
 	/// [blockType][blockIdx]
-	Array<DynamicArrayAuto<ShaderProgramBinaryBlock>, 3> m_blocks = {{m_alloc, m_alloc, m_alloc}};
+	Array<DynamicArrayRaii<ShaderProgramBinaryBlock>, 3> m_blocks = {{m_alloc, m_alloc, m_alloc}};
 
 	/// [blockType][blockIdx][varIdx]
-	Array<DynamicArrayAuto<DynamicArrayAuto<ShaderProgramBinaryVariable>>, 3> m_vars = {
+	Array<DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryVariable>>, 3> m_vars = {
 		{{m_alloc}, {m_alloc}, {m_alloc}}};
 
-	DynamicArrayAuto<ShaderProgramBinaryOpaque> m_opaque = {m_alloc};
-	DynamicArrayAuto<ShaderProgramBinaryConstant> m_consts = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryOpaque> m_opaque = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryConstant> m_consts = {m_alloc};
 
-	DynamicArrayAuto<ShaderProgramBinaryStruct> m_structs = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryStruct> m_structs = {m_alloc};
 	/// [structIndex][memberIndex]
-	DynamicArrayAuto<DynamicArrayAuto<ShaderProgramBinaryStructMember>> m_structMembers = {m_alloc};
+	DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryStructMember>> m_structMembers = {m_alloc};
 	/// @}
 
 	/// Will be stored in a variant
 	/// @{
 
 	/// [blockType][blockInstanceIdx]
-	Array<DynamicArrayAuto<ShaderProgramBinaryBlockInstance>, 3> m_blockInstances = {{m_alloc, m_alloc, m_alloc}};
+	Array<DynamicArrayRaii<ShaderProgramBinaryBlockInstance>, 3> m_blockInstances = {{m_alloc, m_alloc, m_alloc}};
 
-	DynamicArrayAuto<ShaderProgramBinaryOpaqueInstance> m_opaqueInstances = {m_alloc};
-	DynamicArrayAuto<ShaderProgramBinaryConstantInstance> m_constInstances = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryOpaqueInstance> m_opaqueInstances = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryConstantInstance> m_constInstances = {m_alloc};
 
-	DynamicArrayAuto<ShaderProgramBinaryStructInstance> m_structInstances = {m_alloc};
+	DynamicArrayRaii<ShaderProgramBinaryStructInstance> m_structInstances = {m_alloc};
 	/// [structInstance][memberInstance]
-	DynamicArrayAuto<DynamicArrayAuto<ShaderProgramBinaryStructMemberInstance>> m_structMemberInstances = {m_alloc};
+	DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryStructMemberInstance>> m_structMemberInstances = {m_alloc};
 
 	Array<U32, 3> m_workgroupSizes = {kMaxU32, kMaxU32, kMaxU32};
 	Array<U32, 3> m_workgroupSizesConstants = {kMaxU32, kMaxU32, kMaxU32};
@@ -601,7 +601,7 @@ public:
 		[[maybe_unused]] const Bool structFound = findStruct(structName, realStructIdx);
 		ANKI_ASSERT(structFound);
 		const ShaderProgramBinaryStruct& s = m_structs[realStructIdx];
-		DynamicArrayAuto<ShaderProgramBinaryStructMember>& members = m_structMembers[realStructIdx];
+		DynamicArrayRaii<ShaderProgramBinaryStructMember>& members = m_structMembers[realStructIdx];
 
 		// Find member
 		U32 realMemberIdx = kMaxU32;
@@ -769,7 +769,7 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 									 GenericMemoryPoolAllocator<U8>& binaryAlloc)
 {
 	// Count reflectable ghost structs
-	DynamicArrayAuto<U32> ghostStructIndices(tmpAlloc);
+	DynamicArrayRaii<U32> ghostStructIndices(tmpAlloc);
 	for(U32 i = 0; i < ghostStructs.getSize(); ++i)
 	{
 		for(const String& s : symbolsToReflect)
@@ -789,7 +789,7 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 
 	// Add the ghost structs to binary structs
 	const U32 nonGhostStructCount = binary.m_structs.getSize();
-	DynamicArrayAuto<ShaderProgramBinaryStruct> structs(binaryAlloc,
+	DynamicArrayRaii<ShaderProgramBinaryStruct> structs(binaryAlloc,
 														nonGhostStructCount + ghostStructIndices.getSize());
 
 	for(U32 i = 0; i < binary.m_structs.getSize(); ++i)
@@ -804,7 +804,7 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 
 		ANKI_CHECK(Refl::setName(in.m_name, out.m_name));
 
-		DynamicArrayAuto<ShaderProgramBinaryStructMember> members(binaryAlloc, in.m_members.getSize());
+		DynamicArrayRaii<ShaderProgramBinaryStructMember> members(binaryAlloc, in.m_members.getSize());
 		for(U32 j = 0; j < in.m_members.getSize(); ++j)
 		{
 			const ShaderProgramParserMember& inMember = in.m_members[j];
@@ -1060,12 +1060,12 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	if(parser.getMutators().getSize() > 0)
 	{
 		// Initialize
-		DynamicArrayAuto<MutatorValue> mutationValues(tempAllocator, parser.getMutators().getSize());
-		DynamicArrayAuto<U32> dials(tempAllocator, parser.getMutators().getSize(), 0);
-		DynamicArrayAuto<ShaderProgramBinaryVariant> variants(binaryAllocator);
-		DynamicArrayAuto<ShaderProgramBinaryCodeBlock> codeBlocks(binaryAllocator);
-		DynamicArrayAuto<ShaderProgramBinaryMutation> mutations(binaryAllocator, mutationCount);
-		DynamicArrayAuto<U64> codeBlockHashes(tempAllocator);
+		DynamicArrayRaii<MutatorValue> mutationValues(tempAllocator, parser.getMutators().getSize());
+		DynamicArrayRaii<U32> dials(tempAllocator, parser.getMutators().getSize(), 0);
+		DynamicArrayRaii<ShaderProgramBinaryVariant> variants(binaryAllocator);
+		DynamicArrayRaii<ShaderProgramBinaryCodeBlock> codeBlocks(binaryAllocator);
+		DynamicArrayRaii<ShaderProgramBinaryMutation> mutations(binaryAllocator, mutationCount);
+		DynamicArrayRaii<U64> codeBlockHashes(tempAllocator);
 		HashMapAuto<U64, U32> mutationHashToIdx(tempAllocator);
 
 		// Grow the storage of the variants array. Can't have it resize, threads will work on stale data
@@ -1136,9 +1136,9 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	}
 	else
 	{
-		DynamicArrayAuto<MutatorValue> mutation(tempAllocator);
-		DynamicArrayAuto<ShaderProgramBinaryCodeBlock> codeBlocks(binaryAllocator);
-		DynamicArrayAuto<U64> codeBlockHashes(tempAllocator);
+		DynamicArrayRaii<MutatorValue> mutation(tempAllocator);
+		DynamicArrayRaii<ShaderProgramBinaryCodeBlock> codeBlocks(binaryAllocator);
+		DynamicArrayRaii<U64> codeBlockHashes(tempAllocator);
 
 		binary.m_variants.setArray(binaryAllocator.newInstance<ShaderProgramBinaryVariant>(), 1);
 

+ 6 - 6
AnKi/ShaderCompiler/ShaderProgramDump.cpp

@@ -13,7 +13,7 @@ namespace anki {
 #define ANKI_TAB "    "
 
 static void disassembleBlockInstance(const ShaderProgramBinaryBlockInstance& instance,
-									 const ShaderProgramBinaryBlock& block, StringListAuto& lines)
+									 const ShaderProgramBinaryBlock& block, StringListRaii& lines)
 {
 	lines.pushBackSprintf(ANKI_TAB ANKI_TAB ANKI_TAB "%-32s set %4u binding %4u size %4u\n", block.m_name.getBegin(),
 						  block.m_set, block.m_binding, instance.m_size);
@@ -30,7 +30,7 @@ static void disassembleBlockInstance(const ShaderProgramBinaryBlockInstance& ins
 	}
 }
 
-static void disassembleBlock(const ShaderProgramBinaryBlock& block, StringListAuto& lines)
+static void disassembleBlock(const ShaderProgramBinaryBlock& block, StringListRaii& lines)
 {
 	lines.pushBackSprintf(ANKI_TAB "%-32s set %4u binding %4u\n", block.m_name.getBegin(), block.m_set,
 						  block.m_binding);
@@ -42,10 +42,10 @@ static void disassembleBlock(const ShaderProgramBinaryBlock& block, StringListAu
 	}
 }
 
-void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable)
+void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringRaii& humanReadable)
 {
 	GenericMemoryPoolAllocator<U8> alloc = humanReadable.getAllocator();
-	StringListAuto lines(alloc);
+	StringListRaii lines(alloc);
 
 	if(binary.m_libraryName[0])
 	{
@@ -182,9 +182,9 @@ void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& huma
 		compiler.set_common_options(options);
 
 		std::string glsl = compiler.compile();
-		StringListAuto sourceLines(alloc);
+		StringListRaii sourceLines(alloc);
 		sourceLines.splitString(glsl.c_str(), '\n');
-		StringAuto newGlsl(alloc);
+		StringRaii newGlsl(alloc);
 		sourceLines.join("\n" ANKI_TAB ANKI_TAB, newGlsl);
 
 		lines.pushBackSprintf(ANKI_TAB "#bin%05u \n" ANKI_TAB ANKI_TAB "%s\n", count++, newGlsl.cstr());

+ 1 - 1
AnKi/ShaderCompiler/ShaderProgramDump.h

@@ -12,7 +12,7 @@ namespace anki {
 /// @{
 
 /// Create a human readable representation of the shader binary.
-void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable);
+void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringRaii& humanReadable);
 /// @}
 
 } // end namespace anki

+ 26 - 26
AnKi/ShaderCompiler/ShaderProgramParser.cpp

@@ -294,11 +294,11 @@ ShaderProgramParser::~ShaderProgramParser()
 {
 }
 
-void ShaderProgramParser::tokenizeLine(CString line, DynamicArrayAuto<StringAuto>& tokens) const
+void ShaderProgramParser::tokenizeLine(CString line, DynamicArrayRaii<StringRaii>& tokens) const
 {
 	ANKI_ASSERT(line.getLength() > 0);
 
-	StringAuto l(m_alloc, line);
+	StringRaii l(m_alloc, line);
 
 	// Replace all tabs with spaces
 	for(char& c : l)
@@ -320,7 +320,7 @@ void ShaderProgramParser::tokenizeLine(CString line, DynamicArrayAuto<StringAuto
 	}
 }
 
-Error ShaderProgramParser::parsePragmaStart(const StringAuto* begin, const StringAuto* end, CString line, CString fname)
+Error ShaderProgramParser::parsePragmaStart(const StringRaii* begin, const StringRaii* end, CString line, CString fname)
 {
 	ANKI_ASSERT(begin && end);
 
@@ -409,7 +409,7 @@ Error ShaderProgramParser::parsePragmaStart(const StringAuto* begin, const Strin
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaEnd(const StringAuto* begin, const StringAuto* end, CString line, CString fname)
+Error ShaderProgramParser::parsePragmaEnd(const StringRaii* begin, const StringRaii* end, CString line, CString fname)
 {
 	ANKI_ASSERT(begin && end);
 
@@ -432,7 +432,7 @@ Error ShaderProgramParser::parsePragmaEnd(const StringAuto* begin, const StringA
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaMutator(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaMutator(const StringRaii* begin, const StringRaii* end, CString line,
 											  CString fname)
 {
 	ANKI_ASSERT(begin && end);
@@ -506,7 +506,7 @@ Error ShaderProgramParser::parsePragmaMutator(const StringAuto* begin, const Str
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaLibraryName(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaLibraryName(const StringRaii* begin, const StringRaii* end, CString line,
 												  CString fname)
 {
 	ANKI_ASSERT(begin && end);
@@ -526,7 +526,7 @@ Error ShaderProgramParser::parsePragmaLibraryName(const StringAuto* begin, const
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaRayType(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaRayType(const StringRaii* begin, const StringRaii* end, CString line,
 											  CString fname)
 {
 	ANKI_ASSERT(begin && end);
@@ -551,7 +551,7 @@ Error ShaderProgramParser::parsePragmaRayType(const StringAuto* begin, const Str
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaReflect(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaReflect(const StringRaii* begin, const StringRaii* end, CString line,
 											  CString fname)
 {
 	ANKI_ASSERT(begin && end);
@@ -566,7 +566,7 @@ Error ShaderProgramParser::parsePragmaReflect(const StringAuto* begin, const Str
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaSkipMutation(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaSkipMutation(const StringRaii* begin, const StringRaii* end, CString line,
 												   CString fname)
 {
 	ANKI_ASSERT(begin && end);
@@ -624,11 +624,11 @@ Error ShaderProgramParser::parsePragmaSkipMutation(const StringAuto* begin, cons
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parseInclude(const StringAuto* begin, const StringAuto* end, CString line, CString fname,
+Error ShaderProgramParser::parseInclude(const StringRaii* begin, const StringRaii* end, CString line, CString fname,
 										U32 depth)
 {
 	// Gather the path
-	StringAuto path(m_alloc);
+	StringRaii path(m_alloc);
 	for(; begin < end; ++begin)
 	{
 		path.append(*begin);
@@ -645,7 +645,7 @@ Error ShaderProgramParser::parseInclude(const StringAuto* begin, const StringAut
 
 	if((firstChar == '\"' && lastChar == '\"') || (firstChar == '<' && lastChar == '>'))
 	{
-		StringAuto fname2(m_alloc);
+		StringRaii fname2(m_alloc);
 		fname2.create(path.begin() + 1, path.begin() + path.getLength() - 1);
 
 		const Bool dontIgnore =
@@ -672,12 +672,12 @@ Error ShaderProgramParser::parseInclude(const StringAuto* begin, const StringAut
 Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth)
 {
 	// Tokenize
-	DynamicArrayAuto<StringAuto> tokens(m_alloc);
+	DynamicArrayRaii<StringRaii> tokens(m_alloc);
 	tokenizeLine(line, tokens);
 	ANKI_ASSERT(tokens.getSize() > 0);
 
-	const StringAuto* token = tokens.getBegin();
-	const StringAuto* end = tokens.getEnd();
+	const StringRaii* token = tokens.getBegin();
+	const StringRaii* end = tokens.getEnd();
 
 	// Skip the hash
 	Bool foundAloneHash = false;
@@ -801,7 +801,7 @@ Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPra
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaStructBegin(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaStructBegin(const StringRaii* begin, const StringRaii* end, CString line,
 												  CString fname)
 {
 	const U tokenCount = U(end - begin);
@@ -832,7 +832,7 @@ Error ShaderProgramParser::parsePragmaStructBegin(const StringAuto* begin, const
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaMember(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaMember(const StringRaii* begin, const StringRaii* end, CString line,
 											 CString fname)
 {
 	ANKI_ASSERT(m_insideStruct);
@@ -983,7 +983,7 @@ Error ShaderProgramParser::parsePragmaMember(const StringAuto* begin, const Stri
 	return Error::kNone;
 }
 
-Error ShaderProgramParser::parsePragmaStructEnd(const StringAuto* begin, const StringAuto* end, CString line,
+Error ShaderProgramParser::parsePragmaStructEnd(const StringRaii* begin, const StringRaii* end, CString line,
 												CString fname)
 {
 	ANKI_ASSERT(m_insideStruct);
@@ -1031,10 +1031,10 @@ Error ShaderProgramParser::parsePragmaStructEnd(const StringAuto* begin, const S
 		// #	define XXX_LOAD()
 		const Bool isIntegral = getShaderVariableDataTypeInfo(m.m_type).m_isIntegral;
 		const U32 componentCount = getShaderVariableDataTypeInfo(m.m_type).m_size / sizeof(U32);
-		StringAuto values(m_alloc);
+		StringRaii values(m_alloc);
 		for(U32 j = 0; j < componentCount; ++j)
 		{
-			StringAuto tmp(m_alloc);
+			StringRaii tmp(m_alloc);
 			tmp.sprintf("%s(ssbo[%s_%s_OFFSETOF + offset + %uu])%s", (isIntegral) ? "" : "uintBitsToFloat",
 						structName.cstr(), m.m_name.cstr(), j, (j != componentCount - 1) ? "," : "");
 
@@ -1085,7 +1085,7 @@ Error ShaderProgramParser::parseFile(CString fname, U32 depth)
 	Bool foundPragmaOnce = false;
 
 	// Load file in lines
-	StringAuto txt(m_alloc);
+	StringRaii txt(m_alloc);
 	ANKI_CHECK(m_fsystem->readAllText(fname, txt));
 
 	StringListAuto lines(m_alloc);
@@ -1193,7 +1193,7 @@ Error ShaderProgramParser::parse()
 }
 
 void ShaderProgramParser::generateAnkiShaderHeader(ShaderType shaderType, const ShaderCompilerOptions& compilerOptions,
-												   StringAuto& header)
+												   StringRaii& header)
 {
 	header.sprintf(SHADER_HEADER, SHADER_STAGE_NAMES[shaderType].cstr(), compilerOptions.m_mobilePlatform,
 				   compilerOptions.m_forceFullFloatingPointPrecision, kMaxBindlessTextures,
@@ -1216,10 +1216,10 @@ Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation
 	variant.m_alloc = m_alloc;
 
 	// Create the mutator defines
-	StringAuto mutatorDefines(m_alloc);
+	StringRaii mutatorDefines(m_alloc);
 	for(U32 i = 0; i < mutation.getSize(); ++i)
 	{
-		mutatorDefines.append(StringAuto(m_alloc).sprintf("#define %s %d\n", m_mutators[i].m_name.cstr(), mutation[i]));
+		mutatorDefines.append(StringRaii(m_alloc).sprintf("#define %s %d\n", m_mutators[i].m_name.cstr(), mutation[i]));
 	}
 
 	// Generate souce per stage
@@ -1231,11 +1231,11 @@ Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation
 		}
 
 		// Create the header
-		StringAuto header(m_alloc);
+		StringRaii header(m_alloc);
 		generateAnkiShaderHeader(shaderType, m_compilerOptions, header);
 
 		// Create the final source without the bindings
-		StringAuto finalSource(m_alloc);
+		StringRaii finalSource(m_alloc);
 		finalSource.append(header);
 		finalSource.append(mutatorDefines);
 		finalSource.append(m_codeSource);

+ 29 - 29
AnKi/ShaderCompiler/ShaderProgramParser.h

@@ -42,15 +42,15 @@ public:
 	}
 
 private:
-	StringAuto m_name;
-	DynamicArrayAuto<MutatorValue> m_values;
+	StringRaii m_name;
+	DynamicArrayRaii<MutatorValue> m_values;
 };
 
 /// @memberof ShaderProgramParser
 class ShaderProgramParserMember
 {
 public:
-	StringAuto m_name;
+	StringRaii m_name;
 	ShaderVariableDataType m_type;
 	U32 m_dependentMutator = kMaxU32;
 	MutatorValue m_mutatorValue = 0;
@@ -65,8 +65,8 @@ public:
 class ShaderProgramParserGhostStruct
 {
 public:
-	DynamicArrayAuto<ShaderProgramParserMember> m_members;
-	StringAuto m_name;
+	DynamicArrayRaii<ShaderProgramParserMember> m_members;
+	StringRaii m_name;
 
 	ShaderProgramParserGhostStruct(GenericMemoryPoolAllocator<U8> alloc)
 		: m_members(alloc)
@@ -166,7 +166,7 @@ public:
 		return m_rayType;
 	}
 
-	const StringListAuto& getSymbolsToReflect() const
+	const StringListRaii& getSymbolsToReflect() const
 	{
 		return m_symbolsToReflect;
 	}
@@ -178,7 +178,7 @@ public:
 
 	/// Generates the common header that will be used by all AnKi shaders.
 	static void generateAnkiShaderHeader(ShaderType shaderType, const ShaderCompilerOptions& compilerOptions,
-										 StringAuto& header);
+										 StringRaii& header);
 
 private:
 	using Mutator = ShaderProgramParserMutator;
@@ -188,7 +188,7 @@ private:
 	class PartialMutationSkip
 	{
 	public:
-		DynamicArrayAuto<MutatorValue> m_partialMutation;
+		DynamicArrayRaii<MutatorValue> m_partialMutation;
 
 		PartialMutationSkip(const GenericMemoryPoolAllocator<U8>& alloc)
 			: m_partialMutation(alloc)
@@ -199,43 +199,43 @@ private:
 	static constexpr U32 MAX_INCLUDE_DEPTH = 8;
 
 	GenericMemoryPoolAllocator<U8> m_alloc;
-	StringAuto m_fname;
+	StringRaii m_fname;
 	ShaderProgramFilesystemInterface* m_fsystem = nullptr;
 
-	StringListAuto m_codeLines = {m_alloc}; ///< The code.
-	StringAuto m_codeSource = {m_alloc};
+	StringListRaii m_codeLines = {m_alloc}; ///< The code.
+	StringRaii m_codeSource = {m_alloc};
 	U64 m_codeSourceHash = 0;
 
-	DynamicArrayAuto<Mutator> m_mutators = {m_alloc};
-	DynamicArrayAuto<PartialMutationSkip> m_skipMutations = {m_alloc};
+	DynamicArrayRaii<Mutator> m_mutators = {m_alloc};
+	DynamicArrayRaii<PartialMutationSkip> m_skipMutations = {m_alloc};
 
 	ShaderTypeBit m_shaderTypes = ShaderTypeBit::kNone;
 	Bool m_insideShader = false;
 	ShaderCompilerOptions m_compilerOptions;
 
-	StringAuto m_libName = {m_alloc};
+	StringRaii m_libName = {m_alloc};
 	U32 m_rayType = kMaxU32;
 
-	StringListAuto m_symbolsToReflect = {m_alloc};
+	StringListRaii m_symbolsToReflect = {m_alloc};
 
-	DynamicArrayAuto<GhostStruct> m_ghostStructs = {m_alloc};
+	DynamicArrayRaii<GhostStruct> m_ghostStructs = {m_alloc};
 	Bool m_insideStruct = false;
 
 	Error parseFile(CString fname, U32 depth);
 	Error parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth);
-	Error parseInclude(const StringAuto* begin, const StringAuto* end, CString line, CString fname, U32 depth);
-	Error parsePragmaMutator(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaStart(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaEnd(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaSkipMutation(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaLibraryName(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaRayType(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaReflect(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaStructBegin(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaStructEnd(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-	Error parsePragmaMember(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
-
-	void tokenizeLine(CString line, DynamicArrayAuto<StringAuto>& tokens) const;
+	Error parseInclude(const StringRaii* begin, const StringRaii* end, CString line, CString fname, U32 depth);
+	Error parsePragmaMutator(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaStart(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaEnd(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaSkipMutation(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaLibraryName(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaRayType(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaReflect(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaStructBegin(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaStructEnd(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+	Error parsePragmaMember(const StringRaii* begin, const StringRaii* end, CString line, CString fname);
+
+	void tokenizeLine(CString line, DynamicArrayRaii<StringRaii>& tokens) const;
 
 	static Bool tokenIsComment(CString token)
 	{

+ 30 - 30
AnKi/ShaderCompiler/ShaderProgramReflection.cpp

@@ -72,7 +72,7 @@ private:
 	class Var
 	{
 	public:
-		StringAuto m_name;
+		StringRaii m_name;
 		ShaderVariableBlockInfo m_blockInfo;
 		ShaderVariableDataType m_type = ShaderVariableDataType::kNone;
 
@@ -85,8 +85,8 @@ private:
 	class Block
 	{
 	public:
-		StringAuto m_name;
-		DynamicArrayAuto<Var> m_vars;
+		StringRaii m_name;
+		DynamicArrayRaii<Var> m_vars;
 		U32 m_binding = kMaxU32;
 		U32 m_set = kMaxU32;
 		U32 m_size = kMaxU32;
@@ -101,7 +101,7 @@ private:
 	class Opaque
 	{
 	public:
-		StringAuto m_name;
+		StringRaii m_name;
 		ShaderVariableDataType m_type = ShaderVariableDataType::kNone;
 		U32 m_binding = kMaxU32;
 		U32 m_set = kMaxU32;
@@ -116,7 +116,7 @@ private:
 	class Const
 	{
 	public:
-		StringAuto m_name;
+		StringRaii m_name;
 		ShaderVariableDataType m_type = ShaderVariableDataType::kNone;
 		U32 m_constantId = kMaxU32;
 
@@ -129,7 +129,7 @@ private:
 	class StructMember
 	{
 	public:
-		StringAuto m_name;
+		StringRaii m_name;
 		ShaderVariableDataType m_type = ShaderVariableDataType::kNone;
 		U32 m_structIndex = kMaxU32; ///< The member is actually a struct.
 		U32 m_offset = kMaxU32;
@@ -144,8 +144,8 @@ private:
 	class Struct
 	{
 	public:
-		StringAuto m_name;
-		DynamicArrayAuto<StructMember> m_members;
+		StringRaii m_name;
+		DynamicArrayRaii<StructMember> m_members;
 		U32 m_size = 0;
 		U32 m_alignment = 0;
 
@@ -161,26 +161,26 @@ private:
 
 	Error spirvTypeToAnki(const spirv_cross::SPIRType& type, ShaderVariableDataType& out) const;
 
-	Error blockReflection(const spirv_cross::Resource& res, Bool isStorage, DynamicArrayAuto<Block>& blocks) const;
+	Error blockReflection(const spirv_cross::Resource& res, Bool isStorage, DynamicArrayRaii<Block>& blocks) const;
 
-	Error opaqueReflection(const spirv_cross::Resource& res, DynamicArrayAuto<Opaque>& opaques) const;
+	Error opaqueReflection(const spirv_cross::Resource& res, DynamicArrayRaii<Opaque>& opaques) const;
 
-	Error constsReflection(DynamicArrayAuto<Const>& consts) const;
+	Error constsReflection(DynamicArrayRaii<Const>& consts) const;
 
-	Error blockVariablesReflection(spirv_cross::TypeID resourceId, DynamicArrayAuto<Var>& vars) const;
+	Error blockVariablesReflection(spirv_cross::TypeID resourceId, DynamicArrayRaii<Var>& vars) const;
 
 	Error blockVariableReflection(const spirv_cross::SPIRType& type, CString parentVariable, U32 baseOffset,
-								  DynamicArrayAuto<Var>& vars) const;
+								  DynamicArrayRaii<Var>& vars) const;
 
 	Error workgroupSizes(U32& sizex, U32& sizey, U32& sizez, U32& specConstMask);
 
-	Error structsReflection(DynamicArrayAuto<Struct>& structs) const;
+	Error structsReflection(DynamicArrayRaii<Struct>& structs) const;
 
 	Error structReflection(uint32_t id, const spirv_cross::SPIRType& type, U32 depth, Bool& skipped,
-						   DynamicArrayAuto<Struct>& structs, U32& structIndexInStructsArr) const;
+						   DynamicArrayRaii<Struct>& structs, U32& structIndexInStructsArr) const;
 };
 
-Error SpirvReflector::structsReflection(DynamicArrayAuto<Struct>& structs) const
+Error SpirvReflector::structsReflection(DynamicArrayRaii<Struct>& structs) const
 {
 	Error err = Error::kNone;
 
@@ -205,7 +205,7 @@ Error SpirvReflector::structsReflection(DynamicArrayAuto<Struct>& structs) const
 }
 
 Error SpirvReflector::structReflection(uint32_t id, const spirv_cross::SPIRType& type, U32 depth, Bool& skipped,
-									   DynamicArrayAuto<Struct>& structs, U32& structIndexInStructsArr) const
+									   DynamicArrayRaii<Struct>& structs, U32& structIndexInStructsArr) const
 {
 	skipped = false;
 
@@ -363,7 +363,7 @@ Error SpirvReflector::structReflection(uint32_t id, const spirv_cross::SPIRType&
 	return Error::kNone;
 }
 
-Error SpirvReflector::blockVariablesReflection(spirv_cross::TypeID resourceId, DynamicArrayAuto<Var>& vars) const
+Error SpirvReflector::blockVariablesReflection(spirv_cross::TypeID resourceId, DynamicArrayRaii<Var>& vars) const
 {
 	Bool found = false;
 	Error err = Error::kNone;
@@ -394,7 +394,7 @@ Error SpirvReflector::blockVariablesReflection(spirv_cross::TypeID resourceId, D
 }
 
 Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type, CString parentVariable, U32 baseOffset,
-											  DynamicArrayAuto<Var>& vars) const
+											  DynamicArrayRaii<Var>& vars) const
 {
 	ANKI_ASSERT(type.basetype == spirv_cross::SPIRType::Struct);
 
@@ -481,7 +481,7 @@ Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type,
 			{
 				for(U32 i = 0; i < U32(var.m_blockInfo.m_arraySize); ++i)
 				{
-					StringAuto newName(m_alloc);
+					StringRaii newName(m_alloc);
 					newName.sprintf("%s[%u]", var.m_name.getBegin(), i);
 					ANKI_CHECK(blockVariableReflection(
 						memberType, newName, var.m_blockInfo.m_offset + var.m_blockInfo.m_arrayStride * i, vars));
@@ -536,7 +536,7 @@ Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type,
 }
 
 Error SpirvReflector::blockReflection(const spirv_cross::Resource& res, [[maybe_unused]] Bool isStorage,
-									  DynamicArrayAuto<Block>& blocks) const
+									  DynamicArrayRaii<Block>& blocks) const
 {
 	Block newBlock(m_alloc);
 	const spirv_cross::SPIRType type = get_type(res.type_id);
@@ -616,7 +616,7 @@ Error SpirvReflector::blockReflection(const spirv_cross::Resource& res, [[maybe_
 #if ANKI_ENABLE_ASSERTIONS
 	else
 	{
-		DynamicArrayAuto<Var> vars(m_alloc);
+		DynamicArrayRaii<Var> vars(m_alloc);
 		ANKI_CHECK(blockVariablesReflection(res.base_type_id, vars));
 		ANKI_ASSERT(vars.getSize() == otherFound->m_vars.getSize() && "Expecting same vars");
 	}
@@ -664,7 +664,7 @@ Error SpirvReflector::spirvTypeToAnki(const spirv_cross::SPIRType& type, ShaderV
 	return Error::kNone;
 }
 
-Error SpirvReflector::opaqueReflection(const spirv_cross::Resource& res, DynamicArrayAuto<Opaque>& opaques) const
+Error SpirvReflector::opaqueReflection(const spirv_cross::Resource& res, DynamicArrayRaii<Opaque>& opaques) const
 {
 	Opaque newOpaque(m_alloc);
 	const spirv_cross::SPIRType type = get_type(res.type_id);
@@ -747,7 +747,7 @@ Error SpirvReflector::opaqueReflection(const spirv_cross::Resource& res, Dynamic
 	return Error::kNone;
 }
 
-Error SpirvReflector::constsReflection(DynamicArrayAuto<Const>& consts) const
+Error SpirvReflector::constsReflection(DynamicArrayRaii<Const>& consts) const
 {
 	spirv_cross::SmallVector<spirv_cross::SpecializationConstant> specConsts = get_specialization_constants();
 	for(const spirv_cross::SpecializationConstant& c : specConsts)
@@ -869,14 +869,14 @@ Error SpirvReflector::performSpirvReflection(Array<ConstWeakArray<U8>, U32(Shade
 											 GenericMemoryPoolAllocator<U8> tmpAlloc,
 											 ShaderReflectionVisitorInterface& interface)
 {
-	DynamicArrayAuto<Block> uniformBlocks(tmpAlloc);
-	DynamicArrayAuto<Block> storageBlocks(tmpAlloc);
-	DynamicArrayAuto<Block> pushConstantBlock(tmpAlloc);
-	DynamicArrayAuto<Opaque> opaques(tmpAlloc);
-	DynamicArrayAuto<Const> specializationConstants(tmpAlloc);
+	DynamicArrayRaii<Block> uniformBlocks(tmpAlloc);
+	DynamicArrayRaii<Block> storageBlocks(tmpAlloc);
+	DynamicArrayRaii<Block> pushConstantBlock(tmpAlloc);
+	DynamicArrayRaii<Opaque> opaques(tmpAlloc);
+	DynamicArrayRaii<Const> specializationConstants(tmpAlloc);
 	Array<U32, 3> workgroupSizes = {};
 	U32 workgroupSizeSpecConstMask = 0;
-	DynamicArrayAuto<Struct> structs(tmpAlloc);
+	DynamicArrayRaii<Struct> structs(tmpAlloc);
 
 	// Perform reflection for each stage
 	for(const ShaderType type : EnumIterable<ShaderType>())

+ 2 - 1
AnKi/Util/Assert.cpp

@@ -35,7 +35,8 @@ void akassert(const char* exprTxt, const char* file, int line, const char* func)
 
 	printf("Backtrace:\n");
 	U32 count = 0;
-	backtrace(HeapAllocator<U8>(allocAligned, nullptr), [&count](CString symbol) {
+	HeapMemoryPool pool(allocAligned, nullptr);
+	backtrace(pool, [&count](CString symbol) {
 		printf("%.2u: %s\n", count++, symbol.cstr());
 	});
 

+ 5 - 5
AnKi/Util/BitSet.h

@@ -15,9 +15,9 @@ namespace anki {
 /// @{
 
 /// Easy bit manipulation.
-/// @tparam N The number of bits.
+/// @tparam kBitCount The number of bits.
 /// @tparam TChunkType The type of the chunks that the bitset consists. By default it's U8.
-template<U32 N, typename TChunkType = U8>
+template<U32 kBitCount, typename TChunkType = U8>
 class BitSet
 {
 private:
@@ -27,7 +27,7 @@ private:
 	static constexpr U32 kChunkBitCount = sizeof(ChunkType) * 8;
 
 	/// Number of chunks.
-	static constexpr U32 kChunkCount = (N + (kChunkBitCount - 1)) / kChunkBitCount;
+	static constexpr U32 kChunkCount = (kBitCount + (kChunkBitCount - 1)) / kChunkBitCount;
 
 public:
 	/// Constructor. It will set all the bits or unset them.
@@ -278,7 +278,7 @@ private:
 
 	static void position(U32 bit, U32& high, U32& low)
 	{
-		ANKI_ASSERT(bit < N);
+		ANKI_ASSERT(bit < kBitCount);
 		high = bit / kChunkBitCount;
 		low = bit % kChunkBitCount;
 		ANKI_ASSERT(high < kChunkCount);
@@ -288,7 +288,7 @@ private:
 	/// Zero the unused bits.
 	void zeroUnusedBits()
 	{
-		constexpr ChunkType kUnusedBits = kChunkCount * kChunkBitCount - N;
+		constexpr ChunkType kUnusedBits = kChunkCount * kChunkBitCount - kBitCount;
 		constexpr ChunkType kUsedBitmask = std::numeric_limits<ChunkType>::max() >> kUnusedBits;
 		if(kUsedBitmask > 0)
 		{

+ 28 - 0
AnKi/Util/CpuMemoryPools.h

@@ -338,6 +338,34 @@ private:
 	StackAllocatorBuilder<Chunk, StackAllocatorBuilderInterface, Mutex> m_builder;
 };
 
+/// A wrapper class that makes a pointer to a memory pool act like a reference.
+template<typename TMemPool>
+class MemoryPoolPtrWrapper
+{
+public:
+	TMemPool* m_pool;
+
+	MemoryPoolPtrWrapper(TMemPool* pool)
+		: m_pool(pool)
+	{
+	}
+
+	TMemPool* operator&()
+	{
+		return m_pool;
+	}
+
+	void* allocate(PtrSize size, PtrSize alignmentBytes)
+	{
+		return m_pool->allocate(size, alignmentBytes);
+	}
+
+	void free(void* ptr)
+	{
+		m_pool->free(ptr);
+	}
+};
+
 inline void* BaseMemoryPool::allocate(PtrSize size, PtrSize alignmentBytes)
 {
 	void* out = nullptr;

+ 73 - 74
AnKi/Util/DynamicArray.h

@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include <AnKi/Util/Allocator.h>
+#include <AnKi/Util/CpuMemoryPools.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/Forward.h>
 
@@ -67,8 +67,9 @@ public:
 		return *this;
 	}
 
-	/// Move DynamicArrayAuto to this.
-	DynamicArray& operator=(DynamicArrayAuto<T, TSize>&& b);
+	/// Move DynamicArrayRaii to this.
+	template<typename TMemPool>
+	DynamicArray& operator=(DynamicArrayRaii<T, TSize, TMemPool>&& b);
 
 	// Non-copyable
 	DynamicArray& operator=(const DynamicArray& b) = delete;
@@ -173,40 +174,40 @@ public:
 	}
 
 	/// Only create the array. Useful if @a T is non-copyable or movable .
-	template<typename TAllocator>
-	void create(TAllocator alloc, Size size)
+	template<typename TMemPool>
+	void create(TMemPool& pool, Size size)
 	{
 		ANKI_ASSERT(m_data == nullptr && m_size == 0 && m_capacity == 0);
 		if(size > 0)
 		{
-			m_data = alloc.template newArray<Value>(size);
+			m_data = newArray<Value>(pool, size);
 			m_size = size;
 			m_capacity = size;
 		}
 	}
 
 	/// Only create the array. Useful if @a T is non-copyable or movable .
-	template<typename TAllocator>
-	void create(TAllocator alloc, Size size, const Value& v)
+	template<typename TMemPool>
+	void create(TMemPool& pool, Size size, const Value& v)
 	{
 		ANKI_ASSERT(m_data == nullptr && m_size == 0 && m_capacity == 0);
 		if(size > 0)
 		{
-			m_data = alloc.template newArray<Value>(size, v);
+			m_data = newArray<Value>(pool, size, v);
 			m_size = size;
 			m_capacity = size;
 		}
 	}
 
 	/// Destroy the array.
-	template<typename TAllocator>
-	void destroy(TAllocator alloc)
+	template<typename TMemPool>
+	void destroy(TMemPool& pool)
 	{
 		if(m_data)
 		{
 			ANKI_ASSERT(m_size > 0);
 			ANKI_ASSERT(m_capacity > 0);
-			alloc.deleteArray(m_data, m_size);
+			deleteArray(pool, m_data, m_size);
 
 			m_data = nullptr;
 			m_size = 0;
@@ -217,54 +218,54 @@ public:
 	}
 
 	/// Grow or create the array. @a T needs to be copyable and moveable.
-	template<typename TAllocator>
-	void resize(TAllocator alloc, Size size, const Value& v);
+	template<typename TMemPool>
+	void resize(TMemPool& pool, Size size, const Value& v);
 
 	/// Grow or create the array. @a T needs to be copyable, moveable and default constructible.
-	template<typename TAllocator>
-	void resize(TAllocator alloc, Size size);
+	template<typename TMemPool>
+	void resize(TMemPool& pool, Size size);
 
 	/// Push back value.
-	template<typename TAllocator, typename... TArgs>
-	Iterator emplaceBack(TAllocator alloc, TArgs&&... args)
+	template<typename TMemPool, typename... TArgs>
+	Iterator emplaceBack(TMemPool& pool, TArgs&&... args)
 	{
-		resizeStorage(alloc, m_size + 1);
-		alloc.construct(&m_data[m_size], std::forward<TArgs>(args)...);
+		resizeStorage(pool, m_size + 1);
+		callConstructor(m_data[m_size], std::forward<TArgs>(args)...);
 		++m_size;
 		return &m_data[m_size - 1];
 	}
 
 	/// Remove the last value.
-	template<typename TAllocator>
-	void popBack(TAllocator alloc)
+	template<typename TMemPool>
+	void popBack(TMemPool& pool)
 	{
 		if(m_size > 0)
 		{
-			resizeStorage(alloc, m_size - 1);
+			resizeStorage(pool, m_size - 1);
 		}
 	}
 
 	/// Emplace a new element at a specific position. @a T needs to be movable and default constructible.
-	/// @param alloc The allocator.
+	/// @param pool The memory pool.
 	/// @param where Points to the position to emplace. Should be less or equal to what getEnd() returns.
 	/// @param args  Constructor arguments.
-	template<typename TAllocator, typename... TArgs>
-	Iterator emplaceAt(TAllocator alloc, ConstIterator where, TArgs&&... args);
+	template<typename TMemPool, typename... TArgs>
+	Iterator emplaceAt(TMemPool& pool, ConstIterator where, TArgs&&... args);
 
 	/// Removes the (first, last] elements.
-	/// @param alloc The allocator.
+	/// @param pool The memory pool.
 	/// @param first Points to the position of the first element to remove.
 	/// @param last Points to the position of the last element to remove minus one.
-	template<typename TAllocator>
-	void erase(TAllocator alloc, ConstIterator first, ConstIterator last);
+	template<typename TMemPool>
+	void erase(TMemPool& pool, ConstIterator first, ConstIterator last);
 
 	/// Removes one element.
-	/// @param alloc The allocator.
+	/// @param pool The memory pool.
 	/// @param at Points to the position of the element to remove.
-	template<typename TAllocator>
-	void erase(TAllocator alloc, ConstIterator at)
+	template<typename TMemPool>
+	void erase(TMemPool& pool, ConstIterator at)
 	{
-		erase(alloc, at, at + 1);
+		erase(pool, at, at + 1);
 	}
 
 	/// Validate it. Will only work when assertions are enabled.
@@ -304,8 +305,8 @@ public:
 	}
 
 	/// Resizes the storage but DOESN'T CONSTRUCT ANY ELEMENTS. It only moves or destroys.
-	template<typename TAllocator>
-	void resizeStorage(TAllocator alloc, Size newSize);
+	template<typename TMemPool>
+	void resizeStorage(TMemPool& pool, Size newSize);
 
 protected:
 	Value* m_data;
@@ -313,10 +314,10 @@ protected:
 	Size m_capacity = 0;
 };
 
-/// Dynamic array with automatic destruction. It's the same as DynamicArray but it holds the allocator in order to
+/// Dynamic array with automatic destruction. It's the same as DynamicArray but it holds the memory pool in order to
 /// perform automatic destruction. Use it for temp operations and on transient classes.
-template<typename T, typename TSize>
-class DynamicArrayAuto : public DynamicArray<T, TSize>
+template<typename T, typename TSize = U32, typename TMemPool = MemoryPoolPtrWrapper<BaseMemoryPool>>
+class DynamicArrayRaii : public DynamicArray<T, TSize>
 {
 public:
 	using Base = DynamicArray<T, TSize>;
@@ -327,48 +328,46 @@ public:
 	using typename Base::Iterator;
 	using typename Base::ConstIterator;
 	using typename Base::Size;
+	using MemoryPool = TMemPool;
 
-	template<typename TAllocator>
-	DynamicArrayAuto(TAllocator alloc)
+	DynamicArrayRaii(const MemoryPool& pool)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 	}
 
 	/// And resize
-	template<typename TAllocator>
-	DynamicArrayAuto(TAllocator alloc, Size size)
+	DynamicArrayRaii(const MemoryPool& pool, Size size)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 		resize(size);
 	}
 
 	/// With default value
-	template<typename TAllocator>
-	DynamicArrayAuto(TAllocator alloc, Size size, const T& v)
+	DynamicArrayRaii(const MemoryPool& pool, Size size, const T& v)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 		create(size, v);
 	}
 
 	/// Move.
-	DynamicArrayAuto(DynamicArrayAuto&& b)
+	DynamicArrayRaii(DynamicArrayRaii&& b)
 		: Base()
 	{
 		*this = std::move(b);
 	}
 
-	~DynamicArrayAuto()
+	~DynamicArrayRaii()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Copy.
-	DynamicArrayAuto(const DynamicArrayAuto& b)
+	DynamicArrayRaii(const DynamicArrayRaii& b)
 		: Base()
-		, m_alloc(b.m_alloc)
+		, m_pool(b.m_pool)
 	{
 		if(b.getSize())
 		{
@@ -381,9 +380,9 @@ public:
 	}
 
 	/// Move.
-	DynamicArrayAuto& operator=(DynamicArrayAuto&& b)
+	DynamicArrayRaii& operator=(DynamicArrayRaii&& b)
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 
 		m_data = b.m_data;
 		b.m_data = nullptr;
@@ -391,13 +390,13 @@ public:
 		b.m_size = 0;
 		m_capacity = b.m_capacity;
 		b.m_capacity = 0;
-		m_alloc = b.m_alloc;
-		b.m_alloc = {};
+		m_pool = std::move(b.m_pool);
+		b.m_pool = {};
 		return *this;
 	}
 
 	/// Copy.
-	DynamicArrayAuto& operator=(const DynamicArrayAuto& b)
+	DynamicArrayRaii& operator=(const DynamicArrayRaii& b)
 	{
 		destroy();
 		if(b.getSize())
@@ -414,93 +413,93 @@ public:
 	/// @copydoc DynamicArray::create
 	void create(Size size)
 	{
-		Base::create(m_alloc, size);
+		Base::create(m_pool, size);
 	}
 
 	/// @copydoc DynamicArray::create
 	void create(Size size, const Value& v)
 	{
-		Base::create(m_alloc, size, v);
+		Base::create(m_pool, size, v);
 	}
 
 	/// @copydoc DynamicArray::destroy
 	void destroy()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// @copydoc DynamicArray::resize
 	void resize(Size size, const Value& v)
 	{
-		Base::resize(m_alloc, size, v);
+		Base::resize(m_pool, size, v);
 	}
 
 	/// @copydoc DynamicArray::resize
 	void resize(Size size)
 	{
-		Base::resize(m_alloc, size);
+		Base::resize(m_pool, size);
 	}
 
 	/// @copydoc DynamicArray::emplaceBack
 	template<typename... TArgs>
 	Iterator emplaceBack(TArgs&&... args)
 	{
-		return Base::emplaceBack(m_alloc, std::forward<TArgs>(args)...);
+		return Base::emplaceBack(m_pool, std::forward<TArgs>(args)...);
 	}
 
 	/// @copydoc DynamicArray::popBack
 	void popBack()
 	{
-		Base::popBack(m_alloc);
+		Base::popBack(m_pool);
 	}
 
 	/// @copydoc DynamicArray::emplaceAt
 	template<typename... TArgs>
 	Iterator emplaceAt(ConstIterator where, TArgs&&... args)
 	{
-		return Base::emplaceAt(m_alloc, where, std::forward<TArgs>(args)...);
+		return Base::emplaceAt(m_pool, where, std::forward<TArgs>(args)...);
 	}
 
 	/// @copydoc DynamicArray::erase
 	void erase(ConstIterator first, ConstIterator last)
 	{
-		return Base::erase(m_alloc, first, last);
+		return Base::erase(m_pool, first, last);
 	}
 
 	/// @copydoc DynamicArray::erase
 	void erase(ConstIterator at)
 	{
-		return Base::erase(m_alloc, at);
+		return Base::erase(m_pool, at);
 	}
 
 	/// @copydoc DynamicArray::moveAndReset
 	void moveAndReset(Value*& data, Size& size, Size& storageSize)
 	{
 		Base::moveAndReset(data, size, storageSize);
-		// Don't touch the m_alloc
+		// Don't touch the m_pool
 	}
 
 	/// @copydoc DynamicArray::moveAndReset
 	void moveAndReset(WeakArray<Value, Size>& array)
 	{
 		Base::moveAndReset(array);
-		// Don't touch the m_alloc
+		// Don't touch the m_pool
 	}
 
 	/// @copydoc DynamicArray::resizeStorage
 	void resizeStorage(Size newSize)
 	{
-		Base::resizeStorage(m_alloc, newSize);
+		Base::resizeStorage(m_pool, newSize);
 	}
 
-	/// Get the allocator.
-	const GenericMemoryPoolAllocator<T>& getAllocator() const
+	/// Get the pool.
+	const MemoryPool& getMemoryPool() const
 	{
-		return m_alloc;
+		return m_pool;
 	}
 
 private:
-	GenericMemoryPoolAllocator<T> m_alloc;
+	MemoryPool m_pool;
 };
 /// @}
 

+ 28 - 29
AnKi/Util/DynamicArray.inl.h

@@ -8,7 +8,8 @@
 namespace anki {
 
 template<typename T, typename TSize>
-DynamicArray<T, TSize>& DynamicArray<T, TSize>::operator=(DynamicArrayAuto<T, TSize>&& b)
+template<typename TMemPool>
+DynamicArray<T, TSize>& DynamicArray<T, TSize>::operator=(DynamicArrayRaii<T, TSize, TMemPool>&& b)
 {
 	ANKI_ASSERT(m_data == nullptr && m_size == 0 && "Cannot move before destroying");
 	T* data;
@@ -21,27 +22,26 @@ DynamicArray<T, TSize>& DynamicArray<T, TSize>::operator=(DynamicArrayAuto<T, TS
 }
 
 template<typename T, typename TSize>
-template<typename TAllocator>
-void DynamicArray<T, TSize>::resizeStorage(TAllocator alloc, Size newSize)
+template<typename TMemPool>
+void DynamicArray<T, TSize>::resizeStorage(TMemPool& pool, Size newSize)
 {
 	if(newSize > m_capacity)
 	{
 		// Need to grow
 
 		m_capacity = (newSize > Size(F64(m_capacity) * kGrowScale)) ? newSize : Size(F64(m_capacity) * kGrowScale);
-		Value* newStorage =
-			static_cast<Value*>(alloc.getMemoryPool().allocate(m_capacity * sizeof(Value), alignof(Value)));
+		Value* newStorage = static_cast<Value*>(pool.allocate(m_capacity * sizeof(Value), alignof(Value)));
 
 		// Move old elements to the new storage
 		if(m_data)
 		{
 			for(Size i = 0; i < m_size; ++i)
 			{
-				alloc.construct(&newStorage[i], std::move(m_data[i]));
+				callConstructor(newStorage[i], std::move(m_data[i]));
 				m_data[i].~T();
 			}
 
-			alloc.getMemoryPool().free(m_data);
+			pool.free(m_data);
 		}
 
 		m_data = newStorage;
@@ -67,21 +67,20 @@ void DynamicArray<T, TSize>::resizeStorage(TAllocator alloc, Size newSize)
 			m_capacity = newSize;
 			if(newSize)
 			{
-				Value* newStorage =
-					static_cast<Value*>(alloc.getMemoryPool().allocate(m_capacity * sizeof(Value), alignof(Value)));
+				Value* newStorage = static_cast<Value*>(pool.allocate(m_capacity * sizeof(Value), alignof(Value)));
 
 				for(Size i = 0; i < m_size; ++i)
 				{
-					alloc.construct(&newStorage[i], std::move(m_data[i]));
+					callConstructor(newStorage[i], std::move(m_data[i]));
 					m_data[i].~T();
 				}
 
-				alloc.getMemoryPool().free(m_data);
+				pool.free(m_data);
 				m_data = newStorage;
 			}
 			else
 			{
-				alloc.getMemoryPool().free(m_data);
+				pool.free(m_data);
 				m_data = nullptr;
 			}
 		}
@@ -89,18 +88,18 @@ void DynamicArray<T, TSize>::resizeStorage(TAllocator alloc, Size newSize)
 }
 
 template<typename T, typename TSize>
-template<typename TAllocator>
-void DynamicArray<T, TSize>::resize(TAllocator alloc, Size newSize, const Value& v)
+template<typename TMemPool>
+void DynamicArray<T, TSize>::resize(TMemPool& pool, Size newSize, const Value& v)
 {
 	const Bool willGrow = newSize > m_size;
-	resizeStorage(alloc, newSize);
+	resizeStorage(pool, newSize);
 
 	if(willGrow)
 	{
 		// Fill with new values
 		for(U i = m_size; i < newSize; ++i)
 		{
-			alloc.construct(&m_data[i], v);
+			callConstructor(m_data[i], v);
 		}
 
 		m_size = newSize;
@@ -111,18 +110,18 @@ void DynamicArray<T, TSize>::resize(TAllocator alloc, Size newSize, const Value&
 }
 
 template<typename T, typename TSize>
-template<typename TAllocator>
-void DynamicArray<T, TSize>::resize(TAllocator alloc, Size newSize)
+template<typename TMemPool>
+void DynamicArray<T, TSize>::resize(TMemPool& pool, Size newSize)
 {
 	const Bool willGrow = newSize > m_size;
-	resizeStorage(alloc, newSize);
+	resizeStorage(pool, newSize);
 
 	if(willGrow)
 	{
 		// Fill with new values
 		for(U i = m_size; i < newSize; ++i)
 		{
-			alloc.construct(&m_data[i]);
+			callConstructor(m_data[i]);
 		}
 
 		m_size = newSize;
@@ -133,8 +132,8 @@ void DynamicArray<T, TSize>::resize(TAllocator alloc, Size newSize)
 }
 
 template<typename T, typename TSize>
-template<typename TAllocator, typename... TArgs>
-typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TAllocator alloc, ConstIterator where,
+template<typename TMemPool, typename... TArgs>
+typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TMemPool& pool, ConstIterator where,
 																			TArgs&&... args)
 {
 	const Value* wherePtr = where;
@@ -155,7 +154,7 @@ typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TAll
 		ANKI_ASSERT(whereIdx >= 0u && whereIdx <= oldSize);
 
 		// Resize storage
-		resizeStorage(alloc, oldSize + 1u);
+		resizeStorage(pool, oldSize + 1u);
 
 		Size elementsToMoveRight = oldSize - whereIdx;
 		if(elementsToMoveRight == 0)
@@ -167,7 +166,7 @@ typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TAll
 		else
 		{
 			// Construct the last element because we will move to it
-			alloc.construct(&m_data[oldSize]);
+			callConstructor(m_data[oldSize]);
 
 			// Move the elements one place to the right
 			while(elementsToMoveRight--)
@@ -190,13 +189,13 @@ typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TAll
 
 		ANKI_ASSERT(isEmpty());
 
-		resizeStorage(alloc, 1);
+		resizeStorage(pool, 1);
 		outIdx = 0;
 	}
 
 	// Construct the new object
 	ANKI_ASSERT(outIdx != getMaxNumericLimit<Size>());
-	alloc.construct(&m_data[outIdx], std::forward<TArgs>(args)...);
+	callConstructor(m_data[outIdx], std::forward<TArgs>(args)...);
 
 	// Increase the size because resizeStorage will not
 	++m_size;
@@ -205,8 +204,8 @@ typename DynamicArray<T, TSize>::Iterator DynamicArray<T, TSize>::emplaceAt(TAll
 }
 
 template<typename T, typename TSize>
-template<typename TAllocator>
-void DynamicArray<T, TSize>::erase(TAllocator alloc, ConstIterator first, ConstIterator last)
+template<typename TMemPool>
+void DynamicArray<T, TSize>::erase(TMemPool& pool, ConstIterator first, ConstIterator last)
 {
 	ANKI_ASSERT(first != last);
 	ANKI_ASSERT(m_data);
@@ -224,7 +223,7 @@ void DynamicArray<T, TSize>::erase(TAllocator alloc, ConstIterator first, ConstI
 
 	// Resize storage
 	const Size newSize = m_size - Size(last - first);
-	resizeStorage(alloc, newSize);
+	resizeStorage(pool, newSize);
 }
 
 } // end namespace anki

+ 3 - 3
AnKi/Util/File.cpp

@@ -460,14 +460,14 @@ FileOpenFlag File::getMachineEndianness()
 	}
 }
 
-Error File::readAllText(GenericMemoryPoolAllocator<U8> alloc, String& out)
+Error File::readAllText(BaseMemoryPool& pool, String& out)
 {
 	Error err = Error::kNone;
 	PtrSize size = getSize();
 
 	if(size != 0)
 	{
-		out.create(alloc, '?', size);
+		out.create(pool, '?', size);
 		err = read(&out[0], size);
 	}
 	else
@@ -478,7 +478,7 @@ Error File::readAllText(GenericMemoryPoolAllocator<U8> alloc, String& out)
 	return err;
 }
 
-Error File::readAllText(StringAuto& out)
+Error File::readAllText(StringRaii& out)
 {
 	Error err = Error::kNone;
 	PtrSize size = getSize();

+ 2 - 2
AnKi/Util/File.h

@@ -87,10 +87,10 @@ public:
 
 	/// Read all the contents of a text file
 	/// If the file is not rewined it will probably fail
-	Error readAllText(GenericMemoryPoolAllocator<U8> alloc, String& out);
+	Error readAllText(BaseMemoryPool& pool, String& out);
 
 	/// Read all the contents of a text file. If the file is not rewined it will probably fail.
-	Error readAllText(StringAuto& out);
+	Error readAllText(StringRaii& out);
 
 	/// Read 32bit unsigned integer. Set the endianness if the file's endianness is different from the machine's.
 	Error readU32(U32& u);

+ 3 - 3
AnKi/Util/Filesystem.cpp

@@ -7,7 +7,7 @@
 
 namespace anki {
 
-void getFilepathExtension(const CString& filename, StringAuto& out)
+void getFilepathExtension(const CString& filename, StringRaii& out)
 {
 	const Char* pc = std::strrchr(filename.cstr(), '.');
 
@@ -25,7 +25,7 @@ void getFilepathExtension(const CString& filename, StringAuto& out)
 	}
 }
 
-void getFilepathFilename(const CString& filename, StringAuto& out)
+void getFilepathFilename(const CString& filename, StringRaii& out)
 {
 	const Char* pc1 = std::strrchr(filename.cstr(), '/');
 #if ANKI_OS_WINDOWS
@@ -49,7 +49,7 @@ void getFilepathFilename(const CString& filename, StringAuto& out)
 	}
 }
 
-void getParentFilepath(const CString& filename, StringAuto& out)
+void getParentFilepath(const CString& filename, StringRaii& out)
 {
 	const Char* pc1 = std::strrchr(filename.cstr(), '/');
 #if ANKI_OS_WINDOWS

+ 14 - 14
AnKi/Util/Filesystem.h

@@ -17,15 +17,15 @@ namespace anki {
 Bool fileExists(const CString& filename);
 
 /// Get path extension.
-void getFilepathExtension(const CString& filename, StringAuto& out);
+void getFilepathExtension(const CString& filename, StringRaii& out);
 
 /// Get path filename.
 /// On path/to/file.ext return file.ext
-void getFilepathFilename(const CString& filename, StringAuto& out);
+void getFilepathFilename(const CString& filename, StringRaii& out);
 
 /// Get base path.
 /// On path/to/file.ext return path/to
-void getParentFilepath(const CString& filename, StringAuto& out);
+void getParentFilepath(const CString& filename, StringRaii& out);
 
 /// Return true if directory exists?
 Bool directoryExists(const CString& dir);
@@ -35,28 +35,28 @@ Error walkDirectoryTreeInternal(const CString& dir, const Function<Error(const C
 
 /// Walk a directory tree.
 /// @param dir The dir to walk.
-/// @param alloc An allocator for temp allocations.
+/// @param pool A mem pool for temp allocations.
 /// @param func A lambda. See code example on how to use it.
 /// Example:
 /// @code
-/// walkDirectoryTree("./path/to", alloc, [&, this](CString path, Bool isDir) {
+/// walkDirectoryTree("./path/to", pool, [&, this](CString path, Bool isDir) {
 /// 	...
 /// 	return Error::kNone;
 /// });
 /// @endcode
-template<typename TFunc>
-Error walkDirectoryTree(const CString& dir, GenericMemoryPoolAllocator<U8> alloc, TFunc func)
+template<typename TMemPool, typename TFunc>
+Error walkDirectoryTree(const CString& dir, TMemPool& pool, TFunc func)
 {
-	Function<Error(const CString&, Bool)> f(alloc, func);
+	Function<Error(const CString&, Bool)> f(pool, func);
 	const Error err = walkDirectoryTreeInternal(dir, f);
-	f.destroy(alloc);
+	f.destroy(pool);
 	return err;
 }
 
 /// Equivalent to: rm -rf dir
 /// @param dir The directory to remove.
-/// @param alloc A temp allocator that this function requires.
-Error removeDirectory(const CString& dir, GenericMemoryPoolAllocator<U8> alloc);
+/// @param pool A temp mem pool that this function requires.
+Error removeDirectory(const CString& dir, BaseMemoryPool& pool);
 
 /// Remove a file.
 Error removeFile(const CString& filename);
@@ -65,16 +65,16 @@ Error removeFile(const CString& filename);
 Error createDirectory(const CString& dir);
 
 /// Get the home directory.
-Error getHomeDirectory(StringAuto& out);
+Error getHomeDirectory(StringRaii& out);
 
 /// Get the temp directory.
-Error getTempDirectory(StringAuto& out);
+Error getTempDirectory(StringRaii& out);
 
 /// Get the time the file was last modified.
 Error getFileModificationTime(CString filename, U32& year, U32& month, U32& day, U32& hour, U32& min, U32& second);
 
 /// Get the path+filename of the currently running executable.
-Error getApplicationPath(StringAuto& path);
+Error getApplicationPath(StringRaii& path);
 /// @}
 
 } // end namespace anki

+ 9 - 9
AnKi/Util/FilesystemPosix.cpp

@@ -134,7 +134,7 @@ Error walkDirectoryTreeInternal(const CString& dir, const Function<Error(const C
 	return err;
 }
 
-static Error removeDirectoryInternal(const CString& dirname, GenericMemoryPoolAllocator<U8>& alloc)
+static Error removeDirectoryInternal(const CString& dirname, BaseMemoryPool& pool)
 {
 	DIR* dir;
 	struct dirent* entry;
@@ -150,12 +150,12 @@ static Error removeDirectoryInternal(const CString& dirname, GenericMemoryPoolAl
 	{
 		if(strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
 		{
-			StringAuto path(alloc);
+			StringRaii path(&pool);
 			path.sprintf("%s/%s", dirname.cstr(), entry->d_name);
 
 			if(entry->d_type == DT_DIR)
 			{
-				Error err = removeDirectoryInternal(path.toCString(), alloc);
+				Error err = removeDirectoryInternal(path.toCString(), pool);
 				if(err)
 				{
 					return err;
@@ -174,9 +174,9 @@ static Error removeDirectoryInternal(const CString& dirname, GenericMemoryPoolAl
 	return Error::kNone;
 }
 
-Error removeDirectory(const CString& dirname, GenericMemoryPoolAllocator<U8> alloc)
+Error removeDirectory(const CString& dirname, BaseMemoryPool& pool)
 {
-	return removeDirectoryInternal(dirname, alloc);
+	return removeDirectoryInternal(dirname, pool);
 }
 
 Error createDirectory(const CString& dir)
@@ -196,7 +196,7 @@ Error createDirectory(const CString& dir)
 	return err;
 }
 
-Error getHomeDirectory(StringAuto& out)
+Error getHomeDirectory(StringRaii& out)
 {
 #if ANKI_OS_LINUX
 	const char* home = getenv("HOME");
@@ -214,7 +214,7 @@ Error getHomeDirectory(StringAuto& out)
 	return Error::kNone;
 }
 
-Error getTempDirectory(StringAuto& out)
+Error getTempDirectory(StringRaii& out)
 {
 #if ANKI_OS_LINUX
 	out.create("/tmp/");
@@ -245,13 +245,13 @@ Error getFileModificationTime(CString filename, U32& year, U32& month, U32& day,
 	return Error::kNone;
 }
 
-Error getApplicationPath(StringAuto& out)
+Error getApplicationPath(StringRaii& out)
 {
 #if ANKI_OS_ANDROID
 	ANKI_ASSERT(0 && "getApplicationPath() doesn't work on Android");
 	(void)out;
 #else
-	DynamicArrayAuto<Char> buff(out.getAllocator(), 1024);
+	DynamicArrayRaii<Char> buff(&out.getMemoryPool(), 1024);
 
 	const ssize_t result = readlink("/proc/self/exe", &buff[0], buff.getSize());
 	if(result < 0)

+ 4 - 4
AnKi/Util/FilesystemWindows.cpp

@@ -65,7 +65,7 @@ Error createDirectory(const CString& dir)
 	return err;
 }
 
-Error getHomeDirectory(StringAuto& out)
+Error getHomeDirectory(StringRaii& out)
 {
 	char path[MAX_PATH];
 	if(SHGetFolderPathA(NULL, CSIDL_PROFILE, nullptr, 0, path) != S_OK)
@@ -78,7 +78,7 @@ Error getHomeDirectory(StringAuto& out)
 	return Error::kNone;
 }
 
-Error getTempDirectory(StringAuto& out)
+Error getTempDirectory(StringRaii& out)
 {
 	char path[MAX_PATH + 1];
 
@@ -197,9 +197,9 @@ Error walkDirectoryTreeInternal(const CString& dir, const Function<Error(const C
 	return walkDirectoryTreeRecursive(dir, callback, baseDirLen);
 }
 
-Error getApplicationPath(StringAuto& out)
+Error getApplicationPath(StringRaii& out)
 {
-	DynamicArrayAuto<Char> buff(out.getAllocator(), 1024);
+	DynamicArrayRaii<Char> buff(out.getAllocator(), 1024);
 
 	const DWORD result = GetModuleFileNameA(nullptr, &buff[0], buff.getSize());
 	DWORD lastError = GetLastError();

+ 10 - 8
AnKi/Util/Forward.h

@@ -11,7 +11,7 @@
 
 namespace anki {
 
-template<U32 N, typename TChunkType>
+template<U32 kBitCount, typename TChunkType>
 class BitSet;
 
 template<typename T>
@@ -23,22 +23,24 @@ class HashMap;
 template<typename T>
 class Hierarchy;
 
-template<typename T>
+template<typename>
 class List;
 
-template<typename T>
-class ListAuto;
+template<typename, typename>
+class ListRaii;
 
 template<typename T, typename TConfig>
 class SparseArray;
 
 class CString;
 class String;
-class StringAuto;
+
+template<typename>
+class BaseStringRaii;
 
 class ThreadHive;
 
-template<typename T, PtrSize kPreallocatedStorage = ANKI_SAFE_ALIGNMENT>
+template<typename, PtrSize kPreallocatedStorage = ANKI_SAFE_ALIGNMENT>
 class Function;
 
 template<typename, PtrSize>
@@ -53,8 +55,8 @@ class ConstWeakArray;
 template<typename T, typename TSize = U32>
 class DynamicArray;
 
-template<typename T, typename TSize = U32>
-class DynamicArrayAuto;
+template<typename, typename, typename>
+class DynamicArrayRaii;
 
 class F16;
 

+ 15 - 15
AnKi/Util/Function.h

@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include <AnKi/Util/Allocator.h>
+#include <AnKi/Util/CpuMemoryPools.h>
 #include <AnKi/Util/Forward.h>
 #include <AnKi/Util/Array.h>
 
@@ -18,7 +18,7 @@ namespace anki {
 /// allocations. Can be used like:
 /// @code
 /// Function<Error(U32, F32), 16> func;
-/// func.init(allocator, [&someInt](U32 u, F32 f) {someInt = xxx + u + f; return Error::kNone;});
+/// func.init(pool, [&someInt](U32 u, F32 f) {someInt = xxx + u + f; return Error::kNone;});
 /// func.call(10, 1.2f);
 /// @endcode
 /// @tparam kTInlineStorageSize Optional inline storage to avoid deallocations (small object optimization)
@@ -38,10 +38,10 @@ public:
 	Function(const Function&) = delete;
 
 	/// Same as init().
-	template<typename TAlloc, typename T>
-	Function(TAlloc alloc, const T& func)
+	template<typename TMemPool, typename T>
+	Function(TMemPool& pool, const T& func)
 	{
-		init(alloc, func);
+		init(pool, func);
 	}
 
 	// Does nothing important.
@@ -64,10 +64,10 @@ public:
 	}
 
 	/// Initialize the function.
-	/// @param alloc The allocator (it might be used).
+	/// @param pool The memory pool (it might be used).
 	/// @param func The lambda.
-	template<typename TAlloc, typename T>
-	void init(TAlloc alloc, const T& func)
+	template<typename TMemPool, typename T>
+	void init(TMemPool& pool, const T& func)
 	{
 		ANKI_ASSERT(getState() == kStateUninitialized);
 
@@ -91,7 +91,7 @@ public:
 		{
 			setState(kStateAllocated);
 			using CallableT = Callable<T>;
-			CallableT* callable = alloc.template newInstance<CallableT>(func);
+			CallableT* callable = newInstance<CallableT>(pool, func);
 			m_callablePtr = callable;
 
 			callable->m_size = sizeof(CallableT);
@@ -112,14 +112,14 @@ public:
 	}
 
 	/// Destroy the object.
-	template<typename TAlloc>
-	void destroy(TAlloc alloc)
+	template<typename TMemPool>
+	void destroy(TMemPool& pool)
 	{
 		if(getState() == kStateAllocated)
 		{
 			ANKI_ASSERT(m_callablePtr && m_callablePtr->m_destroyCallback);
 			m_callablePtr->m_destroyCallback(*m_callablePtr);
-			alloc.getMemoryPool().free(m_callablePtr);
+			pool.free(m_callablePtr);
 		}
 
 		m_state = kStateUninitialized;
@@ -138,8 +138,8 @@ public:
 	}
 
 	/// Copy from another.
-	template<typename TAlloc>
-	Function& copy(const Function& other, TAlloc alloc)
+	template<typename TMemPool>
+	Function& copy(const Function& other, TMemPool& pool)
 	{
 		ANKI_ASSERT(getState() == kStateUninitialized && "Need to destroy it first");
 
@@ -161,7 +161,7 @@ public:
 			// Allocate callable
 			ANKI_ASSERT(other.m_callablePtr && other.m_callablePtr->m_alignment > 0 && other.m_callablePtr->m_size > 0);
 			m_callablePtr = static_cast<CallableBase*>(
-				alloc.getMemoryPool().allocate(other.m_callablePtr->m_size, other.m_callablePtr->m_alignment));
+				pool.allocate(other.m_callablePtr->m_size, other.m_callablePtr->m_alignment));
 
 			// Copy
 			other.m_callablePtr->m_copyCallback(*other.m_callablePtr, *m_callablePtr);

+ 7 - 7
AnKi/Util/Functions.h

@@ -383,10 +383,10 @@ void callDestructor(T& p)
 template<typename T, typename TMemPool, typename... TArgs>
 [[nodiscard]] T* newInstance(TMemPool& pool, TArgs&&... args)
 {
-	T* ptr = pool.allocate(sizeof(T), alignof(T));
+	T* ptr = static_cast<T*>(pool.allocate(sizeof(T), alignof(T)));
 	if(ANKI_LIKELY(ptr))
 	{
-		callConstructor(ptr, std::forward<TArgs>(args)...);
+		callConstructor(*ptr, std::forward<TArgs>(args)...);
 	}
 
 	return ptr;
@@ -396,12 +396,12 @@ template<typename T, typename TMemPool, typename... TArgs>
 template<typename T, typename TMemPool>
 [[nodiscard]] T* newArray(TMemPool& pool, PtrSize n)
 {
-	T* ptr = pool.allocate(n * sizeof(T), alignof(T));
+	T* ptr = static_cast<T*>(pool.allocate(n * sizeof(T), alignof(T)));
 	if(ANKI_LIKELY(ptr))
 	{
 		for(PtrSize i = 0; i < n; i++)
 		{
-			callConstructor(&ptr[i]);
+			callConstructor(ptr[i]);
 		}
 	}
 
@@ -412,12 +412,12 @@ template<typename T, typename TMemPool>
 template<typename T, typename TMemPool>
 [[nodiscard]] T* newArray(TMemPool& pool, PtrSize n, const T& copy)
 {
-	T* ptr = pool.allocate(n * sizeof(T), alignof(T));
+	T* ptr = static_cast<T*>(pool.allocate(n * sizeof(T), alignof(T)));
 	if(ANKI_LIKELY(ptr))
 	{
 		for(PtrSize i = 0; i < n; i++)
 		{
-			callConstructor(&ptr[i], copy);
+			callConstructor(ptr[i], copy);
 		}
 	}
 
@@ -440,7 +440,7 @@ void deleteInstance(TMemPool& pool, T* ptr)
 {
 	if(ANKI_LIKELY(ptr != nullptr))
 	{
-		callDestructor(&ptr);
+		callDestructor(ptr);
 		pool.free(ptr);
 	}
 }

+ 6 - 5
AnKi/Util/INotify.h

@@ -24,17 +24,18 @@ public:
 	~INotify()
 	{
 		destroyInternal();
-		m_path.destroy(m_alloc);
+		m_path.destroy(*m_pool);
 	}
 
 	// Non-copyable
 	INotify& operator=(const INotify&) = delete;
 
 	/// @param path Path to file or directory.
-	Error init(GenericMemoryPoolAllocator<U8> alloc, CString path)
+	Error init(BaseMemoryPool* pool, CString path)
 	{
-		m_alloc = alloc;
-		m_path.create(alloc, path);
+		ANKI_ASSERT(pool);
+		m_pool = pool;
+		m_path.create(*m_pool, path);
 		return initInternal();
 	}
 
@@ -42,7 +43,7 @@ public:
 	Error pollEvents(Bool& modified);
 
 private:
-	GenericMemoryPoolAllocator<U8> m_alloc;
+	BaseMemoryPool* m_pool = nullptr;
 	String m_path;
 #if ANKI_POSIX
 	int m_fd = -1;

+ 52 - 51
AnKi/Util/List.h

@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include <AnKi/Util/Allocator.h>
+#include <AnKi/Util/CpuMemoryPools.h>
 #include <AnKi/Util/Forward.h>
 #include <functional>
 
@@ -393,91 +393,91 @@ public:
 	}
 
 	/// Destroy the list.
-	template<typename TAllocator>
-	void destroy(TAllocator alloc);
+	template<typename TMemPool>
+	void destroy(TMemPool& pool);
 
 	/// Copy an element at the end of the list.
-	template<typename TAllocator>
-	Iterator pushBack(TAllocator alloc, const T& x)
+	template<typename TMemPool>
+	Iterator pushBack(TMemPool& pool, const T& x)
 	{
-		Node* node = alloc.template newInstance<Node>(x);
+		Node* node = newInstance<Node>(pool, x);
 		Base::pushBackNode(node);
 		return Iterator(node, this);
 	}
 
 	/// Construct an element at the end of the list.
-	template<typename TAllocator, typename... TArgs>
-	Iterator emplaceBack(TAllocator alloc, TArgs&&... args)
+	template<typename TMemPool, typename... TArgs>
+	Iterator emplaceBack(TMemPool& pool, TArgs&&... args)
 	{
-		Node* node = alloc.template newInstance<Node>(std::forward<TArgs>(args)...);
+		Node* node = newInstance<Node>(pool, std::forward<TArgs>(args)...);
 		Base::pushBackNode(node);
 		return Iterator(node, this);
 	}
 
 	/// Copy an element at the beginning of the list.
-	template<typename TAllocator>
-	Iterator pushFront(TAllocator alloc, const T& x)
+	template<typename TMemPool>
+	Iterator pushFront(TMemPool& pool, const T& x)
 	{
-		Node* node = alloc.template newInstance<Node>(x);
+		Node* node = newInstance<Node>(pool, x);
 		Base::pushFrontNode(node);
 		return Iterator(node, this);
 	}
 
 	/// Construct element at the beginning of the list.
-	template<typename TAllocator, typename... TArgs>
-	Iterator emplaceFront(TAllocator alloc, TArgs&&... args)
+	template<typename TMemPool, typename... TArgs>
+	Iterator emplaceFront(TMemPool& pool, TArgs&&... args)
 	{
-		Node* node = alloc.template newInstance<Node>(std::forward<TArgs>(args)...);
+		Node* node = newInstance<Node>(pool, std::forward<TArgs>(args)...);
 		Base::pushFrontNode(node);
 		return Iterator(node, this);
 	}
 
 	/// Copy an element at the given position of the list.
-	template<typename TAllocator>
-	Iterator insert(TAllocator alloc, Iterator pos, const T& x)
+	template<typename TMemPool>
+	Iterator insert(TMemPool& pool, Iterator pos, const T& x)
 	{
-		Node* node = alloc.template newInstance<Node>(x);
+		Node* node = newInstance<Node>(pool, x);
 		Base::insertNode(pos.m_node, node);
 		return Iterator(node, this);
 	}
 
 	/// Construct element at the the given position.
-	template<typename TAllocator, typename... TArgs>
-	Iterator emplace(TAllocator alloc, Iterator pos, TArgs&&... args)
+	template<typename TMemPool, typename... TArgs>
+	Iterator emplace(TMemPool& pool, Iterator pos, TArgs&&... args)
 	{
-		Node* node = alloc.template newInstance<Node>(std::forward<TArgs>(args)...);
+		Node* node = newInstance<Node>(pool, std::forward<TArgs>(args)...);
 		Base::insertNode(pos.m_node, node);
 		return Iterator(node, this);
 	}
 
 	/// Pop a value from the back of the list.
-	template<typename TAllocator>
-	void popBack(TAllocator alloc)
+	template<typename TMemPool>
+	void popBack(TMemPool& pool)
 	{
 		ANKI_ASSERT(Base::m_tail);
 		Node* node = Base::m_tail;
 		Base::popBack();
-		alloc.deleteInstance(node);
+		deleteInstance(pool, node);
 	}
 
 	/// Pop a value from the front of the list.
-	template<typename TAllocator>
-	void popFront(TAllocator alloc)
+	template<typename TMemPool>
+	void popFront(TMemPool& pool)
 	{
 		ANKI_ASSERT(Base::m_head);
 		Node* node = Base::m_head;
 		Base::popFront();
-		alloc.deleteInstance(node);
+		deleteInstance(pool, node);
 	}
 
 	/// Erase an element.
-	template<typename TAllocator>
-	void erase(TAllocator alloc, Iterator pos)
+	template<typename TMemPool>
+	void erase(TMemPool& pool, Iterator pos)
 	{
 		ANKI_ASSERT(pos.m_node);
 		ANKI_ASSERT(pos.m_list == this);
 		Base::removeNode(pos.m_node);
-		alloc.deleteInstance(pos.m_node);
+		deleteInstance(pool, pos.m_node);
 	}
 
 private:
@@ -489,36 +489,37 @@ private:
 };
 
 /// List with automatic destruction.
-template<typename T>
-class ListAuto : public List<T>
+template<typename T, typename TMemPool = MemoryPoolPtrWrapper<BaseMemoryPool>>
+class ListRaii : public List<T>
 {
 public:
 	using Base = List<T>;
 	using Value = T;
 	using typename Base::Iterator;
+	using MemoryPool = TMemPool;
 
-	/// Construct using an allocator.
-	ListAuto(GenericMemoryPoolAllocator<T> alloc)
+	/// Construct using a mem pool.
+	ListRaii(const MemoryPool& pool)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 	}
 
 	/// Move.
-	ListAuto(ListAuto&& b)
+	ListRaii(ListRaii&& b)
 		: Base()
 	{
 		move(b);
 	}
 
 	/// Destroy.
-	~ListAuto()
+	~ListRaii()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Move.
-	ListAuto& operator=(ListAuto&& b)
+	ListRaii& operator=(ListRaii&& b)
 	{
 		move(b);
 		return *this;
@@ -527,61 +528,61 @@ public:
 	/// Copy an element at the end of the list.
 	Iterator pushBack(const Value& x)
 	{
-		return Base::pushBack(m_alloc, x);
+		return Base::pushBack(m_pool, x);
 	}
 
 	/// Construct an element at the end of the list.
 	template<typename... TArgs>
 	Iterator emplaceBack(TArgs&&... args)
 	{
-		return Base::emplaceBack(m_alloc, std::forward<TArgs>(args)...);
+		return Base::emplaceBack(m_pool, std::forward<TArgs>(args)...);
 	}
 
 	/// Construct element at the beginning of the list.
 	template<typename... TArgs>
 	Iterator emplaceFront(TArgs&&... args)
 	{
-		return Base::emplaceFront(m_alloc, std::forward<TArgs>(args)...);
+		return Base::emplaceFront(m_pool, std::forward<TArgs>(args)...);
 	}
 
 	/// Construct element at the the given position.
 	template<typename... TArgs>
 	Iterator emplace(Iterator pos, TArgs&&... args)
 	{
-		return Base::emplace(m_alloc, pos, std::forward(args)...);
+		return Base::emplace(m_pool, pos, std::forward(args)...);
 	}
 
 	/// Pop a value from the back of the list.
 	void popBack()
 	{
-		Base::popBack(m_alloc);
+		Base::popBack(m_pool);
 	}
 
 	/// Pop a value from the front of the list.
 	void popFront()
 	{
-		Base::popFront(m_alloc);
+		Base::popFront(m_pool);
 	}
 
 	/// Erase an element.
 	void erase(Iterator position)
 	{
-		Base::erase(m_alloc, position);
+		Base::erase(m_pool, position);
 	}
 
 	/// Destroy the list.
 	void destroy()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 private:
-	GenericMemoryPoolAllocator<T> m_alloc;
+	MemoryPool m_pool;
 
-	void move(ListAuto& b)
+	void move(ListRaii& b)
 	{
 		Base::move(b);
-		m_alloc = b.m_alloc;
+		m_pool = std::move(b.m_alloc);
 	}
 };
 
@@ -651,7 +652,7 @@ public:
 } // end namespace detail
 
 /// List that doesn't perform any allocations. To work the T nodes will have to inherit from IntrusiveListEnabled or
-/// have 2 member variables `m_next` and `m_prev`.
+/// have 2 member functions and their const versions. The 2 functions are getPreviousListNode() and getNextListNode().
 template<typename T>
 class IntrusiveList : public detail::ListBase<T, T>
 {

+ 3 - 3
AnKi/Util/List.inl.h

@@ -314,14 +314,14 @@ void ListBase<T, TNode>::popFront()
 } // end namespace detail
 
 template<typename T>
-template<typename TAllocator>
-void List<T>::destroy(TAllocator alloc)
+template<typename TMemPool>
+void List<T>::destroy(TMemPool& pool)
 {
 	Node* el = Base::m_head;
 	while(el)
 	{
 		Node* next = el->m_next;
-		alloc.deleteInstance(el);
+		deleteInstance(pool, el);
 		el = next;
 	}
 

+ 3 - 3
AnKi/Util/Process.cpp

@@ -184,7 +184,7 @@ Error Process::kill(ProcessKillSignal k)
 	return Error::kNone;
 }
 
-Error Process::readFromStdout(StringAuto& text)
+Error Process::readFromStdout(StringRaii& text)
 {
 #if !ANKI_OS_ANDROID
 	return readCommon(REPROC_STREAM_OUT, text);
@@ -193,7 +193,7 @@ Error Process::readFromStdout(StringAuto& text)
 #endif
 }
 
-Error Process::readFromStderr(StringAuto& text)
+Error Process::readFromStderr(StringRaii& text)
 {
 #if !ANKI_OS_ANDROID
 	return readCommon(REPROC_STREAM_ERR, text);
@@ -203,7 +203,7 @@ Error Process::readFromStderr(StringAuto& text)
 }
 
 #if !ANKI_OS_ANDROID
-Error Process::readCommon(I32 reprocStream, StringAuto& text)
+Error Process::readCommon(I32 reprocStream, StringRaii& text)
 {
 	ANKI_ASSERT(m_handle);
 

+ 3 - 3
AnKi/Util/Process.h

@@ -62,10 +62,10 @@ public:
 	Error kill(ProcessKillSignal k);
 
 	/// Read from stdout.
-	Error readFromStdout(StringAuto& text);
+	Error readFromStdout(StringRaii& text);
 
 	/// Read from stderr.
-	Error readFromStderr(StringAuto& text);
+	Error readFromStderr(StringRaii& text);
 
 	/// Cleanup a finished process. Call this if you want to start a new process again. Need to have waited before
 	/// calling destroy.
@@ -74,7 +74,7 @@ public:
 private:
 	reproc_t* m_handle = nullptr;
 
-	Error readCommon(I32 reprocStream, StringAuto& text);
+	Error readCommon(I32 reprocStream, StringRaii& text);
 };
 /// @}
 

+ 1 - 1
AnKi/Util/SegregatedListsAllocatorBuilder.h

@@ -89,7 +89,7 @@ public:
 	Error validate() const;
 
 	/// Print debug info.
-	void printFreeBlocks(StringListAuto& strList) const;
+	void printFreeBlocks(StringListRaii& strList) const;
 
 	/// It's 1-(largestBlockOfFreeMemory/totalFreeMemory). 0.0 is no fragmentation, 1.0 is totally fragmented.
 	[[nodiscard]] F32 computeExternalFragmentation(PtrSize baseSize = 1) const;

+ 1 - 1
AnKi/Util/SegregatedListsAllocatorBuilder.inl.h

@@ -514,7 +514,7 @@ Error SegregatedListsAllocatorBuilder<TChunk, TInterface, TLock>::validate() con
 }
 
 template<typename TChunk, typename TInterface, typename TLock>
-void SegregatedListsAllocatorBuilder<TChunk, TInterface, TLock>::printFreeBlocks(StringListAuto& strList) const
+void SegregatedListsAllocatorBuilder<TChunk, TInterface, TLock>::printFreeBlocks(StringListRaii& strList) const
 {
 	LockGuard<TLock> lock(m_lock);
 

+ 1 - 1
AnKi/Util/Serializer.cpp

@@ -29,7 +29,7 @@ Error BinarySerializer::doDynamicArrayBasicType(const void* arr, PtrSize size, U
 		PointerInfo pinfo;
 		pinfo.m_filePos = structFilePos + memberOffset;
 		pinfo.m_value = arrayFilePos - m_beginOfDataFilePos;
-		m_pointerFilePositions.emplaceBack(m_alloc, pinfo);
+		m_pointerFilePositions.emplaceBack(*m_pool, pinfo);
 
 		// Write the array
 		ANKI_CHECK(m_file->seek(arrayFilePos, FileSeekOrigin::BEGINNING));

+ 7 - 7
AnKi/Util/Serializer.h

@@ -84,12 +84,12 @@ public:
 
 	/// Serialize a class.
 	/// @param x What to serialize.
-	/// @param tmpAllocator A temp allocator for some memory needed.
+	/// @param tmpPool A temp mem pool for some memory needed.
 	/// @param file The file to populate.
 	template<typename T>
-	Error serialize(const T& x, GenericMemoryPoolAllocator<U8> tmpAllocator, File& file)
+	Error serialize(const T& x, BaseMemoryPool& tmpPool, File& file)
 	{
-		const Error err = serializeInternal(x, tmpAllocator, file);
+		const Error err = serializeInternal(x, tmpPool, file);
 		if(err)
 		{
 			ANKI_UTIL_LOGE("There was a serialization error");
@@ -160,7 +160,7 @@ private:
 	File* m_file = nullptr;
 	PtrSize m_eofPos; ///< A logical end of the file. Used for allocations.
 	PtrSize m_beginOfDataFilePos; ///< Where the data are located in the file.
-	GenericMemoryPoolAllocator<U8> m_alloc;
+	BaseMemoryPool* m_pool = nullptr;
 	DynamicArray<PointerInfo> m_pointerFilePositions; ///< Array of file positions that contain pointers.
 	DynamicArray<PtrSize> m_structureFilePos;
 	Error m_err = Error::kNone;
@@ -174,7 +174,7 @@ private:
 	Error doDynamicArrayBasicType(const void* arr, PtrSize size, U32 alignment, PtrSize memberOffset);
 
 	template<typename T>
-	Error serializeInternal(const T& x, GenericMemoryPoolAllocator<U8> tmpAllocator, File& file);
+	Error serializeInternal(const T& x, BaseMemoryPool& tmpPool, File& file);
 
 	void check()
 	{
@@ -202,10 +202,10 @@ public:
 
 	/// Serialize a class.
 	/// @param x The struct to read.
-	/// @param allocator The allocator to use to allocate the new structures.
+	/// @param pool The memory pool to use to allocate the new structures.
 	/// @param file The file to read from.
 	template<typename T, typename TFile>
-	static Error deserialize(T*& x, GenericMemoryPoolAllocator<U8> allocator, TFile& file);
+	static Error deserialize(T*& x, BaseMemoryPool& pool, TFile& file);
 
 	/// Read a single value. Can't call this directly.
 	template<typename T>

+ 14 - 15
AnKi/Util/Serializer.inl.h

@@ -23,7 +23,7 @@ inline constexpr const char* kBinarySerializerMagic = "ANKIBIN1";
 } // end namespace detail
 
 template<typename T>
-Error BinarySerializer::serializeInternal(const T& x, GenericMemoryPoolAllocator<U8> tmpAllocator, File& file)
+Error BinarySerializer::serializeInternal(const T& x, BaseMemoryPool& tmpPool, File& file)
 {
 	checkStruct<T>();
 
@@ -32,7 +32,7 @@ Error BinarySerializer::serializeInternal(const T& x, GenericMemoryPoolAllocator
 	ANKI_ASSERT(m_file->tell() == 0);
 
 	m_err = Error::kNone;
-	m_alloc = std::move(tmpAllocator);
+	m_pool = &tmpPool;
 
 	// Write the empty header (will be filled later)
 	detail::BinarySerializerHeader header = {};
@@ -47,16 +47,16 @@ Error BinarySerializer::serializeInternal(const T& x, GenericMemoryPoolAllocator
 
 	// Finaly, serialize
 	ANKI_CHECK(m_file->write(&x, sizeof(T)));
-	m_structureFilePos.emplaceBack(m_alloc, dataFilePos);
+	m_structureFilePos.emplaceBack(tmpPool, dataFilePos);
 	doValue("root", 0, x);
-	m_structureFilePos.popBack(m_alloc);
+	m_structureFilePos.popBack(tmpPool);
 	if(m_err)
 	{
 		return m_err;
 	}
 
 	// Write all pointers. Do that now and not while writing the actual shader in order to avoid the file seeks
-	DynamicArrayAuto<PtrSize> pointerFilePositions(m_alloc);
+	DynamicArrayRaii<PtrSize> pointerFilePositions(tmpPool);
 	for(const PointerInfo& pointer : m_pointerFilePositions)
 	{
 		ANKI_CHECK(m_file->seek(pointer.m_filePos, FileSeekOrigin::BEGINNING));
@@ -84,8 +84,8 @@ Error BinarySerializer::serializeInternal(const T& x, GenericMemoryPoolAllocator
 
 	// Done
 	m_file = nullptr;
-	m_pointerFilePositions.destroy(m_alloc);
-	m_alloc = GenericMemoryPoolAllocator<U8>();
+	m_pointerFilePositions.destroy(tmpPool);
+	m_pool = nullptr;
 	return Error::kNone;
 }
 
@@ -100,14 +100,14 @@ Error BinarySerializer::doArrayComplexType(const T* arr, PtrSize size, PtrSize m
 	PtrSize structFilePos = m_structureFilePos.getBack() + memberOffset;
 	for(PtrSize i = 0; i < size; ++i)
 	{
-		m_structureFilePos.emplaceBack(m_alloc, structFilePos);
+		m_structureFilePos.emplaceBack(*m_pool, structFilePos);
 
 		// Serialize the pointers
 		SerializeFunctor<T>()(arr[i], *this);
 		ANKI_CHECK(m_err);
 
 		// Advance file pos
-		m_structureFilePos.popBack(m_alloc);
+		m_structureFilePos.popBack(*m_pool);
 		structFilePos += sizeof(T);
 	}
 
@@ -139,7 +139,7 @@ Error BinarySerializer::doDynamicArrayComplexType(const T* arr, PtrSize size, Pt
 		PointerInfo pinfo;
 		pinfo.m_filePos = structFilePos + memberOffset;
 		pinfo.m_value = arrayFilePos - m_beginOfDataFilePos;
-		m_pointerFilePositions.emplaceBack(m_alloc, pinfo);
+		m_pointerFilePositions.emplaceBack(*m_pool, pinfo);
 
 		// Write the structures
 		ANKI_CHECK(m_file->seek(arrayFilePos, FileSeekOrigin::BEGINNING));
@@ -148,11 +148,11 @@ Error BinarySerializer::doDynamicArrayComplexType(const T* arr, PtrSize size, Pt
 		// Basically serialize pointers
 		for(PtrSize i = 0; i < size && !m_err; ++i)
 		{
-			m_structureFilePos.emplaceBack(m_alloc, arrayFilePos);
+			m_structureFilePos.emplaceBack(*m_pool, arrayFilePos);
 
 			SerializeFunctor<T>()(arr[i], *this);
 
-			m_structureFilePos.popBack(m_alloc);
+			m_structureFilePos.popBack(*m_pool);
 			arrayFilePos += sizeof(T);
 		}
 		ANKI_CHECK(m_err);
@@ -163,7 +163,7 @@ Error BinarySerializer::doDynamicArrayComplexType(const T* arr, PtrSize size, Pt
 }
 
 template<typename T, typename TFile>
-Error BinaryDeserializer::deserialize(T*& x, GenericMemoryPoolAllocator<U8> allocator, TFile& file)
+Error BinaryDeserializer::deserialize(T*& x, BaseMemoryPool& pool, TFile& file)
 {
 	x = nullptr;
 
@@ -195,8 +195,7 @@ Error BinaryDeserializer::deserialize(T*& x, GenericMemoryPoolAllocator<U8> allo
 	}
 
 	// Allocate & read data
-	U8* const baseAddress =
-		static_cast<U8*>(allocator.getMemoryPool().allocate(header.m_dataSize, ANKI_SAFE_ALIGNMENT));
+	U8* const baseAddress = static_cast<U8*>(pool.allocate(header.m_dataSize, ANKI_SAFE_ALIGNMENT));
 	ANKI_CHECK(file.read(baseAddress, header.m_dataSize));
 
 	// Fix pointers

+ 0 - 148
AnKi/Util/String.cpp

@@ -7,7 +7,6 @@
 #include <AnKi/Util/F16.h>
 #include <cmath> // For HUGE_VAL
 #include <climits> // For LLONG_MAX
-#include <cstdarg> // For var args
 #include <cstdlib> // For stdtod and strtol
 
 namespace anki {
@@ -179,151 +178,4 @@ Error CString::toNumber(Bool& out) const
 	return Error::kNone;
 }
 
-String& String::operator=(StringAuto&& b)
-{
-	m_data = std::move(b.m_data);
-	return *this;
-}
-
-void String::create(Allocator alloc, const CStringType& cstr)
-{
-	auto len = cstr.getLength();
-	auto size = len + 1;
-	m_data.create(alloc, size);
-	memcpy(&m_data[0], &cstr[0], sizeof(Char) * size);
-}
-
-void String::create(Allocator alloc, ConstIterator first, ConstIterator last)
-{
-	ANKI_ASSERT(first != 0 && last != 0);
-	auto length = last - first;
-	m_data.create(alloc, length + 1);
-
-	memcpy(&m_data[0], first, length);
-	m_data[length] = '\0';
-}
-
-void String::create(Allocator alloc, Char c, PtrSize length)
-{
-	ANKI_ASSERT(c != '\0');
-	m_data.create(alloc, length + 1);
-
-	memset(&m_data[0], c, length);
-	m_data[length] = '\0';
-}
-
-void String::appendInternal(Allocator& alloc, const Char* str, PtrSize strLen)
-{
-	ANKI_ASSERT(str != nullptr);
-	ANKI_ASSERT(strLen > 0);
-
-	auto size = m_data.getSize();
-
-	// Fix empty string
-	if(size == 0)
-	{
-		size = 1;
-	}
-
-	DynamicArray<Char, PtrSize> newData;
-	newData.create(alloc, size + strLen);
-
-	if(!m_data.isEmpty())
-	{
-		memcpy(&newData[0], &m_data[0], sizeof(Char) * size);
-	}
-
-	memcpy(&newData[size - 1], str, sizeof(Char) * strLen);
-
-	newData[newData.getSize() - 1] = '\0';
-
-	m_data.destroy(alloc);
-	m_data = std::move(newData);
-}
-
-void String::sprintf(Allocator& alloc, const Char* fmt, va_list& args)
-{
-	Array<Char, 512> buffer;
-
-	va_list args2;
-	va_copy(args2, args); // vsnprintf will alter "args". Copy it case we need to call vsnprintf in the else bellow
-
-	I len = std::vsnprintf(&buffer[0], sizeof(buffer), fmt, args);
-
-	if(len < 0)
-	{
-		ANKI_UTIL_LOGF("vsnprintf() failed");
-	}
-	else if(static_cast<PtrSize>(len) >= sizeof(buffer))
-	{
-		I size = len + 1;
-		m_data.create(alloc, size);
-
-		len = std::vsnprintf(&m_data[0], size, fmt, args2);
-
-		ANKI_ASSERT((len + 1) == size);
-	}
-	else
-	{
-		// buffer was enough
-		create(alloc, CString(&buffer[0]));
-	}
-
-	va_end(args2);
-}
-
-String& String::sprintf(Allocator alloc, const Char* fmt, ...)
-{
-	ANKI_ASSERT(fmt);
-	va_list args;
-	va_start(args, fmt);
-	sprintf(alloc, fmt, args);
-	va_end(args);
-
-	return *this;
-}
-
-String& String::replaceAll(Allocator alloc, CString from, CString to)
-{
-	String tmp = {alloc, toCString()};
-	const PtrSize fromLen = from.getLength();
-	const PtrSize toLen = to.getLength();
-
-	PtrSize pos = kNpos;
-	while((pos = tmp.find(from)) != kNpos)
-	{
-		String tmp2;
-		if(pos > 0)
-		{
-			tmp2.create(alloc, tmp.getBegin(), tmp.getBegin() + pos);
-		}
-
-		if(toLen > 0)
-		{
-			tmp2.append(alloc, to.getBegin(), to.getBegin() + toLen);
-		}
-
-		if(pos + fromLen < tmp.getLength())
-		{
-			tmp2.append(alloc, tmp.getBegin() + pos + fromLen, tmp.getEnd());
-		}
-
-		tmp.destroy(alloc);
-		tmp = std::move(tmp2);
-	}
-
-	destroy(alloc);
-	*this = std::move(tmp);
-	return *this;
-}
-
-StringAuto& StringAuto::sprintf(const Char* fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-	Base::sprintf(m_alloc, fmt, args);
-	va_end(args);
-	return *this;
-}
-
 } // end namespace anki

+ 244 - 97
AnKi/Util/String.h

@@ -13,6 +13,7 @@
 #include <cstdio>
 #include <cctype>
 #include <cinttypes> // For PRId8 etc
+#include <cstdarg> // For var args
 
 namespace anki {
 
@@ -285,7 +286,6 @@ public:
 	using CStringType = CString;
 	using Iterator = Char*;
 	using ConstIterator = const Char*;
-	using Allocator = GenericMemoryPoolAllocator<Char>;
 
 	static constexpr PtrSize kNpos = kMaxPtrSize;
 
@@ -300,14 +300,16 @@ public:
 		*this = std::move(b);
 	}
 
-	String(StringAuto&& b)
+	template<typename TMemPool>
+	String(BaseStringRaii<TMemPool>&& b)
 	{
 		*this = std::move(b);
 	}
 
-	String(Allocator alloc, CString str)
+	template<typename TMemPool>
+	String(TMemPool& pool, CString str)
 	{
-		create(alloc, str);
+		create(pool, str);
 	}
 
 	String(const String&) = delete; // Non-copyable
@@ -326,8 +328,13 @@ public:
 		return *this;
 	}
 
-	/// Move a StringAuto to this one.
-	String& operator=(StringAuto&& b);
+	/// Move a BaseStringRaii to this one.
+	template<typename TMemPool>
+	String& operator=(BaseStringRaii<TMemPool>&& b)
+	{
+		m_data = std::move(b.m_data);
+		return *this;
+	}
 
 	/// Return char at the specified position.
 	template<typename TInt>
@@ -409,56 +416,92 @@ public:
 	}
 
 	/// Initialize using a const string.
-	void create(Allocator alloc, const CStringType& cstr);
+	template<typename TMemPool>
+	void create(TMemPool& pool, const CStringType& cstr)
+	{
+		const U32 size = cstr.getLength() + 1;
+		m_data.create(pool, size);
+		memcpy(&m_data[0], &cstr[0], sizeof(Char) * size);
+	}
 
 	/// Initialize using a range. Copies the range of [first, last)
-	void create(Allocator alloc, ConstIterator first, ConstIterator last);
+	template<typename TMemPool>
+	void create(TMemPool& pool, ConstIterator first, ConstIterator last)
+	{
+		ANKI_ASSERT(first != 0 && last != 0);
+		auto length = last - first;
+		m_data.create(pool, length + 1);
+
+		memcpy(&m_data[0], first, length);
+		m_data[length] = '\0';
+	}
 
 	/// Initialize using a character.
-	void create(Allocator alloc, Char c, PtrSize length);
+	template<typename TMemPool>
+	void create(TMemPool& pool, Char c, PtrSize length)
+	{
+		ANKI_ASSERT(c != '\0');
+		m_data.create(pool, length + 1);
+		memset(&m_data[0], c, length);
+		m_data[length] = '\0';
+	}
 
 	/// Copy one string to this one.
-	void create(Allocator alloc, const String& b)
+	template<typename TMemPool>
+	void create(TMemPool& pool, const String& b)
 	{
-		create(alloc, b.toCString());
+		create(pool, b.toCString());
 	}
 
 	/// Append another string to this one.
-	String& append(Allocator alloc, const String& b)
+	template<typename TMemPool>
+	String& append(TMemPool& pool, const String& b)
 	{
 		if(!b.isEmpty())
 		{
-			appendInternal(alloc, &b.m_data[0], b.m_data.getSize() - 1);
+			appendInternal(pool, &b.m_data[0], b.m_data.getSize() - 1);
 		}
 		return *this;
 	}
 
 	/// Append a const string to this one.
-	String& append(Allocator alloc, const CStringType& cstr)
+	template<typename TMemPool>
+	String& append(TMemPool& pool, const CStringType& cstr)
 	{
 		if(!cstr.isEmpty())
 		{
-			appendInternal(alloc, cstr.cstr(), cstr.getLength());
+			appendInternal(pool, cstr.cstr(), cstr.getLength());
 		}
 		return *this;
 	}
 
 	/// Append using a range. Copies the range of [first, oneAfterLast)
-	String& append(Allocator alloc, ConstIterator first, ConstIterator oneAfterLast)
+	template<typename TMemPool>
+	String& append(TMemPool& pool, ConstIterator first, ConstIterator oneAfterLast)
 	{
 		const PtrSize len = oneAfterLast - first;
-		appendInternal(alloc, first, len);
+		appendInternal(pool, first, len);
 		return *this;
 	}
 
 	/// Create formated string.
+	template<typename TMemPool>
 	ANKI_CHECK_FORMAT(2, 3)
-	String& sprintf(Allocator alloc, const Char* fmt, ...);
+	String& sprintf(TMemPool& pool, const Char* fmt, ...)
+	{
+		ANKI_ASSERT(fmt);
+		va_list args;
+		va_start(args, fmt);
+		sprintf(pool, fmt, args);
+		va_end(args);
+		return *this;
+	}
 
 	/// Destroy the string.
-	void destroy(Allocator alloc)
+	template<typename TMemPool>
+	void destroy(TMemPool& pool)
 	{
-		m_data.destroy(alloc);
+		m_data.destroy(pool);
 	}
 
 	Iterator getBegin()
@@ -544,8 +587,23 @@ public:
 	}
 
 	/// Convert a number to a string.
-	template<typename TNumber>
-	void toString(Allocator alloc, TNumber number);
+	template<typename TMemPool, typename TNumber>
+	void toString(TMemPool& pool, TNumber number)
+	{
+		destroy(pool);
+
+		Array<Char, 512> buff;
+		const I ret = std::snprintf(&buff[0], buff.size(), detail::toStringFormat<TNumber>(), number);
+
+		if(ret < 0 || ret > static_cast<I>(buff.getSize()))
+		{
+			ANKI_UTIL_LOGF("To small intermediate buffer");
+		}
+		else
+		{
+			create(pool, &buff[0]);
+		}
+	}
 
 	/// Convert to F16.
 	Error toNumber(F16& out) const
@@ -627,7 +685,40 @@ public:
 	}
 
 	/// Replace all occurrences of "from" with "to".
-	String& replaceAll(Allocator alloc, CString from, CString to);
+	template<typename TMemPool>
+	String& replaceAll(TMemPool& pool, CString from, CString to)
+	{
+		String tmp(pool, toCString());
+		const PtrSize fromLen = from.getLength();
+		const PtrSize toLen = to.getLength();
+
+		PtrSize pos = kNpos;
+		while((pos = tmp.find(from)) != kNpos)
+		{
+			String tmp2;
+			if(pos > 0)
+			{
+				tmp2.create(pool, tmp.getBegin(), tmp.getBegin() + pos);
+			}
+
+			if(toLen > 0)
+			{
+				tmp2.append(pool, to.getBegin(), to.getBegin() + toLen);
+			}
+
+			if(pos + fromLen < tmp.getLength())
+			{
+				tmp2.append(pool, tmp.getBegin() + pos + fromLen, tmp.getEnd());
+			}
+
+			tmp.destroy(pool);
+			tmp = std::move(tmp2);
+		}
+
+		destroy(pool);
+		*this = std::move(tmp);
+		return *this;
+	}
 
 	/// @brief  Execute a functor for all characters of the string.
 	template<typename TFunc>
@@ -650,7 +741,37 @@ public:
 	}
 
 	/// Internal don't use it.
-	ANKI_INTERNAL void sprintf(Allocator& alloc, const Char* fmt, va_list& args);
+	template<typename TMemPool>
+	ANKI_INTERNAL void sprintf(TMemPool& pool, const Char* fmt, va_list& args)
+	{
+		Array<Char, 512> buffer;
+
+		va_list args2;
+		va_copy(args2, args); // vsnprintf will alter "args". Copy it case we need to call vsnprintf in the else bellow
+
+		I len = std::vsnprintf(&buffer[0], sizeof(buffer), fmt, args);
+
+		if(len < 0)
+		{
+			ANKI_UTIL_LOGF("vsnprintf() failed");
+		}
+		else if(static_cast<PtrSize>(len) >= sizeof(buffer))
+		{
+			I size = len + 1;
+			m_data.create(pool, size);
+
+			len = std::vsnprintf(&m_data[0], size, fmt, args2);
+
+			ANKI_ASSERT((len + 1) == size);
+		}
+		else
+		{
+			// buffer was enough
+			create(pool, CString(&buffer[0]));
+		}
+
+		va_end(args2);
+	}
 
 protected:
 	DynamicArray<Char, PtrSize> m_data;
@@ -661,51 +782,62 @@ protected:
 	}
 
 	/// Append to this string.
-	void appendInternal(Allocator& alloc, const Char* str, PtrSize strLen);
-
-	void move(String& b)
+	template<typename TMemPool>
+	void appendInternal(TMemPool& pool, const Char* str, PtrSize strLen)
 	{
-		ANKI_ASSERT(this != &b);
-		m_data = std::move(b.m_data);
-	}
-};
+		ANKI_ASSERT(str != nullptr);
+		ANKI_ASSERT(strLen > 0);
 
-template<typename TNumber>
-inline void String::toString(Allocator alloc, TNumber number)
-{
-	destroy(alloc);
+		auto size = m_data.getSize();
 
-	Array<Char, 512> buff;
-	const I ret = std::snprintf(&buff[0], buff.size(), detail::toStringFormat<TNumber>(), number);
+		// Fix empty string
+		if(size == 0)
+		{
+			size = 1;
+		}
 
-	if(ret < 0 || ret > static_cast<I>(buff.getSize()))
-	{
-		ANKI_UTIL_LOGF("To small intermediate buffer");
+		DynamicArray<Char, PtrSize> newData;
+		newData.create(pool, size + strLen);
+
+		if(!m_data.isEmpty())
+		{
+			memcpy(&newData[0], &m_data[0], sizeof(Char) * size);
+		}
+
+		memcpy(&newData[size - 1], str, sizeof(Char) * strLen);
+
+		newData[newData.getSize() - 1] = '\0';
+
+		m_data.destroy(pool);
+		m_data = std::move(newData);
 	}
-	else
+
+	void move(String& b)
 	{
-		create(alloc, &buff[0]);
+		ANKI_ASSERT(this != &b);
+		m_data = std::move(b.m_data);
 	}
-}
+};
 
 /// String with automatic cleanup.
-class StringAuto : public String
+template<typename TMemPool = MemoryPoolPtrWrapper<BaseMemoryPool>>
+class BaseStringRaii : public String
 {
 public:
 	using Base = String;
-	using Allocator = typename Base::Allocator;
+	using MemoryPool = TMemPool;
 
-	/// Create with allocator.
-	StringAuto(Allocator alloc)
+	/// Create with pool.
+	BaseStringRaii(const MemoryPool& pool)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 	}
 
 	/// Copy construcor.
-	StringAuto(const StringAuto& b)
+	BaseStringRaii(const BaseStringRaii& b)
 		: Base()
-		, m_alloc(b.m_alloc)
+		, m_pool(b.m_pool)
 	{
 		if(!b.isEmpty())
 		{
@@ -714,31 +846,31 @@ public:
 	}
 
 	/// Move constructor.
-	StringAuto(StringAuto&& b)
+	BaseStringRaii(BaseStringRaii&& b)
 		: Base()
 	{
 		move(b);
 	}
 
-	/// Create with allocator and data.
-	StringAuto(Allocator alloc, const CStringType& cstr)
+	/// Create with memory pool and data.
+	BaseStringRaii(MemoryPool& pool, const CStringType& cstr)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 		create(cstr);
 	}
 
 	/// Automatic destruction.
-	~StringAuto()
+	~BaseStringRaii()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Copy operator.
-	StringAuto& operator=(const StringAuto& b)
+	BaseStringRaii& operator=(const BaseStringRaii& b)
 	{
 		destroy();
-		m_alloc = b.m_alloc;
+		m_pool = b.m_pool;
 		if(!b.isEmpty())
 		{
 			create(b.m_data.getBegin(), b.m_data.getEnd());
@@ -747,7 +879,7 @@ public:
 	}
 
 	/// Copy from string.
-	StringAuto& operator=(const CString& b)
+	BaseStringRaii& operator=(const CString& b)
 	{
 		destroy();
 		if(!b.isEmpty())
@@ -758,120 +890,135 @@ public:
 	}
 
 	/// Move one string to this one.
-	StringAuto& operator=(StringAuto&& b)
+	BaseStringRaii& operator=(BaseStringRaii&& b)
 	{
 		destroy();
 		move(b);
 		return *this;
 	}
 
-	GenericMemoryPoolAllocator<Char> getAllocator() const
+	const MemoryPool& getMemoryPool() const
+	{
+		return m_pool;
+	}
+
+	MemoryPool& getMemoryPool()
 	{
-		return m_alloc;
+		return m_pool;
 	}
 
 	/// Initialize using a const string.
 	void create(const CStringType& cstr)
 	{
-		Base::create(m_alloc, cstr);
+		Base::create(m_pool, cstr);
 	}
 
 	/// Initialize using a range. Copies the range of [first, last)
 	void create(ConstIterator first, ConstIterator last)
 	{
-		Base::create(m_alloc, first, last);
+		Base::create(m_pool, first, last);
 	}
 
 	/// Initialize using a character.
 	void create(Char c, PtrSize length)
 	{
-		Base::create(m_alloc, c, length);
+		Base::create(m_pool, c, length);
 	}
 
 	/// Copy one string to this one.
 	void create(const String& b)
 	{
-		Base::create(m_alloc, b.toCString());
+		Base::create(m_pool, b.toCString());
 	}
 
 	/// Destroy the string.
 	void destroy()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Append another string to this one.
-	StringAuto& append(const String& b)
+	BaseStringRaii& append(const String& b)
 	{
-		Base::append(m_alloc, b);
+		Base::append(m_pool, b);
 		return *this;
 	}
 
 	/// Append a const string to this one.
-	StringAuto& append(const CStringType& cstr)
+	BaseStringRaii& append(const CStringType& cstr)
 	{
-		Base::append(m_alloc, cstr);
+		Base::append(m_pool, cstr);
 		return *this;
 	}
 
 	/// Create formated string.
 	ANKI_CHECK_FORMAT(1, 2)
-	StringAuto& sprintf(const Char* fmt, ...);
+	BaseStringRaii& sprintf(const Char* fmt, ...)
+	{
+		va_list args;
+		va_start(args, fmt);
+		Base::sprintf(m_pool, fmt, args);
+		va_end(args);
+		return *this;
+	}
 
 	/// Convert a number to a string.
 	template<typename TNumber>
 	void toString(TNumber number)
 	{
-		Base::toString(m_alloc, number);
+		Base::toString(m_pool, number);
 	}
 
 	/// Replace all occurrences of "from" with "to".
-	StringAuto& replaceAll(CString from, CString to)
+	BaseStringRaii& replaceAll(CString from, CString to)
 	{
-		Base::replaceAll(m_alloc, from, to);
+		Base::replaceAll(m_pool, from, to);
 		return *this;
 	}
 
 private:
-	GenericMemoryPoolAllocator<Char> m_alloc;
+	MemoryPool m_pool;
 
-	void move(StringAuto& b)
+	void move(BaseStringRaii& b)
 	{
 		Base::move(b);
-		m_alloc = std::move(b.m_alloc);
+		m_pool = std::move(b.m_pool);
 	}
 };
 
-#define ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, op) \
+using StringRaii = BaseStringRaii<>;
+
+#define ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, op, ...) \
+	__VA_ARGS__ \
 	inline Bool operator op(TypeA a, TypeB b) \
 	{ \
 		return CString(a) op CString(b); \
 	}
 
-#define ANKI_STRING_COMPARE_OPS(TypeA, TypeB) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, ==) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, !=) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, <) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, <=) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, >) \
-	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, >=)
+#define ANKI_STRING_COMPARE_OPS(TypeA, TypeB, ...) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, ==, __VA_ARGS__) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, !=, __VA_ARGS__) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, <, __VA_ARGS__) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, <=, __VA_ARGS__) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, >, __VA_ARGS__) \
+	ANKI_STRING_COMPARE_OPERATOR(TypeA, TypeB, >=, __VA_ARGS__)
 
-ANKI_STRING_COMPARE_OPS(const char*, CString)
-ANKI_STRING_COMPARE_OPS(const char*, const String&)
-ANKI_STRING_COMPARE_OPS(const char*, const StringAuto&)
+ANKI_STRING_COMPARE_OPS(const Char*, CString)
+ANKI_STRING_COMPARE_OPS(const Char*, const String&)
+ANKI_STRING_COMPARE_OPS(const Char*, const BaseStringRaii<TMemPool>&, template<typename TMemPool>)
 
-ANKI_STRING_COMPARE_OPS(CString, const char*)
+ANKI_STRING_COMPARE_OPS(CString, const Char*)
 ANKI_STRING_COMPARE_OPS(CString, const String&)
-ANKI_STRING_COMPARE_OPS(CString, const StringAuto&)
+ANKI_STRING_COMPARE_OPS(CString, const BaseStringRaii<TMemPool>&, template<typename TMemPool>)
 
-ANKI_STRING_COMPARE_OPS(const String&, const char*)
+ANKI_STRING_COMPARE_OPS(const String&, const Char*)
 ANKI_STRING_COMPARE_OPS(const String&, CString)
-ANKI_STRING_COMPARE_OPS(const String&, const StringAuto&)
+ANKI_STRING_COMPARE_OPS(const String&, const BaseStringRaii<TMemPool>&, template<typename TMemPool>)
 
-ANKI_STRING_COMPARE_OPS(const StringAuto&, const char*)
-ANKI_STRING_COMPARE_OPS(const StringAuto&, CString)
-ANKI_STRING_COMPARE_OPS(const StringAuto&, const String&)
-ANKI_STRING_COMPARE_OPS(const StringAuto&, const StringAuto&)
+ANKI_STRING_COMPARE_OPS(const BaseStringRaii<TMemPool>&, const Char*, template<typename TMemPool>)
+ANKI_STRING_COMPARE_OPS(const BaseStringRaii<TMemPool>&, CString, template<typename TMemPool>)
+ANKI_STRING_COMPARE_OPS(const BaseStringRaii<TMemPool>&, const String&, template<typename TMemPool>)
+ANKI_STRING_COMPARE_OPS(const BaseStringRaii<TMemPool>&, const BaseStringRaii<TMemPool>&, template<typename TMemPool>)
 
 #undef ANKI_STRING_COMPARE_OPERATOR
 #undef ANKI_STRING_COMPARE_OPS

+ 0 - 155
AnKi/Util/StringList.cpp

@@ -4,116 +4,9 @@
 // http://www.anki3d.org/LICENSE
 
 #include <AnKi/Util/StringList.h>
-#include <cstdarg>
 
 namespace anki {
 
-void StringList::destroy(Allocator alloc)
-{
-	auto it = Base::getBegin();
-	auto endit = Base::getEnd();
-	for(; it != endit; ++it)
-	{
-		(*it).destroy(alloc);
-	}
-
-	Base::destroy(alloc);
-}
-
-void StringList::join(Allocator alloc, const CString& separator, String& out) const
-{
-	StringAuto outl(alloc);
-	join(separator, outl);
-	out = std::move(outl);
-}
-
-void StringList::join(const CString& separator, StringAuto& out) const
-{
-	if(Base::isEmpty())
-	{
-		return;
-	}
-
-	// Count the characters
-	const I sepLen = separator.getLength();
-	I charCount = 0;
-	for(const String& str : *this)
-	{
-		charCount += str.getLength() + sepLen;
-	}
-
-	charCount -= sepLen; // Remove last separator
-	ANKI_ASSERT(charCount > 0);
-
-	// Allocate
-	out.create('?', charCount);
-
-	// Append to output
-	Char* to = &out[0];
-	typename Base::ConstIterator it = Base::getBegin();
-	for(; it != Base::getEnd(); it++)
-	{
-		const String& from = *it;
-		memcpy(to, &from[0], from.getLength() * sizeof(Char));
-		to += from.getLength();
-
-		if(it != Base::end() - 1)
-		{
-			memcpy(to, &separator[0], sepLen * sizeof(Char));
-			to += sepLen;
-		}
-	}
-}
-
-void StringList::splitString(Allocator alloc, const CString& s, const Char separator, Bool keepEmpty)
-{
-	ANKI_ASSERT(Base::isEmpty());
-
-	const Char* begin = &s[0];
-	const Char* end = begin;
-
-	while(1)
-	{
-		if(*end == '\0')
-		{
-			if(begin < end)
-			{
-				Base::emplaceBack(alloc);
-
-				String str;
-				str.create(alloc, begin, end);
-				Base::getBack() = std::move(str);
-			}
-
-			break;
-		}
-		else if(*end == separator)
-		{
-			if(begin < end)
-			{
-				Base::emplaceBack(alloc);
-
-				String str;
-				str.create(alloc, begin, end);
-
-				Base::getBack() = std::move(str);
-				begin = end + 1;
-			}
-			else
-			{
-				if(keepEmpty)
-				{
-					Base::emplaceBack(alloc);
-				}
-
-				++begin;
-			}
-		}
-
-		++end;
-	}
-}
-
 void StringList::sortAll(const Sort method)
 {
 	if(method == Sort::kAscending)
@@ -147,52 +40,4 @@ I StringList::getIndexOf(const CString& value) const
 	return (pos == Base::getSize()) ? -1 : pos;
 }
 
-void StringList::pushBackSprintf(Allocator alloc, const Char* fmt, ...)
-{
-	String str;
-	va_list args;
-	va_start(args, fmt);
-	str.sprintf(alloc, fmt, args);
-	va_end(args);
-
-	Base::emplaceBack(alloc);
-	Base::getBack() = std::move(str);
-}
-
-void StringList::pushFrontSprintf(Allocator alloc, const Char* fmt, ...)
-{
-	String str;
-	va_list args;
-	va_start(args, fmt);
-	str.sprintf(alloc, fmt, args);
-	va_end(args);
-
-	Base::emplaceFront(alloc);
-	Base::getFront() = std::move(str);
-}
-
-void StringListAuto::pushBackSprintf(const Char* fmt, ...)
-{
-	String str;
-	va_list args;
-	va_start(args, fmt);
-	str.sprintf(m_alloc, fmt, args);
-	va_end(args);
-
-	Base::emplaceBack(m_alloc);
-	Base::getBack() = std::move(str);
-}
-
-void StringListAuto::pushFrontSprintf(const Char* fmt, ...)
-{
-	String str;
-	va_list args;
-	va_start(args, fmt);
-	str.sprintf(m_alloc, fmt, args);
-	va_end(args);
-
-	Base::emplaceFront(m_alloc);
-	Base::getFront() = std::move(str);
-}
-
 } // end namespace anki

+ 49 - 31
AnKi/Util/StringList.h

@@ -8,6 +8,7 @@
 #include <AnKi/Util/String.h>
 #include <AnKi/Util/List.h>
 #include <algorithm>
+#include <cstdarg>
 
 namespace anki {
 
@@ -20,7 +21,6 @@ class StringList : public List<String>
 public:
 	using Char = char; ///< Char type
 	using Base = List<String>; ///< Base
-	using Allocator = GenericMemoryPoolAllocator<Char>;
 
 	/// Sort method for sortAll().
 	enum class Sort
@@ -37,13 +37,21 @@ public:
 		return !Base::isEmpty();
 	}
 
-	void destroy(Allocator alloc);
+	template<typename TMemPool>
+	void destroy(TMemPool& pool);
 
 	/// Join all the elements into a single big string using a the seperator @a separator
-	void join(Allocator alloc, const CString& separator, String& out) const;
+	template<typename TMemPool>
+	void join(TMemPool& pool, const CString& separator, String& out) const
+	{
+		BaseStringRaii<TMemPool> outl(pool);
+		join(separator, outl);
+		out = std::move(outl);
+	}
 
 	/// Join all the elements into a single big string using a the seperator @a separator
-	void join(const CString& separator, StringAuto& out) const;
+	template<typename TMemPool>
+	void join(const CString& separator, BaseStringRaii<TMemPool>& out) const;
 
 	/// Returns the index position of the last occurrence of @a value in the list.
 	/// @return -1 of not found
@@ -53,65 +61,71 @@ public:
 	void sortAll(const Sort method = Sort::kAscending);
 
 	/// Push at the end of the list a formated string.
+	template<typename TMemPool>
 	ANKI_CHECK_FORMAT(2, 3)
-	void pushBackSprintf(Allocator alloc, const Char* fmt, ...);
+	void pushBackSprintf(TMemPool& pool, const Char* fmt, ...);
 
 	/// Push at the beginning of the list a formated string.
+	template<typename TMemPool>
 	ANKI_CHECK_FORMAT(2, 3)
-	void pushFrontSprintf(Allocator alloc, const Char* fmt, ...);
+	void pushFrontSprintf(TMemPool& pool, const Char* fmt, ...);
 
 	/// Push back plain CString.
-	void pushBack(Allocator alloc, CString cstr)
+	template<typename TMemPool>
+	void pushBack(TMemPool& pool, CString cstr)
 	{
 		String str;
-		str.create(alloc, cstr);
+		str.create(pool, cstr);
 
-		Base::emplaceBack(alloc);
+		Base::emplaceBack(pool);
 		Base::getBack() = std::move(str);
 	}
 
 	/// Push front plain CString
-	void pushFront(Allocator alloc, CString cstr)
+	template<typename TMemPool>
+	void pushFront(TMemPool& pool, CString cstr)
 	{
 		String str;
-		str.create(alloc, cstr);
+		str.create(pool, cstr);
 
-		Base::emplaceFront(alloc);
+		Base::emplaceFront(pool);
 		Base::getFront() = std::move(str);
 	}
 
 	/// Split a string using a separator (@a separator) and return these strings in a string list.
-	void splitString(Allocator alloc, const CString& s, const Char separator, Bool keepEmpty = false);
+	template<typename TMemPool>
+	void splitString(TMemPool& pool, const CString& s, const Char separator, Bool keepEmpty = false);
 };
 
 /// String list with automatic destruction.
-class StringListAuto : public StringList
+template<typename TMemPool = MemoryPoolPtrWrapper<BaseMemoryPool>>
+class BaseStringListRaii : public StringList
 {
 public:
 	using Base = StringList;
-	using Allocator = typename Base::Allocator;
+	using MemoryPool = TMemPool;
 
-	/// Create using an allocator.
-	StringListAuto(Allocator alloc)
+	/// Create using a mem pool.
+	BaseStringListRaii(const MemoryPool& pool)
 		: Base()
-		, m_alloc(alloc)
+		, m_pool(pool)
 	{
 	}
 
 	/// Move.
-	StringListAuto(StringListAuto&& b)
+	BaseStringListRaii(BaseStringListRaii&& b)
 		: Base()
 	{
 		move(b);
 	}
 
-	~StringListAuto()
+	~BaseStringListRaii()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Move.
-	StringListAuto& operator=(StringListAuto&& b)
+	BaseStringListRaii& operator=(BaseStringListRaii&& b)
 	{
 		move(b);
 		return *this;
@@ -120,7 +134,7 @@ public:
 	/// Destroy.
 	void destroy()
 	{
-		Base::destroy(m_alloc);
+		Base::destroy(m_pool);
 	}
 
 	/// Push at the end of the list a formated string
@@ -134,37 +148,41 @@ public:
 	/// Push back plain CString.
 	void pushBack(CString cstr)
 	{
-		Base::pushBack(m_alloc, cstr);
+		Base::pushBack(m_pool, cstr);
 	}
 
 	/// Push front plain CString.
 	void pushFront(CString cstr)
 	{
-		Base::pushFront(m_alloc, cstr);
+		Base::pushFront(m_pool, cstr);
 	}
 
 	/// Pop front element.
 	void popFront()
 	{
-		getFront().destroy(m_alloc);
-		Base::popFront(m_alloc);
+		getFront().destroy(m_pool);
+		Base::popFront(m_pool);
 	}
 
 	/// Split a string using a separator (@a separator) and return these strings in a string list.
 	void splitString(const CString& s, const Base::Char separator, Bool keepEmpty = false)
 	{
-		Base::splitString(m_alloc, s, separator, keepEmpty);
+		Base::splitString(m_pool, s, separator, keepEmpty);
 	}
 
 private:
-	Allocator m_alloc;
+	MemoryPool m_pool;
 
-	void move(StringListAuto& b)
+	void move(BaseStringListRaii& b)
 	{
 		Base::operator=(std::move(b));
-		m_alloc = std::move(b.m_alloc);
+		m_pool = std::move(b.m_pool);
 	}
 };
+
+using StringListRaii = BaseStringListRaii<>;
 /// @}
 
 } // end namespace anki
+
+#include <AnKi/Util/StringList.inl.h>

+ 164 - 0
AnKi/Util/StringList.inl.h

@@ -0,0 +1,164 @@
+// 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/StringList.h>
+
+namespace anki {
+
+template<typename TMemPool>
+void StringList::destroy(TMemPool& pool)
+{
+	auto it = Base::getBegin();
+	auto endit = Base::getEnd();
+	for(; it != endit; ++it)
+	{
+		(*it).destroy(pool);
+	}
+
+	Base::destroy(pool);
+}
+
+template<typename TMemPool>
+void StringList::join(const CString& separator, BaseStringRaii<TMemPool>& out) const
+{
+	if(Base::isEmpty())
+	{
+		return;
+	}
+
+	// Count the characters
+	const I sepLen = separator.getLength();
+	I charCount = 0;
+	for(const String& str : *this)
+	{
+		charCount += str.getLength() + sepLen;
+	}
+
+	charCount -= sepLen; // Remove last separator
+	ANKI_ASSERT(charCount > 0);
+
+	// Allocate
+	out.create('?', charCount);
+
+	// Append to output
+	Char* to = &out[0];
+	typename Base::ConstIterator it = Base::getBegin();
+	for(; it != Base::getEnd(); it++)
+	{
+		const String& from = *it;
+		memcpy(to, &from[0], from.getLength() * sizeof(Char));
+		to += from.getLength();
+
+		if(it != Base::end() - 1)
+		{
+			memcpy(to, &separator[0], sepLen * sizeof(Char));
+			to += sepLen;
+		}
+	}
+}
+
+template<typename TMemPool>
+void StringList::splitString(TMemPool& pool, const CString& s, const Char separator, Bool keepEmpty)
+{
+	ANKI_ASSERT(Base::isEmpty());
+
+	const Char* begin = &s[0];
+	const Char* end = begin;
+
+	while(1)
+	{
+		if(*end == '\0')
+		{
+			if(begin < end)
+			{
+				Base::emplaceBack(pool);
+
+				String str;
+				str.create(pool, begin, end);
+				Base::getBack() = std::move(str);
+			}
+
+			break;
+		}
+		else if(*end == separator)
+		{
+			if(begin < end)
+			{
+				Base::emplaceBack(pool);
+
+				String str;
+				str.create(pool, begin, end);
+
+				Base::getBack() = std::move(str);
+				begin = end + 1;
+			}
+			else
+			{
+				if(keepEmpty)
+				{
+					Base::emplaceBack(pool);
+				}
+
+				++begin;
+			}
+		}
+
+		++end;
+	}
+}
+
+template<typename TMemPool>
+void StringList::pushBackSprintf(TMemPool& pool, const Char* fmt, ...)
+{
+	String str;
+	va_list args;
+	va_start(args, fmt);
+	str.sprintf(pool, fmt, args);
+	va_end(args);
+
+	Base::emplaceBack(pool);
+	Base::getBack() = std::move(str);
+}
+
+template<typename TMemPool>
+void StringList::pushFrontSprintf(TMemPool& pool, const Char* fmt, ...)
+{
+	String str;
+	va_list args;
+	va_start(args, fmt);
+	str.sprintf(pool, fmt, args);
+	va_end(args);
+
+	Base::emplaceFront(pool);
+	Base::getFront() = std::move(str);
+}
+
+template<typename TMemPool>
+void BaseStringListRaii<TMemPool>::pushBackSprintf(const Char* fmt, ...)
+{
+	String str;
+	va_list args;
+	va_start(args, fmt);
+	str.sprintf(m_pool, fmt, args);
+	va_end(args);
+
+	Base::emplaceBack(m_pool);
+	Base::getBack() = std::move(str);
+}
+
+template<typename TMemPool>
+void BaseStringListRaii<TMemPool>::pushFrontSprintf(const Char* fmt, ...)
+{
+	String str;
+	va_list args;
+	va_start(args, fmt);
+	str.sprintf(m_pool, fmt, args);
+	va_end(args);
+
+	Base::emplaceFront(m_pool);
+	Base::getFront() = std::move(str);
+}
+
+} // end namespace anki

+ 4 - 4
AnKi/Util/System.cpp

@@ -101,11 +101,11 @@ std::tm getLocalTime()
 
 #if ANKI_OS_ANDROID
 /// Get the name of the apk. Doesn't use File to open files because /proc files are a bit special.
-static Error getAndroidApkName(StringAuto& name)
+static Error getAndroidApkName(StringRaii& name)
 {
 	const pid_t pid = getpid();
 
-	StringAuto path(name.getAllocator());
+	StringRaii path(name.getAllocator());
 	path.sprintf("/proc/%d/cmdline", pid);
 
 	const int fd = open(path.cstr(), O_RDONLY);
@@ -154,7 +154,7 @@ void* getAndroidCommandLineArguments(int& argc, char**& argv)
 
 	// Parse the command line args
 	HeapAllocator<U8> alloc(allocAligned, nullptr, "getAndroidCommandLineArguments temp");
-	StringListAuto args(alloc);
+	StringListRaii args(alloc);
 
 	if(jsParam1)
 	{
@@ -164,7 +164,7 @@ void* getAndroidCommandLineArguments(int& argc, char**& argv)
 	}
 
 	// Add the apk name
-	StringAuto apkName(alloc);
+	StringRaii apkName(alloc);
 	if(!getAndroidApkName(apkName))
 	{
 		args.pushFront(apkName);

+ 4 - 4
AnKi/Util/System.h

@@ -22,12 +22,12 @@ U32 getCpuCoresCount();
 void backtraceInternal(const Function<void(CString)>& lambda);
 
 /// Get a backtrace.
-template<typename TFunc>
-void backtrace(GenericMemoryPoolAllocator<U8> alloc, TFunc func)
+template<typename TMemPool, typename TFunc>
+void backtrace(TMemPool& pool, TFunc func)
 {
-	Function<void(CString)> f(alloc, func);
+	Function<void(CString)> f(pool, func);
 	backtraceInternal(f);
-	f.destroy(alloc);
+	f.destroy(pool);
 }
 
 /// Return true if the engine is running from a terminal emulator.

+ 7 - 8
AnKi/Util/ThreadHive.cpp

@@ -60,13 +60,12 @@ public:
 	ThreadHiveSemaphore* m_signalSemaphore;
 };
 
-ThreadHive::ThreadHive(U32 threadCount, GenericMemoryPoolAllocator<U8> alloc, Bool pinToCores)
-	: m_slowAlloc(alloc)
-	, m_alloc(alloc.getMemoryPool().getAllocationCallback(), alloc.getMemoryPool().getAllocationCallbackUserData(),
-			  4_KB)
+ThreadHive::ThreadHive(U32 threadCount, BaseMemoryPool* pool, Bool pinToCores)
+	: m_slowPool(pool)
+	, m_pool(pool->getAllocationCallback(), pool->getAllocationCallbackUserData(), 4_KB)
 	, m_threadCount(threadCount)
 {
-	m_threads = reinterpret_cast<Thread*>(m_slowAlloc.allocate(sizeof(Thread) * threadCount));
+	m_threads = static_cast<Thread*>(m_slowPool->allocate(sizeof(Thread) * threadCount, alignof(Thread)));
 
 	const U32 uuid = m_uuid.fetchAdd(1);
 
@@ -98,7 +97,7 @@ ThreadHive::~ThreadHive()
 			m_threads[threadCount].~Thread();
 		}
 
-		m_slowAlloc.deallocate(static_cast<void*>(m_threads), m_threadCount * sizeof(Thread));
+		m_slowPool->free(static_cast<void*>(m_threads));
 	}
 }
 
@@ -107,7 +106,7 @@ void ThreadHive::submitTasks(ThreadHiveTask* tasks, const U32 taskCount)
 	ANKI_ASSERT(tasks && taskCount > 0);
 
 	// Allocate tasks
-	Task* const htasks = m_alloc.newArray<Task>(taskCount);
+	Task* const htasks = newArray<Task>(m_pool, taskCount);
 
 	// Initialize tasks
 	Task* prevTask = nullptr;
@@ -266,7 +265,7 @@ void ThreadHive::waitAllTasks()
 
 	m_head = nullptr;
 	m_tail = nullptr;
-	m_alloc.getMemoryPool().reset();
+	m_pool.reset();
 
 	ANKI_HIVE_DEBUG_PRINT("mt: done waiting all\n");
 }

+ 7 - 9
AnKi/Util/ThreadHive.h

@@ -7,7 +7,7 @@
 
 #include <AnKi/Util/Thread.h>
 #include <AnKi/Util/WeakArray.h>
-#include <AnKi/Util/Allocator.h>
+#include <AnKi/Util/CpuMemoryPools.h>
 
 namespace anki {
 
@@ -80,7 +80,7 @@ public:
 	static constexpr U32 kMaxThreads = 32;
 
 	/// Create the hive.
-	ThreadHive(U32 threadCount, GenericMemoryPoolAllocator<U8> alloc, Bool pinToCores = false);
+	ThreadHive(U32 threadCount, BaseMemoryPool* pool, Bool pinToCores = false);
 
 	ThreadHive(const ThreadHive&) = delete; // Non-copyable
 
@@ -98,9 +98,8 @@ public:
 	ThreadHiveSemaphore* newSemaphore(const U32 initialValue)
 	{
 		ANKI_ASSERT(initialValue > 0);
-		PtrSize alignment = alignof(ThreadHiveSemaphore);
-		ThreadHiveSemaphore* sem =
-			reinterpret_cast<ThreadHiveSemaphore*>(m_alloc.allocate(sizeof(ThreadHiveSemaphore), &alignment));
+		ThreadHiveSemaphore* sem = static_cast<ThreadHiveSemaphore*>(
+			m_pool.allocate(sizeof(ThreadHiveSemaphore), alignof(ThreadHiveSemaphore)));
 		sem->m_atomic.setNonAtomically(initialValue);
 		return sem;
 	}
@@ -109,8 +108,7 @@ public:
 	void* allocateScratchMemory(PtrSize size, U32 alignment)
 	{
 		ANKI_ASSERT(size > 0 && alignment > 0);
-		PtrSize align = alignment;
-		void* out = m_alloc.allocate(size, &align);
+		void* out = m_pool.allocate(size, alignment);
 #if ANKI_ENABLE_ASSERTIONS
 		memset(out, 0, size);
 #endif
@@ -138,8 +136,8 @@ private:
 	/// Lightweight task.
 	class Task;
 
-	GenericMemoryPoolAllocator<U8> m_slowAlloc;
-	StackAllocator<U8> m_alloc;
+	BaseMemoryPool* m_slowPool;
+	StackMemoryPool m_pool;
 	Thread* m_threads = nullptr;
 	U32 m_threadCount = 0;
 

+ 6 - 6
AnKi/Util/Tracer.cpp

@@ -37,9 +37,9 @@ Tracer::~Tracer()
 	LockGuard<Mutex> lock(m_allThreadLocalMtx);
 	for(ThreadLocal* tlocal : m_allThreadLocal)
 	{
-		m_alloc.deleteInstance(tlocal);
+		deleteInstance(*m_pool, tlocal);
 	}
-	m_allThreadLocal.destroy(m_alloc);
+	m_allThreadLocal.destroy(*m_pool);
 }
 
 Tracer::ThreadLocal& Tracer::getThreadLocal()
@@ -47,13 +47,13 @@ Tracer::ThreadLocal& Tracer::getThreadLocal()
 	ThreadLocal* out = m_threadLocal;
 	if(ANKI_UNLIKELY(out == nullptr))
 	{
-		out = m_alloc.newInstance<ThreadLocal>();
+		out = newInstance<ThreadLocal>(*m_pool);
 		out->m_tid = Thread::getCurrentThreadId();
 		m_threadLocal = out;
 
 		// Store it
 		LockGuard<Mutex> lock(m_allThreadLocalMtx);
-		m_allThreadLocal.emplaceBack(m_alloc, out);
+		m_allThreadLocal.emplaceBack(*m_pool, out);
 	}
 
 	return *out;
@@ -72,7 +72,7 @@ Tracer::Chunk& Tracer::getOrCreateChunk(ThreadLocal& tlocal)
 	else
 	{
 		// Create a new
-		out = m_alloc.newInstance<Chunk>();
+		out = newInstance<Chunk>(*m_pool);
 		tlocal.m_currentChunk = out;
 		tlocal.m_allChunks.pushBack(out);
 	}
@@ -185,7 +185,7 @@ void Tracer::flush(TracerFlushCallback callback, void* callbackUserData)
 			callback(callbackUserData, tlocal->m_tid, WeakArray<TracerEvent>(&chunk->m_events[0], chunk->m_eventCount),
 					 WeakArray<TracerCounter>(&chunk->m_counters[0], chunk->m_counterCount));
 
-			m_alloc.deleteInstance(chunk);
+			deleteInstance(*m_pool, chunk);
 		}
 
 		tlocal->m_currentChunk = nullptr;

+ 3 - 3
AnKi/Util/Tracer.h

@@ -61,8 +61,8 @@ using TracerFlushCallback = void (*)(void* userData, ThreadId tid, ConstWeakArra
 class Tracer
 {
 public:
-	Tracer(GenericMemoryPoolAllocator<U8> alloc)
-		: m_alloc(alloc)
+	Tracer(BaseMemoryPool* pool)
+		: m_pool(pool)
 	{
 	}
 
@@ -109,7 +109,7 @@ private:
 	class ThreadLocal;
 	class Chunk;
 
-	GenericMemoryPoolAllocator<U8> m_alloc;
+	BaseMemoryPool* m_pool = nullptr;
 
 	static thread_local ThreadLocal* m_threadLocal;
 	DynamicArray<ThreadLocal*> m_allThreadLocal; ///< The Tracer should know about all the ThreadLocal.

+ 9 - 5
AnKi/Util/WeakArray.h

@@ -56,7 +56,8 @@ public:
 		}
 	}
 
-	explicit WeakArray(DynamicArrayAuto<T, TSize>& arr)
+	template<typename TMemPool>
+	explicit WeakArray(DynamicArrayRaii<T, TSize, TMemPool>& arr)
 		: WeakArray()
 	{
 		if(arr.getSize())
@@ -112,7 +113,8 @@ public:
 		return *this;
 	}
 
-	WeakArray& operator=(DynamicArrayAuto<T, TSize>& arr)
+	template<typename TMemPool>
+	WeakArray& operator=(DynamicArrayRaii<T, TSize, TMemPool>& arr)
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();
@@ -280,8 +282,9 @@ public:
 		}
 	}
 
-	/// Construct from DynamicArrayAuto.
-	ConstWeakArray(const DynamicArrayAuto<T, TSize>& arr)
+	/// Construct from DynamicArrayRaii.
+	template<typename TMemPool>
+	ConstWeakArray(const DynamicArrayRaii<T, TSize, TMemPool>& arr)
 		: ConstWeakArray()
 	{
 		if(arr.getSize())
@@ -346,7 +349,8 @@ public:
 		return *this;
 	}
 
-	ConstWeakArray& operator=(const DynamicArrayAuto<T, TSize>& arr)
+	template<typename TMemPool>
+	ConstWeakArray& operator=(const DynamicArrayRaii<T, TSize, TMemPool>& arr)
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();

Some files were not shown because too many files changed in this diff