Familyid In C Implementations

Family ID generation

In my implementation of an entity system every component has a family id:

struct CompPosition3D : public Component {
   static const FamilyId familyId = 1;
   CompPosition3D() : x(0), y(0), z(0) {}
   float x,y,z;
};
struct CompPosition3DTemporary : public Component {
   static const FamilyId familyId = 2;
   CompPosition3DTemporary() : x(0), y(0), z(0) {}
   float x,y,z;
};

Inserting numbers directly is working, but is unmaintainable in bigger projects, so a better solution is to use hash values and a much better solution is to generate the hash value at compile time out of a string. I have found a solution to this on the humus webpage (and improvements by Aslan Dzodzikov).

The following does only work on vs2008 and upwards:

class FixedStringHash { 
   //from Aslan Dzodzikov
   //taken from http://www.humus.name/index.php?page=Comments&ID=296&start=16
   //  void PrintHash(const FixedStringHash& _hash) { 
   //    printf( "%x", (unsigned)_hash ); 
   //  } 
   //  PrintHash("Creating Device! Just a test for StringHash"); 
   //this version seems to work only in vs2008 and above :/
   unsigned m_val; 

   template<size_t N> unsigned _Hash(const char (&str)[N]) { 
      typedef const char (&truncated_str)[N-1]; 
      return str[N-1] + 65599 * _Hash((truncated_str)str); 
   } 
   unsigned _Hash(const char (&str)[2]) { return str[1] + 65599 * str[0]; } 
public: 
   template <size_t N> FixedStringHash(const char (&str)[N]) { 
      m_val = _Hash(str); 
   } 
   operator unsigned() { 
      return m_val; 
   } 
};

and the following is working on every visual studio version:

class FixedStringHash {
   //taken from www.humus.name
   uint32_t mHash;
public:
   FixedStringHash(const char (&str)[3]) {
      uint32_t hash1 = str[0];
      mHash          = hash1 * 65599 + str[1];
   }
   FixedStringHash(const char (&str)[4]) {
      uint32_t hash1 = str[0];
      uint32_t hash2 = hash1 * 65599 + str[1];
      mHash          = hash2 * 65599 + str[2];
   }
   FixedStringHash(const char (&str)[5]) {
      uint32_t hash1 = str[0];
      uint32_t hash2 = hash1 * 65599 + str[1];
      uint32_t hash3 = hash2 * 65599 + str[2];
      mHash          = hash3 * 65599 + str[3];
   }
   // ... for longer strings
   operator unsigned() {
      return mHash;
   }
};