Logo ROOT  
Reference Guide
Byteswap.h
Go to the documentation of this file.
1/* @(#)root/base:$Id$ */
2
3/*************************************************************************
4 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_Byteswap
12#define ROOT_Byteswap
13
14/* Originally (mid-1990s), this file contained copy/pasted assembler from RH6.0's
15 * version of <bits/byteswap.h>. Hence, we keep a copy of the FSF copyright below.
16 * I believe all the original code has been excised, perhaps with exception of the
17 * R__bswap_constant_* functions. To be on the safe side, we are keeping the
18 * copyright below.
19 * -- Brian Bockelman, August 2018
20 */
21
22/* Copyright (C) 1997 Free Software Foundation, Inc.
23 This file is part of the GNU C Library.
24
25 The GNU C Library is free software; you can redistribute it and/or
26 modify it under the terms of the GNU Library General Public License as
27 published by the Free Software Foundation; either version 2 of the
28 License, or (at your option) any later version.
29
30 The GNU C Library is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 Library General Public License for more details.
34
35 You should have received a copy of the GNU Library General Public
36 License along with the GNU C Library; see the file COPYING.LIB. If not,
37 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA. */
39
40#include <cstdint>
41
42#ifndef R__USEASMSWAP
43#if (defined(__linux) || defined(__APPLE__)) && \
44 (defined(__i386__) || defined(__x86_64__)) && \
45 (defined(__GNUC__))
46# define R__USEASMSWAP
47#endif
48
49#if defined(_WIN32) && (_MSC_VER >= 1300)
50# include <stdlib.h>
51# pragma intrinsic(_byteswap_ushort,_byteswap_ulong,_byteswap_uint64)
52# define R__USEASMSWAP
53#endif
54#endif /* R__USEASMSWAP */
55
56/* Swap bytes in 16 bit value. */
57#define R__bswap_constant_16(x) \
58 ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
59
60#if defined(R__USEASMSWAP)
61# if defined(__GNUC__)
62# define R__bswap_16(x) __builtin_bswap16(x)
63# elif defined(_MSC_VER)
64# define R__bswap_16(x) _byteswap_ushort(x)
65# endif
66#else
67# define R__bswap_16(x) R__bswap_constant_16(x)
68#endif
69
70/* Swap bytes in 32 bit value. */
71#define R__bswap_constant_32(x) \
72 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
73 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
74
75#if defined(R__USEASMSWAP)
76# if defined(__GNUC__)
77# define R__bswap_32(x) __builtin_bswap32(x)
78# elif defined(_MSC_VER)
79# define R__bswap_32(x) _byteswap_ulong(x)
80# endif
81#else
82# define R__bswap_32(x) R__bswap_constant_32(x)
83#endif
84
85/* Swap bytes in 64 bit value. */
86static inline uint64_t R__bswap_constant_64(uint64_t x) {
87 x = ((x & 0x00000000ffffffff) << 32) | ((x & 0xffffffff00000000) >> 32);
88 x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
89 x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);
90 return x;
91}
92
93#if defined(R__USEASMSWAP)
94# if defined(__GNUC__)
95# define R__bswap_64(x) __builtin_bswap64(x)
96# elif defined(_MSC_VER)
97# define R__bswap_64(x) _byteswap_uint64(x)
98# endif
99#else
100# define R__bswap_64(x) R__bswap_constant_64(x)
101#endif
102
103
104/* Return a value with all bytes in the 16 bit argument swapped. */
105#define Rbswap_16(x) R__bswap_16(x)
106
107/* Return a value with all bytes in the 32 bit argument swapped. */
108#define Rbswap_32(x) R__bswap_32(x)
109
110/* Return a value with all bytes in the 64 bit argument swapped. */
111#define Rbswap_64(x) R__bswap_64(x)
112
113/// \brief Helper templated class for swapping bytes; specializations for `N={2,4,8}`
114/// are provided below. This class can be used to byteswap any other type, e.g. in a
115/// templated function (see example below).
116/// ```
117/// template <typename T>
118/// void byteswap_arg(T &x) {
119/// using value_type = typename RByteSwap<sizeof(T)>::value_type;
120/// x = RByteSwap<sizeof(T)>::bswap(reinterpret_cast<value_type>(x));
121/// }
122/// ```
123template <unsigned N>
124struct RByteSwap {
125};
126
127template <>
128struct RByteSwap<2> {
129 // Signed integers can be safely byteswapped if they are reinterpret_cast'ed to unsigned
130 using value_type = std::uint16_t;
131 static value_type bswap(value_type x) { return Rbswap_16(x); }
132};
133
134template <>
135struct RByteSwap<4> {
136 using value_type = std::uint32_t;
137 static value_type bswap(value_type x) { return Rbswap_32(x); }
138};
139
140template <>
141struct RByteSwap<8> {
142 using value_type = std::uint64_t;
143 static value_type bswap(value_type x) { return Rbswap_64(x); }
144};
145
146#endif /* Byteswap.h */
static uint64_t R__bswap_constant_64(uint64_t x)
Definition: Byteswap.h:86
#define Rbswap_32(x)
Definition: Byteswap.h:108
#define Rbswap_64(x)
Definition: Byteswap.h:111
#define Rbswap_16(x)
Definition: Byteswap.h:105
Double_t x[n]
Definition: legend1.C:17
static value_type bswap(value_type x)
Definition: Byteswap.h:131
std::uint16_t value_type
Definition: Byteswap.h:130
static value_type bswap(value_type x)
Definition: Byteswap.h:137
std::uint32_t value_type
Definition: Byteswap.h:136
std::uint64_t value_type
Definition: Byteswap.h:142
static value_type bswap(value_type x)
Definition: Byteswap.h:143
Helper templated class for swapping bytes; specializations for N={2,4,8} are provided below.
Definition: Byteswap.h:124