From: Tudor Bosman Date: Mon, 24 Jun 2013 19:48:43 +0000 (-0700) Subject: StringPiece comparisons are broken X-Git-Tag: v0.22.0~943 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a664fa91fed10a492ec4560f3e97a4e1b8c7e59d;p=folly.git StringPiece comparisons are broken Summary: 8-bit StringPiece comparisons are broken. The reason is char_traits is magic for 'char', but not 'const char'. Test Plan: test added Reviewed By: chip@fb.com FB internal diff: D861521 --- diff --git a/folly/Range.h b/folly/Range.h index 21f586da..188a534a 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -123,7 +123,8 @@ public: typename std::iterator_traits::reference>::type value_type; typedef typename std::iterator_traits::reference reference; - typedef std::char_traits traits_type; + typedef std::char_traits::type> + traits_type; static const size_type npos; diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index ebc20a5f..b82ac85f 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -207,6 +207,47 @@ TEST(StringPiece, All) { EXPECT_EQ(s2, s); } +template +void expectLT(const T& a, const T& b) { + EXPECT_TRUE(a < b); + EXPECT_TRUE(a <= b); + EXPECT_FALSE(a == b); + EXPECT_FALSE(a >= b); + EXPECT_FALSE(a > b); + + EXPECT_FALSE(b < a); + EXPECT_FALSE(b <= a); + EXPECT_TRUE(b >= a); + EXPECT_TRUE(b > a); +} + +template +void expectEQ(const T& a, const T& b) { + EXPECT_FALSE(a < b); + EXPECT_TRUE(a <= b); + EXPECT_TRUE(a == b); + EXPECT_TRUE(a >= b); + EXPECT_FALSE(a > b); +} + +TEST(StringPiece, EightBitComparisons) { + char values[] = {'\x00', '\x20', '\x40', '\x7f', '\x80', '\xc0', '\xff'}; + constexpr size_t count = sizeof(values) / sizeof(values[0]); + for (size_t i = 0; i < count; ++i) { + std::string a(1, values[i]); + // Defeat copy-on-write + std::string aCopy(a.data(), a.size()); + expectEQ(a, aCopy); + expectEQ(StringPiece(a), StringPiece(aCopy)); + + for (size_t j = i + 1; j < count; ++j) { + std::string b(1, values[j]); + expectLT(a, b); + expectLT(StringPiece(a), StringPiece(b)); + } + } +} + TEST(StringPiece, ToByteRange) { StringPiece a("hello"); ByteRange b(a);