summaryrefslogtreecommitdiff
path: root/cpp/src/slice2objc
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2017-01-16 17:45:00 -0500
committerBernard Normier <bernard@zeroc.com>2017-01-16 17:45:00 -0500
commitd6cb083111e2dbfa2486e681dc3876c613adf926 (patch)
tree7046892e4ff7e6babc068cc4a222aacd7ea0a04d /cpp/src/slice2objc
parentRenamed IceGrid Admin to IceGrid GUI (diff)
downloadice-d6cb083111e2dbfa2486e681dc3876c613adf926.tar.bz2
ice-d6cb083111e2dbfa2486e681dc3876c613adf926.tar.xz
ice-d6cb083111e2dbfa2486e681dc3876c613adf926.zip
Better hashing for Long and Double
Diffstat (limited to 'cpp/src/slice2objc')
-rw-r--r--cpp/src/slice2objc/Gen.cpp35
1 files changed, 26 insertions, 9 deletions
diff --git a/cpp/src/slice2objc/Gen.cpp b/cpp/src/slice2objc/Gen.cpp
index 7beb158413f..d3316087916 100644
--- a/cpp/src/slice2objc/Gen.cpp
+++ b/cpp/src/slice2objc/Gen.cpp
@@ -2026,29 +2026,46 @@ Slice::Gen::TypesVisitor::writeMemberHashCode(const DataMemberList& dataMembers,
TypePtr type = (*q)->type();
string name = fixId((*q)->name(), baseType);
- _M << nl << "h_ = ((h_ << 5) + h_) ^ ";
if(isValueType(type))
{
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
if(builtin)
{
- if(builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble)
+ switch(builtin->kind())
{
- _M << "(2654435761u * (uint)" << name << ");";
- }
- else
- {
- _M << "(2654435761u * " << name << ");";
+ case Builtin::KindLong:
+ {
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ (uint)(" << name << " ^ (" << name << " >> 32));";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ (2654435761u * (uint)" << name << ");";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ _M << sb;
+ _M << nl << "unsigned long long bits_ = (unsigned long long)" << name << ";";
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ (uint)(bits_ ^ (bits_ >> 32));";
+ _M << eb;
+ break;
+ }
+ default:
+ {
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ (2654435761u * " << name << ");";
+ break;
+ }
}
}
else
{
- _M << name << ";";
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ " << name << ";";
}
}
else
{
- _M << "[self->" << name << " hash];";
+ _M << nl << "h_ = ((h_ << 5) + h_) ^ [self->" << name << " hash];";
}
}
_M << nl << "return h_;";