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:
Mark Olesen
2019-05-06 08:34:39 +02:00
committed by Andrew Heather
parent e30dc962b3
commit ac317699d8
11 changed files with 227 additions and 70 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
@ -25,9 +25,9 @@ License
Description
\*---------------------------------------------------------------------------*/
#include <memory>
#include <iostream>
#include "autoPtr.H"
#include "HashPtrTable.H"
@ -56,14 +56,14 @@ void printTable(const HashPtrTable<T>& table)
Info<< ")" << endl;
// Values only, with for-range
// Iterate across values, with for-range
Info<< "values (";
for (auto val : table)
for (const auto& ptr : table)
{
Info<< ' ';
if (val)
if (ptr)
{
Info<< *val;
Info<< *ptr;
}
else
{
@ -86,8 +86,27 @@ int main()
myTable.set("natlog", new double(2.718282));
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;
printTable(myTable);
Info<< myTable2 << nl;
auto iter2 = myTable2.find("pi");
Info<<"PI: " << **iter2 << nl;
HashPtrTable<double> copy(myTable);

View File

@ -249,6 +249,28 @@ int main(int argc, char *argv[])
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;
return 0;

View File

@ -145,15 +145,15 @@ int main(int argc, char *argv[])
const label nElem = 1000000;
argList::noBanner();
argList::addBoolOption("std", "use std::unordered_map or std::set");
argList::addBoolOption("set", "test HashSet");
argList::addBoolOption("find", "test find");
argList::addBoolOption("set", "test HashSet");
argList::addBoolOption("std", "std::unordered_map or std::unordered_set");
argList args(argc, argv);
const bool optStd = args.found("std");
const bool optSet = args.found("set");
const bool optFnd = args.found("find");
const bool optSet = args.found("set");
const bool optStd = args.found("std");
cpuTime timer;
@ -171,7 +171,7 @@ int main(int argc, char *argv[])
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);
printInfo(Info, map) << endl;
@ -243,7 +243,7 @@ int main(int argc, char *argv[])
#ifdef ORDERED
Info<< "using stl::map" << endl;
#else
Info<< "using stl::unordered_set" << endl;
Info<< "using stl::unordered_map" << endl;
#endif
for (label loopi = 0; loopi < nLoops; ++loopi)

View File

@ -48,17 +48,21 @@ using namespace Foam;
template<class T, class Key, class Hash> class HashSorter;
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>
class HashSorter
{
const HashTable<T,Key,Hash>& table;
const HashTable<T, Key, Hash>& table;
public:
HashSorter(const HashTable<T,Key,Hash>& ht)
HashSorter(const HashTable<T, Key, Hash>& ht)
:
table(ht)
{}