From 14550beb3b7b97195e483fb74b5efb906395c31e Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 30 Jul 2019 20:47:29 -0700 Subject: [PATCH] Export of internal Abseil changes. -- 8f685654a7d04eb8a0cb82d31e44e391e906b609 by Derek Mauro : Support constexpr construction of absl::string_view from a string literal in MSVC 2017+. Fixes https://github.com/abseil/abseil-cpp/issues/352 PiperOrigin-RevId: 260853160 -- a3c4c5168ce2a491134d7c87cf7fdc75d1ee2533 by Derek Mauro : Make SwissTable's at() throw when exceptions are enabled Fixes https://github.com/abseil/abseil-cpp/issues/355 PiperOrigin-RevId: 260788026 GitOrigin-RevId: 8f685654a7d04eb8a0cb82d31e44e391e906b609 Change-Id: I9ed498e181faa9c9d16e9b1b01404969d99b8ea9 --- absl/container/BUILD.bazel | 1 + absl/container/CMakeLists.txt | 1 + absl/container/internal/raw_hash_map.h | 11 ++++++++-- absl/strings/string_view.h | 30 ++++++++++++++++---------- absl/strings/string_view_test.cc | 5 +++++ 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index b8cf17fc6..9e2a5b1ea 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 5d7c75dd5..7988b12fe 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 0014cf808..6a9c730c4 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -19,6 +19,7 @@ #include #include +#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 { template MappedReference

at(const key_arg& 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 MappedConstReference

at(const key_arg& 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 f8b20015d..65b1772de 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 823d8ed45..2380e1a37 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