AC_DEFINE([HASH_MAP_CLASS],[HASH_MAP_NAMESPACE::unordered_map],[The template name for unordered maps.])
AC_DEFINE([HASH_MAP_H],[<tr1/unordered_map>],[The header file to include for unordered maps.])
AC_DEFINE([HASH_MAP_NAMESPACE],[std::tr1],[The namespace for unordered maps.])
+ AC_DEFINE([FUNCTIONAL_H],[<tr1/functional>],[The header file for hash<T>.])
+ AC_DEFINE([FUNCTIONAL_HASH_ON_STRING],[1],[Define to 1 if hash<T> needs to use T=String rather than T=char* to hash strings.])
],[
AC_MSG_RESULT([no])
AC_CHECK_HEADERS([ext/hash_map],[
AC_DEFINE([HASH_MAP_CLASS],[HASH_MAP_NAMESPACE::hash_map],[The template name for unordered maps.])
AC_DEFINE([HASH_MAP_H],[<ext/hash_map>],[The header file to include for unordered maps.])
AC_DEFINE([HASH_MAP_NAMESPACE],[__gnu_cxx],[The namespace for unordered maps.])
+ AC_DEFINE([FUNCTIONAL_H],[<ext/functional>],[The header file for hash<T>.])
],[
AC_MSG_ERROR([C++ compiler does not seem to support unordered containers])
])
/* === H E A D E R S ======================================================= */
-#define SUBTRACT_RNG_H <ext/functional>
-
#ifdef USING_PCH
# include "pch.h"
#else
#ifdef HASH_MAP_H
#include HASH_MAP_H
-#endif
-
-#ifdef SUBTRACT_RNG_H
-#include SUBTRACT_RNG_H
-using namespace __gnu_cxx;
+#include FUNCTIONAL_H
#endif
#ifdef _WIN32
synfig::GUID::hasher(const String& str)
{
#ifdef HASH_MAP_H
+ /* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html says:
+ *
+ * "Some earlier hash table implementations gave char* special
+ * treatment: it specialized the default hash function to look
+ * at character array being pointed to, rather than the pointer
+ * itself. This proposal removes that special treatment."
+ *
+ * Unfortunately, the older implementation doesn't seem to want to
+ * accept Strings, so we're left with this conditional compilation.
+ */
+# ifdef FUNCTIONAL_HASH_ON_STRING
+ HASH_MAP_NAMESPACE::hash<const String&> string_hash_;
+ const unsigned int seed(string_hash_(str));
+# else // FUNCTIONAL_HASH_ON_STRING
HASH_MAP_NAMESPACE::hash<const char*> string_hash_;
- const unsigned int seed(
- string_hash_(
- str.c_str()
- )
- );
-#else
+ const unsigned int seed(string_hash_(str.c_str()));
+# endif // FUNCTIONAL_HASH_ON_STRING
+#else // HASH_MAP_H
unsigned int seed(0x3B642879);
for(unsigned int i=0;i<str.size();i++)
{
seed^=(seed*str[i])*i;
seed=(seed>>(32-(i%24)))^(seed<<(i%24));
}
-#endif
+#endif // HASH_MAP_H
GUID_RNG random(seed);
GUID ret(0);
AC_DEFINE([HASH_MAP_CLASS],[HASH_MAP_NAMESPACE::unordered_map],[The template name for unordered maps.])
AC_DEFINE([HASH_MAP_H],[<tr1/unordered_map>],[The header file to include for unordered maps.])
AC_DEFINE([HASH_MAP_NAMESPACE],[std::tr1],[The namespace for unordered maps.])
+ AC_DEFINE([FUNCTIONAL_H],[<tr1/functional>],[The header file for hash<T>.])
+ AC_DEFINE([FUNCTIONAL_HASH_ON_STRING],[1],[Define to 1 if hash<T> needs to use T=String rather than T=char* to hash strings.])
],[
AC_MSG_RESULT([no])
AC_CHECK_HEADERS([ext/hash_map],[
AC_DEFINE([HASH_MAP_CLASS],[HASH_MAP_NAMESPACE::hash_map],[The template name for unordered maps.])
AC_DEFINE([HASH_MAP_H],[<ext/hash_map>],[The header file to include for unordered maps.])
AC_DEFINE([HASH_MAP_NAMESPACE],[__gnu_cxx],[The namespace for unordered maps.])
+ AC_DEFINE([FUNCTIONAL_H],[<ext/functional>],[The header file for hash<T>.])
],[
AC_MSG_ERROR([C++ compiler does not seem to support unordered containers])
])
#ifdef HASH_MAP_H
#include HASH_MAP_H
+#include FUNCTIONAL_H
+
#ifndef __STRING_HASH__
#define __STRING_HASH__
class StringHash
{
+# ifdef FUNCTIONAL_HASH_ON_STRING
+ HASH_MAP_NAMESPACE::hash<const synfig::String&> hasher_;
+# else // FUNCTIONAL_HASH_ON_STRING
HASH_MAP_NAMESPACE::hash<const char*> hasher_;
+# endif // FUNCTIONAL_HASH_ON_STRING
public:
size_t operator()(const synfig::String& x)const
{
+# ifdef FUNCTIONAL_HASH_ON_STRING
+ return hasher_(x);
+# else // FUNCTIONAL_HASH_ON_STRING
return hasher_(x.c_str());
+# endif // FUNCTIONAL_HASH_ON_STRING
}
};
#endif
#ifdef HASH_MAP_H
#include HASH_MAP_H
+#include FUNCTIONAL_H
+
#ifndef __STRING_HASH__
#define __STRING_HASH__
class StringHash
{
+# ifdef FUNCTIONAL_HASH_ON_STRING
+ HASH_MAP_NAMESPACE::hash<const synfig::String&> hasher_;
+# else // FUNCTIONAL_HASH_ON_STRING
HASH_MAP_NAMESPACE::hash<const char*> hasher_;
+# endif // FUNCTIONAL_HASH_ON_STRING
public:
size_t operator()(const synfig::String& x)const
{
+# ifdef FUNCTIONAL_HASH_ON_STRING
+ return hasher_(x);
+# else // FUNCTIONAL_HASH_ON_STRING
return hasher_(x.c_str());
+# endif // FUNCTIONAL_HASH_ON_STRING
}
};
#endif