about summary refs log tree commit diff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/numbers.h13
-rw-r--r--absl/strings/str_cat.cc26
-rw-r--r--absl/strings/str_format.h6
-rw-r--r--absl/strings/string_view.cc4
-rw-r--r--absl/strings/string_view.h6
-rw-r--r--absl/strings/string_view_test.cc12
6 files changed, 39 insertions, 28 deletions
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index 745de67ad86d..9b8ec89a8941 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -37,7 +37,14 @@
 #include <type_traits>
 
 #include "absl/base/internal/bits.h"
+#ifdef __SSE4_2__
+// TODO(jorg): Remove this when we figure out the right way
+// to swap bytes on SSE 4.2 that works with the compilers
+// we claim to support.  Also, add tests for the compiler
+// that doesn't support the Intel _bswap64 intrinsic but
+// does support all the SSE 4.2 intrinsics
 #include "absl/base/internal/endian.h"
+#endif
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
 #include "absl/numeric/int128.h"
@@ -189,12 +196,12 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
 // Returns the number of non-pad digits of the output (it can never be zero
 // since 0 has one digit).
 inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
-  uint64_t be = absl::big_endian::FromHost64(val);
 #ifdef __SSE4_2__
+  uint64_t be = absl::big_endian::FromHost64(val);
   const auto kNibbleMask = _mm_set1_epi8(0xf);
   const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7',
                                         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
-  auto v = _mm_loadu_si64(reinterpret_cast<__m128i*>(&be));  // load lo dword
+  auto v = _mm_loadl_epi64(reinterpret_cast<__m128i*>(&be));  // load lo dword
   auto v4 = _mm_srli_epi64(v, 4);                            // shift 4 right
   auto il = _mm_unpacklo_epi8(v4, v);                        // interleave bytes
   auto m = _mm_and_si128(il, kNibbleMask);                   // mask out nibbles
@@ -202,7 +209,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
   _mm_storeu_si128(reinterpret_cast<__m128i*>(out), hexchars);
 #else
   for (int i = 0; i < 8; ++i) {
-    auto byte = (be >> (8 * i)) & 0xFF;
+    auto byte = (val >> (56 - 8 * i)) & 0xFF;
     auto* hex = &absl::numbers_internal::kHexTable[byte * 2];
     std::memcpy(out + 2 * i, hex, 2);
   }
diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc
index d587789972e4..4bd56f5f4386 100644
--- a/absl/strings/str_cat.cc
+++ b/absl/strings/str_cat.cc
@@ -27,23 +27,21 @@
 namespace absl {
 
 AlphaNum::AlphaNum(Hex hex) {
+  static_assert(numbers_internal::kFastToBufferSize >= 32,
+                "This function only works when output buffer >= 32 bytes long");
   char* const end = &digits_[numbers_internal::kFastToBufferSize];
-  char* writer = end;
-  uint64_t value = hex.value;
-  do {
-    *--writer = absl::numbers_internal::kHexChar[value & 0xF];
-    value >>= 4;
-  } while (value != 0);
-
-  char* beg;
-  if (end - writer < hex.width) {
-    beg = end - hex.width;
-    std::fill_n(beg, writer - beg, hex.fill);
+  auto real_width =
+      absl::numbers_internal::FastHexToBufferZeroPad16(hex.value, end - 16);
+  if (real_width >= hex.width) {
+    piece_ = absl::string_view(end - real_width, real_width);
   } else {
-    beg = writer;
+    // Pad first 16 chars because FastHexToBufferZeroPad16 pads only to 16 and
+    // max pad width can be up to 20.
+    std::memset(end - 32, hex.fill, 16);
+    // Patch up everything else up to the real_width.
+    std::memset(end - real_width - 16, hex.fill, 16);
+    piece_ = absl::string_view(end - hex.width, hex.width);
   }
-
-  piece_ = absl::string_view(beg, end - beg);
 }
 
 AlphaNum::AlphaNum(Dec dec) {
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index 607e2bcaae16..c11c93a24837 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -400,6 +400,12 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format,
 // This function is functionally equivalent to `std::snprintf()` (and
 // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`.
 //
+// In particular, a successful call to `absl::SNPrintF()` writes at most `size`
+// bytes of the formatted output to `output`, including a null terminator, and
+// returns the number of bytes that would have been written if truncation did
+// not occur. In the event of an error, a negative value is returned and `errno`
+// is set.
+//
 // Example:
 //
 //   std::string_view s = "Ulaanbaatar";
diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc
index dc034a83eea8..d5e1a3de9ff3 100644
--- a/absl/strings/string_view.cc
+++ b/absl/strings/string_view.cc
@@ -14,7 +14,7 @@
 
 #include "absl/strings/string_view.h"
 
-#ifndef ABSL_HAVE_STD_STRING_VIEW
+#ifndef ABSL_USES_STD_STRING_VIEW
 
 #include <algorithm>
 #include <climits>
@@ -230,4 +230,4 @@ constexpr string_view::size_type string_view::kMaxSize;
 
 }  // namespace absl
 
-#endif  // ABSL_HAVE_STD_STRING_VIEW
+#endif  // ABSL_USES_STD_STRING_VIEW
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 3438ccc12a7d..07075e80ec64 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -30,7 +30,7 @@
 #include <algorithm>
 #include "absl/base/config.h"
 
-#ifdef ABSL_HAVE_STD_STRING_VIEW
+#ifdef ABSL_USES_STD_STRING_VIEW
 
 #include <string_view>  // IWYU pragma: export
 
@@ -38,7 +38,7 @@ namespace absl {
 using std::string_view;
 }  // namespace absl
 
-#else  // ABSL_HAVE_STD_STRING_VIEW
+#else  // ABSL_USES_STD_STRING_VIEW
 
 #if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \
     (defined(__GNUC__) && !defined(__clang__))
@@ -580,7 +580,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece);
 
 #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP
 
-#endif  // ABSL_HAVE_STD_STRING_VIEW
+#endif  // ABSL_USES_STD_STRING_VIEW
 
 namespace absl {
 
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc
index 86f2fbcd003a..96dacdf048cf 100644
--- a/absl/strings/string_view_test.cc
+++ b/absl/strings/string_view_test.cc
@@ -830,7 +830,7 @@ TEST(StringViewTest, FrontBackSingleChar) {
 // to the standard, but `absl::string_view` implements a different
 // behavior for historical reasons. We work around tests that construct
 // `string_view` from `nullptr` when using libc++.
-#if !defined(ABSL_HAVE_STD_STRING_VIEW) ||                    \
+#if !defined(ABSL_USES_STD_STRING_VIEW) ||                    \
     (!(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 9) && \
      !defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
 #define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1
@@ -938,7 +938,7 @@ TEST(StringViewTest, ConstexprCompiles) {
 #endif
   constexpr absl::string_view cstr_len("cstr", 4);
 
-#if defined(ABSL_HAVE_STD_STRING_VIEW)
+#if defined(ABSL_USES_STD_STRING_VIEW)
   // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)`
   // calls `std::char_traits<char>::length(const char*)` to get the std::string
   // length, but it is not marked constexpr yet. See GCC bug:
@@ -952,7 +952,7 @@ TEST(StringViewTest, ConstexprCompiles) {
 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1
 #endif  // !__GLIBCXX__
 
-#else  // ABSL_HAVE_STD_STRING_VIEW
+#else  // ABSL_USES_STD_STRING_VIEW
 
 // This duplicates the check for __builtin_strlen in the header.
 #if ABSL_HAVE_BUILTIN(__builtin_strlen) || \
@@ -967,7 +967,7 @@ TEST(StringViewTest, ConstexprCompiles) {
 #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1
 #endif
 
-#endif  // ABSL_HAVE_STD_STRING_VIEW
+#endif  // ABSL_USES_STD_STRING_VIEW
 
 #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR
   constexpr absl::string_view cstr_strlen("foo");
@@ -1136,7 +1136,7 @@ TEST(HugeStringView, TwoPointTwoGB) {
 }
 #endif  // THREAD_SANITIZER
 
-#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
+#if !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW)
 TEST(NonNegativeLenTest, NonNegativeLen) {
   ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1),
                                  "len <= kMaxSize");
@@ -1152,7 +1152,7 @@ TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) {
   ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1),
                                  "len <= kMaxSize");
 }
-#endif  // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
+#endif  // !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW)
 
 class StringViewStreamTest : public ::testing::Test {
  public: