From 380fc59b2be2236d07e3e1e30fcd412d4ee8a3ef Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 26 May 2021 22:04:34 +0100 Subject: [PATCH] Further updates to mem_type --- include/etl/experimental/mem_type.h | 349 ++++++++++++++++------------ test/test_mem_type.cpp | 88 +++++++ test/vs2019/etl.vcxproj | 1 + test/vs2019/etl.vcxproj.filters | 3 + 4 files changed, 287 insertions(+), 154 deletions(-) create mode 100644 test/test_mem_type.cpp diff --git a/include/etl/experimental/mem_type.h b/include/etl/experimental/mem_type.h index 68a8c7b5..60cc43f1 100644 --- a/include/etl/experimental/mem_type.h +++ b/include/etl/experimental/mem_type.h @@ -1,4 +1,35 @@ -#pragma once +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2021 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_MEM_TYPE_INCLUDED +#define ETL_MEM_TYPE_INCLUDED #include @@ -6,181 +37,191 @@ #include "../memory.h" #include "../static_assert.h" -//***************************************************************************** -/// mem_type -//***************************************************************************** -template -class mem_type +namespace etl { -public: - - static constexpr size_t Size = Size_; - static constexpr size_t Alignment = Alignment_; - - //*********************************** - template - constexpr mem_type(const mem_type& other) + //***************************************************************************** + /// mem_type + //***************************************************************************** + template + class mem_type { - ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large"); - ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "Other alignment incompatible"); + public: - memcpy(buffer, other.buffer, Size_); - } + static ETL_CONSTANT size_t Size = Size_; + static ETL_CONSTANT size_t Alignment = Alignment_; - //*********************************** - template - constexpr T& get() + //*********************************** + ETL_CONSTEXPR mem_type() + { + } + + //*********************************** + template + ETL_CONSTEXPR mem_type(const mem_type& other) + { + 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 + ETL_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 + ETL_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 + ETL_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 + ETL_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_); + + return *this; + } + + //*********************************** + ETL_CONSTEXPR size_t size() const + { + return Size; + } + + //*********************************** + ETL_CONSTEXPR size_t alignment() const + { + return Alignment; + } + + //*********************************** + ETL_CONSTEXPR char* data() const + { + return buffer; + } + + private: + + etl::aligned_storage buffer; + }; + + //***************************************************************************** + /// mem_type_ptr + //***************************************************************************** + template + class mem_type_ptr { - 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"); + public: - return *reinterpret_cast(buffer); - } + static ETL_CONSTANT size_t Size = Size_; - //*********************************** - template - 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"); + //*********************************** + ETL_CONSTEXPR mem_type_ptr() + : pbuffer(ETL_NULLPTR) + { + } - return *reinterpret_cast(buffer); - } + //*********************************** + ETL_CONSTEXPR mem_type_ptr(char* pbuffer_) + : pbuffer(pbuffer_) + { + } - //*********************************** - template - 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"); + //*********************************** + template + ETL_CONSTEXPR mem_type_ptr(const mem_type_ptr& other, char* pbuffer_) + : pbuffer(pbuffer_) + { + ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large"); - return *reinterpret_cast(buffer); - } + memcpy(buffer, other.buffer, Size_); + } - //*********************************** - 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"); + //*********************************** + void set(char* pbuffer_) + { + pbuffer = pbuffer_; + } - memcpy(buffer, rhs.buffer, Size_); + //*********************************** + template + ETL_CONSTEXPR T& get() + { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); - return *this; - } + return *reinterpret_cast(pbuffer); + } - //*********************************** - constexpr size_t size() const - { - return Size; - } + //*********************************** + template + ETL_CONSTEXPR const T& get() const + { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); - //*********************************** - constexpr size_t alignment() const - { - return Alignment; - } + return *reinterpret_cast(pbuffer); + } - //*********************************** - constexpr char* data() const - { - return buffer; - } + //*********************************** + template + ETL_CONSTEXPR operator T() const + { + ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); -private: + return *reinterpret_cast(pbuffer); + } - etl::aligned_storage buffer; -}; + //*********************************** + template + mem_type_ptr& operator =(const mem_type_ptr& rhs) + { + ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); -//***************************************************************************** -/// mem_type_ptr -//***************************************************************************** -template -class mem_type_ptr -{ -public: + memcpy(pbuffer, rhs.pbuffer, Size_); - static constexpr size_t Size = Size_; + return *this; + } - //*********************************** - constexpr mem_type_ptr() - : pbuffer(ETL_NULLPTR) - { - } + //*********************************** + ETL_CONSTEXPR size_t size() const + { + return Size; + } - //*********************************** - constexpr mem_type_ptr(char* pbuffer_) - : pbuffer(pbuffer_) - { - } + //*********************************** + ETL_CONSTEXPR char* data() const + { + return pbuffer; + } - //*********************************** - template - constexpr mem_type_ptr(const mem_type_ptr= Other_Size, "Other size is too large"); + private: - memcpy(buffer, other.buffer, Size_); - } + char* pbuffer; + }; +} - //*********************************** - void set(char* pbuffer_) - { - pbuffer = pbuffer_; - } - - //*********************************** - template - constexpr T& get() - { - ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); - - return *reinterpret_cast(pbuffer); - } - - //*********************************** - template - 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 - constexpr operator T() const - { - ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of::value) == 0, "Alignment of T is incompatible"); - - return *reinterpret_cast(pbuffer); - } - - //*********************************** - template - mem_type_ptr& operator =(const mem_type_ptr& rhs) - { - ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); - - memcpy(pbuffer, rhs.pbuffer, Size_); - - return *this; - } - - //*********************************** - constexpr size_t size() const - { - return Size; - } - - //*********************************** - constexpr char* data() const - { - return pbuffer; - } - -private: - - char* pbuffer; -}; +#endif diff --git a/test/test_mem_type.cpp b/test/test_mem_type.cpp new file mode 100644 index 00000000..b0d1db30 --- /dev/null +++ b/test/test_mem_type.cpp @@ -0,0 +1,88 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2021 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/experimental/mem_type.h" +#include "etl/largest.h" + +#include +#include +#include +#include + +namespace +{ + struct Data + { + char c; + short s; + std::array a; + }; + + // Test variant types. + using MemType = etl::mem_type::size, + etl::largest::alignment>; + + SUITE(test_mem_type) + { + TEST(test_alignment) + { + MemType memType; + + CHECK(alignof(char) <= MemType::Alignment); + CHECK(alignof(short) <= MemType::Alignment); + CHECK(alignof(Data) <= MemType::Alignment); + + CHECK(alignof(char) <= memType.Alignment); + CHECK(alignof(short) <= memType.Alignment); + CHECK(alignof(Data) <= memType.Alignment); + + CHECK(alignof(char) <= memType.alignment()); + CHECK(alignof(short) <= memType.alignment()); + CHECK(alignof(Data) <= memType.alignment()); + } + + TEST(test_size) + { + MemType memType; + + CHECK(sizeof(char) <= MemType::Size); + CHECK(sizeof(short) <= MemType::Size); + CHECK(sizeof(Data) <= MemType::Size); + + CHECK(sizeof(char) <= memType.Size); + CHECK(sizeof(short) <= memType.Size); + CHECK(sizeof(Data) <= memType.Size); + + CHECK(sizeof(char) <= memType.size()); + CHECK(sizeof(short) <= memType.size()); + CHECK(sizeof(Data) <= memType.size()); + } + }; +} diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 592ece07..f794c3bb 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -4495,6 +4495,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 6d6ac599..820f36d5 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -2534,6 +2534,9 @@ Source Files + + Source Files +