From 445998d7ac4e5d3c50411d377e3b50e960d2d6c2 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 8 Oct 2018 13:53:59 -0700 Subject: Export of internal Abseil changes. -- 714347c156cfe01575c1830a92bc6dea3030065b by Emma Christie : Release absl::EqualsIgnoreCase PiperOrigin-RevId: 216243900 -- 688106e2b9d2924799d597682690851cfba87818 by Abseil Team : Import of CCTZ from GitHub. PiperOrigin-RevId: 216208373 -- 53638e4da238b230af0e56dc31b9fb790e708f36 by Emma Christie : Update StartsWithIgnoreCase(), EndsWithIgnoreCase(), and EqualsIgnoreCase() headers to say that these functions only consider ASCII case inputs. PiperOrigin-RevId: 215930962 GitOrigin-RevId: 714347c156cfe01575c1830a92bc6dea3030065b Change-Id: I7fb3506234185b1a961e0110c1f8302ffe7228fa --- absl/strings/match.cc | 7 ++++++ absl/strings/match.h | 14 ++++++++---- absl/strings/match_test.cc | 11 ++++++++++ .../internal/cctz/include/cctz/civil_time_detail.h | 6 ++++++ absl/time/internal/cctz/include/cctz/time_zone.h | 5 +++++ absl/time/internal/cctz/src/civil_time_test.cc | 2 +- absl/time/internal/cctz/src/time_zone_fixed.cc | 25 +++++++++++++++++----- 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/absl/strings/match.cc b/absl/strings/match.cc index 25bd7f0b..3d10c577 100644 --- a/absl/strings/match.cc +++ b/absl/strings/match.cc @@ -27,6 +27,13 @@ bool CaseEqual(absl::string_view piece1, absl::string_view piece2) { } } // namespace +bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2) { + return (piece1.size() == piece2.size() && + 0 == absl::strings_internal::memcasecmp(piece1.data(), piece2.data(), + piece1.size())); + // memcasecmp uses absl::ascii_tolower(). +} + bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix) { return (text.size() >= prefix.size()) && CaseEqual(text.substr(0, prefix.size()), prefix); diff --git a/absl/strings/match.h b/absl/strings/match.h index 942a196b..6e8ed10f 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -66,16 +66,22 @@ inline bool EndsWith(absl::string_view text, absl::string_view suffix) { ); } -// StartsWithIgnoreCase() +// EqualsIgnoreCase() // -// Returns whether a given string `text` starts with `starts_with`, ignoring +// Returns whether given ASCII strings `piece1` and `piece2` are equal, ignoring // case in the comparison. +bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2); + +// StartsWithIgnoreCase() +// +// Returns whether a given ASCII string `text` starts with `starts_with`, +// ignoring case in the comparison. bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix); // EndsWithIgnoreCase() // -// Returns whether a given string `text` ends with `ends_with`, ignoring case -// in the comparison. +// Returns whether a given ASCII string `text` ends with `ends_with`, ignoring +// case in the comparison. bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix); } // namespace absl diff --git a/absl/strings/match_test.cc b/absl/strings/match_test.cc index d194f0e6..c21e00bf 100644 --- a/absl/strings/match_test.cc +++ b/absl/strings/match_test.cc @@ -80,6 +80,17 @@ TEST(MatchTest, ContainsNull) { EXPECT_FALSE(absl::StrContains(cs, sv2)); } +TEST(MatchTest, EqualsIgnoreCase) { + std::string text = "the"; + absl::string_view data(text); + + EXPECT_TRUE(absl::EqualsIgnoreCase(data, "The")); + EXPECT_TRUE(absl::EqualsIgnoreCase(data, "THE")); + EXPECT_TRUE(absl::EqualsIgnoreCase(data, "the")); + EXPECT_FALSE(absl::EqualsIgnoreCase(data, "Quick")); + EXPECT_FALSE(absl::EqualsIgnoreCase(data, "then")); +} + TEST(MatchTest, StartsWithIgnoreCase) { EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "foo")); EXPECT_TRUE(absl::StartsWithIgnoreCase("foo", "Fo")); diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index 5fe0967f..d7f72717 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -416,6 +416,12 @@ class civil_time { return difference(T{}, lhs.f_, rhs.f_); } + template + friend H AbslHashValue(H h, civil_time a) { + return H::combine(std::move(h), a.f_.y, a.f_.m, a.f_.d, + a.f_.hh, a.f_.mm, a.f_.ss); + } + private: // All instantiations of this template are allowed to call the following // private constructor and access the private fields member. diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h index c86a5552..f28dad17 100644 --- a/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/absl/time/internal/cctz/include/cctz/time_zone.h @@ -224,6 +224,11 @@ class time_zone { return !(lhs == rhs); } + template + friend H AbslHashValue(H h, time_zone tz) { + return H::combine(std::move(h), &tz.effective_impl()); + } + class Impl; private: diff --git a/absl/time/internal/cctz/src/civil_time_test.cc b/absl/time/internal/cctz/src/civil_time_test.cc index f6648c8f..faffde47 100644 --- a/absl/time/internal/cctz/src/civil_time_test.cc +++ b/absl/time/internal/cctz/src/civil_time_test.cc @@ -620,7 +620,7 @@ TEST(CivilTime, Relational) { TEST_RELATIONAL(civil_second(2014, 1, 1, 1, 1, 0), civil_second(2014, 1, 1, 1, 1, 1)); - // Tests the relational operators of two different CivilTime types. + // Tests the relational operators of two different civil-time types. TEST_RELATIONAL(civil_day(2014, 1, 1), civil_minute(2014, 1, 1, 1, 1)); TEST_RELATIONAL(civil_day(2014, 1, 1), civil_month(2014, 2)); diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc index 598b08fd..db9a475a 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -15,8 +15,8 @@ #include "time_zone_fixed.h" #include +#include #include -#include #include #include @@ -29,8 +29,15 @@ namespace { // The prefix used for the internal names of fixed-offset zones. const char kFixedOffsetPrefix[] = "Fixed/UTC"; +const char kDigits[] = "0123456789"; + +char* Format02d(char* p, int v) { + *p++ = kDigits[(v / 10) % 10]; + *p++ = kDigits[v % 10]; + return p; +} + int Parse02d(const char* p) { - static const char kDigits[] = "0123456789"; if (const char* ap = std::strchr(kDigits, *p)) { int v = static_cast(ap - kDigits); if (const char* bp = std::strchr(kDigits, *++p)) { @@ -95,9 +102,17 @@ std::string FixedOffsetToName(const seconds& offset) { } int hours = minutes / 60; minutes %= 60; - char buf[sizeof(kFixedOffsetPrefix) + sizeof("-24:00:00")]; - snprintf(buf, sizeof(buf), "%s%c%02d:%02d:%02d", - kFixedOffsetPrefix, sign, hours, minutes, seconds); + char buf[sizeof(kFixedOffsetPrefix) - 1 + sizeof("-24:00:00")]; + std::strcpy(buf, kFixedOffsetPrefix); + char* ep = buf + sizeof(kFixedOffsetPrefix) - 1; + *ep++ = sign; + ep = Format02d(ep, hours); + *ep++ = ':'; + ep = Format02d(ep, minutes); + *ep++ = ':'; + ep = Format02d(ep, seconds); + *ep++ = '\0'; + assert(ep == buf + sizeof(buf)); return buf; } -- cgit v1.2.3