From 89f1f531d373f5e4eab77960d3b0e8c05d879c7c Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Sun, 1 Oct 2017 13:14:12 +0100 Subject: Make any_internal::FastTypeId() and IdForType() constexpr This means removing all side effects from FastTypeId(). So rather than instantiate dummy_var in the first call to FastTypeId(), move this responsibility to the linker, and only read its address during execution - guaranteed to never change. This allows for more optimization opportunities, with more explicit uses of constexpr --- absl/types/any.h | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'absl/types/any.h') diff --git a/absl/types/any.h b/absl/types/any.h index a51dea11..fe104818 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -94,23 +94,20 @@ namespace absl { namespace any_internal { -// FastTypeId() evaluates at compile/link-time to a unique integer for the -// passed in type. Their values are neither contiguous nor small, making them -// unfit for using as an index into a vector, but a good match for keys into -// maps or straight up comparisons. -// Note that on 64-bit (unix) systems size_t is 64-bit while int is 32-bit and -// the compiler will happily and quietly assign such a 64-bit value to a -// 32-bit integer. While a client should never do that it SHOULD still be safe, -// assuming the BSS segment doesn't span more than 4GiB. +template +struct TypeTag { + constexpr static char dummy_var = 0; +}; + +template +constexpr char TypeTag::dummy_var; + +// FastTypeId() 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. template -inline size_t FastTypeId() { - static_assert(sizeof(char*) <= sizeof(size_t), - "ptr size too large for size_t"); - - // This static variable isn't actually used, only its address, so there are - // no concurrency issues. - static char dummy_var; - return reinterpret_cast(&dummy_var); +constexpr inline const void* FastTypeId() { + return &TypeTag::dummy_var; } } // namespace any_internal @@ -382,10 +379,20 @@ class any { public: virtual ~ObjInterface() = default; virtual std::unique_ptr Clone() const = 0; - virtual size_t type_id() const noexcept = 0; + virtual const void* ObjTypeId() const noexcept = 0; #if ABSL_ANY_DETAIL_HAS_RTTI virtual const std::type_info& Type() const noexcept = 0; #endif // ABSL_ANY_DETAIL_HAS_RTTI + + // Note that on 64-bit (unix) systems size_t is 64-bit while int is 32-bit and + // the compiler will happily and quietly assign such a 64-bit value to a + // 32-bit integer. While a client should never do that it SHOULD still be safe, + // assuming the BSS segment doesn't span more than 4GiB. + size_t type_id() const noexcept { + static_assert(sizeof(void*) <= sizeof(size_t), + "ptr size too large for size_t"); + return reinterpret_cast(ObjTypeId()); + } }; // Hold a value of some queryable type, with an ability to Clone it. @@ -400,7 +407,7 @@ class any { return std::unique_ptr(new Obj(in_place, value)); } - size_t type_id() const noexcept final { return IdForType(); } + const void* ObjTypeId() const noexcept final { return IdForType(); } #if ABSL_ANY_DETAIL_HAS_RTTI const std::type_info& Type() const noexcept final { return typeid(T); } @@ -415,7 +422,7 @@ class any { } template - static size_t IdForType() { + constexpr static const void* IdForType() { // Note: This type dance is to make the behavior consistent with typeid. using NormalizedType = typename std::remove_cv::type>::type; @@ -423,8 +430,9 @@ class any { return any_internal::FastTypeId(); } - size_t GetObjTypeId() const { - return obj_ == nullptr ? any_internal::FastTypeId() : obj_->type_id(); + const void* GetObjTypeId() const { + return obj_ == nullptr ? any_internal::FastTypeId() + : obj_->ObjTypeId(); } // `absl::any` nonmember functions // -- cgit v1.2.3 From b7bdd3a63d78da1cd4e537cf52cfe08068d2a399 Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Tue, 10 Oct 2017 22:07:10 +0100 Subject: Removed unused type_id() function --- absl/types/any.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'absl/types/any.h') diff --git a/absl/types/any.h b/absl/types/any.h index fe104818..f29de037 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -383,16 +383,6 @@ class any { #if ABSL_ANY_DETAIL_HAS_RTTI virtual const std::type_info& Type() const noexcept = 0; #endif // ABSL_ANY_DETAIL_HAS_RTTI - - // Note that on 64-bit (unix) systems size_t is 64-bit while int is 32-bit and - // the compiler will happily and quietly assign such a 64-bit value to a - // 32-bit integer. While a client should never do that it SHOULD still be safe, - // assuming the BSS segment doesn't span more than 4GiB. - size_t type_id() const noexcept { - static_assert(sizeof(void*) <= sizeof(size_t), - "ptr size too large for size_t"); - return reinterpret_cast(ObjTypeId()); - } }; // Hold a value of some queryable type, with an ability to Clone it. @@ -431,8 +421,7 @@ class any { } const void* GetObjTypeId() const { - return obj_ == nullptr ? any_internal::FastTypeId() - : obj_->ObjTypeId(); + return obj_ ? obj_->ObjTypeId() : any_internal::FastTypeId(); } // `absl::any` nonmember functions // -- cgit v1.2.3 From bbf83057e5f611a66ba9dfeabb14ccfd5cf08ac7 Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Wed, 11 Oct 2017 22:11:13 +0100 Subject: Wrap comment at 80 cols --- absl/types/any.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'absl/types/any.h') diff --git a/absl/types/any.h b/absl/types/any.h index f29de037..2e7bf21f 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -103,8 +103,8 @@ template constexpr char TypeTag::dummy_var; // FastTypeId() 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. +// passed in type. These are meant to be good match for keys into maps or +// straight up comparisons. template constexpr inline const void* FastTypeId() { return &TypeTag::dummy_var; -- cgit v1.2.3