Skip to content
Snippets Groups Projects
Commit bdf77bbd authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: simplify hashing overloads of string-types

- this revises the changes made in 95cd8ee7 to replace the
  SFINAE-type of handling of string hashes with direct definitions.

  This places a bit more burden on the developer if creating hashable
  classes derived from std::string or variants of Foam::string, but
  improves reliability when linking.

STYLE: drop template key defaulting from HashSet

- this was never used and `HashSet<>` is much less transparent
  than writing `HashSet<word>` or `wordHashSet`
parent 939c3355
Branches
Tags
No related merge requests found
Showing with 116 additions and 66 deletions
......@@ -52,7 +52,7 @@ Typedef
Foam::wordHashSet
Description
A HashSet with (the default) word keys.
A HashSet with word keys and string hasher.
Typedef
Foam::labelHashSet
......@@ -75,12 +75,22 @@ namespace Foam
// Forward Declarations
template<class T> class MinMax;
template<class Key, class Hash> class HashSet;
// Common hash-set types
//- A HashSet of words, uses string hasher.
typedef HashSet<word, Hash<word>> wordHashSet;
//- A HashSet of labels, uses label hasher.
typedef HashSet<label, Hash<label>> labelHashSet;
/*---------------------------------------------------------------------------*\
Class HashSet Declaration
\*---------------------------------------------------------------------------*/
template<class Key=word, class Hash=Foam::Hash<Key>>
template<class Key, class Hash=Foam::Hash<Key>>
class HashSet
:
public HashTable<zero::null, Key, Hash>
......@@ -401,14 +411,7 @@ public:
};
// Typedefs
//- A HashSet with word keys.
typedef HashSet<word> wordHashSet;
//- A HashSet with label keys and label hasher.
typedef HashSet<label, Hash<label>> labelHashSet;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Global Functions
......
......@@ -39,9 +39,10 @@ Description
namespace Foam
{
template<class Key, class Hash> class HashSet;
template<class T, class Key, class Hash> class HashTable;
template<class T, class Key, class Hash> class HashPtrTable;
template<class Key, class Hash> class HashSet;
template<class T> class Map;
template<class T> class PtrMap;
......
......@@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Original code Copyright (C) 2012-2018 Bernhard Gschaider
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2012-2018 Bernhard Gschaider
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -65,7 +65,7 @@ public:
// Constructors
//- Construct null
//- Default construct
exprString() = default;
//- Copy construct
......@@ -189,6 +189,16 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for exprString is the same as string
template<> struct Hash<expressions::exprString> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -30,12 +30,9 @@ Class
Description
Hash function class.
The default definition is for primitives.
Non-primitives used to hash entries on hash tables will likely need
Non-primitives used to hash entries on hash tables will need
a specialized version.
Note
The second template parameter (bool) is used for SFINAE overloading,
\*---------------------------------------------------------------------------*/
#ifndef Hash_H
......@@ -43,8 +40,6 @@ Note
#include "Hasher.H"
#include <cstdint>
#include <string>
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -55,7 +50,7 @@ namespace Foam
Class Hash Declaration
\*---------------------------------------------------------------------------*/
template<class T, class SFINAEType=bool>
template<class T>
struct Hash
{
unsigned operator()(const T& obj, unsigned seed=0) const
......@@ -67,35 +62,7 @@ struct Hash
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specialization for trivial (integer) types
#undef FOAM_INTHASHER
#define FOAM_INTHASHER(IntType) \
/*! \brief Hashing specialization for IntType */ \
/*! Unseeded (single value) uses natural order, otherwise incremental */ \
template<> struct Hash<IntType> \
{ \
unsigned operator()(const IntType val) const \
{ \
return static_cast<unsigned>(val); \
} \
unsigned operator()(const IntType val, unsigned seed) const \
{ \
return Foam::Hasher(&val, sizeof(IntType), seed); \
} \
}
FOAM_INTHASHER(bool);
FOAM_INTHASHER(char);
FOAM_INTHASHER(int32_t);
FOAM_INTHASHER(int64_t);
FOAM_INTHASHER(uint32_t);
#undef FOAM_INTHASHER
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing specialization for nullptr. Always 0
//- Hashing of nullptr, always 0
template<>
struct Hash<std::nullptr_t>
{
......@@ -105,7 +72,7 @@ struct Hash<std::nullptr_t>
}
};
//- Hashing specialization for pointers, interpret pointer as a integer type
//- Hashing of pointers, treat as unsigned integer
template<>
struct Hash<void*>
{
......@@ -119,20 +86,32 @@ struct Hash<void*>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing partial specialization for derived string types
template<class StringType>
struct Hash
<
StringType,
typename std::enable_if
<std::is_base_of<std::string, StringType>::value, bool>::type
>
{
unsigned operator()(const std::string& str, unsigned seed=0) const
{
return Foam::Hasher(str.data(), str.length(), seed);
// Specialization for common integral types
#undef FOAM_HASH_SPECIALIZATION
#define FOAM_HASH_SPECIALIZATION(Type) \
\
/*! \brief Hashing of integral type: Type */ \
/*! Unseeded (single value) uses natural order, otherwise incremental */ \
template<> \
struct Hash<Type> \
{ \
unsigned operator()(const Type val) const \
{ \
return static_cast<unsigned>(val); \
} \
unsigned operator()(const Type val, unsigned seed) const \
{ \
return Foam::Hasher(&val, sizeof(Type), seed); \
} \
}
};
FOAM_HASH_SPECIALIZATION(bool);
FOAM_HASH_SPECIALIZATION(char);
FOAM_HASH_SPECIALIZATION(int32_t);
FOAM_HASH_SPECIALIZATION(int64_t);
FOAM_HASH_SPECIALIZATION(uint32_t);
#undef FOAM_HASH_SPECIALIZATION
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -58,10 +58,15 @@ namespace Foam
// Forward Declarations
class fileName;
class token;
template<class T> class List;
template<class T> class UList;
typedef List<word> wordList;
//- Hashing for fileName
template<> struct Hash<fileName> : string::hasher {};
/*---------------------------------------------------------------------------*\
Class fileName Declaration
\*---------------------------------------------------------------------------*/
......
......@@ -58,6 +58,10 @@ class token;
Istream& operator>>(Istream& is, keyType& val);
Ostream& operator<<(Ostream& os, const keyType& val);
//- Hashing for keyType
template<> struct Hash<keyType> : string::hasher {};
/*---------------------------------------------------------------------------*\
Class keyType Declaration
\*---------------------------------------------------------------------------*/
......@@ -237,6 +241,8 @@ public:
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
//- Read operator
......
......@@ -62,11 +62,14 @@ namespace Foam
{
// Forward Declarations
class string;
class word;
class wordRe;
class Istream;
class Ostream;
template<class T> struct Hash;
/*---------------------------------------------------------------------------*\
Class string Declaration
\*---------------------------------------------------------------------------*/
......@@ -150,7 +153,8 @@ public:
}
};
//- Hashing functor for string and derived string classes
//- Deprecated hashing functor - use hasher
// \deprecated(2021-04) - use hasher
struct hash : string::hasher {};
......@@ -333,6 +337,17 @@ public:
};
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
//- Hashing for Foam::string
template<> struct Hash<string> : string::hasher {};
//- Hashing for std:::string
template<> struct Hash<std::string> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
//- Read operator
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -55,6 +55,10 @@ class word;
Istream& operator>>(Istream& is, word& val);
Ostream& operator<<(Ostream& os, const word& val);
//- Hashing for word
template<> struct Hash<word> : string::hasher {};
/*---------------------------------------------------------------------------*\
Class word Declaration
\*---------------------------------------------------------------------------*/
......@@ -204,6 +208,8 @@ public:
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
//- Read operator
......
......@@ -70,6 +70,10 @@ class wordRe;
Istream& operator>>(Istream& is, wordRe& val);
Ostream& operator<<(Ostream& os, const wordRe& val);
//- Hashing for wordRe
template<> struct Hash<wordRe> : string::hasher {};
/*---------------------------------------------------------------------------*\
Class wordRe Declaration
\*---------------------------------------------------------------------------*/
......@@ -249,6 +253,8 @@ public:
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
//- Read operator
......
......@@ -106,6 +106,15 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensight
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for FileName is the same as string
template<> struct Hash<ensight::FileName> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -104,6 +104,16 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensight
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for VarName is the same as string
template<> struct Hash<ensight::VarName> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment