Commit 4110699d authored by Mark Olesen's avatar Mark Olesen

ENH: HashTable::emplace_set() method, HashPtrTable support for unique_ptr

- forwarding like the emplace() method, but overwriting existing
  entries as required

- propagate similar changes to HashPtrTable

  For example, with HashPtrTable<labelList> table(...) :

  With 'insert' semantics

      table.emplace("list1", 1000);

  vs
      if (!table.found("list1"))
      {
          table.set("list1", new labelList(1000));
      }
  or
      table.insert("list1", autoPtr<labelList>::New(1000));

  Note that the last example invokes an unnecessary allocation/deletion
  if the insertion is unsuccessful.

  With 'set' semantics:

      table.emplace_set("list1", 15);

  vs
      table.set("list1", new labelList(15));
parent c77afff4
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -35,6 +35,45 @@ Description
using namespace Foam;
class Scalar
{
scalar data_;
public:
Scalar()
:
data_(0)
{}
Scalar(scalar val)
:
data_(val)
{}
~Scalar()
{
Info<<"delete Scalar: " << data_ << endl;
}
const scalar& value() const
{
return data_;
}
scalar& value()
{
return data_;
}
friend Ostream& operator<<(Ostream& os, const Scalar& val)
{
os << val.data_;
return os;
}
};
template<class T>
void printTable(const HashPtrTable<T>& table)
{
......@@ -147,6 +186,38 @@ int main()
Info<<"old" << nl;
printTable(moved);
Info<< "Verifying deletion characteristics" << nl;
{
HashPtrTable<Scalar> tbl;
tbl.set("abc", new Scalar(42.1));
tbl.set("def", nullptr);
tbl.set("pi", new Scalar(3.14159));
tbl.set("natlog", new Scalar(2.718282));
tbl.insert("sqrt2", autoPtr<Scalar>::New(1.414214));
Info<< "Table: " << tbl << nl;
Info<< nl << "... overwrite again" << nl;
tbl.set("abc", new Scalar(42.1));
tbl.set("def", nullptr);
tbl.set("pi", new Scalar(3.14159));
tbl.set("natlog", new Scalar(2.718282));
tbl.emplace("other", 15.6);
Info<< "Table: " << tbl << nl;
Info << nl << "Test emplace and emplace_set" << nl;
tbl.emplace("abc", 100);
tbl.emplace_set("def", 100);
tbl.emplace_set("other", 100);
Info<< "Table: " << tbl << nl;
}
return 0;
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -252,8 +252,10 @@ int main(int argc, char *argv[])
ltable1.insert("abc", identity(2));
ltable1.insert("def", identity(3));
ltable1.insert("ghi", identity(4));
ltable1.emplace("jkl", 10, -35);
ltable1.emplace("jkl", label(10), -35);
ltable1.emplace("mno");
ltable1.emplace("def", label(2), -2); // no overwrite
ltable1.emplace_set("ghi", label(2), -2); // overwrite
labelList list1(identity(4, -4));
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2018 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -41,6 +41,7 @@ SourceFiles
#define HashPtrTable_H
#include "HashTable.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -172,6 +173,16 @@ public:
// Override HashTable methods
//- Emplace insert a new entry, not overwriting existing entries.
// \return True if the entry did not previously exist in the table.
template<class... Args>
inline bool emplace(const Key& key, Args&&... args);
//- Emplace set an entry, overwriting any existing entries.
// \return True, since it always overwrites any entries.
template<class... Args>
inline bool emplace_set(const Key& key, Args&&... args);
//- No insert() with raw pointers (potential memory leaks).
//- Use insert() with autoPtr or set()
inline bool insert(const Key&, T*) = delete;
......@@ -186,6 +197,11 @@ public:
// \return True if the entry inserted (not previously in table)
inline bool insert(const Key& key, autoPtr<T>&& ptr);
//- Insert a new entry, not overwriting existing entries.
//
// \return True if the entry inserted (not previously in table)
inline bool insert(const Key& key, std::unique_ptr<T>&& ptr);
//- Assign a new entry, overwriting existing entries.
inline bool set(const Key& key, T* ptr);
......@@ -194,6 +210,9 @@ public:
//- Assign a new entry, overwriting existing entries.
inline bool set(const Key& key, autoPtr<T>&& ptr);
//- Assign a new entry, overwriting existing entries.
inline bool set(const Key& key, std::unique_ptr<T>&& ptr);
};
......
......@@ -45,11 +45,40 @@ inline Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(const label size)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
template<class... Args>
inline bool Foam::HashPtrTable<T, Key, Hash>::emplace
(
const Key& key,
Args&&... args
)
{
// Use insertion semantics
return
(
!parent_type::found(key)
&& this->parent_type::set(key, new T(std::forward<Args>(args)...))
);
}
template<class T, class Key, class Hash>
template<class... Args>
inline bool Foam::HashPtrTable<T, Key, Hash>::emplace_set
(
const Key& key,
Args&&... args
)
{
return this->set(key, new T(std::forward<Args>(args)...));
}
template<class T, class Key, class Hash>
inline bool Foam::HashPtrTable<T, Key, Hash>::insert
(
const Key& key,
autoPtr<T>&& ptr
autoPtr<T>& ptr
)
{
if (parent_type::insert(key, ptr.get()))
......@@ -79,6 +108,23 @@ inline bool Foam::HashPtrTable<T, Key, Hash>::insert
}
template<class T, class Key, class Hash>
inline bool Foam::HashPtrTable<T, Key, Hash>::insert
(
const Key& key,
std::unique_ptr<T>&& ptr
)
{
if (parent_type::insert(key, ptr.get()))
{
ptr.release(); // Now owned by HashPtrTable
return true;
}
return false;
}
template<class T, class Key, class Hash>
inline bool Foam::HashPtrTable<T, Key, Hash>::set
(
......@@ -112,4 +158,15 @@ inline bool Foam::HashPtrTable<T, Key, Hash>::set
}
template<class T, class Key, class Hash>
inline bool Foam::HashPtrTable<T, Key, Hash>::set
(
const Key& key,
std::unique_ptr<T>&& ptr
)
{
return this->set(key, ptr.release());
}
// ************************************************************************* //
......@@ -364,6 +364,11 @@ public:
template<class... Args>
inline bool emplace(const Key& key, Args&&... args);
//- Emplace set an entry, overwriting any existing entries.
// \return True, since it always overwrites any entries.
template<class... Args>
inline bool emplace_set(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);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -163,6 +163,18 @@ inline bool Foam::HashTable<T, Key, Hash>::emplace
}
template<class T, class Key, class Hash>
template<class... Args>
inline bool Foam::HashTable<T, Key, Hash>::emplace_set
(
const Key& key,
Args&&... args
)
{
return this->setEntry(true, key, std::forward<Args>(args)...);
}
template<class T, class Key, class Hash>
inline bool Foam::HashTable<T, Key, Hash>::insert
(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment