mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-15 16:36:03 +08:00
Updates to mem_cast
This commit is contained in:
parent
abf8d7bb14
commit
8af219c0b3
@ -32,14 +32,59 @@ SOFTWARE.
|
||||
#define ETL_MEM_CAST_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../platform.h"
|
||||
#include "../memory.h"
|
||||
#include "../static_assert.h"
|
||||
#include "../largest.h"
|
||||
#include "../utility.h"
|
||||
#include "../placement_new.h"
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../file_error_numbers.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for array_wrapper exceptions.
|
||||
//***************************************************************************
|
||||
class mem_cast_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
mem_cast_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the buffer pointer alignment is not compatible.
|
||||
//***************************************************************************
|
||||
class mem_cast_alignment_exception : public mem_cast_exception
|
||||
{
|
||||
public:
|
||||
|
||||
mem_cast_alignment_exception(string_type file_name_, numeric_type line_number_)
|
||||
: mem_cast_exception(ETL_ERROR_TEXT("mem_cast:alignment", ETL_MEM_CAST_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pointer is null.
|
||||
//***************************************************************************
|
||||
class mem_cast_nullptr_exception : public mem_cast_exception
|
||||
{
|
||||
public:
|
||||
|
||||
mem_cast_nullptr_exception(string_type file_name_, numeric_type line_number_)
|
||||
: mem_cast_exception(ETL_ERROR_TEXT("mem_cast:null pointer", ETL_MEM_CAST_FILE_ID"B"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
/// mem_cast
|
||||
//*****************************************************************************
|
||||
@ -51,14 +96,20 @@ namespace etl
|
||||
static ETL_CONSTANT size_t Size = Size_;
|
||||
static ETL_CONSTANT size_t Alignment = Alignment_;
|
||||
|
||||
//***********************************
|
||||
/// Default constructor
|
||||
//***********************************
|
||||
ETL_CONSTEXPR mem_cast()
|
||||
: buffer()
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Copy constructor
|
||||
//***********************************
|
||||
template <size_t Other_Size, size_t Other_Alignment>
|
||||
ETL_CONSTEXPR mem_cast(const mem_cast<Other_Size, Other_Alignment>& other)
|
||||
: type_size(other.type_size)
|
||||
{
|
||||
ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large");
|
||||
ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "Other alignment incompatible");
|
||||
@ -66,9 +117,22 @@ namespace etl
|
||||
memcpy(buffer, other.buffer, Size_);
|
||||
}
|
||||
|
||||
#if ETL_CPP11_SUPPORTED
|
||||
//***********************************
|
||||
/// Emplace from parameters
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace(TArgs... args)
|
||||
{
|
||||
::new (static_cast<void*>(buffer)) T(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//***********************************
|
||||
/// Get a reference to T
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR T& get()
|
||||
ETL_CONSTEXPR T& ref()
|
||||
{
|
||||
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");
|
||||
@ -76,26 +140,20 @@ namespace etl
|
||||
return *static_cast<T*>(buffer);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get a const reference to T
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR const T& get() const
|
||||
ETL_CONSTEXPR const T& ref() 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 *static_cast<T*>(buffer);
|
||||
return *static_cast<const T*>(buffer);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_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 *static_cast<T*>(buffer);
|
||||
}
|
||||
|
||||
/// Assignment operator
|
||||
//***********************************
|
||||
template <size_t Other_Size, size_t Other_Alignment>
|
||||
ETL_CONSTEXPR mem_cast& operator =(const mem_cast<Other_Size, Other_Alignment>& rhs)
|
||||
@ -108,24 +166,32 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get the size of the buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR size_t size() const
|
||||
{
|
||||
return Size;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get the alignment of the buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR size_t alignment() const
|
||||
{
|
||||
return Alignment;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get a pointer to the internal buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR char* data()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get a const pointer to the internal buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR const char* data() const
|
||||
{
|
||||
@ -134,6 +200,7 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
/// The internal buffer
|
||||
etl::uninitialized_buffer<Size, 1U, Alignment> buffer;
|
||||
};
|
||||
|
||||
@ -147,65 +214,78 @@ namespace etl
|
||||
|
||||
static ETL_CONSTANT size_t Size = Size_;
|
||||
|
||||
//***********************************
|
||||
/// Default constructor
|
||||
//***********************************
|
||||
ETL_CONSTEXPR mem_cast_ptr()
|
||||
: pbuffer(ETL_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Construct with pointer to buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR mem_cast_ptr(char* pbuffer_)
|
||||
: pbuffer(pbuffer_)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Copy construct with pointer to buffer
|
||||
//***********************************
|
||||
template <size_t Other_Size>
|
||||
ETL_CONSTEXPR mem_cast_ptr(const mem_cast_ptr<Other_Size>& other, char* pbuffer_)
|
||||
: pbuffer(pbuffer_)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large");
|
||||
|
||||
memcpy(buffer, other.buffer, Size_);
|
||||
memcpy(pbuffer, other.pbuffer, Size_);
|
||||
}
|
||||
|
||||
#if ETL_CPP11_SUPPORTED
|
||||
//***********************************
|
||||
/// Emplace from parameters
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace(TArgs... args)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
|
||||
|
||||
::new (pbuffer) T(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//***********************************
|
||||
void set(char* pbuffer_)
|
||||
{
|
||||
pbuffer = pbuffer_;
|
||||
}
|
||||
|
||||
/// Get a reference to T
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR T& get()
|
||||
ETL_CONSTEXPR T& ref()
|
||||
{
|
||||
ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, "Alignment of T is incompatible");
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
|
||||
|
||||
return *reinterpret_cast<T*>(pbuffer);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_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);
|
||||
}
|
||||
|
||||
/// Get a const reference to T
|
||||
//***********************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR operator T() const
|
||||
ETL_CONSTEXPR const T& ref() const
|
||||
{
|
||||
ETL_STATIC_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, "Alignment of T is incompatible");
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
|
||||
|
||||
return *reinterpret_cast<T*>(pbuffer);
|
||||
return *reinterpret_cast<const T*>(pbuffer);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template <size_t Other_Size>
|
||||
mem_cast_ptr& operator =(const mem_cast_ptr<Other_Size>& rhs)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large");
|
||||
|
||||
memcpy(pbuffer, rhs.pbuffer, Size_);
|
||||
@ -213,12 +293,24 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Assignment operator
|
||||
//***********************************
|
||||
ETL_CONSTEXPR size_t size() const
|
||||
{
|
||||
return Size;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get a pointer to the internal buffer
|
||||
//***********************************
|
||||
void data(char* pbuffer_)
|
||||
{
|
||||
pbuffer = pbuffer_;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Get a const pointer to the internal buffer
|
||||
//***********************************
|
||||
ETL_CONSTEXPR char* data() const
|
||||
{
|
||||
@ -227,18 +319,17 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
/// Pointer to the buffer
|
||||
char* pbuffer;
|
||||
};
|
||||
|
||||
#if ETL_CPP11_SUPPORTED
|
||||
//*****************************************************************************
|
||||
/// mem_cast_var
|
||||
/// mem_cast from a variadic list of types
|
||||
//*****************************************************************************
|
||||
template <typename... TTypes>
|
||||
class mem_cast_types : public etl::mem_cast<etl::largest<TTypes...>::size,
|
||||
etl::largest<TTypes...>::alignment>
|
||||
{
|
||||
};
|
||||
using mem_cast_types = etl::mem_cast<etl::largest<TTypes...>::size, etl::largest<TTypes...>::alignment>;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -92,5 +92,6 @@ SOFTWARE.
|
||||
#define ETL_QUEUE_SPSC_LOCKABLE_FILE_ID "59"
|
||||
#define ETL_MESSAGE_ROUTER_REGISTRY_FILE_ID "60"
|
||||
#define ETL_ARRAY_WRAPPER_FILE_ID "61"
|
||||
#define ETL_MEM_CAST_FILE_ID "62"
|
||||
|
||||
#endif
|
||||
|
||||
@ -40,6 +40,20 @@ namespace
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
Data()
|
||||
: c(0)
|
||||
, d(0)
|
||||
, a()
|
||||
{
|
||||
}
|
||||
|
||||
Data(char c_, double d_, std::array<int, 3> a_)
|
||||
: c(c_)
|
||||
, d(d_)
|
||||
, a(a_)
|
||||
{
|
||||
}
|
||||
|
||||
char c;
|
||||
double d;
|
||||
std::array<int, 3> a;
|
||||
@ -120,22 +134,76 @@ namespace
|
||||
CHECK(alignof(Data) <= memCastTypes.alignment());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_emplace_type)
|
||||
{
|
||||
MemCast memCast;
|
||||
|
||||
memCast.emplace<char>(123);
|
||||
CHECK_EQUAL(123, memCast.ref<char>());
|
||||
|
||||
memCast.emplace<double>(1.23);
|
||||
CHECK_EQUAL(1.23, memCast.ref<double>());
|
||||
|
||||
memCast.emplace<Data>(123, 1.23, std::array<int, 3>{ 1, 2, 3 });
|
||||
CHECK(123 == memCast.ref<Data>().c);
|
||||
CHECK(1.23 == memCast.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_to_type)
|
||||
{
|
||||
MemCast memCast;
|
||||
MemCast memCast;
|
||||
|
||||
char* pbuffer = memCast.data();
|
||||
*pbuffer = 123;
|
||||
CHECK_EQUAL(123, memCast.get<char>());
|
||||
CHECK_EQUAL(123, memCast.ref<char>());
|
||||
|
||||
*reinterpret_cast<double*>(pbuffer) = 1.23;
|
||||
CHECK_EQUAL(1.23, memCast.get<double>());
|
||||
CHECK_EQUAL(1.23, memCast.ref<double>());
|
||||
|
||||
*reinterpret_cast<Data*>(pbuffer) = { 123, 1.23, { 1, 2, 3 } };
|
||||
CHECK(123 == memCast.get<Data>().c);
|
||||
CHECK(1.23 == memCast.get<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.get<Data>().a);
|
||||
CHECK(123 == memCast.ref<Data>().c);
|
||||
CHECK(1.23 == memCast.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_const_mem_cast_to_type)
|
||||
{
|
||||
MemCast memCast;
|
||||
const MemCast& memCastRef = memCast;
|
||||
|
||||
char* pbuffer = memCast.data();
|
||||
*pbuffer = 123;
|
||||
CHECK_EQUAL(123, memCastRef.ref<char>());
|
||||
|
||||
*reinterpret_cast<double*>(pbuffer) = 1.23;
|
||||
CHECK_EQUAL(1.23, memCastRef.ref<double>());
|
||||
|
||||
*reinterpret_cast<Data*>(pbuffer) = { 123, 1.23, { 1, 2, 3 } };
|
||||
CHECK(123 == memCastRef.ref<Data>().c);
|
||||
CHECK(1.23 == memCastRef.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCastRef.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_types_to_type)
|
||||
{
|
||||
MemCastTypes memCastTypes;
|
||||
|
||||
char* pbuffer = memCastTypes.data();
|
||||
*pbuffer = 123;
|
||||
CHECK_EQUAL(123, memCastTypes.ref<char>());
|
||||
|
||||
*reinterpret_cast<double*>(pbuffer) = 1.23;
|
||||
CHECK_EQUAL(1.23, memCastTypes.ref<double>());
|
||||
|
||||
*reinterpret_cast<Data*>(pbuffer) = { 123, 1.23, { 1, 2, 3 } };
|
||||
CHECK(123 == memCastTypes.ref<Data>().c);
|
||||
CHECK(1.23 == memCastTypes.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCastTypes.ref<Data>().a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
189
test/test_mem_cast_ptr.cpp
Normal file
189
test/test_mem_cast_ptr.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/******************************************************************************
|
||||
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_cast.h"
|
||||
#include "etl/largest.h"
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
Data()
|
||||
: c(0)
|
||||
, d(0)
|
||||
, a()
|
||||
{
|
||||
}
|
||||
|
||||
Data(char c_, double d_, std::array<int, 3> a_)
|
||||
: c(c_)
|
||||
, d(d_)
|
||||
, a(a_)
|
||||
{
|
||||
}
|
||||
|
||||
char c;
|
||||
double d;
|
||||
std::array<int, 3> a;
|
||||
};
|
||||
|
||||
constexpr size_t Size = etl::largest<char, double, Data>::size;
|
||||
constexpr size_t Alignment = etl::largest<char, double, Data>::alignment;
|
||||
|
||||
// Test variant types.
|
||||
using MemCast = etl::mem_cast_ptr<Size>;
|
||||
|
||||
char c;
|
||||
double d;
|
||||
Data data;
|
||||
|
||||
std::aligned_storage_t<Size, Alignment> buffer;
|
||||
|
||||
SUITE(test_mem_cast)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_size)
|
||||
{
|
||||
MemCast memCast;
|
||||
|
||||
CHECK(sizeof(char) <= MemCast::Size);
|
||||
CHECK(sizeof(short) <= MemCast::Size);
|
||||
CHECK(sizeof(Data) <= MemCast::Size);
|
||||
|
||||
CHECK(sizeof(char) <= memCast.Size);
|
||||
CHECK(sizeof(short) <= memCast.Size);
|
||||
CHECK(sizeof(Data) <= memCast.Size);
|
||||
|
||||
CHECK(sizeof(char) <= memCast.size());
|
||||
CHECK(sizeof(short) <= memCast.size());
|
||||
CHECK(sizeof(Data) <= memCast.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_emplace_type)
|
||||
{
|
||||
char* pbuffer = reinterpret_cast<char*>(&buffer);
|
||||
|
||||
MemCast memCast(pbuffer);
|
||||
|
||||
memCast.emplace<char>(123);
|
||||
CHECK_EQUAL(123, memCast.ref<char>());
|
||||
|
||||
memCast.emplace<double>(1.23);
|
||||
CHECK_EQUAL(1.23, memCast.ref<double>());
|
||||
|
||||
memCast.emplace<Data>(123, 1.23, std::array<int, 3>{ 1, 2, 3 });
|
||||
CHECK(123 == memCast.ref<Data>().c);
|
||||
CHECK(1.23 == memCast.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_to_type)
|
||||
{
|
||||
char* pbuffer = reinterpret_cast<char*>(&buffer);
|
||||
|
||||
MemCast memCast(pbuffer);
|
||||
|
||||
pbuffer = memCast.data();
|
||||
*pbuffer = 123;
|
||||
CHECK_EQUAL(123, memCast.ref<char>());
|
||||
|
||||
*reinterpret_cast<double*>(pbuffer) = 1.23;
|
||||
CHECK_EQUAL(1.23, memCast.ref<double>());
|
||||
|
||||
*reinterpret_cast<Data*>(pbuffer) = { 123, 1.23, { 1, 2, 3 } };
|
||||
CHECK(123 == memCast.ref<Data>().c);
|
||||
CHECK(1.23 == memCast.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_const_mem_cast_to_type)
|
||||
{
|
||||
char* pbuffer = reinterpret_cast<char*>(&buffer);
|
||||
|
||||
const MemCast memCast(pbuffer);
|
||||
|
||||
pbuffer = memCast.data();
|
||||
*pbuffer = 123;
|
||||
CHECK_EQUAL(123, memCast.ref<char>());
|
||||
|
||||
*reinterpret_cast<double*>(pbuffer) = 1.23;
|
||||
CHECK_EQUAL(1.23, memCast.ref<double>());
|
||||
|
||||
*reinterpret_cast<Data*>(pbuffer) = { 123, 1.23, { 1, 2, 3 } };
|
||||
CHECK(123 == memCast.ref<Data>().c);
|
||||
CHECK(1.23 == memCast.ref<Data>().d);
|
||||
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_to_type_no_buffer)
|
||||
{
|
||||
MemCast memCast;
|
||||
|
||||
CHECK_THROW(memCast.ref<char>(), etl::mem_cast_nullptr_exception);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_const_mem_cast_to_type_no_buffer)
|
||||
{
|
||||
const MemCast memCast;
|
||||
|
||||
CHECK_THROW(memCast.ref<char>(), etl::mem_cast_nullptr_exception);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_to_type_misaligned_buffer)
|
||||
{
|
||||
double d;
|
||||
char* pbuffer = reinterpret_cast<char*>(&d);
|
||||
MemCast memCast(pbuffer + 1);
|
||||
|
||||
CHECK_THROW(memCast.ref<double>(), etl::mem_cast_alignment_exception);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_const_mem_cast_to_type_misaligned_buffer)
|
||||
{
|
||||
double d;
|
||||
char* pbuffer = reinterpret_cast<char*>(&d);
|
||||
const MemCast memCast(pbuffer + 1);
|
||||
|
||||
CHECK_THROW(memCast.ref<double>(), etl::mem_cast_alignment_exception);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -4496,6 +4496,7 @@
|
||||
<ClCompile Include="..\test_make_string.cpp" />
|
||||
<ClCompile Include="..\test_mean.cpp" />
|
||||
<ClCompile Include="..\test_mem_cast.cpp" />
|
||||
<ClCompile Include="..\test_mem_cast_ptr.cpp" />
|
||||
<ClCompile Include="..\test_message_packet.cpp" />
|
||||
<ClCompile Include="..\test_message_router_registry.cpp" />
|
||||
<ClCompile Include="..\test_multi_array.cpp" />
|
||||
|
||||
@ -2537,6 +2537,9 @@
|
||||
<ClCompile Include="..\test_mem_cast.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_mem_cast_ptr.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\library.properties">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user