Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/uuid/detail/endian.hpp
Line
Count
Source
1
#ifndef BOOST_UUID_DETAIL_ENDIAN_INCLUDED
2
#define BOOST_UUID_DETAIL_ENDIAN_INCLUDED
3
4
// Copyright 2024 Peter Dimov
5
// Distributed under the Boost Software License, Version 1.0.
6
// https://www.boost.org/LICENSE_1_0.txt
7
8
#include <boost/uuid/detail/is_constant_evaluated.hpp>
9
#include <boost/uuid/detail/cstring.hpp>
10
#include <boost/config.hpp>
11
#include <cstdint>
12
13
#if defined(_MSC_VER) && !defined(__clang__)
14
# include <intrin.h>
15
#endif
16
17
namespace boost {
18
namespace uuids {
19
namespace detail {
20
21
// Byte order macros
22
23
#if defined(__BYTE_ORDER__)
24
25
#define BOOST_UUID_BYTE_ORDER __BYTE_ORDER__
26
#define BOOST_UUID_ORDER_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
27
#define BOOST_UUID_ORDER_BIG_ENDIAN __ORDER_BIG_ENDIAN__
28
29
#elif defined(__LITTLE_ENDIAN__) || defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
30
31
#define BOOST_UUID_BYTE_ORDER 1234
32
#define BOOST_UUID_ORDER_LITTLE_ENDIAN 1234
33
#define BOOST_UUID_ORDER_BIG_ENDIAN 4321
34
35
#elif defined(__BIG_ENDIAN__)
36
37
#define BOOST_UUID_BYTE_ORDER 4321
38
#define BOOST_UUID_ORDER_LITTLE_ENDIAN 1234
39
#define BOOST_UUID_ORDER_BIG_ENDIAN 4321
40
41
#else
42
43
# error Unrecognized platform
44
45
#endif
46
47
// byteswap
48
49
#if defined(__GNUC__) || defined(__clang__)
50
51
BOOST_CXX14_CONSTEXPR inline std::uint16_t byteswap( std::uint16_t x ) noexcept
52
0
{
53
0
    return __builtin_bswap16( x );
54
0
}
55
56
BOOST_CXX14_CONSTEXPR inline std::uint32_t byteswap( std::uint32_t x ) noexcept
57
35
{
58
35
    return __builtin_bswap32( x );
59
35
}
60
61
BOOST_CXX14_CONSTEXPR inline std::uint64_t byteswap( std::uint64_t x ) noexcept
62
0
{
63
0
    return __builtin_bswap64( x );
64
0
}
65
66
#elif defined(_MSC_VER)
67
68
inline std::uint16_t byteswap( std::uint16_t x ) noexcept
69
{
70
    return _byteswap_ushort( x );
71
}
72
73
inline std::uint32_t byteswap( std::uint32_t x ) noexcept
74
{
75
    return _byteswap_ulong( x );
76
}
77
78
inline std::uint64_t byteswap( std::uint64_t x ) noexcept
79
{
80
    return _byteswap_uint64( x );
81
}
82
83
#else
84
85
BOOST_CXX14_CONSTEXPR inline std::uint16_t byteswap( std::uint16_t x ) noexcept
86
{
87
    return static_cast<std::uint16_t>( x << 8 | x >> 8 );
88
}
89
90
BOOST_CXX14_CONSTEXPR inline std::uint32_t byteswap( std::uint32_t x ) noexcept
91
{
92
    std::uint32_t step16 = x << 16 | x >> 16;
93
    return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
94
}
95
96
BOOST_CXX14_CONSTEXPR inline std::uint64_t byteswap( std::uint64_t x ) noexcept
97
{
98
    std::uint64_t step32 = x << 32 | x >> 32;
99
    std::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
100
    return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
101
}
102
103
#endif
104
105
#if defined(__SIZEOF_INT128__)
106
107
BOOST_CXX14_CONSTEXPR inline __uint128_t byteswap( __uint128_t x ) noexcept
108
0
{
109
0
    return ( static_cast<__uint128_t>( detail::byteswap( static_cast<std::uint64_t>( x ) ) ) << 64 ) | detail::byteswap( static_cast<std::uint64_t>( x >> 64 ) );
110
0
}
111
112
#endif
113
114
// load_*_u16
115
116
inline std::uint16_t load_native_u16( void const* p ) noexcept
117
0
{
118
0
    std::uint16_t tmp;
119
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
120
0
    return tmp;
121
0
}
122
123
inline std::uint16_t load_little_u16( void const* p ) noexcept
124
0
{
125
0
    std::uint16_t tmp;
126
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
127
0
128
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
129
0
130
0
    return tmp;
131
0
132
0
#else
133
0
134
0
    return detail::byteswap( tmp );
135
0
136
0
#endif
137
0
}
138
139
BOOST_CXX14_CONSTEXPR inline std::uint16_t load_big_u16( unsigned char const* p ) noexcept
140
0
{
141
0
    if( is_constant_evaluated_cx() )
142
0
    {
143
0
        return static_cast<std::uint16_t>( ( p[ 0 ] << 8 ) | p[ 1 ] );
144
0
    }
145
0
146
0
    std::uint16_t tmp = {};
147
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
148
0
149
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_BIG_ENDIAN
150
0
151
0
    return tmp;
152
0
153
0
#else
154
0
155
0
    return detail::byteswap( tmp );
156
0
157
0
#endif
158
0
}
159
160
// load_*_u32
161
162
inline std::uint32_t load_native_u32( void const* p ) noexcept
163
0
{
164
0
    std::uint32_t tmp;
165
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
166
0
    return tmp;
167
0
}
168
169
BOOST_CXX14_CONSTEXPR inline std::uint32_t load_little_u32( unsigned char const* p ) noexcept
170
84
{
171
84
    if( is_constant_evaluated_cx() )
172
0
    {
173
0
        return
174
175
0
            static_cast<std::uint32_t>( p[ 0 ] )       |
176
0
            static_cast<std::uint32_t>( p[ 1 ] ) <<  8 |
177
0
            static_cast<std::uint32_t>( p[ 2 ] ) << 16 |
178
0
            static_cast<std::uint32_t>( p[ 3 ] ) << 24;
179
0
    }
180
181
84
    std::uint32_t tmp = {};
182
84
    detail::memcpy( &tmp, p, sizeof( tmp ) );
183
184
84
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
185
186
84
    return tmp;
187
188
#else
189
190
    return detail::byteswap( tmp );
191
192
#endif
193
84
}
194
195
BOOST_CXX14_CONSTEXPR inline std::uint32_t load_big_u32( unsigned char const* p ) noexcept
196
0
{
197
0
    if( is_constant_evaluated_cx() )
198
0
    {
199
0
        return
200
0
201
0
            static_cast<std::uint32_t>( p[ 0 ] ) << 24 |
202
0
            static_cast<std::uint32_t>( p[ 1 ] ) << 16 |
203
0
            static_cast<std::uint32_t>( p[ 2 ] ) <<  8 |
204
0
            static_cast<std::uint32_t>( p[ 3 ] );
205
0
    }
206
0
207
0
    std::uint32_t tmp = {};
208
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
209
0
210
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_BIG_ENDIAN
211
0
212
0
    return tmp;
213
0
214
0
#else
215
0
216
0
    return detail::byteswap( tmp );
217
0
218
0
#endif
219
0
}
220
221
// load_*_u64
222
223
inline std::uint64_t load_native_u64( void const* p ) noexcept
224
0
{
225
0
    std::uint64_t tmp = {};
226
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
227
0
    return tmp;
228
0
}
229
230
inline std::uint64_t load_little_u64( void const* p ) noexcept
231
0
{
232
0
    std::uint64_t tmp;
233
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
234
0
235
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
236
0
237
0
    return tmp;
238
0
239
0
#else
240
0
241
0
    return detail::byteswap( tmp );
242
0
243
0
#endif
244
0
}
245
246
BOOST_CXX14_CONSTEXPR inline std::uint64_t load_big_u64( unsigned char const* p ) noexcept
247
0
{
248
0
    if( is_constant_evaluated_cx() )
249
0
    {
250
0
        return
251
0
252
0
            static_cast<std::uint64_t>( p[ 0 ] ) << 56 |
253
0
            static_cast<std::uint64_t>( p[ 1 ] ) << 48 |
254
0
            static_cast<std::uint64_t>( p[ 2 ] ) << 40 |
255
0
            static_cast<std::uint64_t>( p[ 3 ] ) << 32 |
256
0
            static_cast<std::uint64_t>( p[ 4 ] ) << 24 |
257
0
            static_cast<std::uint64_t>( p[ 5 ] ) << 16 |
258
0
            static_cast<std::uint64_t>( p[ 6 ] ) <<  8 |
259
0
            static_cast<std::uint64_t>( p[ 7 ] );
260
0
    }
261
0
262
0
    std::uint64_t tmp = {};
263
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
264
0
265
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_BIG_ENDIAN
266
0
267
0
    return tmp;
268
0
269
0
#else
270
0
271
0
    return detail::byteswap( tmp );
272
0
273
0
#endif
274
0
}
275
276
// load_*_u128
277
278
#if defined(__SIZEOF_INT128__)
279
280
inline __uint128_t load_native_u128( void const* p ) noexcept
281
0
{
282
0
    __uint128_t tmp = {};
283
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
284
0
    return tmp;
285
0
}
286
287
inline __uint128_t load_little_u128( void const* p ) noexcept
288
0
{
289
0
    __uint128_t tmp;
290
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
291
0
292
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_LITTLE_ENDIAN
293
0
294
0
    return tmp;
295
0
296
0
#else
297
0
298
0
    return detail::byteswap( tmp );
299
0
300
0
#endif
301
0
}
302
303
inline __uint128_t load_big_u128( void const* p ) noexcept
304
0
{
305
0
    __uint128_t tmp = {};
306
0
    detail::memcpy( &tmp, p, sizeof( tmp ) );
307
0
308
0
#if BOOST_UUID_BYTE_ORDER == BOOST_UUID_ORDER_BIG_ENDIAN
309
0
310
0
    return tmp;
311
0
312
0
#else
313
0
314
0
    return detail::byteswap( tmp );
315
0
316
0
#endif
317
0
}
318
319
#endif
320
321
// store_*_u16
322
323
inline void store_native_u16( void* p, std::uint16_t v ) noexcept
324
0
{
325
0
    detail::memcpy( p, &v, sizeof( v ) );
326
0
}
327
328
inline void store_little_u16( void* p, std::uint16_t v ) noexcept
329
0
{
330
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_LITTLE_ENDIAN
331
0
332
0
    v = detail::byteswap( v );
333
0
334
0
#endif
335
0
336
0
    detail::memcpy( p, &v, sizeof( v ) );
337
0
}
338
339
inline void store_big_u16( void* p, std::uint16_t v ) noexcept
340
0
{
341
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_BIG_ENDIAN
342
0
343
0
    v = detail::byteswap( v );
344
0
345
0
#endif
346
0
347
0
    detail::memcpy( p, &v, sizeof( v ) );
348
0
}
349
350
// store_*_u32
351
352
inline void store_native_u32( void* p, std::uint32_t v ) noexcept
353
7
{
354
7
    detail::memcpy( p, &v, sizeof( v ) );
355
7
}
356
357
inline void store_little_u32( void* p, std::uint32_t v ) noexcept
358
0
{
359
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_LITTLE_ENDIAN
360
0
361
0
    v = detail::byteswap( v );
362
0
363
0
#endif
364
0
365
0
    detail::memcpy( p, &v, sizeof( v ) );
366
0
}
367
368
inline void store_big_u32( void* p, std::uint32_t v ) noexcept
369
35
{
370
35
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_BIG_ENDIAN
371
372
35
    v = detail::byteswap( v );
373
374
35
#endif
375
376
35
    detail::memcpy( p, &v, sizeof( v ) );
377
35
}
378
379
// store_*_u64
380
381
inline void store_native_u64( void* p, std::uint64_t v ) noexcept
382
0
{
383
0
    detail::memcpy( p, &v, sizeof( v ) );
384
0
}
385
386
inline void store_little_u64( void* p, std::uint64_t v ) noexcept
387
0
{
388
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_LITTLE_ENDIAN
389
0
390
0
    v = detail::byteswap( v );
391
0
392
0
#endif
393
0
394
0
    detail::memcpy( p, &v, sizeof( v ) );
395
0
}
396
397
inline void store_big_u64( void* p, std::uint64_t v ) noexcept
398
0
{
399
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_BIG_ENDIAN
400
0
401
0
    v = detail::byteswap( v );
402
0
403
0
#endif
404
0
405
0
    detail::memcpy( p, &v, sizeof( v ) );
406
0
}
407
408
// store_*_u128
409
410
#if defined(__SIZEOF_INT128__)
411
412
inline void store_native_u128( void* p, __uint128_t v ) noexcept
413
0
{
414
0
    detail::memcpy( p, &v, sizeof( v ) );
415
0
}
416
417
inline void store_little_u128( void* p, __uint128_t v ) noexcept
418
0
{
419
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_LITTLE_ENDIAN
420
0
421
0
    v = detail::byteswap( v );
422
0
423
0
#endif
424
0
425
0
    detail::memcpy( p, &v, sizeof( v ) );
426
0
}
427
428
inline void store_big_u128( void* p, __uint128_t v ) noexcept
429
0
{
430
0
#if BOOST_UUID_BYTE_ORDER != BOOST_UUID_ORDER_BIG_ENDIAN
431
0
432
0
    v = detail::byteswap( v );
433
0
434
0
#endif
435
0
436
0
    detail::memcpy( p, &v, sizeof( v ) );
437
0
}
438
439
#endif
440
441
} // detail
442
} // uuids
443
} // boost
444
445
#endif // #ifndef BOOST_UUID_DETAIL_ENDIAN_INCLUDED