Lunchbox  1.11.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 > int32_t getIndexOfLastBit( T value );
53 
55 template< class T > void byteswap( T& value );
57 
59 // Implementation
60 template<> inline int32_t getIndexOfLastBit< uint32_t >( uint32_t value )
61 {
62 #ifdef __APPLE__
63  return ::fls( value ) - 1;
64 #elif defined __GNUC__
65  return value ? (31 - __builtin_clz( value )) : -1;
66 #elif defined _MSC_VER
67  unsigned long i = 0;
68  return _BitScanReverse( &i, value ) ? i : -1;
69 #else
70  int32_t count = -1;
71  while( value )
72  {
73  ++count;
74  value >>= 1;
75  }
76  return count;
77 #endif
78 }
79 
80 template<> inline int32_t getIndexOfLastBit< uint64_t >( uint64_t value )
81 {
82 #ifdef __GNUC__
83  return value ? (63 - __builtin_clzll( value )) : -1;
84 #elif defined _WIN64
85  unsigned long i = 0;
86  return _BitScanReverse64( &i, value ) ? i : -1;
87 #else
88  int32_t count = -1;
89  while( value )
90  {
91  ++count;
92  value >>= 1;
93  }
94  return count;
95 #endif
96 }
97 
98 #if defined(__linux__) && defined(_LP64)
99 template<> inline int32_t
100 getIndexOfLastBit< unsigned long long >( unsigned long long value )
101 { return getIndexOfLastBit( static_cast< uint64_t >( value )); }
102 #endif
103 #ifdef __APPLE__
104 # ifdef _LP64
105 template<> inline
106 int32_t getIndexOfLastBit< unsigned long >( unsigned long value )
107 { return getIndexOfLastBit( static_cast< uint64_t >( value )); }
108 # else
109 template<> inline
110 int32_t getIndexOfLastBit< unsigned long >( unsigned long value )
111 { return getIndexOfLastBit( static_cast< uint32_t >( value )); }
112 # endif
113 #endif
114 
115 template<> inline void byteswap( void*& ) { /*NOP*/ }
116 template<> inline void byteswap( bool&) { /*NOP*/ }
117 template<> inline void byteswap( char& ) { /*NOP*/ }
118 template<> inline void byteswap( signed char& ) { /*NOP*/ }
119 template<> inline void byteswap( unsigned char& ) { /*NOP*/ }
120 template<> inline void byteswap( std::string& ) { /*NOP*/ }
121 
122 template<> inline void byteswap( uint32_t& value )
123 {
124 #ifdef _MSC_VER
125  value = _byteswap_ulong( value );
126 #elif defined __xlC__
127  __store4r( value, &value );
128 #elif defined LB_GCC_BSWAP_FUNCTION
129  value = bswap_32( value );
130 #else
131  value = __builtin_bswap32( value );
132 #endif
133 }
134 
135 template<> inline void byteswap( int32_t& value )
136 { byteswap( reinterpret_cast< uint32_t& >( value )); }
137 
138 template<> inline void byteswap( float& value )
139 { byteswap( reinterpret_cast< uint32_t& >( value )); }
140 
141 template<> inline void byteswap( uint16_t& value )
142 {
143 #ifdef _MSC_VER
144  value = _byteswap_ushort( value );
145 #elif defined __xlC__
146  __store2r( value, &value );
147 #else
148  value = (uint16_t)(value>>8) | (uint16_t)(value<<8);
149 #endif
150 }
151 
152 template<> inline void byteswap( int16_t& value )
153 { byteswap( reinterpret_cast< uint16_t& >( value )); }
154 
155 #ifdef __APPLE__
156 template<> inline void byteswap( unsigned long& value )
157 { byteswap( reinterpret_cast< unsigned long& >( value )); }
158 #endif
159 
160 template<> inline void byteswap( uint64_t& value )
161 {
162 #ifdef _MSC_VER
163  value = _byteswap_uint64( value );
164 #elif defined __xlC__
165  value = __bswap_constant_64( value );
166 #elif defined LB_GCC_BSWAP_FUNCTION
167  value = bswap_64( value );
168 #else
169  value = __builtin_bswap64( value );
170 #endif
171 }
172 
173 template<> inline void byteswap( int64_t& value )
174 { byteswap( reinterpret_cast< uint64_t& >( value )); }
175 
176 template<> inline void byteswap( double& value )
177 { byteswap( reinterpret_cast< uint64_t& >( value )); }
178 
179 template<> inline void byteswap( servus::uint128_t& value )
180 {
181  byteswap( value.high( ));
182  byteswap( value.low( ));
183 }
184 
185 template< typename T >
186 inline void byteswap( typename std::vector< T >& value )
187 {
188  for( size_t i = 0; i < value.size(); ++i )
189  byteswap( value[i] );
190 }
193 }
194 #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)