LCOV - code coverage report
Current view: top level - lunchbox - bitOperation.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 15 15 100.0 %
Date: 2018-10-03 05:33:11 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 <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             : {
      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>
      53             : int32_t getIndexOfLastBit(T value);
      54             : 
      55             : /** Swap the byte order of the given value. @version 1.5.1 */
      56             : template <class T>
      57             : void byteswap(T& value);
      58             : //@}
      59             : 
      60             : /** @cond IGNORE */
      61             : // Implementation
      62             : template <>
      63           3 : inline int32_t getIndexOfLastBit<uint32_t>(uint32_t value)
      64             : {
      65             : #ifdef __APPLE__
      66             :     return ::fls(value) - 1;
      67             : #elif defined __GNUC__
      68           3 :     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           1 : inline int32_t getIndexOfLastBit<uint64_t>(uint64_t value)
      85             : {
      86             : #ifdef __GNUC__
      87           1 :     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           1 : inline int32_t getIndexOfLastBit<unsigned long long>(unsigned long long value)
     105             : {
     106           1 :     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           1 : 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           1 :     value = __builtin_bswap32(value);
     161             : #endif
     162           1 : }
     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           1 : 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           1 :     value = (uint16_t)(value >> 8) | (uint16_t)(value << 8);
     185             : #endif
     186           1 : }
     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           1 : 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           1 :     value = __builtin_bswap64(value);
     213             : #endif
     214           1 : }
     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             : }
     241             : /** @endcond */
     242             : }
     243             : #endif // LUNCHBOX_BITOPERATION_H

Generated by: LCOV version 1.11