about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2018-10-08T20·53-0700
committerCJ Johnson <johnsoncj@google.com>2018-10-09T19·36-0400
commit445998d7ac4e5d3c50411d377e3b50e960d2d6c2 (patch)
tree8d9c214c92786eae42860786fdaeaafd1ee57f03
parente821380d69a549dc64900693942789d21aa4df5e (diff)
Export of internal Abseil changes.
--
714347c156cfe01575c1830a92bc6dea3030065b by Emma Christie <emmachristie@google.com>:

Release absl::EqualsIgnoreCase

PiperOrigin-RevId: 216243900

--
688106e2b9d2924799d597682690851cfba87818 by Abseil Team <absl-team@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 216208373

--
53638e4da238b230af0e56dc31b9fb790e708f36 by Emma Christie <emmachristie@google.com>:

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
-rw-r--r--absl/strings/match.cc7
-rw-r--r--absl/strings/match.h14
-rw-r--r--absl/strings/match_test.cc11
-rw-r--r--absl/time/internal/cctz/include/cctz/civil_time_detail.h6
-rw-r--r--absl/time/internal/cctz/include/cctz/time_zone.h5
-rw-r--r--absl/time/internal/cctz/src/civil_time_test.cc2
-rw-r--r--absl/time/internal/cctz/src/time_zone_fixed.cc25
7 files changed, 60 insertions, 10 deletions
diff --git a/absl/strings/match.cc b/absl/strings/match.cc
index 25bd7f0b828b..3d10c57784eb 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 942a196b8853..6e8ed10fc50f 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 d194f0e689bf..c21e00bf807c 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 5fe0967f5b24..d7f72717ece2 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 <typename H>
+  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 c86a555250ed..f28dad175506 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 <typename H>
+  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 f6648c8f1f21..faffde470af4 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 598b08fde422..db9a475a9b49 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 <algorithm>
+#include <cassert>
 #include <chrono>
-#include <cstdio>
 #include <cstring>
 #include <string>
 
@@ -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<int>(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;
 }