Merge tag 'refs/tags/sync-piper' into sync-stage
diff --git a/python/setup.py b/python/setup.py index aab240a..696bde2 100755 --- a/python/setup.py +++ b/python/setup.py
@@ -18,6 +18,7 @@ from distutils.command.build_py import build_py as _build_py from distutils.command.clean import clean as _clean +from distutils.command.build_ext import build_ext as _build_ext from distutils.spawn import find_executable # Find the Protocol Compiler. @@ -157,6 +158,22 @@ if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)] +class build_ext(_build_ext): + def get_ext_filename(self, ext_name): + # since python3.5, python extensions' shared libraries use a suffix that corresponds to the value + # of sysconfig.get_config_var('EXT_SUFFIX') and contains info about the architecture the library targets. + # E.g. on x64 linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so" + # When crosscompiling python wheels, we need to be able to override this suffix + # so that the resulting file name matches the target architecture and we end up with a well-formed + # wheel. + filename = _build_ext.get_ext_filename(self, ext_name) + orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") + new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX") + if new_ext_suffix and filename.endswith(orig_ext_suffix): + filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix + return filename + + class test_conformance(_build_py): target = 'test_python' def run(self): @@ -291,6 +308,7 @@ cmdclass={ 'clean': clean, 'build_py': build_py, + 'build_ext': build_ext, 'test_conformance': test_conformance, }, install_requires=install_requires,
diff --git a/src/google/protobuf/stubs/bytestream.cc b/src/google/protobuf/stubs/bytestream.cc index a0f298e..980d6f6 100644 --- a/src/google/protobuf/stubs/bytestream.cc +++ b/src/google/protobuf/stubs/bytestream.cc
@@ -173,12 +173,8 @@ } StringPiece LimitByteSource::Peek() { - StringPiece piece(source_->Peek()); - if (piece.size() > limit_) { - piece.set(piece.data(), limit_); - } - - return piece; + StringPiece piece = source_->Peek(); + return StringPiece(piece.data(), std::min(piece.size(), limit_)); } void LimitByteSource::Skip(size_t n) {
diff --git a/src/google/protobuf/stubs/casts.h b/src/google/protobuf/stubs/casts.h index d8a49ce..ad29dac 100644 --- a/src/google/protobuf/stubs/casts.h +++ b/src/google/protobuf/stubs/casts.h
@@ -116,8 +116,7 @@ template<typename To, typename From> inline To bit_cast(const From& from) { - GOOGLE_COMPILE_ASSERT(sizeof(From) == sizeof(To), - bit_cast_with_different_sizes); + static_assert(sizeof(From) == sizeof(To), "bit_cast_with_different_sizes"); To dest; memcpy(&dest, &from, sizeof(dest)); return dest;
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 2dfcc9b..86aecb1 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h
@@ -123,7 +123,6 @@ // =================================================================== // from google3/util/utf8/public/unilib.h -class StringPiece; namespace internal { // Checks if the buffer contains structurally-valid UTF-8. Implemented in
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc index 7fc7dd8..840f2d1 100644 --- a/src/google/protobuf/stubs/int128.cc +++ b/src/google/protobuf/stubs/int128.cc
@@ -33,6 +33,7 @@ #include <iomanip> #include <ostream> // NOLINT(readability/streams) #include <sstream> +#include <string> #include <google/protobuf/stubs/logging.h> @@ -40,11 +41,7 @@ namespace google { namespace protobuf { - -const uint128_pod kuint128max = { - static_cast<uint64>(PROTOBUF_LONGLONG(0xFFFFFFFFFFFFFFFF)), - static_cast<uint64>(PROTOBUF_LONGLONG(0xFFFFFFFFFFFFFFFF)) -}; +namespace int128_internal { // Returns the 0-based position of the last set bit (i.e., most significant bit) // in the given uint64. The argument may not be 0. @@ -188,6 +185,14 @@ return o << rep; } +void VerifyValidShift(std::string op, int amount) { + // Shifting more than 127 is UB in Abseil, just crash for now to verify + // callers don't depend on it returning 0. + GOOGLE_CHECK_LT(amount, 128) << "Error executing operator " << op + << ": shifts of more than 127 are undefined"; +} + +} // namespace int128_internal } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/int128.h b/src/google/protobuf/stubs/int128.h index dc70d96..8ae4897 100644 --- a/src/google/protobuf/stubs/int128.h +++ b/src/google/protobuf/stubs/int128.h
@@ -33,38 +33,33 @@ #include <google/protobuf/stubs/common.h> #include <iosfwd> +#include <limits> +#include <string> #include <google/protobuf/port_def.inc> namespace google { namespace protobuf { - -struct uint128_pod; - -// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is -// available. -#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR -# define UINT128_CONSTEXPR constexpr -#else -# define UINT128_CONSTEXPR -#endif +namespace int128_internal { // An unsigned 128-bit integer type. Thread-compatible. class PROTOBUF_EXPORT uint128 { public: - UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior. - UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom); + uint128() = default; + + private: + // Use `MakeUint128` instead. + constexpr uint128(uint64 top, uint64 bottom); + + public: #ifndef SWIG - UINT128_CONSTEXPR uint128(int bottom); - UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0 + constexpr uint128(int bottom); + constexpr uint128(uint32 bottom); // Top 96 bits = 0 #endif - UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0 - UINT128_CONSTEXPR uint128(const uint128_pod &val); + constexpr uint128(uint64 bottom); // hi_ = 0 // Trivial copy constructor, assignment operator and destructor. - void Initialize(uint64 top, uint64 bottom); - // Arithmetic operators. uint128& operator+=(const uint128& b); uint128& operator-=(const uint128& b); @@ -82,8 +77,10 @@ uint128& operator++(); uint128& operator--(); - friend uint64 Uint128Low64(const uint128& v); - friend uint64 Uint128High64(const uint128& v); + friend constexpr uint64 Uint128Low64(const uint128& v); + friend constexpr uint64 Uint128High64(const uint128& v); + + friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low); // We add "std::" to avoid including all of port.h. PROTOBUF_EXPORT friend std::ostream& operator<<(std::ostream& o, @@ -100,26 +97,12 @@ uint64 hi_; // Not implemented, just declared for catching automatic type conversions. - uint128(uint8); - uint128(uint16); - uint128(float v); - uint128(double v); + uint128(uint8) = delete; + uint128(uint16) = delete; + uint128(float v) = delete; + uint128(double v) = delete; }; -// This is a POD form of uint128 which can be used for static variables which -// need to be operated on as uint128. -struct uint128_pod { - // Note: The ordering of fields is different than 'class uint128' but the - // same as its 2-arg constructor. This enables more obvious initialization - // of static instances, which is the primary reason for this struct in the - // first place. This does not seem to defeat any optimizations wrt - // operations involving this struct. - uint64 hi; - uint64 lo; -}; - -PROTOBUF_EXPORT extern const uint128_pod kuint128max; - // allow uint128 to be logged PROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o, const uint128& b); @@ -127,8 +110,12 @@ // Methods to access low and high pieces of 128-bit value. // Defined externally from uint128 to facilitate conversion // to native 128-bit types when compilers support them. -inline uint64 Uint128Low64(const uint128& v) { return v.lo_; } -inline uint64 Uint128High64(const uint128& v) { return v.hi_; } +inline constexpr uint64 Uint128Low64(const uint128& v) { return v.lo_; } +inline constexpr uint64 Uint128High64(const uint128& v) { return v.hi_; } + +constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { + return uint128(high, low); +} // TODO: perhaps it would be nice to have int128, a signed 128-bit type? @@ -143,27 +130,17 @@ return !(lhs == rhs); } -inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {} -inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom) +inline constexpr uint128::uint128(uint64 top, uint64 bottom) : lo_(bottom), hi_(top) {} -inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v) - : lo_(v.lo), hi_(v.hi) {} -inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom) +inline constexpr uint128::uint128(uint64 bottom) : lo_(bottom), hi_(0) {} #ifndef SWIG -inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom) +inline constexpr uint128::uint128(uint32 bottom) : lo_(bottom), hi_(0) {} -inline UINT128_CONSTEXPR uint128::uint128(int bottom) +inline constexpr uint128::uint128(int bottom) : lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {} #endif -#undef UINT128_CONSTEXPR - -inline void uint128::Initialize(uint64 top, uint64 bottom) { - hi_ = top; - lo_ = bottom; -} - // Comparison operators. #define CMP128(op) \ @@ -187,9 +164,9 @@ const uint64 lo_flip = ~Uint128Low64(val); const uint64 lo_add = lo_flip + 1; if (lo_add < lo_flip) { - return uint128(hi_flip + 1, lo_add); + return MakeUint128(hi_flip + 1, lo_add); } - return uint128(hi_flip, lo_add); + return MakeUint128(hi_flip, lo_add); } inline bool operator!(const uint128& val) { @@ -199,13 +176,13 @@ // Logical operators. inline uint128 operator~(const uint128& val) { - return uint128(~Uint128High64(val), ~Uint128Low64(val)); + return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); } #define LOGIC128(op) \ inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \ - return uint128(Uint128High64(lhs) op Uint128High64(rhs), \ - Uint128Low64(lhs) op Uint128Low64(rhs)); \ + return MakeUint128(Uint128High64(lhs) op Uint128High64(rhs), \ + Uint128Low64(lhs) op Uint128Low64(rhs)); \ } LOGIC128(|) @@ -229,7 +206,11 @@ // Shift operators. +void VerifyValidShift(std::string op, int amount); + inline uint128 operator<<(const uint128& val, int amount) { + VerifyValidShift("<<", amount); + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. if (amount < 64) { if (amount == 0) { @@ -238,15 +219,14 @@ uint64 new_hi = (Uint128High64(val) << amount) | (Uint128Low64(val) >> (64 - amount)); uint64 new_lo = Uint128Low64(val) << amount; - return uint128(new_hi, new_lo); - } else if (amount < 128) { - return uint128(Uint128Low64(val) << (amount - 64), 0); - } else { - return uint128(0, 0); + return MakeUint128(new_hi, new_lo); } + return MakeUint128(Uint128Low64(val) << (amount - 64), 0); } inline uint128 operator>>(const uint128& val, int amount) { + VerifyValidShift(">>", amount); + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. if (amount < 64) { if (amount == 0) { @@ -255,12 +235,10 @@ uint64 new_hi = Uint128High64(val) >> amount; uint64 new_lo = (Uint128Low64(val) >> amount) | (Uint128High64(val) << (64 - amount)); - return uint128(new_hi, new_lo); - } else if (amount < 128) { - return uint128(0, Uint128High64(val) >> (amount - 64)); - } else { - return uint128(0, 0); + return MakeUint128(new_hi, new_lo); } + + return MakeUint128(0, Uint128High64(val) >> (amount - 64)); } inline uint128& uint128::operator<<=(int amount) { @@ -379,6 +357,17 @@ return *this; } +constexpr uint128 Uint128Max() { + return MakeUint128((std::numeric_limits<uint64>::max)(), + (std::numeric_limits<uint64>::max)()); +} + +} // namespace int128_internal + +using google::protobuf::int128_internal::uint128; +using google::protobuf::int128_internal::Uint128Max; +using google::protobuf::int128_internal::MakeUint128; + } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/int128_unittest.cc b/src/google/protobuf/stubs/int128_unittest.cc index 53dbd09..3689104 100644 --- a/src/google/protobuf/stubs/int128_unittest.cc +++ b/src/google/protobuf/stubs/int128_unittest.cc
@@ -33,6 +33,7 @@ #include <algorithm> #include <sstream> #include <utility> +#include <type_traits> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> @@ -44,16 +45,18 @@ TEST(Int128, AllTests) { uint128 zero(0); + EXPECT_EQ(zero, uint128()); + uint128 one(1); - uint128 one_2arg(0, 1); - uint128 two(0, 2); - uint128 three(0, 3); - uint128 big(2000, 2); - uint128 big_minus_one(2000, 1); - uint128 bigger(2001, 1); - uint128 biggest(kuint128max); - uint128 high_low(1, 0); - uint128 low_high(0, kuint64max); + uint128 one_2arg = MakeUint128(0, 1); + uint128 two = MakeUint128(0, 2); + uint128 three = MakeUint128(0, 3); + uint128 big = MakeUint128(2000, 2); + uint128 big_minus_one = MakeUint128(2000, 1); + uint128 bigger = MakeUint128(2001, 1); + uint128 biggest(Uint128Max()); + uint128 high_low = MakeUint128(1, 0); + uint128 low_high = MakeUint128(0, kuint64max); EXPECT_LT(one, two); EXPECT_GT(two, one); EXPECT_LT(one, big); @@ -92,8 +95,6 @@ EXPECT_EQ(big, (big >> 1) << 1); EXPECT_EQ(one, (one << 80) >> 80); EXPECT_EQ(zero, (one >> 80) << 80); - EXPECT_EQ(zero, big >> 128); - EXPECT_EQ(zero, big << 128); // Shift assignments. uint128 big_copy = big; @@ -117,9 +118,9 @@ big_copy = big; EXPECT_EQ(big >> 73, big_copy >>= 73); big_copy = big; - EXPECT_EQ(big << 128, big_copy <<= 128); + EXPECT_EQ(big << 127, big_copy <<= 127); big_copy = big; - EXPECT_EQ(big >> 128, big_copy >>= 128); + EXPECT_EQ(big >> 127, big_copy >>= 127); EXPECT_EQ(Uint128High64(biggest), kuint64max); EXPECT_EQ(Uint128Low64(biggest), kuint64max); @@ -170,92 +171,13 @@ EXPECT_EQ(big, -(-big)); EXPECT_EQ(two, -((-one) - 1)); - EXPECT_EQ(kuint128max, -one); + EXPECT_EQ(Uint128Max(), -one); EXPECT_EQ(zero, -zero); GOOGLE_LOG(INFO) << one; GOOGLE_LOG(INFO) << big_minus_one; } -TEST(Int128, PodTests) { - uint128_pod pod = { 12345, 67890 }; - uint128 from_pod(pod); - EXPECT_EQ(12345, Uint128High64(from_pod)); - EXPECT_EQ(67890, Uint128Low64(from_pod)); - - uint128 zero(0); - uint128_pod zero_pod = {0, 0}; - uint128 one(1); - uint128_pod one_pod = {0, 1}; - uint128 two(2); - uint128_pod two_pod = {0, 2}; - uint128 three(3); - uint128_pod three_pod = {0, 3}; - uint128 big(1, 0); - uint128_pod big_pod = {1, 0}; - - EXPECT_EQ(zero, zero_pod); - EXPECT_EQ(zero_pod, zero); - EXPECT_EQ(zero_pod, zero_pod); - EXPECT_EQ(one, one_pod); - EXPECT_EQ(one_pod, one); - EXPECT_EQ(one_pod, one_pod); - EXPECT_EQ(two, two_pod); - EXPECT_EQ(two_pod, two); - EXPECT_EQ(two_pod, two_pod); - - EXPECT_NE(one, two_pod); - EXPECT_NE(one_pod, two); - EXPECT_NE(one_pod, two_pod); - - EXPECT_LT(one, two_pod); - EXPECT_LT(one_pod, two); - EXPECT_LT(one_pod, two_pod); - EXPECT_LE(one, one_pod); - EXPECT_LE(one_pod, one); - EXPECT_LE(one_pod, one_pod); - EXPECT_LE(one, two_pod); - EXPECT_LE(one_pod, two); - EXPECT_LE(one_pod, two_pod); - - EXPECT_GT(two, one_pod); - EXPECT_GT(two_pod, one); - EXPECT_GT(two_pod, one_pod); - EXPECT_GE(two, two_pod); - EXPECT_GE(two_pod, two); - EXPECT_GE(two_pod, two_pod); - EXPECT_GE(two, one_pod); - EXPECT_GE(two_pod, one); - EXPECT_GE(two_pod, one_pod); - - EXPECT_EQ(three, one | two_pod); - EXPECT_EQ(three, one_pod | two); - EXPECT_EQ(three, one_pod | two_pod); - EXPECT_EQ(one, three & one_pod); - EXPECT_EQ(one, three_pod & one); - EXPECT_EQ(one, three_pod & one_pod); - EXPECT_EQ(two, three ^ one_pod); - EXPECT_EQ(two, three_pod ^ one); - EXPECT_EQ(two, three_pod ^ one_pod); - EXPECT_EQ(two, three & (~one)); - EXPECT_EQ(three, ~~three); - - EXPECT_EQ(two, two_pod << 0); - EXPECT_EQ(two, one_pod << 1); - EXPECT_EQ(big, one_pod << 64); - EXPECT_EQ(zero, one_pod << 128); - EXPECT_EQ(two, two_pod >> 0); - EXPECT_EQ(one, two_pod >> 1); - EXPECT_EQ(one, big_pod >> 64); - - EXPECT_EQ(one, zero + one_pod); - EXPECT_EQ(one, zero_pod + one); - EXPECT_EQ(one, zero_pod + one_pod); - EXPECT_EQ(one, two - one_pod); - EXPECT_EQ(one, two_pod - one); - EXPECT_EQ(one, two_pod - one_pod); -} - TEST(Int128, OperatorAssignReturnRef) { uint128 v(1); (v += 4) -= 3; @@ -293,38 +215,38 @@ } // Verified with dc. - a = uint128(PROTOBUF_ULONGLONG(0xffffeeeeddddcccc), - PROTOBUF_ULONGLONG(0xbbbbaaaa99998888)); - b = uint128(PROTOBUF_ULONGLONG(0x7777666655554444), - PROTOBUF_ULONGLONG(0x3333222211110000)); + a = MakeUint128(PROTOBUF_ULONGLONG(0xffffeeeeddddcccc), + PROTOBUF_ULONGLONG(0xbbbbaaaa99998888)); + b = MakeUint128(PROTOBUF_ULONGLONG(0x7777666655554444), + PROTOBUF_ULONGLONG(0x3333222211110000)); c = a * b; - EXPECT_EQ(uint128(PROTOBUF_ULONGLONG(0x530EDA741C71D4C3), - PROTOBUF_ULONGLONG(0xBF25975319080000)), + EXPECT_EQ(MakeUint128(PROTOBUF_ULONGLONG(0x530EDA741C71D4C3), + PROTOBUF_ULONGLONG(0xBF25975319080000)), c); EXPECT_EQ(0, c - b * a); EXPECT_EQ(a * a - b * b, (a + b) * (a - b)); // Verified with dc. - a = uint128(PROTOBUF_ULONGLONG(0x0123456789abcdef), - PROTOBUF_ULONGLONG(0xfedcba9876543210)); - b = uint128(PROTOBUF_ULONGLONG(0x02468ace13579bdf), - PROTOBUF_ULONGLONG(0xfdb97531eca86420)); + a = MakeUint128(PROTOBUF_ULONGLONG(0x0123456789abcdef), + PROTOBUF_ULONGLONG(0xfedcba9876543210)); + b = MakeUint128(PROTOBUF_ULONGLONG(0x02468ace13579bdf), + PROTOBUF_ULONGLONG(0xfdb97531eca86420)); c = a * b; - EXPECT_EQ(uint128(PROTOBUF_ULONGLONG(0x97a87f4f261ba3f2), - PROTOBUF_ULONGLONG(0x342d0bbf48948200)), + EXPECT_EQ(MakeUint128(PROTOBUF_ULONGLONG(0x97a87f4f261ba3f2), + PROTOBUF_ULONGLONG(0x342d0bbf48948200)), c); EXPECT_EQ(0, c - b * a); EXPECT_EQ(a*a - b*b, (a+b) * (a-b)); } TEST(Int128, AliasTests) { - uint128 x1(1, 2); - uint128 x2(2, 4); + uint128 x1 = MakeUint128(1, 2); + uint128 x2 = MakeUint128(2, 4); x1 += x1; EXPECT_EQ(x2, x1); - uint128 x3(1, static_cast<uint64>(1) << 63); - uint128 x4(3, 0); + uint128 x3 = MakeUint128(1, static_cast<uint64>(1) << 63); + uint128 x4 = MakeUint128(3, 0); x3 += x3; EXPECT_EQ(x4, x3); } @@ -345,6 +267,12 @@ a = 123; EXPECT_DEATH(a % b, "Division or mod by zero:"); } + +TEST(Int128, ShiftGreater128) { + uint128 a; + EXPECT_DEATH(a << 128, "Left-shift greater or equal 128"); + EXPECT_DEATH(a >> 128, "Right-shift greater or equal 128"); +} #endif // PROTOBUF_HAS_DEATH_TEST TEST(Int128, DivideAndMod) { @@ -359,10 +287,10 @@ EXPECT_EQ(0, q); EXPECT_EQ(0, r); - a = uint128(PROTOBUF_ULONGLONG(0x530eda741c71d4c3), - PROTOBUF_ULONGLONG(0xbf25975319080000)); - q = uint128(PROTOBUF_ULONGLONG(0x4de2cab081), - PROTOBUF_ULONGLONG(0x14c34ab4676e4bab)); + a = MakeUint128(PROTOBUF_ULONGLONG(0x530eda741c71d4c3), + PROTOBUF_ULONGLONG(0xbf25975319080000)); + q = MakeUint128(PROTOBUF_ULONGLONG(0x4de2cab081), + PROTOBUF_ULONGLONG(0x14c34ab4676e4bab)); b = uint128(0x1110001); r = uint128(0x3eb455); ASSERT_EQ(a, q * b + r); // Sanity-check. @@ -400,8 +328,8 @@ // Try a large remainder. b = a / 2 + 1; - uint128 expected_r(PROTOBUF_ULONGLONG(0x29876d3a0e38ea61), - PROTOBUF_ULONGLONG(0xdf92cba98c83ffff)); + uint128 expected_r = MakeUint128(PROTOBUF_ULONGLONG(0x29876d3a0e38ea61), + PROTOBUF_ULONGLONG(0xdf92cba98c83ffff)); // Sanity checks. ASSERT_EQ(a / 2 - 1, expected_r); ASSERT_EQ(a, b + expected_r); @@ -421,8 +349,8 @@ TEST(Int128, DivideAndModRandomInputs) { const int kNumIters = 1 << 18; for (int i = 0; i < kNumIters; ++i) { - const uint128 a(RandomUint64(), RandomUint64()); - const uint128 b(RandomUint64(), RandomUint64()); + const uint128 a = MakeUint128(RandomUint64(), RandomUint64()); + const uint128 b = MakeUint128(RandomUint64(), RandomUint64()); if (b == 0) { continue; // Avoid a div-by-zero. } @@ -432,24 +360,22 @@ } } -#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR TEST(Int128, ConstexprTest) { - constexpr uint128 zero; constexpr uint128 one = 1; - constexpr uint128_pod pod = {2, 3}; - constexpr uint128 from_pod = pod; constexpr uint128 minus_two = -2; EXPECT_EQ(one, uint128(1)); - EXPECT_EQ(from_pod, uint128(2, 3)); - EXPECT_EQ(minus_two, uint128(-1ULL, -2ULL)); + EXPECT_EQ(minus_two, MakeUint128(-1ULL, -2ULL)); } +#if !defined(__GNUC__) || __GNUC__ > 4 +// libstdc++ is missing the required type traits pre gcc-5.0.0 +// https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/manual/status.html#:~:text=20.9.4.3 TEST(Int128, Traits) { EXPECT_TRUE(std::is_trivially_copy_constructible<uint128>::value); EXPECT_TRUE(std::is_trivially_copy_assignable<uint128>::value); EXPECT_TRUE(std::is_trivially_destructible<uint128>::value); } -#endif // GOOGLE_PROTOBUF_HAS_CONSTEXPR +#endif // !defined(__GNUC__) || __GNUC__ > 4 TEST(Int128, OStream) { struct { @@ -464,28 +390,28 @@ {uint128(0), std::ios::oct, 0, '_', "0"}, {uint128(0), std::ios::hex, 0, '_', "0"}, // crossover between lo_ and hi_ - {uint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"}, - {uint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"}, - {uint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"}, - {uint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"}, - {uint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"}, - {uint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"}, + {MakeUint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"}, + {MakeUint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"}, + {MakeUint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"}, + {MakeUint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"}, + {MakeUint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"}, + {MakeUint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"}, // just the top bit - {uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0, + {MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0, '_', "170141183460469231731687303715884105728"}, - {uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0, + {MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0, '_', "2000000000000000000000000000000000000000000"}, - {uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0, + {MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0, '_', "80000000000000000000000000000000"}, // maximum uint128 value - {uint128(-1, -1), std::ios::dec, 0, '_', + {MakeUint128(-1, -1), std::ios::dec, 0, '_', "340282366920938463463374607431768211455"}, - {uint128(-1, -1), std::ios::oct, 0, '_', + {MakeUint128(-1, -1), std::ios::oct, 0, '_', "3777777777777777777777777777777777777777777"}, - {uint128(-1, -1), std::ios::hex, 0, '_', + {MakeUint128(-1, -1), std::ios::hex, 0, '_', "ffffffffffffffffffffffffffffffff"}, // uppercase - {uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_', + {MakeUint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_', "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"}, // showbase {uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},
diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h index 110ccdc..20b61f7 100644 --- a/src/google/protobuf/stubs/logging.h +++ b/src/google/protobuf/stubs/logging.h
@@ -31,9 +31,11 @@ #ifndef GOOGLE_PROTOBUF_STUBS_LOGGING_H_ #define GOOGLE_PROTOBUF_STUBS_LOGGING_H_ +#include <google/protobuf/stubs/int128.h> #include <google/protobuf/stubs/macros.h> #include <google/protobuf/stubs/port.h> #include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/stringpiece.h> #include <google/protobuf/port_def.inc> @@ -64,8 +66,6 @@ #endif }; -class StringPiece; -class uint128; namespace internal { class LogFinisher;
diff --git a/src/google/protobuf/stubs/macros.h b/src/google/protobuf/stubs/macros.h index c556d02..fcb0687 100644 --- a/src/google/protobuf/stubs/macros.h +++ b/src/google/protobuf/stubs/macros.h
@@ -31,21 +31,19 @@ #ifndef GOOGLE_PROTOBUF_MACROS_H__ #define GOOGLE_PROTOBUF_MACROS_H__ -#include <google/protobuf/stubs/port.h> - namespace google { namespace protobuf { #undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS #define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete #undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS #define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete // =================================================================== // from google3/base/basictypes.h @@ -89,31 +87,6 @@ ((sizeof(a) / sizeof(*(a))) / \ static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -namespace internal { - -template <bool> -struct CompileAssert { -}; - -} // namespace internal - -#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg) - } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/status_macros.h b/src/google/protobuf/stubs/status_macros.h index 0c64317..407ff4c 100644 --- a/src/google/protobuf/stubs/status_macros.h +++ b/src/google/protobuf/stubs/status_macros.h
@@ -60,7 +60,7 @@ template<typename T> Status DoAssignOrReturn(T& lhs, StatusOr<T> result) { if (result.ok()) { - lhs = result.ValueOrDie(); + lhs = result.value(); } return result.status(); }
diff --git a/src/google/protobuf/stubs/statusor.cc b/src/google/protobuf/stubs/statusor.cc index c744b8d..9c0a178 100644 --- a/src/google/protobuf/stubs/statusor.cc +++ b/src/google/protobuf/stubs/statusor.cc
@@ -35,14 +35,14 @@ namespace google { namespace protobuf { namespace util { -namespace internal { +namespace statusor_internal { void StatusOrHelper::Crash(const Status& status) { GOOGLE_LOG(FATAL) << "Attempting to fetch value instead of handling error " << status.ToString(); } -} // namespace internal +} // namespace statusor_internal } // namespace util } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h index dc265f0..a569502 100644 --- a/src/google/protobuf/stubs/statusor.h +++ b/src/google/protobuf/stubs/statusor.h
@@ -42,7 +42,7 @@ // // StatusOr<float> result = DoBigCalculationThatCouldFail(); // if (result.ok()) { -// float answer = result.ValueOrDie(); +// float answer = result.value(); // printf("Big calculation yielded: %f", answer); // } else { // LOG(ERROR) << result.status(); @@ -52,17 +52,7 @@ // // StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg); // if (result.ok()) { -// std::unique_ptr<Foo> foo(result.ValueOrDie()); -// foo->DoSomethingCool(); -// } else { -// LOG(ERROR) << result.status(); -// } -// -// Example client usage for a StatusOr<std::unique_ptr<T>>: -// -// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg); -// if (result.ok()) { -// std::unique_ptr<Foo> foo = result.ConsumeValueOrDie(); +// std::unique_ptr<Foo> foo(result.value()); // foo->DoSomethingCool(); // } else { // LOG(ERROR) << result.status(); @@ -93,17 +83,21 @@ namespace google { namespace protobuf { namespace util { +namespace statusor_internal { template<typename T> class StatusOr { template<typename U> friend class StatusOr; public: + using value_type = T; + + // Construct a new StatusOr with Status::UNKNOWN status. // Construct a new StatusOr with UnknownError() status. - StatusOr(); + explicit StatusOr(); // Construct a new StatusOr with the given non-ok status. After calling - // this constructor, calls to ValueOrDie() will CHECK-fail. + // this constructor, calls to value() will CHECK-fail. // // NOTE: Not explicit - we want to use StatusOr<T> as a return // value, so it is convenient and sensible to be able to do 'return @@ -116,7 +110,7 @@ // Construct a new StatusOr with the given value. If T is a plain pointer, // value must not be nullptr. After calling this constructor, calls to - // ValueOrDie() will succeed, and calls to status() will return OK. + // value() will succeed, and calls to status() will return OK. // // NOTE: Not explicit - we want to use StatusOr<T> as a return type // so it is convenient and sensible to be able to do 'return T()' @@ -149,9 +143,6 @@ bool ok() const; // Returns a reference to our current value, or CHECK-fails if !this->ok(). - // If you need to initialize a T object from the stored value, - // ConsumeValueOrDie() may be more efficient. - const T& ValueOrDie() const; const T& value () const; private: @@ -162,8 +153,6 @@ //////////////////////////////////////////////////////////////////////////////// // Implementation details for StatusOr<T> -namespace internal { - class PROTOBUF_EXPORT StatusOrHelper { public: // Move type-agnostic error handling to the .cc. @@ -185,8 +174,6 @@ static inline bool IsValueNull(const T* t) { return t == nullptr; } }; -} // namespace internal - template <typename T> inline StatusOr<T>::StatusOr() : status_(util::UnknownError("")) {} @@ -201,7 +188,7 @@ template<typename T> inline StatusOr<T>::StatusOr(const T& value) { - if (internal::StatusOrHelper::Specialize<T>::IsValueNull(value)) { + if (StatusOrHelper::Specialize<T>::IsValueNull(value)) { status_ = util::InternalError("nullptr is not a valid argument."); } else { status_ = util::OkStatus(); @@ -246,20 +233,17 @@ } template<typename T> -inline const T& StatusOr<T>::ValueOrDie() const { +inline const T& StatusOr<T>::value() const { if (!status_.ok()) { - internal::StatusOrHelper::Crash(status_); + StatusOrHelper::Crash(status_); } return value_; } -template<typename T> -inline const T& StatusOr<T>::value() const { - if (!status_.ok()) { - internal::StatusOrHelper::Crash(status_); - } - return value_; -} +} // namespace statusor_internal + +using ::google::protobuf::util::statusor_internal::StatusOr; + } // namespace util } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/statusor_test.cc b/src/google/protobuf/stubs/statusor_test.cc index c51945f..403adcc 100644 --- a/src/google/protobuf/stubs/statusor_test.cc +++ b/src/google/protobuf/stubs/statusor_test.cc
@@ -84,7 +84,7 @@ const int kI = 4; StatusOr<int> thing(kI); EXPECT_TRUE(thing.ok()); - EXPECT_EQ(kI, thing.ValueOrDie()); + EXPECT_EQ(kI, thing.value()); } TEST(StatusOr, TestCopyCtorStatusOk) { @@ -92,7 +92,7 @@ StatusOr<int> original(kI); StatusOr<int> copy(original); EXPECT_EQ(original.status(), copy.status()); - EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie()); + EXPECT_EQ(original.value(), copy.value()); } TEST(StatusOr, TestCopyCtorStatusNotOk) { @@ -106,7 +106,7 @@ StatusOr<int> original(kI); StatusOr<double> copy(original); EXPECT_EQ(original.status(), copy.status()); - EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie()); + EXPECT_EQ(original.value(), copy.value()); } TEST(StatusOr, TestCopyCtorStatusNotOkConverting) { @@ -121,7 +121,7 @@ StatusOr<int> target; target = source; EXPECT_EQ(source.status(), target.status()); - EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie()); + EXPECT_EQ(source.value(), target.value()); } TEST(StatusOr, TestAssignmentStatusNotOk) { @@ -137,7 +137,7 @@ StatusOr<double> target; target = source; EXPECT_EQ(source.status(), target.status()); - EXPECT_DOUBLE_EQ(source.ValueOrDie(), target.ValueOrDie()); + EXPECT_DOUBLE_EQ(source.value(), target.value()); } TEST(StatusOr, TestAssignmentStatusNotOkConverting) { @@ -158,13 +158,13 @@ TEST(StatusOr, TestValue) { const int kI = 4; StatusOr<int> thing(kI); - EXPECT_EQ(kI, thing.ValueOrDie()); + EXPECT_EQ(kI, thing.value()); } TEST(StatusOr, TestValueConst) { const int kI = 4; const StatusOr<int> thing(kI); - EXPECT_EQ(kI, thing.ValueOrDie()); + EXPECT_EQ(kI, thing.value()); } TEST(StatusOr, TestPointerDefaultCtor) { @@ -183,7 +183,7 @@ const int kI = 4; StatusOr<const int*> thing(&kI); EXPECT_TRUE(thing.ok()); - EXPECT_EQ(&kI, thing.ValueOrDie()); + EXPECT_EQ(&kI, thing.value()); } TEST(StatusOr, TestPointerCopyCtorStatusOk) { @@ -191,7 +191,7 @@ StatusOr<const int*> original(&kI); StatusOr<const int*> copy(original); EXPECT_EQ(original.status(), copy.status()); - EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie()); + EXPECT_EQ(original.value(), copy.value()); } TEST(StatusOr, TestPointerCopyCtorStatusNotOk) { @@ -205,8 +205,7 @@ StatusOr<Derived*> original(&derived); StatusOr<Base2*> copy(original); EXPECT_EQ(original.status(), copy.status()); - EXPECT_EQ(static_cast<const Base2*>(original.ValueOrDie()), - copy.ValueOrDie()); + EXPECT_EQ(static_cast<const Base2*>(original.value()), copy.value()); } TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) { @@ -221,7 +220,7 @@ StatusOr<const int*> target; target = source; EXPECT_EQ(source.status(), target.status()); - EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie()); + EXPECT_EQ(source.value(), target.value()); } TEST(StatusOr, TestPointerAssignmentStatusNotOk) { @@ -237,8 +236,7 @@ StatusOr<Base2*> target; target = source; EXPECT_EQ(source.status(), target.status()); - EXPECT_EQ(static_cast<const Base2*>(source.ValueOrDie()), - target.ValueOrDie()); + EXPECT_EQ(static_cast<const Base2*>(source.value()), target.value()); } TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) { @@ -259,13 +257,13 @@ TEST(StatusOr, TestPointerValue) { const int kI = 0; StatusOr<const int*> thing(&kI); - EXPECT_EQ(&kI, thing.ValueOrDie()); + EXPECT_EQ(&kI, thing.value()); } TEST(StatusOr, TestPointerValueConst) { const int kI = 0; const StatusOr<const int*> thing(&kI); - EXPECT_EQ(&kI, thing.ValueOrDie()); + EXPECT_EQ(&kI, thing.value()); } } // namespace
diff --git a/src/google/protobuf/stubs/stringpiece.cc b/src/google/protobuf/stubs/stringpiece.cc index 353c78c..a014d1f 100644 --- a/src/google/protobuf/stubs/stringpiece.cc +++ b/src/google/protobuf/stubs/stringpiece.cc
@@ -39,31 +39,13 @@ namespace google { namespace protobuf { +namespace stringpiece_internal { + std::ostream& operator<<(std::ostream& o, StringPiece piece) { o.write(piece.data(), piece.size()); return o; } -// Out-of-line error path. -void StringPiece::LogFatalSizeTooBig(size_t size, const char* details) { - GOOGLE_LOG(FATAL) << "size too big: " << size << " details: " << details; -} - -StringPiece::StringPiece(StringPiece x, stringpiece_ssize_type pos) - : ptr_(x.ptr_ + pos), length_(x.length_ - pos) { - GOOGLE_DCHECK_LE(0, pos); - GOOGLE_DCHECK_LE(pos, x.length_); -} - -StringPiece::StringPiece(StringPiece x, - stringpiece_ssize_type pos, - stringpiece_ssize_type len) - : ptr_(x.ptr_ + pos), length_(std::min(len, x.length_ - pos)) { - GOOGLE_DCHECK_LE(0, pos); - GOOGLE_DCHECK_LE(pos, x.length_); - GOOGLE_DCHECK_GE(len, 0); -} - void StringPiece::CopyToString(std::string* target) const { target->assign(ptr_, length_); } @@ -89,10 +71,9 @@ return false; } -stringpiece_ssize_type StringPiece::copy(char* buf, - size_type n, - size_type pos) const { - stringpiece_ssize_type ret = std::min(length_ - pos, n); +StringPiece::size_type StringPiece::copy( + char* buf, size_type n, size_type pos) const { + size_type ret = std::min(length_ - pos, n); memcpy(buf, ptr_ + pos, ret); return ret; } @@ -101,7 +82,8 @@ return find(s, 0) != npos; } -stringpiece_ssize_type StringPiece::find(StringPiece s, size_type pos) const { +StringPiece::size_type StringPiece::find( + StringPiece s, size_type pos) const { if (length_ <= 0 || pos > static_cast<size_type>(length_)) { if (length_ == 0 && pos == 0 && s.length_ == 0) return 0; return npos; @@ -111,7 +93,7 @@ return result == ptr_ + length_ ? npos : result - ptr_; } -stringpiece_ssize_type StringPiece::find(char c, size_type pos) const { +StringPiece::size_type StringPiece::find(char c, size_type pos) const { if (length_ <= 0 || pos >= static_cast<size_type>(length_)) { return npos; } @@ -120,7 +102,7 @@ return result != nullptr ? result - ptr_ : npos; } -stringpiece_ssize_type StringPiece::rfind(StringPiece s, size_type pos) const { +StringPiece::size_type StringPiece::rfind(StringPiece s, size_type pos) const { if (length_ < s.length_) return npos; const size_t ulen = length_; if (s.length_ == 0) return std::min(ulen, pos); @@ -131,10 +113,10 @@ } // Search range is [0..pos] inclusive. If pos == npos, search everything. -stringpiece_ssize_type StringPiece::rfind(char c, size_type pos) const { +StringPiece::size_type StringPiece::rfind(char c, size_type pos) const { // Note: memrchr() is not available on Windows. - if (length_ <= 0) return npos; - for (stringpiece_ssize_type i = + if (empty()) return npos; + for (difference_type i = std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) { if (ptr_[i] == c) { @@ -154,16 +136,16 @@ // bool table[UCHAR_MAX + 1] static inline void BuildLookupTable(StringPiece characters_wanted, bool* table) { - const stringpiece_ssize_type length = characters_wanted.length(); + const StringPiece::size_type length = characters_wanted.length(); const char* const data = characters_wanted.data(); - for (stringpiece_ssize_type i = 0; i < length; ++i) { + for (StringPiece::size_type i = 0; i < length; ++i) { table[static_cast<unsigned char>(data[i])] = true; } } -stringpiece_ssize_type StringPiece::find_first_of(StringPiece s, - size_type pos) const { - if (length_ <= 0 || s.length_ <= 0) { +StringPiece::size_type StringPiece::find_first_of( + StringPiece s, size_type pos) const { + if (empty() || s.empty()) { return npos; } // Avoid the cost of BuildLookupTable() for a single-character search. @@ -171,7 +153,7 @@ bool lookup[UCHAR_MAX + 1] = { false }; BuildLookupTable(s, lookup); - for (stringpiece_ssize_type i = pos; i < length_; ++i) { + for (size_type i = pos; i < length_; ++i) { if (lookup[static_cast<unsigned char>(ptr_[i])]) { return i; } @@ -179,16 +161,16 @@ return npos; } -stringpiece_ssize_type StringPiece::find_first_not_of(StringPiece s, - size_type pos) const { - if (length_ <= 0) return npos; - if (s.length_ <= 0) return 0; +StringPiece::size_type StringPiece::find_first_not_of( + StringPiece s, size_type pos) const { + if (empty()) return npos; + if (s.empty()) return 0; // Avoid the cost of BuildLookupTable() for a single-character search. if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); bool lookup[UCHAR_MAX + 1] = { false }; BuildLookupTable(s, lookup); - for (stringpiece_ssize_type i = pos; i < length_; ++i) { + for (size_type i = pos; i < length_; ++i) { if (!lookup[static_cast<unsigned char>(ptr_[i])]) { return i; } @@ -196,9 +178,9 @@ return npos; } -stringpiece_ssize_type StringPiece::find_first_not_of(char c, - size_type pos) const { - if (length_ <= 0) return npos; +StringPiece::size_type StringPiece::find_first_not_of( + char c, size_type pos) const { + if (empty()) return npos; for (; pos < static_cast<size_type>(length_); ++pos) { if (ptr_[pos] != c) { @@ -208,15 +190,15 @@ return npos; } -stringpiece_ssize_type StringPiece::find_last_of(StringPiece s, - size_type pos) const { - if (length_ <= 0 || s.length_ <= 0) return npos; +StringPiece::size_type StringPiece::find_last_of( + StringPiece s, size_type pos) const { + if (empty() || s.empty()) return npos; // Avoid the cost of BuildLookupTable() for a single-character search. if (s.length_ == 1) return find_last_of(s.ptr_[0], pos); bool lookup[UCHAR_MAX + 1] = { false }; BuildLookupTable(s, lookup); - for (stringpiece_ssize_type i = + for (difference_type i = std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) { if (lookup[static_cast<unsigned char>(ptr_[i])]) { return i; @@ -225,12 +207,12 @@ return npos; } -stringpiece_ssize_type StringPiece::find_last_not_of(StringPiece s, - size_type pos) const { - if (length_ <= 0) return npos; +StringPiece::size_type StringPiece::find_last_not_of( + StringPiece s, size_type pos) const { + if (empty()) return npos; - stringpiece_ssize_type i = std::min(pos, static_cast<size_type>(length_ - 1)); - if (s.length_ <= 0) return i; + size_type i = std::min(pos, length()-1); + if (s.empty()) return i; // Avoid the cost of BuildLookupTable() for a single-character search. if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos); @@ -245,11 +227,11 @@ return npos; } -stringpiece_ssize_type StringPiece::find_last_not_of(char c, - size_type pos) const { - if (length_ <= 0) return npos; +StringPiece::size_type StringPiece::find_last_not_of( + char c, size_type pos) const { + if (empty()) return npos; - for (stringpiece_ssize_type i = + for (difference_type i = std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) { if (ptr_[i] != c) { return i; @@ -259,12 +241,13 @@ } StringPiece StringPiece::substr(size_type pos, size_type n) const { - if (pos > length_) pos = length_; - if (n > length_ - pos) n = length_ - pos; + if (pos > length()) pos = length(); + if (n > length_ - pos) n = length() - pos; return StringPiece(ptr_ + pos, n); } const StringPiece::size_type StringPiece::npos = size_type(-1); +} // namespace stringpiece_internal } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h index 0a426fe..1e896e0 100644 --- a/src/google/protobuf/stubs/stringpiece.h +++ b/src/google/protobuf/stubs/stringpiece.h
@@ -154,52 +154,26 @@ namespace google { namespace protobuf { -// StringPiece has *two* size types. -// StringPiece::size_type -// is unsigned -// is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64 -// no future changes intended -// stringpiece_ssize_type -// is signed -// is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64 -// future changes intended: http://go/64BitStringPiece -// -typedef std::string::difference_type stringpiece_ssize_type; - -// STRINGPIECE_CHECK_SIZE protects us from 32-bit overflows. -// TODO(mec): delete this after stringpiece_ssize_type goes 64 bit. -#if !defined(NDEBUG) -#define STRINGPIECE_CHECK_SIZE 1 -#elif defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 -#define STRINGPIECE_CHECK_SIZE 1 -#else -#define STRINGPIECE_CHECK_SIZE 0 -#endif +namespace stringpiece_internal { class PROTOBUF_EXPORT StringPiece { + public: + using traits_type = std::char_traits<char>; + using value_type = char; + using pointer = char*; + using const_pointer = const char*; + using reference = char&; + using const_reference = const char&; + using const_iterator = const char*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = std::ptrdiff_t; + private: const char* ptr_; - stringpiece_ssize_type length_; - - // Prevent overflow in debug mode or fortified mode. - // sizeof(stringpiece_ssize_type) may be smaller than sizeof(size_t). - static stringpiece_ssize_type CheckedSsizeTFromSizeT(size_t size) { -#if STRINGPIECE_CHECK_SIZE > 0 -#ifdef max -#undef max -#endif - if (size > static_cast<size_t>( - std::numeric_limits<stringpiece_ssize_type>::max())) { - // Some people grep for this message in logs - // so take care if you ever change it. - LogFatalSizeTooBig(size, "size_t to int conversion"); - } -#endif - return static_cast<stringpiece_ssize_type>(size); - } - - // Out-of-line error path. - static void LogFatalSizeTooBig(size_t size, const char* details); + size_type length_; public: // We provide non-explicit singleton constructors so users can pass @@ -213,7 +187,7 @@ StringPiece(const char* str) // NOLINT(runtime/explicit) : ptr_(str), length_(0) { if (str != nullptr) { - length_ = CheckedSsizeTFromSizeT(strlen(str)); + length_ = strlen(str); } } @@ -221,78 +195,40 @@ StringPiece( // NOLINT(runtime/explicit) const std::basic_string<char, std::char_traits<char>, Allocator>& str) : ptr_(str.data()), length_(0) { - length_ = CheckedSsizeTFromSizeT(str.size()); + length_ = str.size(); } - StringPiece(const char* offset, stringpiece_ssize_type len) - : ptr_(offset), length_(len) { - assert(len >= 0); - } - - // Substring of another StringPiece. - // pos must be non-negative and <= x.length(). - StringPiece(StringPiece x, stringpiece_ssize_type pos); - // Substring of another StringPiece. - // pos must be non-negative and <= x.length(). - // len must be non-negative and will be pinned to at most x.length() - pos. - StringPiece(StringPiece x, - stringpiece_ssize_type pos, - stringpiece_ssize_type len); + StringPiece(const char* offset, size_type len) + : ptr_(offset), length_(len) {} // data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is // typically a mistake to pass data() to a routine that expects a NUL // terminated string. - const char* data() const { return ptr_; } - stringpiece_ssize_type size() const { return length_; } - stringpiece_ssize_type length() const { return length_; } + const_pointer data() const { return ptr_; } + size_type size() const { return length_; } + size_type length() const { return length_; } bool empty() const { return length_ == 0; } - void clear() { - ptr_ = nullptr; - length_ = 0; - } - - void set(const char* data, stringpiece_ssize_type len) { - assert(len >= 0); - ptr_ = data; - length_ = len; - } - - void set(const char* str) { - ptr_ = str; - if (str != nullptr) - length_ = CheckedSsizeTFromSizeT(strlen(str)); - else - length_ = 0; - } - - void set(const void* data, stringpiece_ssize_type len) { - ptr_ = reinterpret_cast<const char*>(data); - length_ = len; - } - - char operator[](stringpiece_ssize_type i) const { - assert(0 <= i); + char operator[](size_type i) const { assert(i < length_); return ptr_[i]; } - void remove_prefix(stringpiece_ssize_type n) { + void remove_prefix(size_type n) { assert(length_ >= n); ptr_ += n; length_ -= n; } - void remove_suffix(stringpiece_ssize_type n) { + void remove_suffix(size_type n) { assert(length_ >= n); length_ -= n; } // returns {-1, 0, 1} int compare(StringPiece x) const { - const stringpiece_ssize_type min_size = - length_ < x.length_ ? length_ : x.length_; + size_type min_size = length_ < x.length_ ? length_ : x.length_; int r = memcmp(ptr_, x.ptr_, static_cast<size_t>(min_size)); if (r < 0) return -1; if (r > 0) return 1; @@ -336,53 +272,41 @@ bool ConsumeFromEnd(StringPiece x); // standard STL container boilerplate - typedef char value_type; - typedef const char* pointer; - typedef const char& reference; - typedef const char& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; static const size_type npos; - typedef const char* const_iterator; - typedef const char* iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - iterator begin() const { return ptr_; } - iterator end() const { return ptr_ + length_; } + const_iterator begin() const { return ptr_; } + const_iterator end() const { return ptr_ + length_; } const_reverse_iterator rbegin() const { return const_reverse_iterator(ptr_ + length_); } const_reverse_iterator rend() const { return const_reverse_iterator(ptr_); } - stringpiece_ssize_type max_size() const { return length_; } - stringpiece_ssize_type capacity() const { return length_; } + size_type max_size() const { return length_; } + size_type capacity() const { return length_; } // cpplint.py emits a false positive [build/include_what_you_use] - stringpiece_ssize_type copy(char* buf, size_type n, size_type pos = 0) const; // NOLINT + size_type copy(char* buf, size_type n, size_type pos = 0) const; // NOLINT bool contains(StringPiece s) const; - stringpiece_ssize_type find(StringPiece s, size_type pos = 0) const; - stringpiece_ssize_type find(char c, size_type pos = 0) const; - stringpiece_ssize_type rfind(StringPiece s, size_type pos = npos) const; - stringpiece_ssize_type rfind(char c, size_type pos = npos) const; + size_type find(StringPiece s, size_type pos = 0) const; + size_type find(char c, size_type pos = 0) const; + size_type rfind(StringPiece s, size_type pos = npos) const; + size_type rfind(char c, size_type pos = npos) const; - stringpiece_ssize_type find_first_of(StringPiece s, size_type pos = 0) const; - stringpiece_ssize_type find_first_of(char c, size_type pos = 0) const { + size_type find_first_of(StringPiece s, size_type pos = 0) const; + size_type find_first_of(char c, size_type pos = 0) const { return find(c, pos); } - stringpiece_ssize_type find_first_not_of(StringPiece s, - size_type pos = 0) const; - stringpiece_ssize_type find_first_not_of(char c, size_type pos = 0) const; - stringpiece_ssize_type find_last_of(StringPiece s, - size_type pos = npos) const; - stringpiece_ssize_type find_last_of(char c, size_type pos = npos) const { + size_type find_first_not_of(StringPiece s, size_type pos = 0) const; + size_type find_first_not_of(char c, size_type pos = 0) const; + size_type find_last_of(StringPiece s, size_type pos = npos) const; + size_type find_last_of(char c, size_type pos = npos) const { return rfind(c, pos); } - stringpiece_ssize_type find_last_not_of(StringPiece s, + size_type find_last_not_of(StringPiece s, size_type pos = npos) const; - stringpiece_ssize_type find_last_not_of(char c, size_type pos = npos) const; + size_type find_last_not_of(char c, size_type pos = npos) const; StringPiece substr(size_type pos, size_type n = npos) const; }; @@ -391,7 +315,7 @@ // one of the arguments is a literal, the compiler can elide a lot of the // following comparisons. inline bool operator==(StringPiece x, StringPiece y) { - stringpiece_ssize_type len = x.size(); + StringPiece::size_type len = x.size(); if (len != y.size()) { return false; } @@ -405,7 +329,7 @@ } inline bool operator<(StringPiece x, StringPiece y) { - const stringpiece_ssize_type min_size = + const StringPiece::size_type min_size = x.size() < y.size() ? x.size() : y.size(); const int r = memcmp(x.data(), y.data(), static_cast<size_t>(min_size)); return (r < 0) || (r == 0 && x.size() < y.size()); @@ -426,6 +350,10 @@ // allow StringPiece to be logged extern std::ostream& operator<<(std::ostream& o, StringPiece piece); +} // namespace stringpiece_internal + +using ::google::protobuf::stringpiece_internal::StringPiece; + } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc index 846e1ae..e85a2e5 100644 --- a/src/google/protobuf/stubs/stringpiece_unittest.cc +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc
@@ -305,16 +305,9 @@ const StringPiece a("abcdefghijklmnopqrstuvwxyz"); const StringPiece b("abc"); const StringPiece c("xyz"); - StringPiece d("foobar"); const StringPiece e; const StringPiece f("123" "\0" "456", 7); - d.clear(); - EXPECT_EQ(d.size(), 0); - EXPECT_TRUE(d.empty()); - EXPECT_TRUE(d.data() == nullptr); - EXPECT_TRUE(d.begin() == d.end()); - EXPECT_EQ(StringPiece::npos, std::string::npos); EXPECT_EQ(a.find(b), 0); @@ -324,26 +317,16 @@ EXPECT_EQ(a.find(c, StringPiece::npos), StringPiece::npos); EXPECT_EQ(b.find(c), StringPiece::npos); EXPECT_EQ(b.find(c, StringPiece::npos), StringPiece::npos); - EXPECT_EQ(a.find(d), 0); EXPECT_EQ(a.find(e), 0); - EXPECT_EQ(a.find(d, 12), 12); EXPECT_EQ(a.find(e, 17), 17); StringPiece g("xx not found bb"); EXPECT_EQ(a.find(g), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.find(b), StringPiece::npos); EXPECT_EQ(e.find(b), StringPiece::npos); - EXPECT_EQ(d.find(b, 4), StringPiece::npos); EXPECT_EQ(e.find(b, 7), StringPiece::npos); size_t empty_search_pos = std::string().find(std::string()); - EXPECT_EQ(d.find(d), empty_search_pos); - EXPECT_EQ(d.find(e), empty_search_pos); - EXPECT_EQ(e.find(d), empty_search_pos); EXPECT_EQ(e.find(e), empty_search_pos); - EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); - EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); - EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); EXPECT_EQ(a.find('a'), 0); @@ -359,13 +342,9 @@ EXPECT_EQ(g.find('o', 5), 8); EXPECT_EQ(a.find('b', 5), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.find('\0'), StringPiece::npos); EXPECT_EQ(e.find('\0'), StringPiece::npos); - EXPECT_EQ(d.find('\0', 4), StringPiece::npos); EXPECT_EQ(e.find('\0', 7), StringPiece::npos); - EXPECT_EQ(d.find('x'), StringPiece::npos); EXPECT_EQ(e.find('x'), StringPiece::npos); - EXPECT_EQ(d.find('x', 4), StringPiece::npos); EXPECT_EQ(e.find('x', 7), StringPiece::npos); EXPECT_EQ(a.rfind(b), 0); @@ -376,23 +355,13 @@ EXPECT_EQ(a.rfind(c, 0), StringPiece::npos); EXPECT_EQ(b.rfind(c), StringPiece::npos); EXPECT_EQ(b.rfind(c, 0), StringPiece::npos); - EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string())); EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string())); - EXPECT_EQ(a.rfind(d, 12), 12); EXPECT_EQ(a.rfind(e, 17), 17); EXPECT_EQ(a.rfind(g), StringPiece::npos); - EXPECT_EQ(d.rfind(b), StringPiece::npos); EXPECT_EQ(e.rfind(b), StringPiece::npos); - EXPECT_EQ(d.rfind(b, 4), StringPiece::npos); EXPECT_EQ(e.rfind(b, 7), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); - EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); - EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); - EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); - EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); - EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); EXPECT_EQ(g.rfind('o'), 8); @@ -405,9 +374,7 @@ EXPECT_EQ(f.rfind('3'), 2); EXPECT_EQ(f.rfind('5'), 5); // empty string nonsense - EXPECT_EQ(d.rfind('o'), StringPiece::npos); EXPECT_EQ(e.rfind('o'), StringPiece::npos); - EXPECT_EQ(d.rfind('o', 4), StringPiece::npos); EXPECT_EQ(e.rfind('o', 7), StringPiece::npos); EXPECT_EQ(a.find_first_of(b), 0); @@ -425,13 +392,8 @@ EXPECT_EQ(a.find_first_of(f), StringPiece::npos); EXPECT_EQ(f.find_first_of(a), StringPiece::npos); // empty string nonsense - EXPECT_EQ(a.find_first_of(d), StringPiece::npos); EXPECT_EQ(a.find_first_of(e), StringPiece::npos); - EXPECT_EQ(d.find_first_of(b), StringPiece::npos); EXPECT_EQ(e.find_first_of(b), StringPiece::npos); - EXPECT_EQ(d.find_first_of(d), StringPiece::npos); - EXPECT_EQ(e.find_first_of(d), StringPiece::npos); - EXPECT_EQ(d.find_first_of(e), StringPiece::npos); EXPECT_EQ(e.find_first_of(e), StringPiece::npos); EXPECT_EQ(a.find_first_not_of(b), 3); @@ -440,14 +402,9 @@ EXPECT_EQ(c.find_first_not_of(a), StringPiece::npos); EXPECT_EQ(f.find_first_not_of(a), 0); EXPECT_EQ(a.find_first_not_of(f), 0); - EXPECT_EQ(a.find_first_not_of(d), 0); EXPECT_EQ(a.find_first_not_of(e), 0); // empty string nonsense - EXPECT_EQ(d.find_first_not_of(a), StringPiece::npos); EXPECT_EQ(e.find_first_not_of(a), StringPiece::npos); - EXPECT_EQ(d.find_first_not_of(d), StringPiece::npos); - EXPECT_EQ(e.find_first_not_of(d), StringPiece::npos); - EXPECT_EQ(d.find_first_not_of(e), StringPiece::npos); EXPECT_EQ(e.find_first_not_of(e), StringPiece::npos); StringPiece h("===="); @@ -459,9 +416,7 @@ EXPECT_EQ(f.find_first_not_of('\0', 3), 4); EXPECT_EQ(f.find_first_not_of('\0', 2), 2); // empty string nonsense - EXPECT_EQ(d.find_first_not_of('x'), StringPiece::npos); EXPECT_EQ(e.find_first_not_of('x'), StringPiece::npos); - EXPECT_EQ(d.find_first_not_of('\0'), StringPiece::npos); EXPECT_EQ(e.find_first_not_of('\0'), StringPiece::npos); // StringPiece g("xx not found bb"); @@ -483,21 +438,11 @@ EXPECT_EQ(f.find_last_of(i, 6), 6); EXPECT_EQ(f.find_last_of(a, 4), StringPiece::npos); // empty string nonsense - EXPECT_EQ(f.find_last_of(d), StringPiece::npos); EXPECT_EQ(f.find_last_of(e), StringPiece::npos); - EXPECT_EQ(f.find_last_of(d, 4), StringPiece::npos); EXPECT_EQ(f.find_last_of(e, 4), StringPiece::npos); - EXPECT_EQ(d.find_last_of(d), StringPiece::npos); - EXPECT_EQ(d.find_last_of(e), StringPiece::npos); - EXPECT_EQ(e.find_last_of(d), StringPiece::npos); EXPECT_EQ(e.find_last_of(e), StringPiece::npos); - EXPECT_EQ(d.find_last_of(f), StringPiece::npos); EXPECT_EQ(e.find_last_of(f), StringPiece::npos); - EXPECT_EQ(d.find_last_of(d, 4), StringPiece::npos); - EXPECT_EQ(d.find_last_of(e, 4), StringPiece::npos); - EXPECT_EQ(e.find_last_of(d, 4), StringPiece::npos); EXPECT_EQ(e.find_last_of(e, 4), StringPiece::npos); - EXPECT_EQ(d.find_last_of(f, 4), StringPiece::npos); EXPECT_EQ(e.find_last_of(f, 4), StringPiece::npos); EXPECT_EQ(a.find_last_not_of(b), a.size()-1); @@ -509,21 +454,11 @@ EXPECT_EQ(a.find_last_not_of(b, 3), 3); EXPECT_EQ(a.find_last_not_of(b, 2), StringPiece::npos); // empty string nonsense - EXPECT_EQ(f.find_last_not_of(d), f.size()-1); EXPECT_EQ(f.find_last_not_of(e), f.size()-1); - EXPECT_EQ(f.find_last_not_of(d, 4), 4); EXPECT_EQ(f.find_last_not_of(e, 4), 4); - EXPECT_EQ(d.find_last_not_of(d), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of(e), StringPiece::npos); - EXPECT_EQ(e.find_last_not_of(d), StringPiece::npos); EXPECT_EQ(e.find_last_not_of(e), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of(f), StringPiece::npos); EXPECT_EQ(e.find_last_not_of(f), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of(d, 4), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of(e, 4), StringPiece::npos); - EXPECT_EQ(e.find_last_not_of(d, 4), StringPiece::npos); EXPECT_EQ(e.find_last_not_of(e, 4), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of(f, 4), StringPiece::npos); EXPECT_EQ(e.find_last_not_of(f, 4), StringPiece::npos); EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1); @@ -533,9 +468,7 @@ EXPECT_EQ(h.find_last_not_of('=', 2), StringPiece::npos); EXPECT_EQ(b.find_last_not_of('b', 1), 0); // empty string nonsense - EXPECT_EQ(d.find_last_not_of('x'), StringPiece::npos); EXPECT_EQ(e.find_last_not_of('x'), StringPiece::npos); - EXPECT_EQ(d.find_last_not_of('\0'), StringPiece::npos); EXPECT_EQ(e.find_last_not_of('\0'), StringPiece::npos); EXPECT_EQ(a.substr(0, 3), b); @@ -546,33 +479,15 @@ EXPECT_EQ(a.substr(3, 2), "de"); // empty string nonsense EXPECT_EQ(a.substr(99, 2), e); - EXPECT_EQ(d.substr(99), e); - EXPECT_EQ(d.substr(0, 99), e); - EXPECT_EQ(d.substr(99, 99), e); + EXPECT_EQ(e.substr(99), e); + EXPECT_EQ(e.substr(0, 99), e); + EXPECT_EQ(e.substr(99, 99), e); // use of npos EXPECT_EQ(a.substr(0, StringPiece::npos), a); EXPECT_EQ(a.substr(23, StringPiece::npos), c); EXPECT_EQ(a.substr(StringPiece::npos, 0), e); EXPECT_EQ(a.substr(StringPiece::npos, 1), e); EXPECT_EQ(a.substr(StringPiece::npos, StringPiece::npos), e); - - // Substring constructors. - EXPECT_EQ(StringPiece(a, 0, 3), b); - EXPECT_EQ(StringPiece(a, 23), c); - EXPECT_EQ(StringPiece(a, 23, 3), c); - EXPECT_EQ(StringPiece(a, 23, 99), c); - EXPECT_EQ(StringPiece(a, 0), a); - EXPECT_EQ(StringPiece(a, 3, 2), "de"); - // empty string nonsense - EXPECT_EQ(StringPiece(d, 0, 99), e); - // Verify that they work taking an actual string, not just a StringPiece. - std::string a2 = a.as_string(); - EXPECT_EQ(StringPiece(a2, 0, 3), b); - EXPECT_EQ(StringPiece(a2, 23), c); - EXPECT_EQ(StringPiece(a2, 23, 3), c); - EXPECT_EQ(StringPiece(a2, 23, 99), c); - EXPECT_EQ(StringPiece(a2, 0), a); - EXPECT_EQ(StringPiece(a2, 3, 2), "de"); } TEST(StringPiece, Custom) { @@ -647,23 +562,7 @@ c.remove_suffix(c.size()); EXPECT_EQ(c, e); - // set - c.set("foobar", 6); - EXPECT_EQ(c, a); - c.set("foobar", 0); - EXPECT_EQ(c, e); - c.set("foobar", 7); - EXPECT_NE(c, a); - - c.set("foobar"); - EXPECT_EQ(c, a); - - c.set(static_cast<const void*>("foobar"), 6); - EXPECT_EQ(c, a); - c.set(static_cast<const void*>("foobar"), 0); - EXPECT_EQ(c, e); - c.set(static_cast<const void*>("foobar"), 7); - EXPECT_NE(c, a); + c = StringPiece("foobar", 7); // as_string std::string s3(a.as_string().c_str(), 7); @@ -680,21 +579,25 @@ } // Consume - a.set("foobar"); - EXPECT_TRUE(a.Consume("foo")); - EXPECT_EQ(a, "bar"); - EXPECT_FALSE(a.Consume("foo")); - EXPECT_FALSE(a.Consume("barbar")); - EXPECT_FALSE(a.Consume("ar")); - EXPECT_EQ(a, "bar"); + { + StringPiece str("foobar"); + EXPECT_TRUE(str.Consume("foo")); + EXPECT_EQ(str, "bar"); + EXPECT_FALSE(str.Consume("foo")); + EXPECT_FALSE(str.Consume("barbar")); + EXPECT_FALSE(str.Consume("ar")); + EXPECT_EQ(str, "bar"); + } - a.set("foobar"); - EXPECT_TRUE(a.ConsumeFromEnd("bar")); - EXPECT_EQ(a, "foo"); - EXPECT_FALSE(a.ConsumeFromEnd("bar")); - EXPECT_FALSE(a.ConsumeFromEnd("foofoo")); - EXPECT_FALSE(a.ConsumeFromEnd("fo")); - EXPECT_EQ(a, "foo"); + { + StringPiece str("foobar"); + EXPECT_TRUE(str.ConsumeFromEnd("bar")); + EXPECT_EQ(str, "foo"); + EXPECT_FALSE(str.ConsumeFromEnd("bar")); + EXPECT_FALSE(str.ConsumeFromEnd("foofoo")); + EXPECT_FALSE(str.ConsumeFromEnd("fo")); + EXPECT_EQ(str, "foo"); + } } TEST(StringPiece, Contains) { @@ -713,10 +616,6 @@ EXPECT_EQ(s.data(), (const char*)nullptr); EXPECT_EQ(s.size(), 0); - s.set(nullptr); - EXPECT_EQ(s.data(), (const char*)nullptr); - EXPECT_EQ(s.size(), 0); - // .ToString() on a StringPiece with nullptr should produce the empty string. EXPECT_EQ("", s.ToString()); EXPECT_EQ("", s.as_string());
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc index 2603164..0761986 100644 --- a/src/google/protobuf/stubs/stringprintf.cc +++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -162,7 +162,7 @@ // that accepts an array of arguments. The best I can do is stick // this COMPILE_ASSERT right next to the actual statement. - GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch); + static_assert(kStringPrintfVectorMaxArgs == 32, "arg_count_mismatch"); return StringPrintf(format, cstr[0], cstr[1], cstr[2], cstr[3], cstr[4], cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 2ecdb2b..84ea62e 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc
@@ -545,7 +545,7 @@ }; size_t escaped_len = 0; - for (int i = 0; i < src.size(); ++i) { + for (StringPiece::size_type i = 0; i < src.size(); ++i) { unsigned char c = static_cast<unsigned char>(src[i]); escaped_len += c_escaped_len[c]; } @@ -569,7 +569,7 @@ dest->resize(cur_dest_len + escaped_len); char* append_ptr = &(*dest)[cur_dest_len]; - for (int i = 0; i < src.size(); ++i) { + for (StringPiece::size_type i = 0; i < src.size(); ++i) { unsigned char c = static_cast<unsigned char>(src[i]); switch (c) { case '\n': *append_ptr++ = '\\'; *append_ptr++ = 'n'; break; @@ -1244,7 +1244,7 @@ // platforms these days. Just in case some system exists where DBL_DIG // is significantly larger -- and risks overflowing our buffer -- we have // this assert. - GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); + static_assert(DBL_DIG < 20, "DBL_DIG_is_too_big"); if (value == std::numeric_limits<double>::infinity()) { strcpy(buffer, "inf"); @@ -1362,7 +1362,7 @@ // platforms these days. Just in case some system exists where FLT_DIG // is significantly larger -- and risks overflowing our buffer -- we have // this assert. - GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); + static_assert(FLT_DIG < 10, "FLT_DIG_is_too_big"); if (value == std::numeric_limits<double>::infinity()) { strcpy(buffer, "inf"); @@ -1619,7 +1619,8 @@ std::string tmp; int num_replacements = 0; int pos = 0; - for (int match_pos = s->find(substring.data(), pos, substring.length()); + for (StringPiece::size_type match_pos = + s->find(substring.data(), pos, substring.length()); match_pos != std::string::npos; pos = match_pos + substring.length(), match_pos = s->find(substring.data(), pos, substring.length())) { ++num_replacements;
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index 31c5489..84fc232 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h
@@ -377,14 +377,14 @@ // For now, long long is 64-bit on all the platforms we care about, so these // functions can simply pass the call to strto[u]ll. inline int64 strto64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), - sizeof_int64_is_not_sizeof_long_long); + static_assert(sizeof(int64) == sizeof(long long), + "sizeof_int64_is_not_sizeof_long_long"); return strtoll(nptr, endptr, base); } inline uint64 strtou64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), - sizeof_uint64_is_not_sizeof_long_long); + static_assert(sizeof(uint64) == sizeof(unsigned long long), + "sizeof_uint64_is_not_sizeof_long_long"); return strtoull(nptr, endptr, base); }
diff --git a/src/google/protobuf/util/internal/object_writer.cc b/src/google/protobuf/util/internal/object_writer.cc index b7667b6..4dabd37 100644 --- a/src/google/protobuf/util/internal/object_writer.cc +++ b/src/google/protobuf/util/internal/object_writer.cc
@@ -74,7 +74,7 @@ break; } case DataPiece::TYPE_BYTES: { - ow->RenderBytes(name, data.ToBytes().ValueOrDie()); + ow->RenderBytes(name, data.ToBytes().value()); break; } case DataPiece::TYPE_NULL: {
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index ff4fe54..717cee4 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -253,7 +253,7 @@ CodedOutputStream* stream) { util::StatusOr<std::string> c = data.ToBytes(); if (c.ok()) { - WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream); + WireFormatLite::WriteBytes(field_number, c.value(), stream); } return c.status(); }
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index f82c414..9878826 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -436,7 +436,7 @@ StrAppend(&value_storage_, value_.str()); value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding()); } else if (value_.type() == DataPiece::TYPE_BYTES) { - value_storage_ = value_.ToBytes().ValueOrDie(); + value_storage_ = value_.ToBytes().value(); value_ = DataPiece(value_storage_, true, value_.use_strict_base64_decoding()); }