Equalizer
1.2.1
|
00001 00002 /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com> 00003 * 2011, Stefan Eilemann <eile@eyescale.ch> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1 as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00019 #ifndef COBASE_BITOPERATION_H 00020 #define COBASE_BITOPERATION_H 00021 00022 #include <co/base/types.h> 00023 #ifdef _MSC_VER 00024 # pragma warning (push) 00025 # pragma warning (disable: 4985) // inconsistent decl of ceil 00026 # include <intrin.h> 00027 # pragma warning (pop) 00028 #endif 00029 00030 namespace co 00031 { 00032 namespace base 00033 { 00035 template< class T > int32_t getIndexOfLastBit( T value ); 00036 00037 template<> inline int32_t getIndexOfLastBit< uint32_t >( uint32_t value ) 00038 { 00039 #ifdef Darwin 00040 return ::fls( value ) - 1; 00041 #elif defined __GNUC__ 00042 return value ? (31 - __builtin_clz( value )) : -1; 00043 #elif defined _MSC_VER 00044 unsigned long i = 0; 00045 return _BitScanReverse( &i, value ) ? i : -1; 00046 #else 00047 int32_t count = -1; 00048 while( value ) 00049 { 00050 ++count; 00051 value >>= 1; 00052 } 00053 return count; 00054 #endif 00055 } 00056 00057 template<> inline int32_t getIndexOfLastBit< uint64_t >( uint64_t value ) 00058 { 00059 #ifdef __GNUC__ 00060 return value ? (63 - __builtin_clzll( value )) : -1; 00061 #elif defined _WIN64 00062 unsigned long i = 0; 00063 return _BitScanReverse64( &i, value ) ? i : -1; 00064 #else 00065 int32_t count = -1; 00066 while( value ) 00067 { 00068 ++count; 00069 value >>= 1; 00070 } 00071 return count; 00072 #endif 00073 } 00074 00075 #if defined(Linux) && defined(_LP64) 00076 template<> inline int32_t 00077 getIndexOfLastBit< unsigned long long >( unsigned long long value ) 00078 { return getIndexOfLastBit( static_cast< uint64_t >( value )); } 00079 #endif 00080 #ifdef Darwin 00081 # ifdef _LP64 00082 template<> inline 00083 int32_t getIndexOfLastBit< unsigned long >( unsigned long value ) 00084 { return getIndexOfLastBit( static_cast< uint64_t >( value )); } 00085 # else 00086 template<> inline 00087 int32_t getIndexOfLastBit< unsigned long >( unsigned long value ) 00088 { return getIndexOfLastBit( static_cast< uint32_t >( value )); } 00089 # endif 00090 #endif 00091 } 00092 } 00093 #endif //COBASE_BITOPERATION_H