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;
 	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)); }
 	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
 #endif

+ 49 - 0
Source/Core/Memory.cpp

@@ -27,12 +27,61 @@
  */
  */
 
 
 #include "Memory.h"
 #include "Memory.h"
+#include <stdlib.h>
+#include <stdint.h>
 
 
 namespace Rml {
 namespace Rml {
 namespace Core {
 namespace Core {
 
 
 namespace Detail {
 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()
 BasicStackAllocator& GetGlobalBasicStackAllocator()
 {
 {
 	static BasicStackAllocator stack_allocator(10 * 1024);
 	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/Types.h"
+#include "../../Include/RmlUi/Core/Traits.h"
 
 
 namespace Rml {
 namespace Rml {
 namespace Core {
 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.
 		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.
 		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.
 		Do not use this class directly.
 	*/
 	*/
 	class BasicStackAllocator
 	class BasicStackAllocator
 	{
 	{
 	public:
 	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:
 	private:
 		const size_t N;
 		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.
 	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.
 	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,
 	  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.
 	  where memory is allocated and then quickly thrown away.
 */
 */