mirror of
https://github.com/darlinghq/darling-libcxx.git
synced 2024-12-11 13:47:01 +00:00
Version #next on the hash functions for scalars. This builds on Dave's work, extends it to T*, and changes the way double and long double are handled (no longer convert to float on 32 bit). I also picked up a minor bug with uninitialized bits on the upper end of size_t when sizeof(size_t) > sizeof(T), e.g. in hash<float>. Most of the functionality has been put in one place: __scalar_hash in <memory>. Unfortunately I could not reuse __scalar_hash for hash<long double> on x86 because of the padding bits which need to be zeroed. I didn't want to add this zeroing step to the more general __scalar_hash when it isn't needed (in the absence of padding bits). I'm not ignoring the hash<string> issue (possibly changing that to a better hash). I just haven't gotten there yet.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@145778 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2891675aad
commit
cf2654bae7
@ -1916,123 +1916,91 @@ struct _LIBCPP_VISIBLE hash<unsigned long>
|
||||
|
||||
template <>
|
||||
struct _LIBCPP_VISIBLE hash<long long>
|
||||
: public unary_function<long long, size_t>
|
||||
: public __scalar_hash<long long>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(long long __v) const _NOEXCEPT
|
||||
{
|
||||
if (sizeof(long long) == sizeof(size_t))
|
||||
return __v;
|
||||
union
|
||||
{
|
||||
long long __l;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
} __s;
|
||||
} __u;
|
||||
__u.__l = __v;
|
||||
return __u.__s.__a ^ __u.__s.__b;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _LIBCPP_VISIBLE hash<unsigned long long>
|
||||
: public unary_function<unsigned long long, size_t>
|
||||
: public __scalar_hash<unsigned long long>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(unsigned long long __v) const _NOEXCEPT
|
||||
{
|
||||
if (sizeof(unsigned long long) == sizeof(size_t))
|
||||
return __v;
|
||||
union
|
||||
{
|
||||
unsigned long long __l;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
} __s;
|
||||
} __u;
|
||||
__u.__l = __v;
|
||||
return __u.__s.__a ^ __u.__s.__b;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _LIBCPP_VISIBLE hash<float>
|
||||
: public unary_function<float, size_t>
|
||||
: public __scalar_hash<float>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(float __v) const _NOEXCEPT
|
||||
{
|
||||
// -0.0 and 0.0 should return same hash
|
||||
if (__v == 0)
|
||||
return 0;
|
||||
union
|
||||
{
|
||||
size_t __d;
|
||||
float __f;
|
||||
} __u;
|
||||
__u.__f = __v;
|
||||
return __u.__d;
|
||||
return __scalar_hash<float>::operator()(__v);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _LIBCPP_VISIBLE hash<double>
|
||||
: public unary_function<double, size_t>
|
||||
: public __scalar_hash<double>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(double __v) const _NOEXCEPT
|
||||
{
|
||||
if (__v == 0)
|
||||
return 0;
|
||||
if (sizeof(double) == sizeof(size_t))
|
||||
{
|
||||
union
|
||||
{
|
||||
double __f;
|
||||
size_t __d;
|
||||
} __u;
|
||||
__u.__f = __v;
|
||||
return __u.__d;
|
||||
}
|
||||
union
|
||||
{
|
||||
float __f;
|
||||
size_t __d;
|
||||
} __u;
|
||||
__u.__f = __v;
|
||||
return __u.__d;
|
||||
// -0.0 and 0.0 should return same hash
|
||||
if (__v == 0)
|
||||
return 0;
|
||||
return __scalar_hash<double>::operator()(__v);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _LIBCPP_VISIBLE hash<long double>
|
||||
: public unary_function<long double, size_t>
|
||||
: public __scalar_hash<long double>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(long double __v) const _NOEXCEPT
|
||||
{
|
||||
// -0.0 and 0.0 should return same hash
|
||||
if (__v == 0)
|
||||
return 0;
|
||||
if (sizeof(double) == sizeof(size_t))
|
||||
#if defined(__i386__)
|
||||
// Zero out padding bits
|
||||
union
|
||||
{
|
||||
union
|
||||
long double __t;
|
||||
struct
|
||||
{
|
||||
double __f;
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
size_t __c;
|
||||
size_t __d;
|
||||
} __u;
|
||||
__u.__f = __v;
|
||||
return __u.__d;
|
||||
}
|
||||
union {
|
||||
float __f;
|
||||
size_t __d;
|
||||
};
|
||||
} __u;
|
||||
__u.__f = __v;
|
||||
return __u.__d;
|
||||
__u.__a = 0;
|
||||
__u.__b = 0;
|
||||
__u.__c = 0;
|
||||
__u.__d = 0;
|
||||
__u.__t = __v;
|
||||
return __u.__a ^ __u.__b ^ __u.__c ^ __u.__d;
|
||||
#elif defined(__x86_64__)
|
||||
// Zero out padding bits
|
||||
union
|
||||
{
|
||||
long double __t;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
};
|
||||
} __u;
|
||||
__u.__a = 0;
|
||||
__u.__b = 0;
|
||||
__u.__t = __v;
|
||||
return __u.__a ^ __u.__b;
|
||||
#else
|
||||
return __scalar_hash<long double>::operator()(__v);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
110
include/memory
110
include/memory
@ -2719,18 +2719,116 @@ operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {re
|
||||
|
||||
template <class _Tp> struct hash;
|
||||
|
||||
template<class _Tp>
|
||||
struct _LIBCPP_VISIBLE hash<_Tp*>
|
||||
: public unary_function<_Tp*, size_t>
|
||||
template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
|
||||
struct __scalar_hash;
|
||||
|
||||
template <class _Tp>
|
||||
struct __scalar_hash<_Tp, 0>
|
||||
: public unary_function<_Tp, size_t>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(_Tp* __v) const _NOEXCEPT
|
||||
size_t operator()(_Tp __v) const _NOEXCEPT
|
||||
{
|
||||
const size_t* const __p = reinterpret_cast<const size_t*>(&__v);
|
||||
return *__p;
|
||||
union
|
||||
{
|
||||
_Tp __t;
|
||||
size_t __a;
|
||||
} __u;
|
||||
__u.__a = 0;
|
||||
__u.__t = __v;
|
||||
return __u.__a;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __scalar_hash<_Tp, 1>
|
||||
: public unary_function<_Tp, size_t>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(_Tp __v) const _NOEXCEPT
|
||||
{
|
||||
union
|
||||
{
|
||||
_Tp __t;
|
||||
size_t __a;
|
||||
} __u;
|
||||
__u.__t = __v;
|
||||
return __u.__a;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __scalar_hash<_Tp, 2>
|
||||
: public unary_function<_Tp, size_t>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(_Tp __v) const _NOEXCEPT
|
||||
{
|
||||
union
|
||||
{
|
||||
_Tp __t;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
};
|
||||
} __u;
|
||||
__u.__t = __v;
|
||||
return __u.__a ^ __u.__b;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __scalar_hash<_Tp, 3>
|
||||
: public unary_function<_Tp, size_t>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(_Tp __v) const _NOEXCEPT
|
||||
{
|
||||
union
|
||||
{
|
||||
_Tp __t;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
size_t __c;
|
||||
};
|
||||
} __u;
|
||||
__u.__t = __v;
|
||||
return __u.__a ^ __u.__b ^ __u.__c;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __scalar_hash<_Tp, 4>
|
||||
: public unary_function<_Tp, size_t>
|
||||
{
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(_Tp __v) const _NOEXCEPT
|
||||
{
|
||||
union
|
||||
{
|
||||
_Tp __t;
|
||||
struct
|
||||
{
|
||||
size_t __a;
|
||||
size_t __b;
|
||||
size_t __c;
|
||||
size_t __d;
|
||||
};
|
||||
} __u;
|
||||
__u.__t = __v;
|
||||
return __u.__a ^ __u.__b ^ __u.__c ^ __u.__d;
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Tp>
|
||||
struct _LIBCPP_VISIBLE hash<_Tp*>
|
||||
: public __scalar_hash<_Tp*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Tp, class _Dp>
|
||||
struct _LIBCPP_VISIBLE hash<unique_ptr<_Tp, _Dp> >
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user