mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: additional HashTable emplace/insert/set methods (#1286)
- support move insert/set and emplace insertion. These adjustments can be used for improved memory efficiency, and allow hash tables of non-copyable objects (eg, std::unique_ptr). - extend special HashTable output treatment to include pointer-like objects such as autoPtr and unique_ptr. ENH: HashTable::at() method with checking. Fatal if entry does not exist.
This commit is contained in:
committed by
Andrew Heather
parent
e30dc962b3
commit
ac317699d8
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011 OpenFOAM Foundation
|
| Copyright (C) 2011 OpenFOAM Foundation
|
||||||
@ -25,9 +25,9 @@ License
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "autoPtr.H"
|
#include "autoPtr.H"
|
||||||
#include "HashPtrTable.H"
|
#include "HashPtrTable.H"
|
||||||
@ -56,14 +56,14 @@ void printTable(const HashPtrTable<T>& table)
|
|||||||
|
|
||||||
Info<< ")" << endl;
|
Info<< ")" << endl;
|
||||||
|
|
||||||
// Values only, with for-range
|
// Iterate across values, with for-range
|
||||||
Info<< "values (";
|
Info<< "values (";
|
||||||
for (auto val : table)
|
for (const auto& ptr : table)
|
||||||
{
|
{
|
||||||
Info<< ' ';
|
Info<< ' ';
|
||||||
if (val)
|
if (ptr)
|
||||||
{
|
{
|
||||||
Info<< *val;
|
Info<< *ptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -86,8 +86,27 @@ int main()
|
|||||||
myTable.set("natlog", new double(2.718282));
|
myTable.set("natlog", new double(2.718282));
|
||||||
myTable.insert("sqrt2", autoPtr<double>::New(1.414214));
|
myTable.insert("sqrt2", autoPtr<double>::New(1.414214));
|
||||||
|
|
||||||
|
HashTable<std::unique_ptr<double>, word, string::hash> myTable1;
|
||||||
|
|
||||||
|
myTable1.set("abc", std::unique_ptr<double>(new double(42.1)));
|
||||||
|
myTable1.set("pi", std::unique_ptr<double>(new double(3.14159)));
|
||||||
|
myTable1.set("natlog", std::unique_ptr<double>(new double(2.718282)));
|
||||||
|
|
||||||
|
HashTable<autoPtr<double>, word, string::hash> myTable2;
|
||||||
|
|
||||||
|
myTable2.set("abc", autoPtr<double>(new double(42.1)));
|
||||||
|
myTable2.set("pi", autoPtr<double>(new double(3.14159)));
|
||||||
|
myTable2.set("natlog", autoPtr<double>(new double(2.718282)));
|
||||||
|
myTable2.insert("sqrt2", autoPtr<double>::New(1.414214));
|
||||||
|
|
||||||
// Info<< myTable << endl;
|
// Info<< myTable << endl;
|
||||||
printTable(myTable);
|
printTable(myTable);
|
||||||
|
Info<< myTable2 << nl;
|
||||||
|
|
||||||
|
auto iter2 = myTable2.find("pi");
|
||||||
|
|
||||||
|
Info<<"PI: " << **iter2 << nl;
|
||||||
|
|
||||||
|
|
||||||
HashPtrTable<double> copy(myTable);
|
HashPtrTable<double> copy(myTable);
|
||||||
|
|
||||||
|
|||||||
@ -249,6 +249,28 @@ int main(int argc, char *argv[])
|
|||||||
Info<< nl << "Ending scope" << nl;
|
Info<< nl << "Ending scope" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Info<< nl << "Table<labelList> copy/move/emplace insertion" << nl;
|
||||||
|
|
||||||
|
HashTable<labelList> ltable1(0);
|
||||||
|
ltable1.insert("abc", identity(2));
|
||||||
|
ltable1.insert("def", identity(3));
|
||||||
|
ltable1.insert("ghi", identity(4));
|
||||||
|
ltable1.emplace("jkl", 10, -35);
|
||||||
|
ltable1.emplace("mno");
|
||||||
|
|
||||||
|
labelList list1(identity(4, -4));
|
||||||
|
|
||||||
|
Info<<"move insert " << list1 << nl;
|
||||||
|
|
||||||
|
ltable1.insert("pqr", std::move(list1));
|
||||||
|
|
||||||
|
Info<<"after insert " << list1 << nl;
|
||||||
|
|
||||||
|
Info<< nl << "HashTable<labelList>: "
|
||||||
|
<< ltable1 << nl;
|
||||||
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -145,15 +145,15 @@ int main(int argc, char *argv[])
|
|||||||
const label nElem = 1000000;
|
const label nElem = 1000000;
|
||||||
|
|
||||||
argList::noBanner();
|
argList::noBanner();
|
||||||
argList::addBoolOption("std", "use std::unordered_map or std::set");
|
|
||||||
argList::addBoolOption("set", "test HashSet");
|
|
||||||
argList::addBoolOption("find", "test find");
|
argList::addBoolOption("find", "test find");
|
||||||
|
argList::addBoolOption("set", "test HashSet");
|
||||||
|
argList::addBoolOption("std", "std::unordered_map or std::unordered_set");
|
||||||
|
|
||||||
argList args(argc, argv);
|
argList args(argc, argv);
|
||||||
|
|
||||||
const bool optStd = args.found("std");
|
|
||||||
const bool optSet = args.found("set");
|
|
||||||
const bool optFnd = args.found("find");
|
const bool optFnd = args.found("find");
|
||||||
|
const bool optSet = args.found("set");
|
||||||
|
const bool optStd = args.found("std");
|
||||||
|
|
||||||
|
|
||||||
cpuTime timer;
|
cpuTime timer;
|
||||||
@ -171,7 +171,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (false)
|
if (false)
|
||||||
{
|
{
|
||||||
// verify that resizing around (0) doesn't fail
|
// Verify that resizing around (0) doesn't fail
|
||||||
HashTable<label, label, Hash<label>> map(32);
|
HashTable<label, label, Hash<label>> map(32);
|
||||||
printInfo(Info, map) << endl;
|
printInfo(Info, map) << endl;
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef ORDERED
|
#ifdef ORDERED
|
||||||
Info<< "using stl::map" << endl;
|
Info<< "using stl::map" << endl;
|
||||||
#else
|
#else
|
||||||
Info<< "using stl::unordered_set" << endl;
|
Info<< "using stl::unordered_map" << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (label loopi = 0; loopi < nLoops; ++loopi)
|
for (label loopi = 0; loopi < nLoops; ++loopi)
|
||||||
|
|||||||
@ -48,17 +48,21 @@ using namespace Foam;
|
|||||||
template<class T, class Key, class Hash> class HashSorter;
|
template<class T, class Key, class Hash> class HashSorter;
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
Ostream& operator<<(Ostream& os, const HashSorter<T, Key, Hash>& sorter);
|
Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const HashSorter<T, Key, Hash>& sorter
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
class HashSorter
|
class HashSorter
|
||||||
{
|
{
|
||||||
const HashTable<T,Key,Hash>& table;
|
const HashTable<T, Key, Hash>& table;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HashSorter(const HashTable<T,Key,Hash>& ht)
|
HashSorter(const HashTable<T, Key, Hash>& ht)
|
||||||
:
|
:
|
||||||
table(ht)
|
table(ht)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward Declarations
|
||||||
class bitSet;
|
class bitSet;
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -143,7 +143,11 @@ struct plusEqOp
|
|||||||
|
|
||||||
//- List of values from HashTable, optionally sorted.
|
//- List of values from HashTable, optionally sorted.
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
List<T> values(const HashTable<T, Key, Hash>& tbl, const bool doSort=false)
|
List<T> values
|
||||||
|
(
|
||||||
|
const HashTable<T, Key, Hash>& tbl,
|
||||||
|
const bool doSort=false
|
||||||
|
)
|
||||||
{
|
{
|
||||||
List<T> output(tbl.size());
|
List<T> output(tbl.size());
|
||||||
|
|
||||||
|
|||||||
@ -422,28 +422,28 @@ public:
|
|||||||
|
|
||||||
//- Combine entries from HashSets
|
//- Combine entries from HashSets
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
HashSet<Key,Hash> operator|
|
HashSet<Key, Hash> operator|
|
||||||
(
|
(
|
||||||
const HashSet<Key,Hash>& hash1,
|
const HashSet<Key, Hash>& hash1,
|
||||||
const HashSet<Key,Hash>& hash2
|
const HashSet<Key, Hash>& hash2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Create a HashSet that only contains entries found in both HashSets
|
//- Create a HashSet that only contains entries found in both HashSets
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
HashSet<Key,Hash> operator&
|
HashSet<Key, Hash> operator&
|
||||||
(
|
(
|
||||||
const HashSet<Key,Hash>& hash1,
|
const HashSet<Key, Hash>& hash1,
|
||||||
const HashSet<Key,Hash>& hash2
|
const HashSet<Key, Hash>& hash2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Create a HashSet that only contains unique entries (xor)
|
//- Create a HashSet that only contains unique entries (xor)
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
HashSet<Key,Hash> operator^
|
HashSet<Key, Hash> operator^
|
||||||
(
|
(
|
||||||
const HashSet<Key,Hash>& hash1,
|
const HashSet<Key, Hash>& hash1,
|
||||||
const HashSet<Key,Hash>& hash2
|
const HashSet<Key, Hash>& hash2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -300,11 +300,12 @@ Foam::label Foam::HashTable<T, Key, Hash>::countEntries
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
|
template<class... Args>
|
||||||
bool Foam::HashTable<T, Key, Hash>::setEntry
|
bool Foam::HashTable<T, Key, Hash>::setEntry
|
||||||
(
|
(
|
||||||
|
const bool overwrite,
|
||||||
const Key& key,
|
const Key& key,
|
||||||
const T& obj,
|
Args&&... args
|
||||||
const bool overwrite
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!capacity_)
|
if (!capacity_)
|
||||||
@ -330,9 +331,10 @@ bool Foam::HashTable<T, Key, Hash>::setEntry
|
|||||||
if (!curr)
|
if (!curr)
|
||||||
{
|
{
|
||||||
// Not found, insert it at the head
|
// Not found, insert it at the head
|
||||||
table_[index] = new node_type(key, obj, table_[index]);
|
table_[index] =
|
||||||
++size_;
|
new node_type(table_[index], key, std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
++size_;
|
||||||
if (double(size_)/capacity_ > 0.8 && capacity_ < maxTableSize)
|
if (double(size_)/capacity_ > 0.8 && capacity_ < maxTableSize)
|
||||||
{
|
{
|
||||||
#ifdef FULLDEBUG
|
#ifdef FULLDEBUG
|
||||||
@ -360,7 +362,7 @@ bool Foam::HashTable<T, Key, Hash>::setEntry
|
|||||||
// or that it behaves the same as a copy construct.
|
// or that it behaves the same as a copy construct.
|
||||||
|
|
||||||
delete curr;
|
delete curr;
|
||||||
ep = new node_type(key, obj, ep);
|
ep = new node_type(ep, key, std::forward<Args>(args)...);
|
||||||
|
|
||||||
// Replace current element - within list or insert at the head
|
// Replace current element - within list or insert at the head
|
||||||
if (prev)
|
if (prev)
|
||||||
@ -838,7 +840,7 @@ bool Foam::HashTable<T, Key, Hash>::operator==
|
|||||||
{
|
{
|
||||||
const const_iterator other(this->cfind(iter.key()));
|
const const_iterator other(this->cfind(iter.key()));
|
||||||
|
|
||||||
if (!other.found() || other.val() != iter.val())
|
if (!other.good() || other.val() != iter.val())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,7 +97,7 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward Declarations
|
||||||
|
|
||||||
template<class T> class List;
|
template<class T> class List;
|
||||||
template<class T> class UList;
|
template<class T> class UList;
|
||||||
@ -155,7 +155,8 @@ class HashTable
|
|||||||
|
|
||||||
//- Assign a new hash-entry to a possibly already existing key.
|
//- Assign a new hash-entry to a possibly already existing key.
|
||||||
// \return True if the new entry was set.
|
// \return True if the new entry was set.
|
||||||
bool setEntry(const Key& key, const T& obj, const bool overwrite);
|
template<class... Args>
|
||||||
|
bool setEntry(const bool overwrite, const Key& key, Args&&... args);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -257,6 +258,12 @@ public:
|
|||||||
//- Return true if the hash table is empty
|
//- Return true if the hash table is empty
|
||||||
inline bool empty() const;
|
inline bool empty() const;
|
||||||
|
|
||||||
|
//- Find and return a hashed entry. FatalError if it does not exist.
|
||||||
|
inline T& at(const Key& key);
|
||||||
|
|
||||||
|
//- Find and return a hashed entry. FatalError if it does not exist.
|
||||||
|
inline const T& at(const Key& key) const;
|
||||||
|
|
||||||
//- Return true if hashed entry is found in table
|
//- Return true if hashed entry is found in table
|
||||||
inline bool found(const Key& key) const;
|
inline bool found(const Key& key) const;
|
||||||
|
|
||||||
@ -361,16 +368,27 @@ public:
|
|||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
//- Insert a new entry, not overwriting existing entries.
|
//- Emplace insert a new entry, not overwriting existing entries.
|
||||||
// \return True if the entry inserted, which means that it did
|
// \return True if the entry did not previously exist in the table.
|
||||||
// not previously exist in the table.
|
template<class... Args>
|
||||||
|
inline bool emplace(const Key& key, Args&&... args);
|
||||||
|
|
||||||
|
//- Copy insert a new entry, not overwriting existing entries.
|
||||||
|
// \return True if the entry did not previously exist in the table.
|
||||||
inline bool insert(const Key& key, const T& obj);
|
inline bool insert(const Key& key, const T& obj);
|
||||||
|
|
||||||
//- Assign a new entry, overwriting existing entries.
|
//- Move insert a new entry, not overwriting existing entries.
|
||||||
//
|
// \return True if the entry did not previously exist in the table.
|
||||||
|
inline bool insert(const Key& key, T&& obj);
|
||||||
|
|
||||||
|
//- Copy assign a new entry, overwriting existing entries.
|
||||||
// \return True, since it always overwrites any entries.
|
// \return True, since it always overwrites any entries.
|
||||||
inline bool set(const Key& key, const T& obj);
|
inline bool set(const Key& key, const T& obj);
|
||||||
|
|
||||||
|
//- Move assign a new entry, overwriting existing entries.
|
||||||
|
// \return True, since it always overwrites any entries.
|
||||||
|
inline bool set(const Key& key, T&& obj);
|
||||||
|
|
||||||
//- Erase an entry specified by given iterator
|
//- Erase an entry specified by given iterator
|
||||||
// This invalidates the iterator until the next ++ operation.
|
// This invalidates the iterator until the next ++ operation.
|
||||||
//
|
//
|
||||||
@ -513,20 +531,20 @@ public:
|
|||||||
inline T& operator()(const Key& key, const T& deflt);
|
inline T& operator()(const Key& key, const T& deflt);
|
||||||
|
|
||||||
//- Copy assign
|
//- Copy assign
|
||||||
void operator=(const HashTable<T, Key, Hash>& rhs);
|
void operator=(const this_type& rhs);
|
||||||
|
|
||||||
//- Copy assign from an initializer list
|
//- Copy assign from an initializer list
|
||||||
void operator=(std::initializer_list<std::pair<Key, T>> rhs);
|
void operator=(std::initializer_list<std::pair<Key, T>> rhs);
|
||||||
|
|
||||||
//- Move assign
|
//- Move assign
|
||||||
void operator=(HashTable<T, Key, Hash>&& rhs);
|
void operator=(this_type&& rhs);
|
||||||
|
|
||||||
//- Equality. Tables are equal if all keys and values are equal,
|
//- Equality. Tables are equal if all keys and values are equal,
|
||||||
//- independent of order or underlying storage size.
|
//- independent of order or underlying storage size.
|
||||||
bool operator==(const HashTable<T, Key, Hash>& rhs) const;
|
bool operator==(const this_type& rhs) const;
|
||||||
|
|
||||||
//- The opposite of the equality operation.
|
//- The opposite of the equality operation.
|
||||||
bool operator!=(const HashTable<T, Key, Hash>& rhs) const;
|
bool operator!=(const this_type& rhs) const;
|
||||||
|
|
||||||
//- Add entries into this HashTable
|
//- Add entries into this HashTable
|
||||||
this_type& operator+=(const this_type& rhs);
|
this_type& operator+=(const this_type& rhs);
|
||||||
@ -584,8 +602,7 @@ protected:
|
|||||||
// This can be used directly instead of comparing to end()
|
// This can be used directly instead of comparing to end()
|
||||||
inline bool good() const;
|
inline bool good() const;
|
||||||
|
|
||||||
//- True if iterator points to an entry
|
//- True if iterator points to an entry - same as good()
|
||||||
// This can be used directly instead of comparing to end()
|
|
||||||
inline bool found() const;
|
inline bool found() const;
|
||||||
|
|
||||||
//- The key associated with the iterator
|
//- The key associated with the iterator
|
||||||
@ -703,7 +720,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// Member functions/operators
|
// Member Functions/Operators
|
||||||
|
|
||||||
//- Non-const access to referenced object (value)
|
//- Non-const access to referenced object (value)
|
||||||
using Iterator<false>::val;
|
using Iterator<false>::val;
|
||||||
@ -719,7 +736,7 @@ public:
|
|||||||
template<class TypeT = T>
|
template<class TypeT = T>
|
||||||
typename std::enable_if
|
typename std::enable_if
|
||||||
<
|
<
|
||||||
std::is_pointer<TypeT>::value,
|
Detail::isPointer<TypeT>::value,
|
||||||
T
|
T
|
||||||
>::type operator->() const { return this->val(); }
|
>::type operator->() const { return this->val(); }
|
||||||
|
|
||||||
@ -773,7 +790,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// Member functions/operators
|
// Member Functions/Operators
|
||||||
|
|
||||||
//- Const access to referenced value
|
//- Const access to referenced value
|
||||||
using Iterator<true>::val;
|
using Iterator<true>::val;
|
||||||
@ -789,7 +806,7 @@ public:
|
|||||||
template<class TypeT = T>
|
template<class TypeT = T>
|
||||||
typename std::enable_if
|
typename std::enable_if
|
||||||
<
|
<
|
||||||
std::is_pointer<TypeT>::value,
|
Detail::isPointer<TypeT>::value,
|
||||||
const T
|
const T
|
||||||
>::type operator->() const { return this->val(); }
|
>::type operator->() const { return this->val(); }
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,7 @@ SourceFiles
|
|||||||
#define HashTableDetail_H
|
#define HashTableDetail_H
|
||||||
|
|
||||||
#include "zero.H"
|
#include "zero.H"
|
||||||
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -44,14 +45,32 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward Declarations
|
||||||
class Ostream;
|
class Ostream;
|
||||||
|
template<class T> class autoPtr;
|
||||||
|
|
||||||
namespace Detail
|
namespace Detail
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class Detail::HashTablePair Declaration
|
Class isPointer Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Test for pointer-like behaviour
|
||||||
|
template<class T>
|
||||||
|
struct isPointer : public std::is_pointer<T> {};
|
||||||
|
|
||||||
|
//- An autoPtr is pointer-like
|
||||||
|
template<class T>
|
||||||
|
struct isPointer<autoPtr<T>> : public std::true_type {};
|
||||||
|
|
||||||
|
//- A unique_ptr is pointer-like
|
||||||
|
template<class T>
|
||||||
|
struct isPointer<std::unique_ptr<T>> : public std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class HashTablePair Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//- Internal storage type for HashTable entries
|
//- Internal storage type for HashTable entries
|
||||||
@ -97,16 +116,17 @@ struct HashTablePair
|
|||||||
void operator=(const HashTablePair&) = delete;
|
void operator=(const HashTablePair&) = delete;
|
||||||
|
|
||||||
|
|
||||||
//- Construct from key, value, next pointer
|
//- Construct from next pointer, key, contents
|
||||||
|
template<class... Args>
|
||||||
HashTablePair
|
HashTablePair
|
||||||
(
|
(
|
||||||
|
HashTablePair* next,
|
||||||
const key_type& key,
|
const key_type& key,
|
||||||
const mapped_type& val,
|
Args&&... args
|
||||||
HashTablePair* next
|
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
key_(key),
|
key_(key),
|
||||||
val_(val),
|
val_(std::forward<Args>(args)...),
|
||||||
next_(next)
|
next_(next)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -131,7 +151,7 @@ struct HashTablePair
|
|||||||
|
|
||||||
//- Write (key, val) pair - for pointer types
|
//- Write (key, val) pair - for pointer types
|
||||||
template<class TypeT = T>
|
template<class TypeT = T>
|
||||||
typename std::enable_if<std::is_pointer<TypeT>::value, void>::type
|
typename std::enable_if<Detail::isPointer<TypeT>::value, void>::type
|
||||||
print(Ostream& os) const
|
print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << key_;
|
os << key_;
|
||||||
@ -144,7 +164,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 = T>
|
||||||
typename std::enable_if<!std::is_pointer<TypeT>::value, void>::type
|
typename std::enable_if<!Detail::isPointer<TypeT>::value, void>::type
|
||||||
print(Ostream& os) const
|
print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << key_ << ' ' << val_;
|
os << key_ << ' ' << val_;
|
||||||
@ -153,7 +173,7 @@ struct HashTablePair
|
|||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class Detail::HashTableSingle Declaration
|
Class HashTableSingle Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//- Internal storage type for HashSet entries
|
//- Internal storage type for HashSet entries
|
||||||
@ -196,12 +216,13 @@ struct HashTableSingle
|
|||||||
void operator=(const HashTableSingle&) = delete;
|
void operator=(const HashTableSingle&) = delete;
|
||||||
|
|
||||||
|
|
||||||
//- Construct from key, (ununsed) value, next pointer
|
//- Construct from next pointer, key, (ununsed) contents
|
||||||
|
template<class... Args>
|
||||||
HashTableSingle
|
HashTableSingle
|
||||||
(
|
(
|
||||||
|
HashTableSingle* next,
|
||||||
const key_type& key,
|
const key_type& key,
|
||||||
const mapped_type&,
|
Args&&...
|
||||||
HashTableSingle* next
|
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
key_(key),
|
key_(key),
|
||||||
|
|||||||
@ -61,12 +61,46 @@ inline bool Foam::HashTable<T, Key, Hash>::empty() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
inline T& Foam::HashTable<T, Key, Hash>::at(const Key& key)
|
||||||
|
{
|
||||||
|
const iterator iter(this->find(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>
|
||||||
|
inline const T& Foam::HashTable<T, Key, Hash>::at(const Key& key) const
|
||||||
|
{
|
||||||
|
const const_iterator iter(this->cfind(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 bool Foam::HashTable<T, Key, Hash>::found(const Key& key) const
|
inline bool Foam::HashTable<T, Key, Hash>::found(const Key& key) const
|
||||||
{
|
{
|
||||||
if (size_)
|
if (size_)
|
||||||
{
|
{
|
||||||
return Iterator<true>(this, key).found();
|
return Iterator<true>(this, key).good();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -116,6 +150,18 @@ Foam::HashTable<T, Key, Hash>::cfind
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
template<class... Args>
|
||||||
|
inline bool Foam::HashTable<T, Key, Hash>::emplace
|
||||||
|
(
|
||||||
|
const Key& key,
|
||||||
|
Args&&... args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return this->setEntry(false, key, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline bool Foam::HashTable<T, Key, Hash>::insert
|
inline bool Foam::HashTable<T, Key, Hash>::insert
|
||||||
(
|
(
|
||||||
@ -123,7 +169,18 @@ inline bool Foam::HashTable<T, Key, Hash>::insert
|
|||||||
const T& val
|
const T& val
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return this->setEntry(key, val, false); // No overwrite
|
return this->setEntry(false, key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
inline bool Foam::HashTable<T, Key, Hash>::insert
|
||||||
|
(
|
||||||
|
const Key& key,
|
||||||
|
T&& val
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return this->setEntry(false, key, std::forward<T>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +191,18 @@ inline bool Foam::HashTable<T, Key, Hash>::set
|
|||||||
const T& val
|
const T& val
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return this->setEntry(key, val, true); // Overwrite
|
return this->setEntry(true, key, val); // Overwrite
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
inline bool Foam::HashTable<T, Key, Hash>::set
|
||||||
|
(
|
||||||
|
const Key& key,
|
||||||
|
T&& val
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return this->setEntry(true, key, std::forward<T>(val)); // Overwrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,7 +214,7 @@ inline const T& Foam::HashTable<T, Key, Hash>::lookup
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const const_iterator iter(this->cfind(key));
|
const const_iterator iter(this->cfind(key));
|
||||||
return iter.found() ? iter.val() : deflt;
|
return iter.good() ? iter.val() : deflt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,7 +225,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
|
|||||||
{
|
{
|
||||||
const iterator iter(this->find(key));
|
const iterator iter(this->find(key));
|
||||||
|
|
||||||
if (!iter.found())
|
if (!iter.good())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< key << " not found in table. Valid entries: "
|
<< key << " not found in table. Valid entries: "
|
||||||
@ -174,7 +242,7 @@ inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
|
|||||||
{
|
{
|
||||||
const const_iterator iter(this->cfind(key));
|
const const_iterator iter(this->cfind(key));
|
||||||
|
|
||||||
if (!iter.found())
|
if (!iter.good())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< key << " not found in table. Valid entries: "
|
<< key << " not found in table. Valid entries: "
|
||||||
@ -191,7 +259,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
|
|||||||
{
|
{
|
||||||
const iterator iter(this->find(key));
|
const iterator iter(this->find(key));
|
||||||
|
|
||||||
if (iter.found())
|
if (iter.good())
|
||||||
{
|
{
|
||||||
return iter.val();
|
return iter.val();
|
||||||
}
|
}
|
||||||
@ -210,7 +278,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()
|
|||||||
{
|
{
|
||||||
const iterator iter(this->find(key));
|
const iterator iter(this->find(key));
|
||||||
|
|
||||||
if (iter.found())
|
if (iter.good())
|
||||||
{
|
{
|
||||||
return iter.val();
|
return iter.val();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,7 @@ bool Foam::HashTable<T, Key, Hash>::addEntry(Istream& is, const bool overwrite)
|
|||||||
|
|
||||||
is >> key >> val;
|
is >> key >> val;
|
||||||
|
|
||||||
const bool ok = this->setEntry(key, val, overwrite);
|
const bool ok = this->setEntry(overwrite, key, val);
|
||||||
|
|
||||||
is.fatalCheck
|
is.fatalCheck
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user