@@ -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
4752namespace 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 // *************************************************************************
0 commit comments