ENH: simplify hashing overloads of string-types

- this revises the changes made in 95cd8ee75c 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`
This commit is contained in:
Mark Olesen
2021-12-03 12:51:31 +01:00
parent 939c335504
commit bdf77bbdd1
11 changed files with 116 additions and 66 deletions

View File

@ -52,7 +52,7 @@ Typedef
Foam::wordHashSet Foam::wordHashSet
Description Description
A HashSet with (the default) word keys. A HashSet with word keys and string hasher.
Typedef Typedef
Foam::labelHashSet Foam::labelHashSet
@ -75,12 +75,22 @@ namespace Foam
// Forward Declarations // Forward Declarations
template<class T> class MinMax; 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 Class HashSet Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class Key=word, class Hash=Foam::Hash<Key>> template<class Key, class Hash=Foam::Hash<Key>>
class HashSet class HashSet
: :
public HashTable<zero::null, Key, Hash> 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 // Global Functions

View File

@ -39,9 +39,10 @@ Description
namespace Foam 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 HashTable;
template<class T, class Key, class Hash> class HashPtrTable; 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 Map;
template<class T> class PtrMap; template<class T> class PtrMap;

View File

@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Original code Copyright (C) 2012-2018 Bernhard Gschaider Copyright (C) 2012-2018 Bernhard Gschaider
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -65,7 +65,7 @@ public:
// Constructors // Constructors
//- Construct null //- Default construct
exprString() = default; exprString() = default;
//- Copy construct //- Copy construct
@ -189,6 +189,16 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace expressions } // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for exprString is the same as string
template<> struct Hash<expressions::exprString> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -30,12 +30,9 @@ Class
Description Description
Hash function class. Hash function class.
The default definition is for primitives. 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. a specialized version.
Note
The second template parameter (bool) is used for SFINAE overloading,
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Hash_H #ifndef Hash_H
@ -43,8 +40,6 @@ Note
#include "Hasher.H" #include "Hasher.H"
#include <cstdint> #include <cstdint>
#include <string>
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,7 +50,7 @@ namespace Foam
Class Hash Declaration Class Hash Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class T, class SFINAEType=bool> template<class T>
struct Hash struct Hash
{ {
unsigned operator()(const T& obj, unsigned seed=0) const unsigned operator()(const T& obj, unsigned seed=0) const
@ -67,35 +62,7 @@ struct Hash
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specialization for trivial (integer) types //- Hashing of nullptr, always 0
#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
template<> template<>
struct Hash<std::nullptr_t> 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<> template<>
struct Hash<void*> struct Hash<void*>
{ {
@ -119,20 +86,32 @@ struct Hash<void*>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing partial specialization for derived string types // Specialization for common integral types
template<class StringType>
struct Hash #undef FOAM_HASH_SPECIALIZATION
< #define FOAM_HASH_SPECIALIZATION(Type) \
StringType, \
typename std::enable_if /*! \brief Hashing of integral type: Type */ \
<std::is_base_of<std::string, StringType>::value, bool>::type /*! Unseeded (single value) uses natural order, otherwise incremental */ \
> template<> \
{ struct Hash<Type> \
unsigned operator()(const std::string& str, unsigned seed=0) const { \
{ unsigned operator()(const Type val) const \
return Foam::Hasher(str.data(), str.length(), seed); { \
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
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -58,10 +58,15 @@ namespace Foam
// Forward Declarations // Forward Declarations
class fileName; class fileName;
class token; class token;
template<class T> class List; template<class T> class List;
template<class T> class UList; template<class T> class UList;
typedef List<word> wordList; typedef List<word> wordList;
//- Hashing for fileName
template<> struct Hash<fileName> : string::hasher {};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class fileName Declaration Class fileName Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

View File

@ -58,6 +58,10 @@ class token;
Istream& operator>>(Istream& is, keyType& val); Istream& operator>>(Istream& is, keyType& val);
Ostream& operator<<(Ostream& os, const keyType& val); Ostream& operator<<(Ostream& os, const keyType& val);
//- Hashing for keyType
template<> struct Hash<keyType> : string::hasher {};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class keyType Declaration Class keyType Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -237,6 +241,8 @@ public:
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators // IOstream Operators
//- Read operator //- Read operator

View File

@ -62,11 +62,14 @@ namespace Foam
{ {
// Forward Declarations // Forward Declarations
class string;
class word; class word;
class wordRe; class wordRe;
class Istream; class Istream;
class Ostream; class Ostream;
template<class T> struct Hash;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class string Declaration 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 {}; 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 // IOstream Operators
//- Read operator //- Read operator

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -55,6 +55,10 @@ class word;
Istream& operator>>(Istream& is, word& val); Istream& operator>>(Istream& is, word& val);
Ostream& operator<<(Ostream& os, const word& val); Ostream& operator<<(Ostream& os, const word& val);
//- Hashing for word
template<> struct Hash<word> : string::hasher {};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class word Declaration Class word Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -204,6 +208,8 @@ public:
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators // IOstream Operators
//- Read operator //- Read operator

View File

@ -70,6 +70,10 @@ class wordRe;
Istream& operator>>(Istream& is, wordRe& val); Istream& operator>>(Istream& is, wordRe& val);
Ostream& operator<<(Ostream& os, const wordRe& val); Ostream& operator<<(Ostream& os, const wordRe& val);
//- Hashing for wordRe
template<> struct Hash<wordRe> : string::hasher {};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class wordRe Declaration Class wordRe Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -249,6 +253,8 @@ public:
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators // IOstream Operators
//- Read operator //- Read operator

View File

@ -106,6 +106,15 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensight } // End namespace ensight
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for FileName is the same as string
template<> struct Hash<ensight::FileName> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -104,6 +104,16 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensight } // End namespace ensight
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for VarName is the same as string
template<> struct Hash<ensight::VarName> : string::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //