X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FBits.h;h=b6d0a23e2a7c044ca37c1455bafb64bc0f957739;hb=bc857f03fc85a34e84ae8fcdf2d910259940f711;hp=2b5225243ea74c2db0c54793879487a700ff7a52;hpb=982acaae2b98b489e407adc4db700530f98a52fb;p=folly.git diff --git a/folly/Bits.h b/folly/Bits.h index 2b522524..b6d0a23e 100644 --- a/folly/Bits.h +++ b/folly/Bits.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,19 +55,19 @@ #ifndef FOLLY_BITS_H_ #define FOLLY_BITS_H_ -#include "folly/Portability.h" - -#ifndef __GNUC__ -#error GCC required +#if !defined(__clang__) && !(defined(_MSC_VER) && (_MSC_VER < 1900)) +#define FOLLY_INTRINSIC_CONSTEXPR constexpr +#else +// GCC and MSVC 2015+ are the only compilers with +// intrinsics constexpr. +#define FOLLY_INTRINSIC_CONSTEXPR const #endif -#ifndef FOLLY_NO_CONFIG -#include "folly/folly-config.h" -#endif +#include -#include "folly/detail/BitsDetail.h" -#include "folly/detail/BitIteratorDetail.h" -#include "folly/Likely.h" +#include +#include +#include #if FOLLY_HAVE_BYTESWAP_H # include @@ -86,7 +86,7 @@ namespace folly { // Generate overloads for findFirstSet as wrappers around // appropriate ffs, ffsl, ffsll gcc builtins template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -97,7 +97,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -109,7 +109,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -121,7 +121,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_signed::value), unsigned int>::type @@ -135,7 +135,7 @@ typename std::enable_if< // findLastSet: return the 1-based index of the highest bit set // for x > 0, findLastSet(x) == 1 + floor(log2(x)) template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -146,7 +146,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -158,7 +158,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_unsigned::value && @@ -170,7 +170,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< (std::is_integral::value && std::is_signed::value), @@ -180,7 +180,7 @@ typename std::enable_if< } template -inline constexpr +inline FOLLY_INTRINSIC_CONSTEXPR typename std::enable_if< std::is_integral::value && std::is_unsigned::value, T>::type @@ -232,6 +232,8 @@ struct EndianIntBase { static T swap(T x); }; +#ifndef _MSC_VER + /** * If we have the bswap_16 macro from byteswap.h, use it; otherwise, provide our * own definition. @@ -249,6 +251,8 @@ our_bswap16(Int16 x) { } #endif +#endif + #define FB_GEN(t, fn) \ template<> inline t EndianIntBase::swap(t x) { return fn(x); } @@ -257,12 +261,21 @@ template<> inline t EndianIntBase::swap(t x) { return fn(x); } // __builtin_bswap16 for some reason, so we have to provide our own. FB_GEN( int8_t,) FB_GEN(uint8_t,) +#ifdef _MSC_VER +FB_GEN( int64_t, _byteswap_uint64) +FB_GEN(uint64_t, _byteswap_uint64) +FB_GEN( int32_t, _byteswap_ulong) +FB_GEN(uint32_t, _byteswap_ulong) +FB_GEN( int16_t, _byteswap_ushort) +FB_GEN(uint16_t, _byteswap_ushort) +#else FB_GEN( int64_t, __builtin_bswap64) FB_GEN(uint64_t, __builtin_bswap64) FB_GEN( int32_t, __builtin_bswap32) FB_GEN(uint32_t, __builtin_bswap32) FB_GEN( int16_t, our_bswap16) FB_GEN(uint16_t, our_bswap16) +#endif #undef FB_GEN @@ -334,10 +347,12 @@ class Endian { return detail::EndianInt::little(x); } +#if !defined(__ANDROID__) FB_GEN(64) FB_GEN(32) FB_GEN(16) FB_GEN(8) +#endif }; #undef FB_GEN @@ -366,7 +381,7 @@ class BitIterator /** * Return the number of bits in an element of the underlying iterator. */ - static size_t bitsPerBlock() { + static unsigned int bitsPerBlock() { return std::numeric_limits< typename std::make_unsigned< typename std::iterator_traits::value_type @@ -378,11 +393,14 @@ class BitIterator * Construct a BitIterator that points at a given bit offset (default 0) * in iter. */ + #pragma GCC diagnostic push // bitOffset shadows a member + #pragma GCC diagnostic ignored "-Wshadow" explicit BitIterator(const BaseIter& iter, size_t bitOffset=0) : bititerator_detail::BitIteratorBase::type(iter), bitOffset_(bitOffset) { assert(bitOffset_ < bitsPerBlock()); } + #pragma GCC diagnostic pop size_t bitOffset() const { return bitOffset_; @@ -449,10 +467,10 @@ class BitIterator ssize_t distance_to(const BitIterator& other) const { return (other.base_reference() - this->base_reference()) * bitsPerBlock() + - (other.bitOffset_ - bitOffset_); + other.bitOffset_ - bitOffset_; } - ssize_t bitOffset_; + unsigned int bitOffset_; }; /** @@ -514,6 +532,7 @@ template struct Unaligned; /** * Representation of an unaligned value of a POD type. */ +FOLLY_PACK_PUSH template struct Unaligned< T, @@ -521,7 +540,8 @@ struct Unaligned< Unaligned() = default; // uninitialized /* implicit */ Unaligned(T v) : value(v) { } T value; -} __attribute__((packed)); +} FOLLY_PACK_ATTR; +FOLLY_PACK_POP /** * Read an unaligned value of type T and return it. @@ -546,4 +566,3 @@ inline void storeUnaligned(void* p, T value) { } // namespace folly #endif /* FOLLY_BITS_H_ */ -