Skip to content

Commit 4f38779

Browse files
committed
Updated packed macro
1 parent 0568293 commit 4f38779

File tree

4 files changed

+113
-8
lines changed

4 files changed

+113
-8
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,7 @@ support/time remaining test.xlsx
388388
test/vs2022/Debug MSVC C++20 - Force C++03
389389
test/vs2022/Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser
390390
test/test_file_list.txt
391+
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/CopilotIndices
392+
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/FileContentIndex
393+
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/v17
394+
test/etl_error_handler/assert_function/build-make

include/etl/platform.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,15 +457,19 @@ SOFTWARE.
457457
//*************************************
458458
// Determine if the ETL should use __attribute__((packed).
459459
#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6)
460-
#define ETL_PACKED __attribute__((packed))
460+
#define ETL_PACKED_CLASS(class_type) class __attribute__((packed)) class_type
461+
#define ETL_PACKED_STRUCT(struct_type) struct __attribute__((packed)) struct_type
461462
#define ETL_END_PACKED
462463
#define ETL_HAS_PACKED 1
463464
#elif defined(ETL_COMPILER_MICROSOFT)
464-
#define ETL_PACKED __pragma(pack(push, 1))
465+
#define ETL_PACKED_CLASS(class_type) __pragma(pack(push, 1)) class class_type
466+
#define ETL_PACKED_STRUCT(struct_type) __pragma(pack(push, 1)) struct struct_type
467+
#define ETL_PACKED
465468
#define ETL_END_PACKED __pragma(pack(pop))
466469
#define ETL_HAS_PACKED 1
467470
#else
468-
#define ETL_PACKED
471+
#define ETL_PACKED_CLASS(class_type) class class_type
472+
#define ETL_PACKED_STRUCT(struct_type) struct struct_type
469473
#define ETL_END_PACKED
470474
#define ETL_HAS_PACKED 0
471475
#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
@@ -678,7 +678,7 @@ namespace
678678
uint32_t c = 0x87654321;
679679
};
680680

681-
struct ETL_PACKED Packed
681+
ETL_PACKED_STRUCT(Packed)
682682
{
683683
uint32_t a = 0x12345678;
684684
uint8_t b = 0x9A;

0 commit comments

Comments
 (0)