diff options
author | Abseil Team <absl-team@google.com> | 2020-03-31T19·32-0700 |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2020-03-31T20·34-0400 |
commit | fba8a316c30690097de5d6127ad307d84a1b74ca (patch) | |
tree | 952cde69de3f0bca33453bf166514711e3abd5e0 /absl/base/internal | |
parent | 79e0dc11514df035a8d07a356f9ee1800fb2160c (diff) |
Export of internal Abseil changes
-- 2dd5008c7b4176859e320c7c337078adb173b662 by Tom Manshreck <shreck@google.com>: Internal change PiperOrigin-RevId: 304022549 -- 6442abd78697b03cfe698b0d0dac7f1eb4b5cb38 by Andy Getzendanner <durandal@google.com>: Internal change PiperOrigin-RevId: 303890410 -- eb8b37b468b0f23da09d3de714272928ef61f942 by Gennadiy Rozental <rogeeff@google.com>: Roll changes forward with ChunkIterator templatized. This should facilitate usage of "small" chunk iterator for a regular usage and proper "big" iterator internally in Cord implementation. This way Cord users are not exposed to stack size overhead if they have a lot of chunk iterators or recursive implementation which relies on chunk iterators. PiperOrigin-RevId: 303877118 -- 9623c569e7c55b45254e95f2d14c5badf9c901aa by Gennadiy Rozental <rogeeff@google.com>: Switch Flags implementation of fast type id to use absl/base/internal/fast_type_id.h PiperOrigin-RevId: 303861019 -- e2931e8d53c86d0816da6bbc8ba58cf5a3a443bb by Matthew Brown <matthewbr@google.com>: Internal Change PiperOrigin-RevId: 303832407 -- b549ed6e441e920b8ad6f02a80b9fd543820ef86 by Tom Manshreck <shreck@google.com>: Update Cord header file comments to Abseil standards PiperOrigin-RevId: 303823232 -- fc633d4f31a2d058f2b6a7029fc7c9820cd71c92 by Evan Brown <ezb@google.com>: Remove top-level const from K/V in map_slot_type::mutable_value and map_slot_type::key. This allows us to move between `map_slot_type::mutable_value`s internally even when the key_type and/or mapped_type specified by the user are const. PiperOrigin-RevId: 303811694 -- 909b3ce7cb3583ee9c374d36ff5f82bba02a1b64 by Derek Mauro <dmauro@google.com>: Add hardening assertions to the preconditions of absl::Cord PiperOrigin-RevId: 303419537 -- 9d32f79eabd54e6cb17bcc28b53e9bcfeb3cf6f4 by Greg Falcon <gfalcon@google.com>: Don't use MSVC-specific bit manipulations when using Clang on Windows. This fixes a compiler warning. Note that we do not have continuous testing for this configuration; this CL is best-effort support. PiperOrigin-RevId: 303322582 -- f6e0a35a2b9081d2a9eef73789b7bc1b5e46e5ad by Gennadiy Rozental <rogeeff@google.com>: Introduce standlone FastTypeId utility to represent compile time unique type id. PiperOrigin-RevId: 303180545 -- 99120e9fbdb5b2d327139ab8f617533d7bc3345b by Abseil Team <absl-team@google.com>: Changed absl's import of std::string_view to using string_view = std::string_view. This should help tools (e.g. include-what-you-use) discover where absl::string_view is defined. PiperOrigin-RevId: 303169095 GitOrigin-RevId: 2dd5008c7b4176859e320c7c337078adb173b662 Change-Id: I1e18ae08e23686ac963e7ea5e5bd499e18d51048
Diffstat (limited to 'absl/base/internal')
-rw-r--r-- | absl/base/internal/bits.h | 24 | ||||
-rw-r--r-- | absl/base/internal/fast_type_id.h | 48 | ||||
-rw-r--r-- | absl/base/internal/fast_type_id_test.cc | 123 |
3 files changed, 183 insertions, 12 deletions
diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h index 8b03453c184f..14c51d8b3013 100644 --- a/absl/base/internal/bits.h +++ b/absl/base/internal/bits.h @@ -24,7 +24,7 @@ // Clang on Windows has __builtin_clzll; otherwise we need to use the // windows intrinsic functions. -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) #include <intrin.h> #if defined(_M_X64) #pragma intrinsic(_BitScanReverse64) @@ -36,7 +36,7 @@ #include "absl/base/attributes.h" -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) // We can achieve something similar to attribute((always_inline)) with MSVC by // using the __forceinline keyword, however this is not perfect. MSVC is // much less aggressive about inlining, and even with the __forceinline keyword. @@ -73,14 +73,14 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) { } ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) { -#if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64) // MSVC does not have __buitin_clzll. Use _BitScanReverse64. unsigned long result = 0; // NOLINT(runtime/int) if (_BitScanReverse64(&result, n)) { return 63 - result; } return 64; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(__clang__) // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse unsigned long result = 0; // NOLINT(runtime/int) if ((n >> 32) && _BitScanReverse(&result, n >> 32)) { @@ -90,7 +90,7 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) { return 63 - result; } return 64; -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) // Use __builtin_clzll, which uses the following instructions: // x86: bsr // ARM64: clz @@ -126,13 +126,13 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) { } ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32(uint32_t n) { -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) unsigned long result = 0; // NOLINT(runtime/int) if (_BitScanReverse(&result, n)) { return 31 - result; } return 32; -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) // Use __builtin_clz, which uses the following instructions: // x86: bsr // ARM64: clz @@ -163,11 +163,11 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64Slow(uint64_t n) { } ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) { -#if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64) unsigned long result = 0; // NOLINT(runtime/int) _BitScanForward64(&result, n); return result; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(__clang__) unsigned long result = 0; // NOLINT(runtime/int) if (static_cast<uint32_t>(n) == 0) { _BitScanForward(&result, n >> 32); @@ -175,7 +175,7 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) { } _BitScanForward(&result, n); return result; -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int) "__builtin_ctzll does not take 64-bit arg"); return __builtin_ctzll(n); @@ -196,11 +196,11 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32Slow(uint32_t n) { } ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) { -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) unsigned long result = 0; // NOLINT(runtime/int) _BitScanForward(&result, n); return result; -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) static_assert(sizeof(int) == sizeof(n), "__builtin_ctz does not take 32-bit arg"); return __builtin_ctz(n); diff --git a/absl/base/internal/fast_type_id.h b/absl/base/internal/fast_type_id.h new file mode 100644 index 000000000000..3db59e83745b --- /dev/null +++ b/absl/base/internal/fast_type_id.h @@ -0,0 +1,48 @@ +// +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ +#define ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { + +template <typename Type> +struct FastTypeTag { + constexpr static char dummy_var = 0; +}; + +template <typename Type> +constexpr char FastTypeTag<Type>::dummy_var; + +// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the +// passed-in type. These are meant to be good match for keys into maps or +// straight up comparisons. +using FastTypeIdType = const void*; + +template <typename Type> +constexpr inline FastTypeIdType FastTypeId() { + return &FastTypeTag<Type>::dummy_var; +} + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ diff --git a/absl/base/internal/fast_type_id_test.cc b/absl/base/internal/fast_type_id_test.cc new file mode 100644 index 000000000000..16f3c1458bdf --- /dev/null +++ b/absl/base/internal/fast_type_id_test.cc @@ -0,0 +1,123 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/internal/fast_type_id.h" + +#include <cstdint> +#include <map> +#include <vector> + +#include "gtest/gtest.h" + +namespace { +namespace bi = absl::base_internal; + +// NOLINTNEXTLINE +#define PRIM_TYPES(A) \ + A(bool) \ + A(short) \ + A(unsigned short) \ + A(int) \ + A(unsigned int) \ + A(long) \ + A(unsigned long) \ + A(long long) \ + A(unsigned long long) \ + A(float) \ + A(double) \ + A(long double) + +TEST(FastTypeIdTest, PrimitiveTypes) { + bi::FastTypeIdType type_ids[] = { +#define A(T) bi::FastTypeId<T>(), + PRIM_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<const T>(), + PRIM_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<volatile T>(), + PRIM_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<const volatile T>(), + PRIM_TYPES(A) +#undef A + }; + size_t total_type_ids = sizeof(type_ids) / sizeof(bi::FastTypeIdType); + + for (int i = 0; i < total_type_ids; ++i) { + EXPECT_EQ(type_ids[i], type_ids[i]); + for (int j = 0; j < i; ++j) { + EXPECT_NE(type_ids[i], type_ids[j]); + } + } +} + +#define FIXED_WIDTH_TYPES(A) \ + A(int8_t) \ + A(uint8_t) \ + A(int16_t) \ + A(uint16_t) \ + A(int32_t) \ + A(uint32_t) \ + A(int64_t) \ + A(uint64_t) + +TEST(FastTypeIdTest, FixedWidthTypes) { + bi::FastTypeIdType type_ids[] = { +#define A(T) bi::FastTypeId<T>(), + FIXED_WIDTH_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<const T>(), + FIXED_WIDTH_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<volatile T>(), + FIXED_WIDTH_TYPES(A) +#undef A +#define A(T) bi::FastTypeId<const volatile T>(), + FIXED_WIDTH_TYPES(A) +#undef A + }; + size_t total_type_ids = sizeof(type_ids) / sizeof(bi::FastTypeIdType); + + for (int i = 0; i < total_type_ids; ++i) { + EXPECT_EQ(type_ids[i], type_ids[i]); + for (int j = 0; j < i; ++j) { + EXPECT_NE(type_ids[i], type_ids[j]); + } + } +} + +TEST(FastTypeIdTest, AliasTypes) { + using int_alias = int; + EXPECT_EQ(bi::FastTypeId<int_alias>(), bi::FastTypeId<int>()); +} + +TEST(FastTypeIdTest, TemplateSpecializations) { + EXPECT_NE(bi::FastTypeId<std::vector<int>>(), + bi::FastTypeId<std::vector<long>>()); + + EXPECT_NE((bi::FastTypeId<std::map<int, float>>()), + (bi::FastTypeId<std::map<int, double>>())); +} + +struct Base {}; +struct Derived : Base {}; +struct PDerived : private Base {}; + +TEST(FastTypeIdTest, Inheritance) { + EXPECT_NE(bi::FastTypeId<Base>(), bi::FastTypeId<Derived>()); + EXPECT_NE(bi::FastTypeId<Base>(), bi::FastTypeId<PDerived>()); +} + +} // namespace |