aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/stubs/port.h
diff options
context:
space:
mode:
authorGravatar Bo Yang <teboring@google.com>2016-09-19 13:45:07 -0700
committerGravatar Bo Yang <teboring@google.com>2016-10-10 11:23:36 -0700
commitcc8ca5b6a5478b40546d4206392eb1471454460d (patch)
treec0b45abfa16d7d373a6ea8f7fe50f1de00ab938e /src/google/protobuf/stubs/port.h
parent337a028bb65ccca4dda768695950b5aba53ae2c9 (diff)
Integrate internal changes
Diffstat (limited to 'src/google/protobuf/stubs/port.h')
-rw-r--r--src/google/protobuf/stubs/port.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index d7f93b4c..376be5f7 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -327,6 +327,61 @@ static inline uint64 bswap_64(uint64 x) {
#endif
// ===================================================================
+// from google3/util/bits/bits.h
+
+class Bits {
+ public:
+ static uint32 Log2FloorNonZero(uint32 n) {
+#if defined(__GNUC__)
+ return 31 ^ __builtin_clz(n);
+#elif defined(COMPILER_MSVC) && defined(_M_IX86)
+ _asm {
+ bsr ebx, n
+ mov n, ebx
+ }
+ return n;
+#else
+ return Log2FloorNonZero_Portable(n);
+#endif
+ }
+
+ static uint64 Log2FloorNonZero64(uint64 n) {
+#if defined(__GNUC__)
+ return 63 ^ __builtin_clzll(n);
+#else
+ return Log2FloorNonZero64_Portable(n);
+#endif
+ }
+ private:
+ static int Log2FloorNonZero_Portable(uint32 n) {
+ if (n == 0)
+ return -1;
+ int log = 0;
+ uint32 value = n;
+ for (int i = 4; i >= 0; --i) {
+ int shift = (1 << i);
+ uint32 x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ assert(value == 1);
+ return log;
+ }
+
+ static int Log2FloorNonZero64_Portable(uint64 n) {
+ const uint32 topbits = static_cast<uint32>(n >> 32);
+ if (topbits == 0) {
+ // Top bits are zero, so scan in bottom bits
+ return Log2FloorNonZero(static_cast<uint32>(n));
+ } else {
+ return 32 + Log2FloorNonZero(topbits);
+ }
+ }
+};
+
+// ===================================================================
// from google3/util/endian/endian.h
LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x);