mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Merge branch 'pull-request/#989-Packed-unaligned_type' into development
# Conflicts: # .gitignore
This commit is contained in:
commit
3b54c4e7a2
1
.gitignore
vendored
1
.gitignore
vendored
@ -391,3 +391,4 @@ test/test_file_list.txt
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/CopilotIndices
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/FileContentIndex
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/v17
|
||||
test/etl_error_handler/assert_function/build-make
|
||||
|
||||
@ -103,5 +103,5 @@ SOFTWARE.
|
||||
#define ETL_EXPECTED_FILE_ID "70"
|
||||
#define ETL_ALIGNMENT_FILE_ID "71"
|
||||
#define ETL_BASE64_FILE_ID "72"
|
||||
|
||||
#define ETL_UNALIGNED_TYPE_FILE_ID "73"
|
||||
#endif
|
||||
|
||||
@ -463,15 +463,19 @@ SOFTWARE.
|
||||
//*************************************
|
||||
// Determine if the ETL should use __attribute__((packed).
|
||||
#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6)
|
||||
#define ETL_PACKED __attribute__((packed))
|
||||
#define ETL_PACKED_CLASS(class_type) class __attribute__((packed)) class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) struct __attribute__((packed)) struct_type
|
||||
#define ETL_END_PACKED
|
||||
#define ETL_HAS_PACKED 1
|
||||
#elif defined(ETL_COMPILER_MICROSOFT)
|
||||
#define ETL_PACKED __pragma(pack(push, 1))
|
||||
#define ETL_PACKED_CLASS(class_type) __pragma(pack(push, 1)) class class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) __pragma(pack(push, 1)) struct struct_type
|
||||
#define ETL_PACKED
|
||||
#define ETL_END_PACKED __pragma(pack(pop))
|
||||
#define ETL_HAS_PACKED 1
|
||||
#else
|
||||
#define ETL_PACKED
|
||||
#define ETL_PACKED_CLASS(class_type) class class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) struct struct_type
|
||||
#define ETL_END_PACKED
|
||||
#define ETL_HAS_PACKED 0
|
||||
#endif
|
||||
|
||||
@ -41,19 +41,48 @@ SOFTWARE.
|
||||
#include "iterator.h"
|
||||
#include "algorithm.h"
|
||||
#include "bit.h"
|
||||
#include "array.h"
|
||||
#include "exception.h"
|
||||
#include "file_error_numbers.h"
|
||||
|
||||
#include <bit>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace etl
|
||||
{
|
||||
struct unaligned_type_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
unaligned_type_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Buffer size exception.
|
||||
//***************************************************************************
|
||||
class unaligned_type_buffer_size : public unaligned_type_exception
|
||||
{
|
||||
public:
|
||||
|
||||
unaligned_type_buffer_size(string_type file_name_, numeric_type line_number_)
|
||||
: unaligned_type_exception(ETL_ERROR_TEXT("unaligned_type:buffer size", ETL_UNALIGNED_TYPE_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace private_unaligned_type
|
||||
{
|
||||
//*************************************************************************
|
||||
/// unaligned_type_common
|
||||
/// Contains all functionality that doesn't require the type.
|
||||
/// ETL_PACKED ensures that GCC does not complain when used in a packed object.
|
||||
//*************************************************************************
|
||||
template <size_t Size_>
|
||||
class ETL_PACKED unaligned_type_common
|
||||
ETL_PACKED_CLASS(unaligned_type_common)
|
||||
{
|
||||
public:
|
||||
|
||||
@ -227,7 +256,7 @@ namespace etl
|
||||
///\tparam Endian The endianness of the arithmetic type.
|
||||
//*************************************************************************
|
||||
template <typename T, int Endian_>
|
||||
class ETL_PACKED unaligned_type : public private_unaligned_type::unaligned_type_common<sizeof(T)>
|
||||
ETL_PACKED_CLASS(unaligned_type) : public private_unaligned_type::unaligned_type_common<sizeof(T)>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -243,8 +272,8 @@ namespace etl
|
||||
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::reverse_iterator reverse_iterator;
|
||||
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
static ETL_CONSTANT int Endian = Endian_;
|
||||
static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common<sizeof(T)>::Size;
|
||||
static ETL_CONSTANT int Endian = Endian_;
|
||||
static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common<sizeof(T)>::Size;
|
||||
|
||||
//*************************************************************************
|
||||
/// Default constructor
|
||||
@ -261,6 +290,24 @@ namespace etl
|
||||
unaligned_copy<T>::copy(value, this->storage);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Construct from an address.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 unaligned_type(const void* address)
|
||||
{
|
||||
etl::copy_n(reinterpret_cast<const char*>(address), sizeof(T), this->storage);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Construct from an address and size.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 unaligned_type(const void* address, size_t buffer_size)
|
||||
{
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
|
||||
|
||||
etl::copy_n(reinterpret_cast<const char*>(address), sizeof(T), this->storage);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor
|
||||
//*************************************************************************
|
||||
@ -315,6 +362,56 @@ namespace etl
|
||||
return value;
|
||||
}
|
||||
|
||||
// For run time pointer
|
||||
static unaligned_type<T, Endian_>& at_address(void* address)
|
||||
{
|
||||
//auto p = (::new(address) unaligned_type<T, Endian_>());
|
||||
|
||||
//return *p;
|
||||
|
||||
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
// For const run time pointer
|
||||
static const unaligned_type<T, Endian_>& at_address(const void* address)
|
||||
{
|
||||
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
// For run time pointer and size
|
||||
static unaligned_type<T, Endian_>& at_address(void* address, size_t buffer_size)
|
||||
{
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
|
||||
|
||||
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
// For const run time pointer and size
|
||||
static const unaligned_type<T, Endian_>& at_address(const void* address, size_t buffer_size)
|
||||
{
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
|
||||
|
||||
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
// For run time pointer and compile time size
|
||||
template <size_t Size>
|
||||
static unaligned_type<T, Endian_>& at_address(void* address)
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Buffer size to small for type");
|
||||
|
||||
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
// For const run time pointer and compile time size
|
||||
template <size_t Size>
|
||||
static unaligned_type<T, Endian_>& at_address(const void* address)
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Buffer size to small for type");
|
||||
|
||||
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Unaligned copy
|
||||
//*************************************************************************
|
||||
|
||||
@ -730,7 +730,7 @@ namespace
|
||||
uint32_t c = 0x87654321;
|
||||
};
|
||||
|
||||
struct ETL_PACKED Packed
|
||||
ETL_PACKED_STRUCT(Packed)
|
||||
{
|
||||
uint32_t a = 0x12345678;
|
||||
uint8_t b = 0x9A;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user