STYLE: adjustments to HashSet, HashTable

- use HashTable emplace instead of insert to avoid unneeded argument
  (for HashSet).

- use emplace when generating zero-initialized values for
  HashTable::operator()

- drop unused parameter from Detail::HashTableSingle,
  adjust templates parameter names

- forward HashTable::operator[] to the semantically identical
  HashTable::at() to avoid code duplication
This commit is contained in:
Mark Olesen
2019-09-27 14:52:52 +02:00
committed by Andrew Heather
parent 8a75bdb12f
commit 0840bfdcb8
4 changed files with 32 additions and 55 deletions

View File

@ -181,7 +181,7 @@ public:
// not previously exist in the set. // not previously exist in the set.
bool insert(const Key& key) bool insert(const Key& key)
{ {
return this->parent_type::insert(key, zero::null()); return this->parent_type::emplace(key);
} }
//- Same as insert (no value to overwrite) //- Same as insert (no value to overwrite)

View File

@ -120,8 +120,8 @@ class HashTable
typedef typename std::conditional typedef typename std::conditional
< <
std::is_same<zero::null, typename std::remove_cv<T>::type>::value, std::is_same<zero::null, typename std::remove_cv<T>::type>::value,
Detail::HashTableSingle<T, Key>, Detail::HashTableSingle<Key>,
Detail::HashTablePair<T, Key> Detail::HashTablePair<Key, T>
>::type node_type; >::type node_type;
@ -835,7 +835,7 @@ public:
}; };
//- Iterating over keys only // Iterator (keys)
//- An iterator wrapper for returning a reference to the key //- An iterator wrapper for returning a reference to the key
template<class Iter> template<class Iter>

View File

@ -56,17 +56,14 @@ namespace Detail
Class isPointer Declaration Class isPointer Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
//- Test for pointer-like behaviour //- Pointer-like behaviour
template<class T> template<class T> struct isPointer : std::is_pointer<T> {};
struct isPointer : public std::is_pointer<T> {};
//- An autoPtr is pointer-like //- Pointer-like behaviour for autoPtr
template<class T> template<class T> struct isPointer<autoPtr<T>> : std::true_type {};
struct isPointer<autoPtr<T>> : public std::true_type {};
//- A unique_ptr is pointer-like //- Pointer-like behaviour for std::unique_ptr
template<class T> template<class T> struct isPointer<std::unique_ptr<T>> : std::true_type {};
struct isPointer<std::unique_ptr<T>> : public std::true_type {};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -77,16 +74,16 @@ struct isPointer<std::unique_ptr<T>> : public std::true_type {};
// Structure with a (K,V) tuple and a linked-list for collisions // Structure with a (K,V) tuple and a linked-list for collisions
// Could store key/val as std::pair, but no particular advantage // Could store key/val as std::pair, but no particular advantage
// unless the iterator dereference type changes. // unless the iterator dereference type changes.
template<class T, class Key> template<class K, class V>
struct HashTablePair struct HashTablePair
{ {
// Types // Types
//- Type of key //- Type of key
typedef Key key_type; typedef K key_type;
//- Type of content //- Type of content
typedef T mapped_type; typedef V mapped_type;
//- This struct stores a value //- This struct stores a value
static constexpr bool stores_value() static constexpr bool stores_value()
@ -150,7 +147,7 @@ struct HashTablePair
} }
//- Write (key, val) pair - for pointer types //- Write (key, val) pair - for pointer types
template<class TypeT = T> template<class TypeT = V>
typename std::enable_if<Detail::isPointer<TypeT>::value, void>::type typename std::enable_if<Detail::isPointer<TypeT>::value, void>::type
print(Ostream& os) const print(Ostream& os) const
{ {
@ -163,7 +160,7 @@ struct HashTablePair
} }
//- Write (key, val) pair - for non-pointer types //- Write (key, val) pair - for non-pointer types
template<class TypeT = T> template<class TypeT = V>
typename std::enable_if<!Detail::isPointer<TypeT>::value, void>::type typename std::enable_if<!Detail::isPointer<TypeT>::value, void>::type
print(Ostream& os) const print(Ostream& os) const
{ {
@ -178,13 +175,13 @@ struct HashTablePair
//- Internal storage type for HashSet entries //- Internal storage type for HashSet entries
// Structure with a single (K) value and a linked-list for collisions // Structure with a single (K) value and a linked-list for collisions
template<class T, class Key> template<class K>
struct HashTableSingle struct HashTableSingle
{ {
// Types // Types
//- Type of key //- Type of key
typedef Key key_type; typedef K key_type;
//- Type of content //- Type of content
typedef Foam::zero::null mapped_type; typedef Foam::zero::null mapped_type;

View File

@ -64,7 +64,7 @@ inline bool Foam::HashTable<T, Key, Hash>::empty() const
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline T& Foam::HashTable<T, Key, Hash>::at(const Key& key) inline T& Foam::HashTable<T, Key, Hash>::at(const Key& key)
{ {
const iterator iter(this->find(key)); iterator iter(this->find(key));
if (!iter.good()) if (!iter.good())
{ {
@ -166,10 +166,10 @@ template<class T, class Key, class Hash>
inline bool Foam::HashTable<T, Key, Hash>::insert inline bool Foam::HashTable<T, Key, Hash>::insert
( (
const Key& key, const Key& key,
const T& val const T& obj
) )
{ {
return this->setEntry(false, key, val); return this->setEntry(false, key, obj);
} }
@ -177,10 +177,10 @@ template<class T, class Key, class Hash>
inline bool Foam::HashTable<T, Key, Hash>::insert inline bool Foam::HashTable<T, Key, Hash>::insert
( (
const Key& key, const Key& key,
T&& val T&& obj
) )
{ {
return this->setEntry(false, key, std::forward<T>(val)); return this->setEntry(false, key, std::forward<T>(obj));
} }
@ -188,10 +188,10 @@ template<class T, class Key, class Hash>
inline bool Foam::HashTable<T, Key, Hash>::set inline bool Foam::HashTable<T, Key, Hash>::set
( (
const Key& key, const Key& key,
const T& val const T& obj
) )
{ {
return this->setEntry(true, key, val); // Overwrite return this->setEntry(true, key, obj); // Overwrite
} }
@ -199,10 +199,10 @@ template<class T, class Key, class Hash>
inline bool Foam::HashTable<T, Key, Hash>::set inline bool Foam::HashTable<T, Key, Hash>::set
( (
const Key& key, const Key& key,
T&& val T&& obj
) )
{ {
return this->setEntry(true, key, std::forward<T>(val)); // Overwrite return this->setEntry(true, key, std::forward<T>(obj)); // Overwrite
} }
@ -223,48 +223,28 @@ inline const T& Foam::HashTable<T, Key, Hash>::lookup
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
{ {
const iterator iter(this->find(key)); return this->at(key);
if (!iter.good())
{
FatalErrorInFunction
<< key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
return iter.val();
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
{ {
const const_iterator iter(this->cfind(key)); return this->at(key);
if (!iter.good())
{
FatalErrorInFunction
<< key << " not found in table. Valid entries: "
<< toc()
<< exit(FatalError);
}
return iter.val();
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key) inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
{ {
const iterator iter(this->find(key)); iterator iter(this->find(key));
if (iter.good()) if (iter.good())
{ {
return iter.val(); return iter.val();
} }
this->insert(key, mapped_type()); this->emplace(key);
return find(key).val(); return find(key).val();
} }
@ -276,7 +256,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()
const T& deflt const T& deflt
) )
{ {
const iterator iter(this->find(key)); iterator iter(this->find(key));
if (iter.good()) if (iter.good())
{ {