Browse Source

Calc StringHash compile time if possible (#2876)

1vanK 3 years ago
parent
commit
ed57c445e1

+ 1 - 1
Source/Samples/03_Sprites/Sprites.cpp

@@ -35,7 +35,7 @@
 static const unsigned NUM_SPRITES = 100;
 
 // Custom variable identifier for storing sprite velocity within the UI element
-static const StringHash VAR_VELOCITY("Velocity");
+static constexpr StringHash VAR_VELOCITY = "Velocity"_hash;
 
 URHO3D_DEFINE_APPLICATION_MAIN(Sprites)
 

+ 5 - 5
Source/Urho3D/AngelScript/Generated_Classes.cpp

@@ -2498,8 +2498,8 @@ static void StringHash__StringHash_constspStringHashamp(StringHash* _ptr, const
     new(_ptr) StringHash(rhs);
 }
 
-// explicit StringHash::StringHash(unsigned value) noexcept
-static void StringHash__StringHash_unsigned(StringHash* _ptr, unsigned value)
+// explicit constexpr StringHash::StringHash(unsigned value) noexcept
+static void StringHash_constexpr_StringHash_unsigned(StringHash* _ptr, unsigned value)
 {
     new(_ptr) StringHash(value);
 }
@@ -2513,13 +2513,13 @@ static void StringHash__StringHash_constspStringamp(StringHash* _ptr, const Stri
 // class StringHash | File: ../Math/StringHash.h
 static void Register_StringHash(asIScriptEngine* engine)
 {
-    // StringHash::StringHash(const char* str) noexcept
+    // constexpr StringHash::StringHash(const char* str) noexcept
     // Error: type "const char*" can not automatically bind
 
     // StringHash::StringHash(const StringHash& rhs) noexcept = default
     engine->RegisterObjectBehaviour("StringHash", asBEHAVE_CONSTRUCT, "void f(const StringHash&in)", AS_FUNCTION_OBJFIRST(StringHash__StringHash_constspStringHashamp), AS_CALL_CDECL_OBJFIRST);
-    // explicit StringHash::StringHash(unsigned value) noexcept
-    engine->RegisterObjectBehaviour("StringHash", asBEHAVE_CONSTRUCT, "void f(uint)", AS_FUNCTION_OBJFIRST(StringHash__StringHash_unsigned), AS_CALL_CDECL_OBJFIRST);
+    // explicit constexpr StringHash::StringHash(unsigned value) noexcept
+    engine->RegisterObjectBehaviour("StringHash", asBEHAVE_CONSTRUCT, "void f(uint)", AS_FUNCTION_OBJFIRST(StringHash_constexpr_StringHash_unsigned), AS_CALL_CDECL_OBJFIRST);
     // StringHash::StringHash(const String& str) noexcept
     engine->RegisterObjectBehaviour("StringHash", asBEHAVE_CONSTRUCT, "void f(const String&in)", AS_FUNCTION_OBJFIRST(StringHash__StringHash_constspStringamp), AS_CALL_CDECL_OBJFIRST);
 

+ 1 - 1
Source/Urho3D/AngelScript/Generated_Members.h

@@ -5129,7 +5129,7 @@ template <class T> void RegisterMembers_StringHash(asIScriptEngine* engine, cons
     // bool StringHash::operator <(const StringHash& rhs) const
     engine->RegisterObjectMethod(className, "int opCmp(const StringHash& in) const", AS_FUNCTION_OBJFIRST(StringHash_bool_operatorles_constspStringHashamp<T>), AS_CALL_CDECL_OBJFIRST);
 
-    // static unsigned StringHash::Calculate(const char* str, unsigned hash = 0)
+    // static constexpr u32 StringHash::Calculate(const char* str, unsigned hash = 0)
     // Error: type "const char*" can not automatically bind
     // static StringHashRegister* StringHash::GetGlobalStringHashRegister()
     // Error: type "StringHashRegister*" can not automatically bind

+ 3 - 17
Source/Urho3D/Math/StringHash.cpp

@@ -22,11 +22,10 @@
 
 #include "../Precompiled.h"
 
-#include "../Math/MathDefs.h"
-#include "../Math/StringHash.h"
 #include "../Container/HashMap.h"
 #include "../Core/StringHashRegister.h"
 #include "../IO/Log.h"
+#include "../Math/StringHash.h"
 
 #include <cstdio>
 
@@ -52,13 +51,13 @@ static StringHashRegister& GetGlobalStringHashRegister()
 
 const StringHash StringHash::ZERO;
 
+#ifdef URHO3D_HASH_DEBUG
 StringHash::StringHash(const char* str) noexcept :
     value_(Calculate(str))
 {
-#ifdef URHO3D_HASH_DEBUG
     Urho3D::GetGlobalStringHashRegister().RegisterString(*this, str);
-#endif
 }
+#endif
 
 StringHash::StringHash(const String& str) noexcept :
     value_(Calculate(str.CString()))
@@ -68,19 +67,6 @@ StringHash::StringHash(const String& str) noexcept :
 #endif
 }
 
-unsigned StringHash::Calculate(const char* str, unsigned hash)
-{
-    if (!str)
-        return hash;
-
-    while (*str)
-    {
-        hash = SDBMHash(hash, (unsigned char)*str++);
-    }
-
-    return hash;
-}
-
 StringHashRegister* StringHash::GetGlobalStringHashRegister()
 {
 #ifdef URHO3D_HASH_DEBUG

+ 30 - 5
Source/Urho3D/Math/StringHash.h

@@ -23,6 +23,7 @@
 #pragma once
 
 #include "../Container/Str.h"
+#include "../Math/MathDefs.h"
 
 namespace Urho3D
 {
@@ -34,8 +35,8 @@ class URHO3D_API StringHash
 {
 public:
     /// Construct with zero value.
-    StringHash() noexcept :
-        value_(0)
+    StringHash() noexcept
+        : value_(0)
     {
     }
 
@@ -43,13 +44,21 @@ public:
     StringHash(const StringHash& rhs) noexcept = default;
 
     /// Construct with an initial value.
-    explicit StringHash(unsigned value) noexcept :
-        value_(value)
+    constexpr explicit StringHash(unsigned value) noexcept
+        : value_(value)
     {
     }
 
+#ifdef URHO3D_HASH_DEBUG
     /// Construct from a C string.
     StringHash(const char* str) noexcept;        // NOLINT(google-explicit-constructor)
+#else
+    constexpr StringHash(const char* str) noexcept
+        : value_(Calculate(str))
+    {
+    }
+#endif
+                                                 
     /// Construct from a string.
     StringHash(const String& str) noexcept;      // NOLINT(google-explicit-constructor)
 
@@ -100,7 +109,18 @@ public:
     unsigned ToHash() const { return value_; }
 
     /// Calculate hash value from a C string.
-    static unsigned Calculate(const char* str, unsigned hash = 0);
+    static constexpr u32 Calculate(const char* str, unsigned hash = 0)
+    {
+        if (!str)
+            return hash;
+
+        while (*str)
+        {
+            hash = SDBMHash(hash, (unsigned char)*str++);
+        }
+
+        return hash;
+    }
 
     /// Get global StringHashRegister. Use for debug purposes only. Return nullptr if URHO3D_HASH_DEBUG is off.
     static StringHashRegister* GetGlobalStringHashRegister();
@@ -113,4 +133,9 @@ private:
     unsigned value_;
 };
 
+constexpr StringHash operator ""_hash(const char* str, size_t)
+{
+    return StringHash(StringHash::Calculate(str));
+}
+
 }