Lunchbox  1.16.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
bitOperation.h
1 
2 /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
3  * 2011-2012, Stefan Eilemann <eile@eyescale.ch>
4  * 2012, Daniel Nachbaur <danielnachbaur@gmail.com>
5  *
6  * This library is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License version 2.1 as published
8  * by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef LUNCHBOX_BITOPERATION_H
21 #define LUNCHBOX_BITOPERATION_H
22 
23 #include <lunchbox/compiler.h> // GCC version
24 #include <lunchbox/types.h>
25 #include <servus/uint128_t.h>
26 
27 #ifdef _MSC_VER
28 #pragma warning(push)
29 #pragma warning(disable : 4985) // inconsistent decl of ceil
30 #include <intrin.h>
31 #pragma warning(pop)
32 #elif defined __xlC__
33 #include <builtins.h>
34 #include <byteswap.h>
35 #elif defined(LB_GCC_4_3_OR_OLDER) && !defined(__clang__) && !defined(__APPLE__)
36 #include <byteswap.h>
37 #define LB_GCC_BSWAP_FUNCTION
38 #endif
39 
40 namespace lunchbox
41 {
52 template <class T>
53 int32_t getIndexOfLastBit(T value);
54 
56 template <class T>
57 void byteswap(T& value);
59 
61 // Implementation
62 template <>
63 inline int32_t getIndexOfLastBit<uint32_t>(uint32_t value)
64 {
65 #ifdef __APPLE__
66  return ::fls(value) - 1;
67 #elif defined __GNUC__
68  return value ? (31 - __builtin_clz(value)) : -1;
69 #elif defined _MSC_VER
70  unsigned long i = 0;
71  return _BitScanReverse(&i, value) ? i : -1;
72 #else
73  int32_t count = -1;
74  while (value)
75  {
76  ++count;
77  value >>= 1;
78  }
79  return count;
80 #endif
81 }
82 
83 template <>
84 inline int32_t getIndexOfLastBit<uint64_t>(uint64_t value)
85 {
86 #ifdef __GNUC__
87  return value ? (63 - __builtin_clzll(value)) : -1;
88 #elif defined _WIN64
89  unsigned long i = 0;
90  return _BitScanReverse64(&i, value) ? i : -1;
91 #else
92  int32_t count = -1;
93  while (value)
94  {
95  ++count;
96  value >>= 1;
97  }
98  return count;
99 #endif
100 }
101 
102 #if defined(__linux__) && defined(_LP64)
103 template <>
104 inline int32_t getIndexOfLastBit<unsigned long long>(unsigned long long value)
105 {
106  return getIndexOfLastBit(static_cast<uint64_t>(value));
107 }
108 #endif
109 #ifdef __APPLE__
110 #ifdef _LP64
111 template <>
112 inline int32_t getIndexOfLastBit<unsigned long>(unsigned long value)
113 {
114  return getIndexOfLastBit(static_cast<uint64_t>(value));
115 }
116 #else
117 template <>
118 inline int32_t getIndexOfLastBit<unsigned long>(unsigned long value)
119 {
120  return getIndexOfLastBit(static_cast<uint32_t>(value));
121 }
122 #endif
123 #endif
124 
125 template <>
126 inline void byteswap(void*&)
127 { /*NOP*/
128 }
129 template <>
130 inline void byteswap(bool&)
131 { /*NOP*/
132 }
133 template <>
134 inline void byteswap(char&)
135 { /*NOP*/
136 }
137 template <>
138 inline void byteswap(signed char&)
139 { /*NOP*/
140 }
141 template <>
142 inline void byteswap(unsigned char&)
143 { /*NOP*/
144 }
145 template <>
146 inline void byteswap(std::string&)
147 { /*NOP*/
148 }
149 
150 template <>
151 inline void byteswap(uint32_t& value)
152 {
153 #ifdef _MSC_VER
154  value = _byteswap_ulong(value);
155 #elif defined __xlC__
156  __store4r(value, &value);
157 #elif defined LB_GCC_BSWAP_FUNCTION
158  value = bswap_32(value);
159 #else
160  value = __builtin_bswap32(value);
161 #endif
162 }
163 
164 template <>
165 inline void byteswap(int32_t& value)
166 {
167  byteswap(reinterpret_cast<uint32_t&>(value));
168 }
169 
170 template <>
171 inline void byteswap(float& value)
172 {
173  byteswap(reinterpret_cast<uint32_t&>(value));
174 }
175 
176 template <>
177 inline void byteswap(uint16_t& value)
178 {
179 #ifdef _MSC_VER
180  value = _byteswap_ushort(value);
181 #elif defined __xlC__
182  __store2r(value, &value);
183 #else
184  value = (uint16_t)(value >> 8) | (uint16_t)(value << 8);
185 #endif
186 }
187 
188 template <>
189 inline void byteswap(int16_t& value)
190 {
191  byteswap(reinterpret_cast<uint16_t&>(value));
192 }
193 
194 #ifdef __APPLE__
195 template <>
196 inline void byteswap(unsigned long& value)
197 {
198  byteswap(reinterpret_cast<unsigned long&>(value));
199 }
200 #endif
201 
202 template <>
203 inline void byteswap(uint64_t& value)
204 {
205 #ifdef _MSC_VER
206  value = _byteswap_uint64(value);
207 #elif defined __xlC__
208  value = __bswap_constant_64(value);
209 #elif defined LB_GCC_BSWAP_FUNCTION
210  value = bswap_64(value);
211 #else
212  value = __builtin_bswap64(value);
213 #endif
214 }
215 
216 template <>
217 inline void byteswap(int64_t& value)
218 {
219  byteswap(reinterpret_cast<uint64_t&>(value));
220 }
221 
222 template <>
223 inline void byteswap(double& value)
224 {
225  byteswap(reinterpret_cast<uint64_t&>(value));
226 }
227 
228 template <>
229 inline void byteswap(servus::uint128_t& value)
230 {
231  byteswap(value.high());
232  byteswap(value.low());
233 }
234 
235 template <typename T>
236 inline void byteswap(typename std::vector<T>& value)
237 {
238  for (size_t i = 0; i < value.size(); ++i)
239  byteswap(value[i]);
240 }
242 }
243 #endif // LUNCHBOX_BITOPERATION_H
Basic type definitions not provided by the operating system.
void byteswap(T &value)
Swap the byte order of the given value.
int32_t getIndexOfLastBit(T value)
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:29