Browse Source

Attempt at fixing compilation with gnustl_static, see #87

Michael Ragazzon 5 years ago
parent
commit
20b78498e5
3 changed files with 61 additions and 34 deletions
  1. 4 0
      Include/RmlUi/Core/Types.h
  2. 49 0
      Source/Core/Memory.cpp
  3. 8 34
      Source/Core/Memory.h

+ 4 - 0
Include/RmlUi/Core/Types.h

@@ -198,6 +198,10 @@ template <> struct hash<::Rml::Core::PropertyId> {
 	using utype = typename ::std::underlying_type<::Rml::Core::PropertyId>::type;
 	size_t operator() (const ::Rml::Core::PropertyId& t) const { ::std::hash<utype> h; return h(static_cast<utype>(t)); }
 };
+template <> struct hash<::Rml::Core::Character> {
+    using utype = typename ::std::underlying_type<::Rml::Core::Character>::type;
+    size_t operator() (const ::Rml::Core::Character& t) const { ::std::hash<utype> h; return h(static_cast<utype>(t)); }
+};
 }
 
 #endif

+ 49 - 0
Source/Core/Memory.cpp

@@ -27,12 +27,61 @@
  */
 
 #include "Memory.h"
+#include <stdlib.h>
+#include <stdint.h>
 
 namespace Rml {
 namespace Core {
 
 namespace Detail {
 
+// std::align replacement to support compilers missing this feature.
+// From https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350
+//
+inline void* rmlui_align(size_t alignment, size_t size, void*& ptr, size_t& space)
+{
+    uintptr_t pn = reinterpret_cast<uintptr_t>(ptr);
+    uintptr_t aligned = (pn + alignment - 1) & -alignment;
+    size_t padding = aligned - pn;
+    if (space < size + padding)
+        return nullptr;
+    space -= padding;
+    return ptr = reinterpret_cast<void*>(aligned);
+}
+
+BasicStackAllocator::BasicStackAllocator(size_t N) : N(N), data((byte*)malloc(N)), p(data)
+{}
+
+BasicStackAllocator::~BasicStackAllocator() noexcept {
+    RMLUI_ASSERT(p == data);
+    free(data);
+}
+
+void* BasicStackAllocator::allocate(size_t alignment, size_t byte_size)
+{
+    size_t available_space = N - ((byte*)p - data);
+
+    if (rmlui_align(alignment, byte_size, p, available_space))
+    {
+        void* result = p;
+        p = (byte*)p + byte_size;
+        return result;
+    }
+
+    // Fall back to malloc
+    return malloc(byte_size);
+}
+
+void BasicStackAllocator::deallocate(void* obj) noexcept
+{
+    if (obj < data || obj >= data + N)
+    {
+        free(obj);
+        return;
+    }
+    p = obj;
+}
+
 BasicStackAllocator& GetGlobalBasicStackAllocator()
 {
 	static BasicStackAllocator stack_allocator(10 * 1024);

+ 8 - 34
Source/Core/Memory.h

@@ -31,6 +31,7 @@
 
 
 #include "../../Include/RmlUi/Core/Types.h"
+#include "../../Include/RmlUi/Core/Traits.h"
 
 namespace Rml {
 namespace Core {
@@ -44,45 +45,18 @@ namespace Detail {
 		A very cheap allocator which only moves a pointer up and down during allocation and deallocation, respectively.
 		The allocator is initialized with some fixed memory. If it runs out, it falls back to malloc.
 		
-		Warning: Using this is quite dangerous as deallocation must happen in exact reverse order of allocation.
+		Warning: Using this is dangerous as deallocation must happen in exact reverse order of allocation.
 		
 		Do not use this class directly.
 	*/
 	class BasicStackAllocator
 	{
 	public:
-		BasicStackAllocator(size_t N) : N(N), data((byte*)malloc(N)), p(data)
-		{}
-
-		~BasicStackAllocator() noexcept {
-			RMLUI_ASSERT(p == data);
-			free(data);
-		}
-
-		void* allocate(size_t alignment, size_t byte_size)
-		{
-			size_t available_space = N - ((byte*)p - data);
-
-			if (std::align(alignment, byte_size, p, available_space))
-			{
-				void* result = p;
-				p = (byte*)p + byte_size;
-				return result;
-			}
-
-			// Fall back to malloc
-			return malloc(byte_size);
-		}
-
-		void deallocate(void* obj) noexcept
-		{
-			if (obj < data || obj >= data + N)
-			{
-				free(obj);
-				return;
-			}
-			p = obj;
-		}
+		BasicStackAllocator(size_t N);
+		~BasicStackAllocator() noexcept;
+
+		void* allocate(size_t alignment, size_t byte_size);
+		void deallocate(void* obj) noexcept;
 
 	private:
 		const size_t N;
@@ -104,7 +78,7 @@ namespace Detail {
 	heap on the very first construction of a global stack allocator, and will persist and be re-used after.
 	Falls back to malloc if there is not enough space left.
 
-	Warning: Using this is quite dangerous as deallocation must happen in exact reverse order of allocation.
+	Warning: Using this is dangerous as deallocation must happen in exact reverse order of allocation.
 	  Memory is shared between different global stack allocators. Should only be used for highly localized code,
 	  where memory is allocated and then quickly thrown away.
 */