about summary refs log tree commit diff
path: root/absl
diff options
context:
space:
mode:
Diffstat (limited to 'absl')
-rw-r--r--absl/container/BUILD.bazel1
-rw-r--r--absl/container/CMakeLists.txt1
-rw-r--r--absl/container/internal/raw_hash_map.h11
-rw-r--r--absl/strings/string_view.h30
-rw-r--r--absl/strings/string_view_test.cc5
5 files changed, 35 insertions, 13 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index b8cf17fc6072..9e2a5b1eacb9 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -573,6 +573,7 @@ cc_library(
     deps = [
         ":container_memory",
         ":raw_hash_set",
+        "//absl/base:throw_delegate",
     ],
 )
 
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 5d7c75dd59cd..7988b12fe3b8 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -594,6 +594,7 @@ absl_cc_library(
   DEPS
     absl::container_memory
     absl::raw_hash_set
+    absl::throw_delegate
   PUBLIC
 )
 
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 0014cf808053..6a9c730c4644 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -19,6 +19,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "absl/base/internal/throw_delegate.h"
 #include "absl/container/internal/container_memory.h"
 #include "absl/container/internal/raw_hash_set.h"  // IWYU pragma: export
 
@@ -136,14 +137,20 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> {
   template <class K = key_type, class P = Policy>
   MappedReference<P> at(const key_arg<K>& key) {
     auto it = this->find(key);
-    if (it == this->end()) std::abort();
+    if (it == this->end()) {
+      base_internal::ThrowStdOutOfRange(
+          "absl::container_internal::raw_hash_map<>::at");
+    }
     return Policy::value(&*it);
   }
 
   template <class K = key_type, class P = Policy>
   MappedConstReference<P> at(const key_arg<K>& key) const {
     auto it = this->find(key);
-    if (it == this->end()) std::abort();
+    if (it == this->end()) {
+      base_internal::ThrowStdOutOfRange(
+          "absl::container_internal::raw_hash_map<>::at");
+    }
     return Policy::value(&*it);
   }
 
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index f8b20015df6a..65b1772de747 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -172,19 +172,9 @@ class string_view {
   // Implicit constructor of a `string_view` from nul-terminated `str`. When
   // accepting possibly null strings, use `absl::NullSafeStringView(str)`
   // instead (see below).
-#if ABSL_HAVE_BUILTIN(__builtin_strlen) || \
-    (defined(__GNUC__) && !defined(__clang__))
-  // GCC has __builtin_strlen according to
-  // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but
-  // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above.
-  // __builtin_strlen is constexpr.
   constexpr string_view(const char* str)  // NOLINT(runtime/explicit)
       : ptr_(str),
-        length_(CheckLengthInternal(str ? __builtin_strlen(str) : 0)) {}
-#else
-  constexpr string_view(const char* str)  // NOLINT(runtime/explicit)
-      : ptr_(str), length_(CheckLengthInternal(str ? strlen(str) : 0)) {}
-#endif
+        length_(str ? CheckLengthInternal(StrlenInternal(str)) : 0) {}
 
   // Implicit constructor of a `string_view` from a `const char*` and length.
   constexpr string_view(const char* data, size_type len)
@@ -495,6 +485,24 @@ class string_view {
     return ABSL_ASSERT(len <= kMaxSize), len;
   }
 
+  static constexpr size_type StrlenInternal(const char* str) {
+#if defined(_MSC_VER) && _MSC_VER >= 1910 && !defined(__clang__)
+    // MSVC 2017+ can evaluate this at compile-time.
+    const char* begin = str;
+    while (*str != '\0') ++str;
+    return str - begin;
+#elif ABSL_HAVE_BUILTIN(__builtin_strlen) || \
+    (defined(__GNUC__) && !defined(__clang__))
+    // GCC has __builtin_strlen according to
+    // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but
+    // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above.
+    // __builtin_strlen is constexpr.
+    return __builtin_strlen(str);
+#else
+    return str ? strlen(str) : 0;
+#endif
+  }
+
   const char* ptr_;
   size_type length_;
 };
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc
index 823d8ed4581d..2380e1a377a3 100644
--- a/absl/strings/string_view_test.cc
+++ b/absl/strings/string_view_test.cc
@@ -941,6 +941,11 @@ TEST(StringViewTest, ConstexprCompiles) {
 #error GCC/clang should have constexpr string_view.
 #endif
 
+// MSVC 2017+ should be able to construct a constexpr string_view from a cstr.
+#if defined(_MSC_VER) && _MSC_VER >= 1910
+#define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1
+#endif
+
 #endif  // ABSL_HAVE_STD_STRING_VIEW
 
 #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR