From d8777dc2f6b7334103e5d9b9131143501fb2d4b9 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 26 May 2021 11:09:02 +0100 Subject: [PATCH] Further updates to mem_type --- include/etl/experimental/mem_type.h | 91 +++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/include/etl/experimental/mem_type.h b/include/etl/experimental/mem_type.h index 0b9532de..68a8c7b5 100644 --- a/include/etl/experimental/mem_type.h +++ b/include/etl/experimental/mem_type.h @@ -1,46 +1,68 @@ #pragma once -template + +#include + +#include "../platform.h" +#include "../memory.h" +#include "../static_assert.h" + +//***************************************************************************** +/// mem_type +//***************************************************************************** +template class mem_type { public: - static constexpr size_t Size = Size_; + static constexpr size_t Size = Size_; + static constexpr size_t Alignment = Alignment_; //*********************************** - template - mem_type(const mem_type + constexpr mem_type(const mem_type& other) { - ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large"); + ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large"); + ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "Other alignment incompatible"); memcpy(buffer, other.buffer, Size_); } //*********************************** template - T& get() + constexpr T& get() { + ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large"); + ETL_STATIC_ASSERT(Alignment >= etl::alignment_of::value, "Alignment of T is incompatible"); + return *reinterpret_cast(buffer); } //*********************************** template - const T& get() const + constexpr const T& get() const { + ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large"); + ETL_STATIC_ASSERT(Alignment >= etl::alignment_of::value, "Alignment of T is incompatible"); + return *reinterpret_cast(buffer); } //*********************************** template - operator T() const + constexpr operator T() const { + ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large"); + ETL_STATIC_ASSERT(Alignment >= etl::alignment_of::value, "Alignment of T is incompatible"); + return *reinterpret_cast(buffer); } //*********************************** - template - mem_type& operator =(const mem_type& rhs) + template + constexpr mem_type& operator =(const mem_type& rhs) { ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); + ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "RHS alignment incompatible"); memcpy(buffer, rhs.buffer, Size_); @@ -53,17 +75,26 @@ public: return Size; } + //*********************************** + constexpr size_t alignment() const + { + return Alignment; + } + //*********************************** constexpr char* data() const { - return buffer; + return buffer; } private: - char buffer[Size] + etl::aligned_storage buffer; }; +//***************************************************************************** +/// mem_type_ptr +//***************************************************************************** template class mem_type_ptr { @@ -72,45 +103,57 @@ public: static constexpr size_t Size = Size_; //*********************************** - mem_type_ptr() + constexpr mem_type_ptr() : pbuffer(ETL_NULLPTR) { } //*********************************** - mem_type_ptr(char* pbuffer_) + constexpr mem_type_ptr(char* pbuffer_) : pbuffer(pbuffer_) { } //*********************************** template - mem_type_ptr(const mem_type_ptr= Other_Size, "Other size is too large"); + ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large"); - memcpy(buffer, other.buffer, Size_); + memcpy(buffer, other.buffer, Size_); + } + + //*********************************** + void set(char* pbuffer_) + { + pbuffer = pbuffer_; } //*********************************** template - T& get() + constexpr T& get() { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); + return *reinterpret_cast(pbuffer); } //*********************************** template - const T& get() const + constexpr const T& get() const { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); + return *reinterpret_cast(pbuffer); } //*********************************** template - operator T() const + constexpr operator T() const { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); + return *reinterpret_cast(pbuffer); } @@ -118,11 +161,11 @@ public: template mem_type_ptr& operator =(const mem_type_ptr& rhs) { - ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); + ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); - memcpy(pbuffer, rhs.pbuffer, Size_); + memcpy(pbuffer, rhs.pbuffer, Size_); - return *this; + return *this; } //*********************************** @@ -134,7 +177,7 @@ public: //*********************************** constexpr char* data() const { - return pbuffer; + return pbuffer; } private: