Skip to content

Commit 3b54c4e

Browse files
committed
Merge branch 'pull-request/#989-Packed-unaligned_type' into development
# Conflicts: # .gitignore
2 parents 56c95b4 + 4f38779 commit 3b54c4e

File tree

5 files changed

+111
-9
lines changed

5 files changed

+111
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,4 @@ test/test_file_list.txt
391391
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/CopilotIndices
392392
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/FileContentIndex
393393
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/v17
394+
test/etl_error_handler/assert_function/build-make

include/etl/file_error_numbers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,5 @@ SOFTWARE.
103103
#define ETL_EXPECTED_FILE_ID "70"
104104
#define ETL_ALIGNMENT_FILE_ID "71"
105105
#define ETL_BASE64_FILE_ID "72"
106-
106+
#define ETL_UNALIGNED_TYPE_FILE_ID "73"
107107
#endif

include/etl/platform.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,19 @@ SOFTWARE.
463463
//*************************************
464464
// Determine if the ETL should use __attribute__((packed).
465465
#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6)
466-
#define ETL_PACKED __attribute__((packed))
466+
#define ETL_PACKED_CLASS(class_type) class __attribute__((packed)) class_type
467+
#define ETL_PACKED_STRUCT(struct_type) struct __attribute__((packed)) struct_type
467468
#define ETL_END_PACKED
468469
#define ETL_HAS_PACKED 1
469470
#elif defined(ETL_COMPILER_MICROSOFT)
470-
#define ETL_PACKED __pragma(pack(push, 1))
471+
#define ETL_PACKED_CLASS(class_type) __pragma(pack(push, 1)) class class_type
472+
#define ETL_PACKED_STRUCT(struct_type) __pragma(pack(push, 1)) struct struct_type
473+
#define ETL_PACKED
471474
#define ETL_END_PACKED __pragma(pack(pop))
472475
#define ETL_HAS_PACKED 1
473476
#else
474-
#define ETL_PACKED
477+
#define ETL_PACKED_CLASS(class_type) class class_type
478+
#define ETL_PACKED_STRUCT(struct_type) struct struct_type
475479
#define ETL_END_PACKED
476480
#define ETL_HAS_PACKED 0
477481
#endif

include/etl/unaligned_type.h

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,48 @@ SOFTWARE.
4141
#include "iterator.h"
4242
#include "algorithm.h"
4343
#include "bit.h"
44+
#include "array.h"
45+
#include "exception.h"
46+
#include "file_error_numbers.h"
47+
48+
#include <bit>
4449

4550
#include <string.h>
4651

4752
namespace etl
4853
{
54+
struct unaligned_type_exception : public etl::exception
55+
{
56+
public:
57+
58+
unaligned_type_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
59+
: exception(reason_, file_name_, line_number_)
60+
{
61+
}
62+
};
63+
64+
//***************************************************************************
65+
/// Buffer size exception.
66+
//***************************************************************************
67+
class unaligned_type_buffer_size : public unaligned_type_exception
68+
{
69+
public:
70+
71+
unaligned_type_buffer_size(string_type file_name_, numeric_type line_number_)
72+
: unaligned_type_exception(ETL_ERROR_TEXT("unaligned_type:buffer size", ETL_UNALIGNED_TYPE_FILE_ID"A"), file_name_, line_number_)
73+
{
74+
}
75+
};
76+
4977
namespace private_unaligned_type
5078
{
5179
//*************************************************************************
5280
/// unaligned_type_common
5381
/// Contains all functionality that doesn't require the type.
82+
/// ETL_PACKED ensures that GCC does not complain when used in a packed object.
5483
//*************************************************************************
5584
template <size_t Size_>
56-
class ETL_PACKED unaligned_type_common
85+
ETL_PACKED_CLASS(unaligned_type_common)
5786
{
5887
public:
5988

@@ -227,7 +256,7 @@ namespace etl
227256
///\tparam Endian The endianness of the arithmetic type.
228257
//*************************************************************************
229258
template <typename T, int Endian_>
230-
class ETL_PACKED unaligned_type : public private_unaligned_type::unaligned_type_common<sizeof(T)>
259+
ETL_PACKED_CLASS(unaligned_type) : public private_unaligned_type::unaligned_type_common<sizeof(T)>
231260
{
232261
public:
233262

@@ -243,8 +272,8 @@ namespace etl
243272
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::reverse_iterator reverse_iterator;
244273
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::const_reverse_iterator const_reverse_iterator;
245274

246-
static ETL_CONSTANT int Endian = Endian_;
247-
static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common<sizeof(T)>::Size;
275+
static ETL_CONSTANT int Endian = Endian_;
276+
static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common<sizeof(T)>::Size;
248277

249278
//*************************************************************************
250279
/// Default constructor
@@ -261,6 +290,24 @@ namespace etl
261290
unaligned_copy<T>::copy(value, this->storage);
262291
}
263292

293+
//*************************************************************************
294+
/// Construct from an address.
295+
//*************************************************************************
296+
ETL_CONSTEXPR14 unaligned_type(const void* address)
297+
{
298+
etl::copy_n(reinterpret_cast<const char*>(address), sizeof(T), this->storage);
299+
}
300+
301+
//*************************************************************************
302+
/// Construct from an address and size.
303+
//*************************************************************************
304+
ETL_CONSTEXPR14 unaligned_type(const void* address, size_t buffer_size)
305+
{
306+
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
307+
308+
etl::copy_n(reinterpret_cast<const char*>(address), sizeof(T), this->storage);
309+
}
310+
264311
//*************************************************************************
265312
/// Copy constructor
266313
//*************************************************************************
@@ -315,6 +362,56 @@ namespace etl
315362
return value;
316363
}
317364

365+
// For run time pointer
366+
static unaligned_type<T, Endian_>& at_address(void* address)
367+
{
368+
//auto p = (::new(address) unaligned_type<T, Endian_>());
369+
370+
//return *p;
371+
372+
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
373+
}
374+
375+
// For const run time pointer
376+
static const unaligned_type<T, Endian_>& at_address(const void* address)
377+
{
378+
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
379+
}
380+
381+
// For run time pointer and size
382+
static unaligned_type<T, Endian_>& at_address(void* address, size_t buffer_size)
383+
{
384+
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
385+
386+
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
387+
}
388+
389+
// For const run time pointer and size
390+
static const unaligned_type<T, Endian_>& at_address(const void* address, size_t buffer_size)
391+
{
392+
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::unaligned_type_buffer_size));
393+
394+
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
395+
}
396+
397+
// For run time pointer and compile time size
398+
template <size_t Size>
399+
static unaligned_type<T, Endian_>& at_address(void* address)
400+
{
401+
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Buffer size to small for type");
402+
403+
return *reinterpret_cast<unaligned_type<T, Endian_>*>(address);
404+
}
405+
406+
// For const run time pointer and compile time size
407+
template <size_t Size>
408+
static unaligned_type<T, Endian_>& at_address(const void* address)
409+
{
410+
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Buffer size to small for type");
411+
412+
return *reinterpret_cast<const unaligned_type<T, Endian_>*>(address);
413+
}
414+
318415
//*************************************************************************
319416
/// Unaligned copy
320417
//*************************************************************************

test/test_utility.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ namespace
730730
uint32_t c = 0x87654321;
731731
};
732732

733-
struct ETL_PACKED Packed
733+
ETL_PACKED_STRUCT(Packed)
734734
{
735735
uint32_t a = 0x12345678;
736736
uint8_t b = 0x9A;

0 commit comments

Comments
 (0)