jaulib
v1.3.0
Jau Support Library (C++, Java, ..)
include
jau
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
* @anchor packed_t_alignment_cast
82
* Background for using packed_t:
83
*
84
* Due to the potentially unaligned memory address of `buffer`,
85
* we can't just directly use pointer arithmetic like:
86
* <pre>
87
* // return uint16_t from memory
88
* return *( (uint16_t *) ( buffer ) );
89
*
90
* // store uint16_t to memory
91
* *( (uint16_t *) ( buffer ) ) = v;
92
* </pre>
93
*
94
* The universal alternative using `memcpy()` is costly:
95
* <pre>
96
* // return uint16_t from memory
97
* memcpy(&v, buffer, sizeof(v));
98
* return v;
99
*
100
* // store uint16_t to memory
101
* memcpy(buffer, &v, sizeof(v));
102
* </pre>
103
*
104
* Solution is to use the *free of costs* high performance *compiler magic* 'struct __attribute__((__packed__))'.<br />
105
* The offset memory is pointer_cast() into the desired packed_t type and its packed_t::store accessed thereafter:
106
* <pre>
107
* // return uint16_t from memory
108
* return pointer_cast<const packed_t<uint16_t>*>( buffer )->store;
109
*
110
* // store uint16_t to memory
111
* pointer_cast<packed_t<uint16_t>*>( buffer )->store = v;
112
* </pre>
113
*/
114
template
<
typename
T> __pack (
struct
packed_t {
115
T store;
116
} ) ;
117
118
/**@}*/
119
120
}
// namespace jau
121
122
/**@}*/
123
124
#endif
/* PACKED_ATTRIBUTE_HPP_ */
jau
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition:
backtrace.hpp:32
Generated on Sun May 12 2024 09:05:28 for jaulib by
1.9.4