Further updates to mem_type

This commit is contained in:
John Wellbelove 2021-05-26 11:09:02 +01:00
parent ab7fcbee64
commit d8777dc2f6

View File

@ -1,46 +1,68 @@
#pragma once
template <size_t Size_>
#include <stdint.h>
#include "../platform.h"
#include "../memory.h"
#include "../static_assert.h"
//*****************************************************************************
/// mem_type
//*****************************************************************************
template <size_t Size_ , size_t Alignment_>
class mem_type
{
public:
static constexpr size_t Size = Size_;
static constexpr size_t Size = Size_;
static constexpr size_t Alignment = Alignment_;
//***********************************
template <size_t Other_Size>
mem_type(const mem_type<Other_Size& other)
template <size_t Other_Size, size_t Other_Alignment>
constexpr mem_type(const mem_type<Other_Size, Other_Alignment>& 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 <typename T>
T& get()
constexpr T& get()
{
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large");
ETL_STATIC_ASSERT(Alignment >= etl::alignment_of<T>::value, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(buffer);
}
//***********************************
template <typename T>
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<T>::value, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(buffer);
}
//***********************************
template <typename T>
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<T>::value, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(buffer);
}
//***********************************
template <size_t Other_Size>
mem_type& operator =(const mem_type<Other_Size>& rhs)
template <size_t Other_Size, size_t Other_Alignment>
constexpr mem_type& operator =(const mem_type<Other_Size, Other_Alignment>& 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<Size, Alignment> buffer;
};
//*****************************************************************************
/// mem_type_ptr
//*****************************************************************************
template <size_t Size_>
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 <size_t Other_Size>
mem_type_ptr(const mem_type_ptr<Other_Size& other, char* pbuffer_)
constexpr mem_type_ptr(const mem_type_ptr<Other_Size& other, char* pbuffer_)
: pbuffer(pbuffer_)
{
ETL_STATIC_ASSERT(Size >= 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 <typename T>
T& get()
constexpr T& get()
{
ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(pbuffer);
}
//***********************************
template <typename T>
const T& get() const
constexpr const T& get() const
{
ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(pbuffer);
}
//***********************************
template <typename T>
operator T() const
constexpr operator T() const
{
ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, "Alignment of T is incompatible");
return *reinterpret_cast<T*>(pbuffer);
}
@ -118,11 +161,11 @@ public:
template <size_t Other_Size>
mem_type_ptr& operator =(const mem_type_ptr<Other_Size>& 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: