BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_byteorderutil_impl.h
Go to the documentation of this file.
1/// @file bsls_byteorderutil_impl.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_byteorderutil_impl.h -*-C++-*-
8#ifndef INCLUDED_BSLS_BYTEORDERUTIL_IMPL
9#define INCLUDED_BSLS_BYTEORDERUTIL_IMPL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_byteorderutil_impl bsls_byteorderutil_impl
15/// @brief Provide implementation of byte-order manipulation functions.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_byteorderutil_impl
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_byteorderutil_impl-purpose"> Purpose</a>
25/// * <a href="#bsls_byteorderutil_impl-classes"> Classes </a>
26/// * <a href="#bsls_byteorderutil_impl-macros"> Macros </a>
27/// * <a href="#bsls_byteorderutil_impl-description"> Description </a>
28///
29/// # Purpose {#bsls_byteorderutil_impl-purpose}
30/// Provide implementation of byte-order manipulation functions.
31///
32/// # Classes {#bsls_byteorderutil_impl-classes}
33///
34/// - bsls::ByteOrderUtil_Impl: namespace for swapping functions
35///
36/// # Macros {#bsls_byteorderutil_impl-macros}
37///
38/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_16(x) return `x` with bytes swapped
39/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32(x) return `x` with bytes swapped
40/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64(x) return `x` with bytes swapped
41/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P16(&x) return `x` with bytes swapped
42/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32(&x) return `x` with bytes swapped
43/// - BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(&x) return `x` with bytes swapped
44/// - BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_16(x) return `x` with bytes swapped
45/// - BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_32(x) return `x` with bytes swapped
46/// - BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_64(x) return `x` with bytes swapped
47///
48/// @see bsls_byteorderutil, bsls_byteorder
49///
50/// # Description {#bsls_byteorderutil_impl-description}
51/// This component provides a template class `ByteOrderUtil_Impl`
52/// and a set of macros suitable for swapping byte orders of all integral types.
53/// The `*_CUSTOMSWAP_*` macros use assembly language or compiler primitives,
54/// whereas the `*_GENERICSWAP_*` macros use C bitwise operations to perform the
55/// swap. The `*_CUSTOMSWAP_*` macros are not defined on all platforms; callers
56/// must perform an `#ifdef` to see if they are defined before calling them. At
57/// most one of `*_CUSTOMSWAP_NN` and `*_CUSTOMSWAP_PNN` are defined on any one
58/// platform for any value of `NN`, while `*_GENERICSWAP_NN` macros are defined
59/// on all platforms and are meant to be called when the other macros are not
60/// available, and are also used for benchmarking.
61/// @}
62/** @} */
63/** @} */
64
65/** @addtogroup bsl
66 * @{
67 */
68/** @addtogroup bsls
69 * @{
70 */
71/** @addtogroup bsls_byteorderutil_impl
72 * @{
73 */
74
75#include <bsls_assert.h>
76#include <bsls_platform.h>
77#include <bsls_types.h>
78
79#ifdef BSLS_PLATFORM_CMP_MSVC
80#include <stdlib.h> // '_byteswap_*'
81#endif
82
83
84namespace bsls {
85
86 // =========================
87 // struct ByteOrderUtil_Impl
88 // =========================
89
90template <class TYPE, Types::size_type WIDTH = sizeof(TYPE)>
92
93/// This `class` provides a namespace for functions used for reversing the
94/// byte order of values having integral type.
95template <class TYPE>
96struct ByteOrderUtil_Impl<TYPE, 1> {
97
98 // CLASS METHODS
99
100 /// Return the value that results from reversing the order of the bytes
101 /// in the specified `x`.
102 static TYPE swapBytes(TYPE x);
103};
104
105/// This `class` provides a namespace for functions used for reversing the
106/// byte order of values having integral type.
107template <class TYPE>
108struct ByteOrderUtil_Impl<TYPE, 2> {
109
110 // CLASS METHODS
111
112 /// Return the value that results from reversing the order of the bytes
113 /// in the specified `x`.
114 static TYPE swapBytes(TYPE x);
115};
116
117/// This `class` provides a namespace for functions used for reversing the
118/// byte order of values having integral type.
119template <class TYPE>
120struct ByteOrderUtil_Impl<TYPE, 4> {
121
122 // CLASS METHODS
123
124 /// Return the value that results from reversing the order of the bytes
125 /// in the specified `x`.
126 static TYPE swapBytes(TYPE x);
127};
128
129/// This `class` provides a namespace for functions used for reversing the
130/// byte order of values having integral type.
131template <class TYPE>
132struct ByteOrderUtil_Impl<TYPE, 8> {
133
134 // CLASS METHODS
135
136 /// Return the value that results from reversing the order of the bytes
137 /// in the specified `x`.
138 static TYPE swapBytes(TYPE x);
139};
140
141} // close package namespace
142
143// ============================================================================
144// MACROS
145// ============================================================================
146
147// These macros are only intended to be used in this component and
148// @ref bsls_byteorderutil .
149
150// We did benchmarks and found that many of the custom assembly implementations
151// below were slower than the generic implementation, so we disable the slow
152// ones unless 'BSLS_BYTEORDERUTIL_IMPL_ENABLE_COUNTERPRODUCTIVE_MACROS' is
153// defined.
154
155 // -------------------------------------------------
156 // macro BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT
157 // -------------------------------------------------
158
159// We don't have access to 'BSLMF_ASSERT' here in 'bsls' -- do a crude
160// compile-time assert for use in @ref bsls_byteorderutil . This macro will
161// deliberately cause a compilation error if 'expr' evaluates to 'false'.
162// 'expr' must be a compile-time expression. Note that this macro can only be
163// called in a code body. This macro is only intended to be used in this
164// component and @ref bsls_byteorderutil .
165
166#if (defined(BSLS_ASSERT_SAFE_IS_ACTIVE) || \
167 defined(BSLS_ASSERT_IS_ACTIVE))
168
169# define BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(expr) \
170 { enum { k_NOT_INFINITY = 1 / static_cast<int>(expr) }; \
171 (void) k_NOT_INFINITY; }
172
173#else
174
175# define BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(expr)
176
177#endif
178
179#ifndef BSLS_BYTEORDERUTIL_IMPL_ENABLE_COUNTERPRODUCTIVE_MACROS
180#define BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS 1
181#endif
182
183#if (defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 40300) \
184 || defined(BSLS_PLATFORM_CMP_CLANG)
185
186// ----------------------------------------------------------------------------
187// Advanced GNU
188
189// Let the 16-bit GNU implementation default to
190// 'BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_16' or other platform-specific GNU
191// implementations.
192
193#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS) || \
194 !defined(BSLS_PLATFORM_OS_SOLARIS)
195
196#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32(dstType, x) \
197 return static_cast<dstType>(__builtin_bswap32(static_cast<int>(x)))
198
199#endif
200
201#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS) || \
202 !defined(BSLS_PLATFORM_OS_SOLARIS) || \
203 !defined(BSLS_PLATFORM_CPU_64_BIT) || !defined(BDE_BUILD_TARGET_OPT)
204
205#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64(dstType, x) \
206 return static_cast<dstType>(__builtin_bswap64( \
207 static_cast<BloombergLP::bsls::Types::Int64>(x)))
208
209#endif
210
211#elif defined(BSLS_PLATFORM_CMP_MSVC)
212
213// ----------------------------------------------------------------------------
214// Microsoft Visual C++
215
216#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS)
217
218#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_16(dstType, x) \
219 return static_cast<dstType>(_byteswap_ushort( \
220 static_cast<unsigned short>(x)))
221
222#endif
223
224#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32(dstType, x) \
225 return static_cast<dstType>(_byteswap_ulong(static_cast<unsigned int>(x)))
226
227#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64(dstType, x) \
228 return static_cast<dstType>(_byteswap_uint64( \
229 static_cast<BloombergLP::bsls::Types::Uint64>(x)))
230
231#elif defined(BSLS_PLATFORM_CPU_POWERPC) && defined(BSLS_PLATFORM_CMP_IBM) \
232 && !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS)
233
234// ----------------------------------------------------------------------------
235// POWERPC-AIX
236
237unsigned short
238bsls_byteOrderUtil_Impl_powerpc_swap_p16(const unsigned short *x);
239 // Return the specified '*x' with byte order swapped.
240
241// The following is equivalent to:
242//..
243// lhbrx r3,0,r3
244//..
245// The following is necessary to work around the bug reported in DRQS 16073004
246// using inline assembly with xlC10:
247#pragma mc_func bsls_byteOrderUtil_Impl_powerpc_swap_p16 { "7c601e2c" }
248#pragma reg_killed_by bsls_byteOrderUtil_Impl_powerpc_swap_p16 gr3
249
250unsigned int bsls_byteOrderUtil_Impl_powerpc_swap_p32(const unsigned int *x);
251 // Return the specified '*x' with byte order swapped.
252
253// The following is equivalent to:
254//..
255// lwbrx r3,0,r3
256//..
257// This follows the AIX ABI: the first argument is received in 'r3' and the
258// return value is stored in 'r3'. The hex value specified for 'mc_func' is
259// the opcode of the above code.
260
261#pragma mc_func bsls_byteOrderUtil_Impl_powerpc_swap_p32 { "7c601c2c" }
262#pragma reg_killed_by bsls_byteOrderUtil_Impl_powerpc_swap_p32 gr3
263
264unsigned long long bsls_byteOrderUtil_Impl_powerpc_swap_p64(
265 const unsigned long long *x);
266 // Return the specified '*x' with byte order swapped.
267
268#ifdef BSLS_PLATFORM_CPU_32_BIT
269// The following is equivalent to:
270//..
271// lwbrx r4,0,r3 // reverse the 4 higher-order bytes
272// addi r3,r3,4 // change r3 to point to the 4 lower-order bytes
273// lwbrx r3,0,r3 // reverse the 4 lower-order bytes
274//..
275#pragma mc_func bsls_byteOrderUtil_Impl_powerpc_swap_p64 \
276 { "7c801c2c" "38630004" "7c601c2c"}
277#pragma reg_killed_by bsls_byteOrderUtil_Impl_powerpc_swap_p64 gr3,gr4
278
279#else // BSLS_PLATFORM_CPU_64_BIT
280// The following is equivalent to:
281//..
282// addi r4,r3,4 // move address of the 4 lower-order bytes to 'r4'
283// lwbrx r3,0,r3 // reverse the 4 higher-order bytes
284// lwbrx r4,0,r4 // reverse the 4 lower-order bytes
285// rldimi r3,r4,32,0 // rotate 'r4' left and insert to 'r3' with a mask
286//..
287#pragma mc_func bsls_byteOrderUtil_Impl_powerpc_swap_p64 \
288 { "38830004" "7c601c2c" "7c80242c" "7883000e" }
289#pragma reg_killed_by bsls_byteOrderUtil_Impl_powerpc_swap_p64 gr3,gr4,cr0
290
291#endif // BSLS_PLATFORM_CPU_32_BIT else
292
293#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P16(dstType, x) \
294 { \
295 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(2 == sizeof *x); \
296 return static_cast<dstType>(bsls_byteOrderUtil_Impl_powerpc_swap_p16( \
297 reinterpret_cast<const unsigned short *>(x))); \
298 }
299
300#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32(dstType, x) \
301 { \
302 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(4 == sizeof *x); \
303 return static_cast<dstType>(bsls_byteOrderUtil_Impl_powerpc_swap_p32( \
304 reinterpret_cast<const unsigned int *>(x))); \
305 }
306
307#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(dstType, x) \
308 { \
309 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof *x); \
310 return static_cast<dstType>(bsls_byteOrderUtil_Impl_powerpc_swap_p64( \
311 reinterpret_cast<const BloombergLP::bsls::Types::Uint64 *>(x))); \
312 }
313
314#endif // BSLS_PLATFORM_CPU_POWERPC
315
316#if defined(BSLS_PLATFORM_CPU_SPARC)
317
318// ----------------------------------------------------------------------------
319// Sparc
320
321#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
322
323#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS) || \
324 !defined(BDE_BUILD_TARGET_OPT)
325
326// LEVEL 1 METHODS
327
328// We have to use "r"(x) instead of "m"(*x) because certain instructions do not
329// support the 'm' constraint. The 'm' constraint is the only way to tell the
330// compiler we are reading the value of '*x' and not just 'x'.
331
332#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P16(dstType, x) \
333 { \
334 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(2 == sizeof *x); \
335 unsigned int y; \
336 asm("lduha [%1] %2, %0" \
337 : "=r" (y) \
338 : "r" (x), "i"(0x88), "m" ( \
339 *reinterpret_cast<const unsigned short *>(x))); \
340 \
341 return static_cast<dstType>(y); \
342 }
343
344#endif // !disabled || !opt
345
346#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS) && \
347 !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32) && \
348 !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32)
349
350// sparc GNU pre-4.03 impl
351
352#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32(dstType, x) \
353 { \
354 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(4 == sizeof *x); \
355 unsigned int y; \
356 asm("lduwa [%1] %2, %0" \
357 : "=r" (y) \
358 : "r" (x), "i"(0x88), "m" ( \
359 *reinterpret_cast<const unsigned int *>(x))); \
360 \
361 return static_cast<dstType>(y); \
362 }
363
364#endif // not disabled, ...CUSTOMSWAP_32, CUSTOMSWAP_P32 not defined
365
366#if !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64) \
367 && !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64)
368
369#if defined(BSLS_PLATFORM_CPU_64_BIT)
370
371// sparc GNU pre-4.03 impl
372
373// The pragma here is to suppress a warning triggered by the addition of the
374// 'char *' cast needed to avoid potential aliasing issues (even though they're
375// likely false alarms).
376
377#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(dstType, x) \
378 { \
379 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof *x); \
380 BloombergLP::bsls::Types::Uint64 y; \
381 \
382 asm("ldxa [%1] %2, %0" \
383 : "=r" (y) \
384 : "r" (x), "i"(0x88), "m" ( \
385 *reinterpret_cast<const BloombergLP::bsls::Types::Uint64 *>(x))); \
386 \
387 return static_cast<dstType>(y); \
388 }
389
390#else
391
392// sparc GNU pre-4.03 impl
393
394// asm("ldxa [%1] %2, %0\n\t" // After the load, the full data is in '%0'.
395// // But we have to split it into two registers
396// // since we are running in 32-bit mode.
397//
398// "srl %0, 0, %R0\n\t" // The '%R0' specifies the lower-order bits of
399// // a pair register, while '%0' specifies the
400// // higher-order bits. Move the lower-order
401// // bits of the result to '%R0'.
402//
403// "srlx %0, 32, %0" // Shift the higher-order bits of the result.
404// : "=r" (y)
405// : "r" (x), "i"(0x88), "m" (*x));
406
407#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(dstType, x) \
408 { \
409 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof *x); \
410 BloombergLP::bsls::Types::Uint64 y; \
411 asm("ldxa [%1] %2, %0\n\t" \
412 "srl %0, 0, %R0\n\t" \
413 "srlx %0, 32, %0" \
414 : "=r" (y) \
415 : "r" (x), "i"(0x88), "m" ( \
416 *reinterpret_cast<BloombergLP::bsls::Types::Uint64 *>(x))); \
417 \
418 return static_cast<dstType>(y); \
419 }
420
421#endif // BSLS_PLATFORM_CPU_64_BIT else
422
423#endif // 64 bit not defined
424
425#else // BSLS_PLATFORM_CMP_GNU || BSLS_PLATFORM_CMP_CLANG else
426
427#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS) || \
428 !defined(BDE_BUILD_TARGET_OPT)
429
430// Solaris non-GNU assembly implementations must be out of line. Removed 16-
431// and 32-bit implementations since the generic implementations, which are
432// always inline, are probably faster than a function call.
433
434extern "C" {
435unsigned long long bsls_byteOrderUtil_Impl_sparc_CC_swap_p64(
436 const unsigned long long *x);
437 // Return the specified '*x' with byte order swapped. Sparc CC impl in
438 // .cpp file.
439}
440
441#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(dstType, x) \
442 { \
443 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof *x); \
444 return static_cast<dstType>( \
445 bsls_byteOrderUtil_Impl_sparc_CC_swap_p64( \
446 reinterpret_cast<const unsigned long long *>(x))); \
447 }
448
449#endif // !disabled || !opt
450
451#endif // BSLS_PLATFORM_CMP_GNU || BSLS_PLATFORM_CMP_CLANG else
452
453#elif (defined(BSLS_PLATFORM_CPU_X86) || defined(BSLS_PLATFORM_CPU_X86_64)) \
454 && (defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG))
455
456#if !defined(BSLS_BYTEORDERUTIL_IMPL_DISABLE_COUNTERPRODUCTIVE_MACROS)
457
458// Note that 32 and 64 bit may have already been defined by the advanced GNU
459// case.
460
461// x86 GNU impl
462
463#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_16(dstType, x) \
464 { \
465 unsigned short y; \
466 __asm__ ("xchg %b0, %h0" : "=Q" (y) : "0" ( \
467 static_cast<unsigned short>(x))); \
468 \
469 return static_cast<dstType>(y); \
470 }
471
472#endif // !disabled
473
474#if !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32) \
475 && !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64) \
476 && !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32) \
477 && !defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64)
478
479// x86 GNU pre-4.03 impl
480
481#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32(dstType, x) \
482 { \
483 unsigned int y; \
484 __asm__ ("bswap %0" : "=r" (y) : "0" (static_cast<unsigned int>(x))); \
485 \
486 return static_cast<dstType>(y); \
487 }
488
489#if BSLS_PLATFORM_CPU_32_BIT
490
491// x86 GNU pre-4.03 impl
492
493#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64(dstType, x) \
494 { \
495 typedef BloombergLP::bsls::Types::Uint64 Uint64; \
496 \
497 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof x); \
498 \
499 unsigned int res, tmp; \
500 __asm__ ("bswap %0\n\t" \
501 "bswap %1\n\t" \
502 : "=r" (res), "=r" (tmp) \
503 : "0" ((unsigned)x), "1" ((unsigned)(x >> 32))); \
504 \
505 return static_cast<dstType>(((Uint64)res << 32) | (Uint64)tmp); \
506 }
507
508#else // BSLS_PLATFORM_CPU_64_BIT
509
510// x86 GNU pre-4.03 impl
511
512#define BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64(dstType, x) \
513 { \
514 typedef BloombergLP::bsls::Types::Uint64 Uint64; \
515 \
516 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof x); \
517 \
518 Uint64 y; \
519 __asm__ ("bswap %0" : "=r" (y) : "0" (x)); \
520 \
521 return static_cast<dstType>(y); \
522 }
523
524#endif // 32 & 64 not previously defined
525#endif // BSLS_PLATFORM_CPU_32_BIT else
526#endif // (BSLS_PLATFORM_CMP_GNU || BSLS_PLATFORM_CMP_CLANG) && X86
527
528#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_16(dstType, x) \
529 { \
530 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(2 == sizeof x); \
531 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(2 == sizeof(dstType)); \
532 \
533 return static_cast<dstType>((((x) & 0xff00u) >> 8) | \
534 (((x) & 0x00ffu) << 8)); \
535 }
536
537#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_32(dstType, x) \
538 { \
539 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(4 == sizeof x); \
540 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(4 == sizeof(dstType)); \
541 \
542 return static_cast<dstType>((((x) & 0x000000ffU) << 24) \
543 | (((x) & 0x0000ff00U) << 8) \
544 | (((x) & 0x00ff0000U) >> 8) \
545 | (((x) & 0xff000000U) >> 24)); \
546 }
547
548#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_64(dstType, x) \
549 { \
550 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof x); \
551 BSLS_BYTEORDERUTIL_IMPL_COMPILE_TIME_ASSERT(8 == sizeof(dstType)); \
552 \
553 return static_cast<dstType>((((x) & 0x00000000000000ffULL) << 56) \
554 | (((x) & 0x000000000000ff00ULL) << 40) \
555 | (((x) & 0x0000000000ff0000ULL) << 24) \
556 | (((x) & 0x00000000ff000000ULL) << 8) \
557 | (((x) & 0x000000ff00000000ULL) >> 8) \
558 | (((x) & 0x0000ff0000000000ULL) >> 24) \
559 | (((x) & 0x00ff000000000000ULL) >> 40) \
560 | (((x) & 0xff00000000000000ULL) >> 56)); \
561 }
562
563namespace bsls {
564
565// ============================================================================
566// INLINE DEFINITIONS
567// ============================================================================
568
569 // -------------------------
570 // struct ByteOrderUtil_Impl
571 // -------------------------
572
573// CLASS METHODS
574template <class TYPE>
575inline
577{
578 return x;
579}
580
581template <class TYPE>
582inline
584{
585 // These macros all return a value of type 'TYPE'.
586
587#if defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_16)
588 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_16( TYPE, x);
589#elif defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P16)
590 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P16(TYPE, &x);
591#else
593#endif
594}
595
596template <class TYPE>
597inline
599{
600 // These macros all return a value of type 'TYPE'.
601
602#if defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32)
603 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_32( TYPE, x);
604#elif defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32)
605 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P32(TYPE, &x);
606#else
608#endif
609}
610
611template <class TYPE>
612inline
614{
615 // These macros all return a value of type 'TYPE'.
616
617#if defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64)
618 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_64( TYPE, x);
619#elif defined(BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64)
620# ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
621# pragma GCC diagnostic push
622# pragma GCC diagnostic ignored "-Wstrict-aliasing"
623# endif
624
625 BSLS_BYTEORDERUTIL_IMPL_CUSTOMSWAP_P64(TYPE, &x);
626
627# ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
628# pragma GCC diagnostic pop
629# endif
630#else
632#endif
633}
634
635} // close package namespace
636
637
638#endif
639
640// ----------------------------------------------------------------------------
641// Copyright 2014 Bloomberg Finance L.P.
642//
643// Licensed under the Apache License, Version 2.0 (the "License");
644// you may not use this file except in compliance with the License.
645// You may obtain a copy of the License at
646//
647// http://www.apache.org/licenses/LICENSE-2.0
648//
649// Unless required by applicable law or agreed to in writing, software
650// distributed under the License is distributed on an "AS IS" BASIS,
651// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
652// See the License for the specific language governing permissions and
653// limitations under the License.
654// ----------------------------- END-OF-FILE ----------------------------------
655
656/** @} */
657/** @} */
658/** @} */
#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_32(dstType, x)
Definition bsls_byteorderutil_impl.h:537
#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_16(dstType, x)
Definition bsls_byteorderutil_impl.h:528
#define BSLS_BYTEORDERUTIL_IMPL_GENERICSWAP_64(dstType, x)
Definition bsls_byteorderutil_impl.h:548
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691
Definition bsls_byteorderutil_impl.h:91