Commit 4ee65d12 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: HashTable and HashSet improvements

- unfriend HashSet, HashTable IO operators

- global min(), max(), minMax() functions taking a labelHashSet and an
  optional limit. For example,

      labelHashSet set = ...;

      Info<< "min is " << min(set) << nl;
      Info<< "max (non-negative) " << max(set, 0) << nl;

- make HashTable iterator '->' dereferencing more consistent by also
  supporting non-pointer types as well.

- read HashTable values in-situ to avoid copying
parent 05739d6a
......@@ -32,6 +32,7 @@ Description
#include "HashOps.H"
#include "HashSet.H"
#include "Map.H"
#include "MinMax.H"
#include "labelPairHashes.H"
#include "FlatOutput.H"
......@@ -184,6 +185,9 @@ int main(int argc, char *argv[])
1, 11, 42
};
Info<<"Set with min/max:" << minMax(setB)
<< " min:" << min(setB) << " max:" << max(setB) << nl;
setB = FixedList<label, 4>({1, 2, 3, 4});
setB = {1, 2, 4};
setB = List<label>({1, 2, 4});
......
......@@ -261,14 +261,24 @@ int main(int argc, char *argv[])
labelList list1(identity(4, -4));
Info<<"move insert " << list1 << nl;
Info<< "move insert " << list1 << nl;
ltable1.insert("pqr", std::move(list1));
Info<<"after insert " << list1 << nl;
Info<< "after insert " << list1 << nl;
Info<< nl << "HashTable<labelList>: "
<< ltable1 << nl;
// Use '->' dereferencing
const auto iter = ltable1.cfind("ghi");
if (iter)
{
Info<< "got with " << iter->size() << nl;
}
}
Info<< "\nEnd\n" << endl;
......
......@@ -171,6 +171,7 @@ containers/Bits/bitSet/bitSetIO.C
containers/Bits/BitOps/BitOps.C
containers/Bits/PackedList/PackedListCore.C
containers/HashTables/HashOps/HashOps.C
containers/HashTables/HashSet/hashSets.C
containers/HashTables/HashTable/HashTableCore.C
containers/Lists/SortableList/ParSortableListName.C
containers/Lists/ListOps/ListOps.C
......
......@@ -73,10 +73,7 @@ namespace Foam
{
// Forward declarations
template<class Key, class Hash> class HashSet;
template<class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashSet<Key, Hash>& tbl);
template<class T> class MinMax;
/*---------------------------------------------------------------------------*\
......@@ -380,15 +377,6 @@ public:
inline this_type& operator-=(const this_type& rhs);
// IOstream Operator
friend Ostream& operator<< <Key, Hash>
(
Ostream& os,
const HashSet<Key, Hash>& tbl
);
// Housekeeping
//- Not applicable for HashSet
......@@ -418,8 +406,36 @@ 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
//- Find the min value in labelHashSet, optionally limited by second argument.
// For an empty set, returns the second argument (eg, labelMax).
label min(const labelHashSet& set, label minValue = labelMax);
//- Find the max value in labelHashSet, optionally limited by second argument.
// For an empty set, returns the second argument (eg, labelMin).
label max(const labelHashSet& set, label maxValue = labelMin);
//- Find the min/max values of labelHashSet
MinMax<label> minMax(const labelHashSet& set);
// Global Operators
//- Write the list of HashSet keys
template<class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashSet<Key, Hash>& tbl);
//- Combine entries from HashSets
template<class Key, class Hash>
HashSet<Key, Hash> operator|
......@@ -447,13 +463,6 @@ HashSet<Key, Hash> operator^
);
//- A HashSet with word keys.
typedef HashSet<word> wordHashSet;
//- A HashSet with label keys and label hasher.
typedef HashSet<label, Hash<label>> labelHashSet;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -104,12 +104,6 @@ template<class T> class UList;
template<class T, unsigned N> class FixedList;
template<class T, class Key, class Hash> class HashTable;
template<class T, class Key, class Hash>
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& tbl);
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
/*---------------------------------------------------------------------------*\
Class HashTable Declaration
......@@ -149,10 +143,6 @@ class HashTable
// No checks for zero-sized tables.
inline label hashKeyIndex(const Key& key) const;
//- Read entry (key, val) and assign
// \return True if the new entry was set.
bool addEntry(Istream& is, const bool overwrite = false);
//- Assign a new hash-entry to a possibly already existing key.
// \return True if the new entry was set.
template<class... Args>
......@@ -732,7 +722,7 @@ public:
inline reference operator*() const { return this->val(); }
inline reference operator()() const { return this->val(); }
//- For pointer types, allow direct pointer dereferencing
//- Direct pointer dereferencing (pointer types)
template<class TypeT = T>
typename std::enable_if
<
......@@ -740,6 +730,14 @@ public:
T
>::type operator->() const { return this->val(); }
//- Address of iterated value (non-pointer types)
template<class TypeT = T>
typename std::enable_if
<
!Detail::isPointer<TypeT>::value,
T*
>::type operator->() const { return &(this->val()); }
inline iterator& operator++();
inline iterator operator++(int);
};
......@@ -802,7 +800,7 @@ public:
inline reference operator*() const { return this->val(); }
inline reference operator()() const { return this->val(); }
//- For pointer types, allow direct pointer dereferencing
//- Direct pointer dereferencing (pointer types)
template<class TypeT = T>
typename std::enable_if
<
......@@ -810,6 +808,14 @@ public:
const T
>::type operator->() const { return this->val(); }
//- Address of iterated value (non-pointer types)
template<class TypeT = T>
typename std::enable_if
<
!Detail::isPointer<TypeT>::value,
const T*
>::type operator->() const { return &(this->val()); }
inline const_iterator& operator++();
inline const_iterator operator++(int);
......@@ -911,22 +917,16 @@ public:
//- when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
};
// IOstream Operator
// IOstream Operators
friend Istream& operator>> <T, Key, Hash>
(
Istream& is,
HashTable<T, Key, Hash>& tbl
);
template<class T, class Key, class Hash>
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& tbl);
friend Ostream& operator<< <T, Key, Hash>
(
Ostream& os,
const HashTable<T, Key, Hash>& tbl
);
};
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -29,28 +29,6 @@ License
#include "Istream.H"
#include "Ostream.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T, class Key, class Hash>
bool Foam::HashTable<T, Key, Hash>::addEntry(Istream& is, const bool overwrite)
{
typename node_type::key_type key;
typename node_type::mapped_type val;
is >> key >> val;
const bool ok = this->setEntry(overwrite, key, val);
is.fatalCheck
(
"HashTable::addEntry(Istream&) : "
"reading entry"
);
return ok;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
......@@ -168,11 +146,11 @@ template<class T, class Key, class Hash>
Foam::Istream& Foam::operator>>
(
Istream& is,
HashTable<T, Key, Hash>& L
HashTable<T, Key, Hash>& tbl
)
{
// Anull existing table
L.clear();
tbl.clear();
is.fatalCheck(FUNCTION_NAME);
......@@ -193,23 +171,31 @@ Foam::Istream& Foam::operator>>
if (len)
{
if (2*len > L.capacity_)
if (delimiter != token::BEGIN_LIST)
{
L.resize(2*len);
FatalIOErrorInFunction(is)
<< "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
}
if (delimiter == token::BEGIN_LIST)
if (2*len > tbl.capacity())
{
for (label i=0; i<len; ++i)
{
L.addEntry(is);
}
tbl.resize(2*len);
}
else
for (label i=0; i<len; ++i)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, '(', found " << firstToken.info()
<< exit(FatalIOError);
Key key;
is >> key; // Read the key
T& val = tbl(key); // Insert nameless T() into table
is >> val; // Read directly into the table value
is.fatalCheck
(
"operator>>(Istream&, HashTable&) : "
"reading entry"
);
}
}
......@@ -236,7 +222,17 @@ Foam::Istream& Foam::operator>>
{
is.putBack(lastToken);
L.addEntry(is);
Key key;
is >> key; // Read the key
T& val = tbl(key); // Insert nameless T() into table
is >> val; // Read directly into the table value
is.fatalCheck
(
"operator>>(Istream&, HashTable&) : "
"reading entry"
);
is >> lastToken;
}
......@@ -250,7 +246,6 @@ Foam::Istream& Foam::operator>>
}
is.fatalCheck(FUNCTION_NAME);
return is;
}
......
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