@@ -41,19 +41,48 @@ SOFTWARE.
41
41
#include " iterator.h"
42
42
#include " algorithm.h"
43
43
#include " bit.h"
44
+ #include " array.h"
45
+ #include " exception.h"
46
+ #include " file_error_numbers.h"
47
+
48
+ #include < bit>
44
49
45
50
#include < string.h>
46
51
47
52
namespace etl
48
53
{
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
+
49
77
namespace private_unaligned_type
50
78
{
51
79
// *************************************************************************
52
80
// / unaligned_type_common
53
81
// / Contains all functionality that doesn't require the type.
82
+ // / ETL_PACKED ensures that GCC does not complain when used in a packed object.
54
83
// *************************************************************************
55
84
template <size_t Size_>
56
- class ETL_PACKED unaligned_type_common
85
+ ETL_PACKED_CLASS ( unaligned_type_common)
57
86
{
58
87
public:
59
88
@@ -227,7 +256,7 @@ namespace etl
227
256
// /\tparam Endian The endianness of the arithmetic type.
228
257
// *************************************************************************
229
258
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)>
231
260
{
232
261
public:
233
262
@@ -243,8 +272,8 @@ namespace etl
243
272
typedef typename private_unaligned_type::unaligned_type_common<sizeof (T)>::reverse_iterator reverse_iterator;
244
273
typedef typename private_unaligned_type::unaligned_type_common<sizeof (T)>::const_reverse_iterator const_reverse_iterator;
245
274
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;
248
277
249
278
// *************************************************************************
250
279
// / Default constructor
@@ -261,6 +290,24 @@ namespace etl
261
290
unaligned_copy<T>::copy (value, this ->storage );
262
291
}
263
292
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
+
264
311
// *************************************************************************
265
312
// / Copy constructor
266
313
// *************************************************************************
@@ -315,6 +362,56 @@ namespace etl
315
362
return value;
316
363
}
317
364
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
+
318
415
// *************************************************************************
319
416
// / Unaligned copy
320
417
// *************************************************************************
0 commit comments