From 2fcea6b79fa426d6965202424a6c37085a1c3f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Mon, 2 Jul 2018 17:53:49 +0200 Subject: [PATCH] Core/StackArray: Moved StackArray class to its own header --- ChangeLog.md | 2 + include/Nazara/Core/MemoryHelper.hpp | 75 +-------- include/Nazara/Core/MemoryHelper.inl | 183 --------------------- include/Nazara/Core/StackArray.hpp | 93 +++++++++++ include/Nazara/Core/StackArray.inl | 208 ++++++++++++++++++++++++ src/Nazara/Core/Posix/DirectoryImpl.cpp | 4 +- src/Nazara/Network/Posix/SocketImpl.cpp | 6 +- src/Nazara/Network/Win32/SocketImpl.cpp | 6 +- src/Nazara/Physics2D/PhysWorld2D.cpp | 4 +- src/Nazara/Physics3D/PhysWorld3D.cpp | 4 +- src/Nazara/Renderer/Renderer.cpp | 4 +- 11 files changed, 318 insertions(+), 271 deletions(-) create mode 100644 include/Nazara/Core/StackArray.hpp create mode 100644 include/Nazara/Core/StackArray.inl diff --git a/ChangeLog.md b/ChangeLog.md index 17a0a1521..8690c48e0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -119,6 +119,8 @@ Nazara Engine: - Added RigidBody2D::ClosestPointQuery - Fix Sprite copy constructor not copying corner colors - Added ObjectLibrary::Clear method +- ⚠️ StackArray class and macro was moved from Core/MemoryHelper.hpp to Core/StackArray.hpp +- ⚠️ Renamed NazaraStackAllocation[NoInit] macro to NazaraStackArray[NoInit] Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp index 6452c7562..9d4a71ee4 100644 --- a/include/Nazara/Core/MemoryHelper.hpp +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -16,6 +16,7 @@ #define NAZARA_ALLOCA_SUPPORT #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) + #include // with Clang/GCC, using alloca with a size of zero does nothing good @@ -24,16 +25,7 @@ #endif -#ifdef NAZARA_ALLOCA_SUPPORT - #define NazaraStackAllocation(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size) - #define NazaraStackAllocationNoInit(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size, Nz::NoInitTag()) -#else - #define NazaraStackAllocation(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size) - #define NazaraStackAllocationNoInit(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size, Nz::NoInitTag()) -#endif - #include -#include namespace Nz { @@ -45,71 +37,6 @@ namespace Nz template void PlacementDestroy(T* ptr); - - struct NoInitTag {}; - - template - class StackArray - { - public: - using value_type = T; - using const_iterator = const value_type*; - using const_pointer = const value_type*; - using const_reference = const value_type&; - using const_reverse_iterator = std::reverse_iterator; - using difference_type = std::ptrdiff_t; - using iterator = value_type*; - using pointer = value_type*; - using reference = value_type&; - using reverse_iterator = std::reverse_iterator; - using size_type = std::size_t; - - StackArray(T* stackMemory, std::size_t size); - StackArray(T* stackMemory, std::size_t size, NoInitTag); - ~StackArray(); - - reference back(); - const_reference back() const; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - T* data() noexcept; - const T* data() const noexcept; - - bool empty() const noexcept; - - iterator end() noexcept; - const_iterator end() const noexcept; - - void fill(const T& value); - - reference front() noexcept; - const_reference front() const noexcept; - - size_type max_size() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - size_type size() const noexcept; - - reference operator[](size_type pos); - const_reference operator[](size_type pos) const; - - private: - std::size_t m_size; - T* m_ptr; - }; - } #include diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index dfab05f15..afe2eca6b 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -11,10 +11,8 @@ #include #include -#include #include #include -#include #include namespace Nz @@ -79,187 +77,6 @@ namespace Nz if (ptr) ptr->~T(); } - - /*! - * \ingroup core - * \class Nz::StackArray - * \brief Core class that represents a stack-allocated (if alloca is present) array - */ - - template - StackArray::StackArray(T* stackMemory, std::size_t size) : - m_size(size), - m_ptr(stackMemory) - { - for (std::size_t i = 0; i < m_size; ++i) - PlacementNew(&m_ptr[i]); - } - - template - StackArray::StackArray(T* stackMemory, std::size_t size, NoInitTag) : - m_size(size), - m_ptr(stackMemory) - { - } - - template - StackArray::~StackArray() - { - for (std::size_t i = 0; i < m_size; ++i) - m_ptr[i].~T(); - - #ifndef NAZARA_ALLOCA_SUPPORT - OperatorDelete(m_ptr); - #endif - } - - template - typename StackArray::reference StackArray::back() - { - assert(m_size != 0); - return m_ptr[m_size - 1]; - } - - template - typename StackArray::const_reference StackArray::back() const - { - assert(m_size != 0); - return m_ptr[m_size - 1]; - } - - template - typename StackArray::iterator StackArray::begin() noexcept - { - return iterator(&m_ptr[0]); - } - - template - typename StackArray::const_iterator StackArray::begin() const noexcept - { - return const_iterator(&m_ptr[0]); - } - - template - typename StackArray::const_iterator StackArray::cbegin() const noexcept - { - return const_iterator(&m_ptr[0]); - } - - template - typename StackArray::const_iterator StackArray::cend() const noexcept - { - return const_iterator(&m_ptr[m_size]); - } - - template - typename StackArray::const_reverse_iterator StackArray::crbegin() const noexcept - { - return const_reverse_iterator(&m_ptr[m_size]); - } - - template - typename StackArray::const_reverse_iterator StackArray::crend() const noexcept - { - return const_reverse_iterator(&m_ptr[0]); - } - - template - T* StackArray::data() noexcept - { - return m_ptr; - } - - template - const T* StackArray::data() const noexcept - { - return m_ptr; - } - - template - bool StackArray::empty() const noexcept - { - return m_size == 0; - } - - template - typename StackArray::iterator StackArray::end() noexcept - { - return iterator(&m_ptr[m_size]); - } - - template - typename StackArray::const_iterator StackArray::end() const noexcept - { - return const_iterator(&m_ptr[m_size]); - } - - template - void StackArray::fill(const T& value) - { - std::fill(begin(), end(), value); - } - - template - typename StackArray::reference StackArray::front() noexcept - { - return m_ptr[0]; - } - - template - typename StackArray::const_reference StackArray::front() const noexcept - { - return m_ptr[0]; - } - - template - typename StackArray::size_type StackArray::max_size() const noexcept - { - return size(); - } - - template - typename StackArray::reverse_iterator StackArray::rbegin() noexcept - { - return reverse_iterator(&m_ptr[m_size]); - } - - template - typename StackArray::const_reverse_iterator StackArray::rbegin() const noexcept - { - return reverse_iterator(&m_ptr[m_size]); - } - - template - typename StackArray::reverse_iterator StackArray::rend() noexcept - { - return reverse_iterator(&m_ptr[0]); - } - - template - typename StackArray::const_reverse_iterator StackArray::rend() const noexcept - { - return reverse_iterator(&m_ptr[0]); - } - - template - typename StackArray::size_type StackArray::size() const noexcept - { - return m_size; - } - - template - typename StackArray::reference StackArray::operator[](size_type pos) - { - assert(pos < m_size); - return m_ptr[pos]; - } - - template - typename StackArray::const_reference StackArray::operator[](size_type pos) const - { - assert(pos < m_size); - return m_ptr[pos]; - } } #include diff --git a/include/Nazara/Core/StackArray.hpp b/include/Nazara/Core/StackArray.hpp new file mode 100644 index 000000000..1bed2b16c --- /dev/null +++ b/include/Nazara/Core/StackArray.hpp @@ -0,0 +1,93 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_STACKARRAY_HPP +#define NAZARA_STACKARRAY_HPP + +#include + +#ifdef NAZARA_ALLOCA_SUPPORT + #define NazaraStackArray(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size) + #define NazaraStackArrayNoInit(T, size) Nz::StackArray(static_cast(NAZARA_ALLOCA((size) * sizeof(T))), size, typename Nz::StackArray::NoInitTag()) +#else + #define NazaraStackArray(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size) + #define NazaraStackArrayNoInit(T, size) Nz::StackArray(static_cast(Nz::OperatorNew((size) * sizeof(T))), size, typename Nz::StackArray::NoInitTag()) +#endif + +#include +#include + +namespace Nz +{ + template + class StackArray + { + public: + struct NoInitTag {}; + + using value_type = T; + using const_iterator = const value_type*; + using const_pointer = const value_type*; + using const_reference = const value_type&; + using const_reverse_iterator = std::reverse_iterator; + using difference_type = std::ptrdiff_t; + using iterator = value_type*; + using pointer = value_type*; + using reference = value_type&; + using reverse_iterator = std::reverse_iterator; + using size_type = std::size_t; + + StackArray(T* stackMemory, std::size_t size); + StackArray(T* stackMemory, std::size_t size, NoInitTag); + ~StackArray(); + + reference back(); + const_reference back() const; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + T* data() noexcept; + const T* data() const noexcept; + + bool empty() const noexcept; + + iterator end() noexcept; + const_iterator end() const noexcept; + + void fill(const T& value); + + reference front() noexcept; + const_reference front() const noexcept; + + size_type max_size() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + size_type size() const noexcept; + + reference operator[](size_type pos); + const_reference operator[](size_type pos) const; + + private: + std::size_t m_size; + T* m_ptr; + }; + +} + +#include + +#endif // NAZARA_STACKARRAY_HPP diff --git a/include/Nazara/Core/StackArray.inl b/include/Nazara/Core/StackArray.inl new file mode 100644 index 000000000..989ffdf88 --- /dev/null +++ b/include/Nazara/Core/StackArray.inl @@ -0,0 +1,208 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// I'm not proud of those five following lines but ti's hard to do with another way now +#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION + #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED +#else + #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::StackArray + * \brief Core class that represents a stack-allocated (if alloca is present) array + */ + template + StackArray::StackArray(T* stackMemory, std::size_t size) : + m_size(size), + m_ptr(stackMemory) + { + for (std::size_t i = 0; i < m_size; ++i) + PlacementNew(&m_ptr[i]); + } + + template + StackArray::StackArray(T* stackMemory, std::size_t size, NoInitTag) : + m_size(size), + m_ptr(stackMemory) + { + } + + template + StackArray::~StackArray() + { + for (std::size_t i = 0; i < m_size; ++i) + PlacementDestroy(&m_ptr[i]); + + #ifndef NAZARA_ALLOCA_SUPPORT + OperatorDelete(m_ptr); + #endif + } + + template + typename StackArray::reference StackArray::back() + { + assert(m_size != 0); + return m_ptr[m_size - 1]; + } + + template + typename StackArray::const_reference StackArray::back() const + { + assert(m_size != 0); + return m_ptr[m_size - 1]; + } + + template + typename StackArray::iterator StackArray::begin() noexcept + { + return iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::begin() const noexcept + { + return const_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::cbegin() const noexcept + { + return const_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_iterator StackArray::cend() const noexcept + { + return const_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::crbegin() const noexcept + { + return const_reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::crend() const noexcept + { + return const_reverse_iterator(&m_ptr[0]); + } + + template + T* StackArray::data() noexcept + { + return m_ptr; + } + + template + const T* StackArray::data() const noexcept + { + return m_ptr; + } + + template + bool StackArray::empty() const noexcept + { + return m_size == 0; + } + + template + typename StackArray::iterator StackArray::end() noexcept + { + return iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_iterator StackArray::end() const noexcept + { + return const_iterator(&m_ptr[m_size]); + } + + template + void StackArray::fill(const T& value) + { + std::fill(begin(), end(), value); + } + + template + typename StackArray::reference StackArray::front() noexcept + { + return m_ptr[0]; + } + + template + typename StackArray::const_reference StackArray::front() const noexcept + { + return m_ptr[0]; + } + + template + typename StackArray::size_type StackArray::max_size() const noexcept + { + return size(); + } + + template + typename StackArray::reverse_iterator StackArray::rbegin() noexcept + { + return reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::const_reverse_iterator StackArray::rbegin() const noexcept + { + return reverse_iterator(&m_ptr[m_size]); + } + + template + typename StackArray::reverse_iterator StackArray::rend() noexcept + { + return reverse_iterator(&m_ptr[0]); + } + + template + typename StackArray::const_reverse_iterator StackArray::rend() const noexcept + { + return reverse_iterator(&m_ptr[0]); + } + + template + typename StackArray::size_type StackArray::size() const noexcept + { + return m_size; + } + + template + typename StackArray::reference StackArray::operator[](size_type pos) + { + assert(pos < m_size); + return m_ptr[pos]; + } + + template + typename StackArray::const_reference StackArray::operator[](size_type pos) const + { + assert(pos < m_size); + return m_ptr[pos]; + } +} + +#include + +// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine) +#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED + #undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION +#endif diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp index e688aabf6..e0a7968f0 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.cpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,7 +39,7 @@ namespace Nz std::size_t resultNameSize = std::strlen(m_result->d_name); std::size_t fullNameSize = pathSize + 1 + resultNameSize; - StackArray fullName = NazaraStackAllocationNoInit(char, fullNameSize + 1); + StackArray fullName = NazaraStackArrayNoInit(char, fullNameSize + 1); std::memcpy(&fullName[0], path.GetConstBuffer(), pathSize * sizeof(char)); fullName[pathSize] = '/'; std::memcpy(&fullName[pathSize + 1], m_result->d_name, resultNameSize * sizeof(char)); diff --git a/src/Nazara/Network/Posix/SocketImpl.cpp b/src/Nazara/Network/Posix/SocketImpl.cpp index c8140f019..7f94f5a9d 100644 --- a/src/Nazara/Network/Posix/SocketImpl.cpp +++ b/src/Nazara/Network/Posix/SocketImpl.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -574,7 +574,7 @@ namespace Nz NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); - StackArray sysBuffers = NazaraStackAllocation(iovec, bufferCount); + StackArray sysBuffers = NazaraStackArray(iovec, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { sysBuffers[i].iov_base = buffers[i].data; @@ -698,7 +698,7 @@ namespace Nz NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); - StackArray sysBuffers = NazaraStackAllocation(iovec, bufferCount); + StackArray sysBuffers = NazaraStackArray(iovec, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { sysBuffers[i].iov_base = buffers[i].data; diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 6d2e33f7f..15b89801b 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include // Some compilers (older versions of MinGW) lack Mstcpip.h which defines some structs/defines @@ -615,7 +615,7 @@ namespace Nz IpAddress senderIp; - StackArray winBuffers = NazaraStackAllocation(WSABUF, bufferCount); + StackArray winBuffers = NazaraStackArray(WSABUF, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { winBuffers[i].buf = static_cast(buffers[i].data); @@ -714,7 +714,7 @@ namespace Nz IpAddressImpl::SockAddrBuffer nameBuffer; int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); - StackArray winBuffers = NazaraStackAllocation(WSABUF, bufferCount); + StackArray winBuffers = NazaraStackArray(WSABUF, bufferCount); for (std::size_t i = 0; i < bufferCount; ++i) { winBuffers[i].buf = static_cast(buffers[i].data); diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index ea648b197..b967e63e5 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include @@ -44,7 +44,7 @@ namespace Nz { //TODO: constexpr if to prevent copy/cast if sizeof(cpVect) == sizeof(Vector2f) - StackArray nVertices = NazaraStackAllocation(Vector2f, vertexCount); + StackArray nVertices = NazaraStackArray(Vector2f, vertexCount); for (int i = 0; i < vertexCount; ++i) nVertices[i].Set(float(vertices[i].x), float(vertices[i].y)); diff --git a/src/Nazara/Physics3D/PhysWorld3D.cpp b/src/Nazara/Physics3D/PhysWorld3D.cpp index e85ddcf0b..225c28b9e 100644 --- a/src/Nazara/Physics3D/PhysWorld3D.cpp +++ b/src/Nazara/Physics3D/PhysWorld3D.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include @@ -173,7 +173,7 @@ namespace Nz using ContactJoint = void*; // Query all joints first, to prevent removing a joint from the list while iterating on it - StackArray contacts = NazaraStackAllocationNoInit(ContactJoint, NewtonContactJointGetContactCount(contactJoint)); + StackArray contacts = NazaraStackArray(ContactJoint, NewtonContactJointGetContactCount(contactJoint)); std::size_t contactIndex = 0; for (ContactJoint contact = NewtonContactJointGetFirstContact(contactJoint); contact; contact = NewtonContactJointGetNextContact(contactJoint, contact)) { diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index d2a3ed7e1..57f90ea3d 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -1762,7 +1762,7 @@ namespace Nz glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); maxLength++; - StackArray nameBuffer = NazaraStackAllocation(GLchar, maxLength + 1); + StackArray nameBuffer = NazaraStackArray(GLchar, maxLength + 1); for (GLint i = 0; i < count; i++) { GLint size;