LCOV - code coverage report
Current view: top level - lunchbox - bitOperation.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 15 15 100.0 %
Date: 2014-10-01 Functions: 6 6 100.0 %

          Line data    Source code
       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 <lunchbox/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             : {
      42             : /**
      43             :  * @defgroup bitops Bit Operations.
      44             :  *
      45             :  * Example: @include tests/bitOperation.cpp
      46             :  */
      47             : //@{
      48             : /**
      49             :  * @return the position of the last (most significant) set bit, or -1.
      50             :  * @version 1.8
      51             :  */
      52             : template< class T > int32_t getIndexOfLastBit( T value );
      53             : 
      54             : /** Swap the byte order of the given value. @version 1.5.1 */
      55             : template< class T > void byteswap( T& value );
      56             : //@}
      57             : 
      58             : /** @cond IGNORE */
      59             : // Implementation
      60           3 : template<> inline int32_t getIndexOfLastBit< uint32_t >( uint32_t value )
      61             : {
      62             : #ifdef __APPLE__
      63             :     return ::fls( value ) - 1;
      64             : #elif defined __GNUC__
      65           3 :     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   159521360 : template<> inline int32_t getIndexOfLastBit< uint64_t >( uint64_t value )
      81             : {
      82             : #ifdef  __GNUC__
      83   159521360 :     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           1 : getIndexOfLastBit< unsigned long long >( unsigned long long value )
     101           1 : { 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           1 : 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           1 :     value = __builtin_bswap32( value );
     132             : #endif
     133           1 : }
     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           1 : 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           1 :     value = (uint16_t)(value>>8) | (uint16_t)(value<<8);
     149             : #endif
     150           1 : }
     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           1 : 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           1 :     value = __builtin_bswap64( value );
     170             : #endif
     171           1 : }
     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( 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             : }
     191             : /** @endcond */
     192             : 
     193             : }
     194             : #endif //LUNCHBOX_BITOPERATION_H

Generated by: LCOV version 1.10