Re: [PATCH] D18938: is_integral_or_enum ❥ enum class ⇒ hashable enum class
Daniel Berlin via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 9 12:56:53 PDT 2016
This looks better than the hackery i came up with, so LGTM :)
One nit in case we want to care:
+ return ::llvm::hashing::detail::hash_integer_value((uint64_t)value);
So, you are guaranteed this value is either an enum, *or* convertible to
unsigned long long.
But what is the enum is not an unsigned type?
IE will this not still trigger on:
enum class e2: int {};
?
I know these are all just hash values, so who cares, but in practice, you
may just want to use an explicit cast to std::underlying_type instead of
uint64_t.
or something. Again, my C++ knowledge mostly died after C++98, so not sure
what the "right" answer is here.
On Sat, Apr 9, 2016 at 12:48 PM, JF Bastien <jfb at chromium.org> wrote:
> jfb created this revision.
> jfb added reviewers: dberlin, chandlerc.
> jfb added a subscriber: llvm-commits.
>
> As discussed in D18775 making AtomicOrdering an enum class makes it
> non-hashable, which shouldn't be the case. Hashing.h defines hash_value for
> all is_integral_or_enum, but type_traits.h's definition of
> is_integral_or_enum only checks for *inplicit* conversion to integral types
> which leaves enum classes out and is very confusing because is_enum is true
> for enum classes.
>
> This patch:
> - Adds a check for is_enum when determining is_integral_or_enum.
> - Explicitly converts the value parameter in hash_value to handle enum
> class hashing.
>
> Note that the warning at the top of Hashing.h still applies: each
> execution of the program has a high probability of producing a different
> hash_code for a given input. Thus their values are not stable to save or
> persist, and should only be used during the execution for the construction
> of hashing datastructures.
>
> http://reviews.llvm.org/D18938
>
> Files:
> include/llvm/ADT/Hashing.h
> include/llvm/Support/type_traits.h
>
> Index: include/llvm/Support/type_traits.h
> ===================================================================
> --- include/llvm/Support/type_traits.h
> +++ include/llvm/Support/type_traits.h
> @@ -54,20 +54,22 @@
> };
>
> /// \brief Metafunction that determines whether the given type is either
> an
> -/// integral type or an enumeration type.
> +/// integral type or an enumeration type, including enum classes.
> ///
> /// Note that this accepts potentially more integral types than
> is_integral
> -/// because it is based on merely being convertible implicitly to an
> integral
> -/// type.
> +/// because it is based on being implicitly convertible to an integral
> type.
> +/// Also note that enum classes aren't implicitly convertible to integral
> types,
> +/// the value may therefore need to be explicitly converted before being
> used.
> template <typename T> class is_integral_or_enum {
> typedef typename std::remove_reference<T>::type UnderlyingT;
>
> public:
> static const bool value =
> !std::is_class<UnderlyingT>::value && // Filter conversion
> operators.
> !std::is_pointer<UnderlyingT>::value &&
> !std::is_floating_point<UnderlyingT>::value &&
> - std::is_convertible<UnderlyingT, unsigned long long>::value;
> + (std::is_enum<UnderlyingT>::value ||
> + std::is_convertible<UnderlyingT, unsigned long long>::value);
> };
>
> /// \brief If T is a pointer, just return it. If it is not, return T&.
> Index: include/llvm/ADT/Hashing.h
> ===================================================================
> --- include/llvm/ADT/Hashing.h
> +++ include/llvm/ADT/Hashing.h
> @@ -632,7 +632,7 @@
> template <typename T>
> typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
> hash_value(T value) {
> - return ::llvm::hashing::detail::hash_integer_value(value);
> + return ::llvm::hashing::detail::hash_integer_value((uint64_t)value);
> }
>
> // Declared and documented above, but defined here so that any of the
> hashing
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160409/1bce0050/attachment.html>
More information about the llvm-commits
mailing list