jaulib
v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
packed_attribute.hpp
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2020 Gothel Software e.K.
3
* Copyright (c) 2020 ZAFENA AB
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining
6
* a copy of this software and associated documentation files (the
7
* "Software"), to deal in the Software without restriction, including
8
* without limitation the rights to use, copy, modify, merge, publish,
9
* distribute, sublicense, and/or sell copies of the Software, and to
10
* permit persons to whom the Software is furnished to do so, subject to
11
* the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be
14
* included in all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
*
24
*/
25
26
#ifndef PACKED_ATTRIBUTE_HPP_
27
#define PACKED_ATTRIBUTE_HPP_
28
29
/** \addtogroup CppLang
30
*
31
* @{
32
*/
33
34
/** packed__: lead in macro, requires __packed lead out as well. Consider using __pack(...). */
35
#ifndef packed__
36
#ifdef _MSC_VER
37
#define packed__ __pragma( pack(push, 1) )
38
#else
39
#define packed__
40
#endif
41
#endif
42
43
/** __packed: lead out macro, requires packed__ lead in as well. Consider using __pack(...). */
44
#ifndef __packed
45
#ifdef _MSC_VER
46
#define __packed __pragma( pack(pop))
47
#else
48
#define __packed __attribute__ ((packed))
49
#endif
50
#endif
51
52
/** __pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros. */
53
#ifndef __pack
54
#ifdef _MSC_VER
55
#define __pack(...) __pragma( pack(push, 1) ) __VA_ARGS__ __pragma( pack(pop))
56
#else
57
#define __pack(...) __VA_ARGS__ __attribute__ ((packed))
58
#endif
59
#endif
60
61
/**@}*/
62
63
namespace
jau
{
64
65
/** \addtogroup CppLang
66
*
67
* @{
68
*/
69
70
/**
71
* Support aligned memory transfer from and to potentially unaligned memory.
72
*
73
* This template causes little to no runtime costs.
74
*
75
* A casted data pointer to `packed_t<T>*` is similar to 'T * p = (T *) buffer', having `uint8_t * buffer`.
76
* However, `packed_t<T>*` doesn't have any intrinsic alignment corrections due to
77
* its used `__attribute__((__packed__))`.
78
*
79
* packed_t is used in \ref ByteUtils.
80
*
81
* packet_t is also used to implement pre C++20 jau::bit_cast
82
*
83
* @anchor packed_t_alignment_cast
84
* Background for using packed_t:
85
*
86
* Due to the potentially unaligned memory address of `buffer`,
87
* we can't just directly use pointer arithmetic like:
88
* <pre>
89
* // return uint16_t from memory
90
* return *( (uint16_t *) ( buffer ) );
91
*
92
* // store uint16_t to memory
93
* *( (uint16_t *) ( buffer ) ) = v;
94
* </pre>
95
*
96
* The universal alternative using `memcpy()` is costly:
97
* <pre>
98
* // return uint16_t from memory
99
* memcpy(&v, buffer, sizeof(v));
100
* return v;
101
*
102
* // store uint16_t to memory
103
* memcpy(buffer, &v, sizeof(v));
104
* </pre>
105
*
106
* Solution is to use the *free of costs* high performance *compiler magic* 'struct __attribute__((__packed__))'.<br />
107
* The offset memory is pointer_cast() into the desired packed_t type and its packed_t::store accessed thereafter:
108
* <pre>
109
* // return uint16_t from memory
110
* return pointer_cast<const packed_t<uint16_t>*>( buffer )->store;
111
*
112
* // store uint16_t to memory
113
* pointer_cast<packed_t<uint16_t>*>( buffer )->store = v;
114
* </pre>
115
*/
116
template
<
typename
T> __pack (
struct
packed_t {
117
T store;
118
} ) ;
119
120
/**@}*/
121
122
}
// namespace jau
123
124
/**@}*/
125
126
#endif
/* PACKED_ATTRIBUTE_HPP_ */
jau
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition
backtrace.hpp:32
include
jau
packed_attribute.hpp
Generated by
1.13.2