Lunchbox
1.4.0
|
00001 00002 /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com> 00003 * 2011-2012, 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 LUNCHBOX_BITOPERATION_H 00020 #define LUNCHBOX_BITOPERATION_H 00021 00022 #include <lunchbox/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 lunchbox 00031 { 00033 template< class T > int32_t getIndexOfLastBit( T value ); 00034 00035 template<> inline int32_t getIndexOfLastBit< uint32_t >( uint32_t value ) 00036 { 00037 #ifdef __APPLE__ 00038 return ::fls( value ) - 1; 00039 #elif defined __GNUC__ 00040 return value ? (31 - __builtin_clz( value )) : -1; 00041 #elif defined _MSC_VER 00042 unsigned long i = 0; 00043 return _BitScanReverse( &i, value ) ? i : -1; 00044 #else 00045 int32_t count = -1; 00046 while( value ) 00047 { 00048 ++count; 00049 value >>= 1; 00050 } 00051 return count; 00052 #endif 00053 } 00054 00055 template<> inline int32_t getIndexOfLastBit< uint64_t >( uint64_t value ) 00056 { 00057 #ifdef __GNUC__ 00058 return value ? (63 - __builtin_clzll( value )) : -1; 00059 #elif defined _WIN64 00060 unsigned long i = 0; 00061 return _BitScanReverse64( &i, value ) ? i : -1; 00062 #else 00063 int32_t count = -1; 00064 while( value ) 00065 { 00066 ++count; 00067 value >>= 1; 00068 } 00069 return count; 00070 #endif 00071 } 00072 00073 #if defined(__linux__) && defined(_LP64) 00074 template<> inline int32_t 00075 getIndexOfLastBit< unsigned long long >( unsigned long long value ) 00076 { return getIndexOfLastBit( static_cast< uint64_t >( value )); } 00077 #endif 00078 #ifdef __APPLE__ 00079 # ifdef _LP64 00080 template<> inline 00081 int32_t getIndexOfLastBit< unsigned long >( unsigned long value ) 00082 { return getIndexOfLastBit( static_cast< uint64_t >( value )); } 00083 # else 00084 template<> inline 00085 int32_t getIndexOfLastBit< unsigned long >( unsigned long value ) 00086 { return getIndexOfLastBit( static_cast< uint32_t >( value )); } 00087 # endif 00088 #endif 00089 } 00090 #endif //LUNCHBOX_BITOPERATION_H