We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ideally, std::hash<gsl::not_null<T>> would only be "enabled" (see [unord.hash]) if std::hash<T> is enabled.
std::hash<gsl::not_null<T>>
std::hash<T>
This can be achieved very easily in C++20:
--- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -175,6 +175,9 @@ not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete; namespace std { template <class T> +#if __cpp_concepts + requires std::is_invocable_v<std::hash<T>, T> +#endif struct hash<gsl::not_null<T>> { std::size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); } @@ -278,6 +281,9 @@ template <class T> strict_not_null(T) -> strict_not_null<T>; namespace std { template <class T> +#if __cpp_concepts + requires std::is_invocable_v<std::hash<T>, T> +#endif struct hash<gsl::strict_not_null<T>> { std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value); }
For portability to older standards something like this works:
--- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -170,14 +170,27 @@ not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete; template <class T> not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete; +template <class T, class U = decltype(std::declval<T>().get()), bool enabled = std::is_invocable_v<std::hash<U>, U>> +struct not_null_hash +{ + std::size_t operator()(const T& value) const { return std::hash<U>{}(value.get()); } +}; + +template <class T, class U> +struct not_null_hash<T, U, false> +{ + not_null_hash() = delete; + not_null_hash(const not_null_hash&) = delete; + not_null_hash& operator=(const not_null_hash&) = delete; +}; + } // namespace gsl namespace std { template <class T> -struct hash<gsl::not_null<T>> +struct hash<gsl::not_null<T>> : gsl::not_null_hash<gsl::not_null<T>> { - std::size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); } }; } // namespace std @@ -278,9 +291,8 @@ template <class T> strict_not_null(T) -> strict_not_null<T>; namespace std { template <class T> -struct hash<gsl::strict_not_null<T>> +struct hash<gsl::strict_not_null<T>> : gsl::not_null_hash<gsl::strict_not_null<T>> { - std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value); } }; } // namespace std
The text was updated successfully, but these errors were encountered:
not_null<>
Disable std::hash<gsl::not_null<T>> if std::hash<T> is not enabled. (#…
4b5b5a1
…1109) Resolves #914
Successfully merging a pull request may close this issue.
Ideally,
std::hash<gsl::not_null<T>>
would only be "enabled" (see [unord.hash]) ifstd::hash<T>
is enabled.This can be achieved very easily in C++20:
For portability to older standards something like this works:
The text was updated successfully, but these errors were encountered: