Commit acc048a2 authored by Mark Olesen's avatar Mark Olesen
Browse files

Merge branch 'consistency-updates' into 'develop'

Consistency updates

See merge request !111
parents 1889ea83 d4041e7d
......@@ -56,7 +56,6 @@ int main(int argc, char *argv[])
Info<< "element:" << *iter << endl;
}
Info<< nl << "And again using the same STL iterator: " << nl << endl;
forAllIters(myList, iter)
......
......@@ -36,14 +36,9 @@ void printTable(const HashPtrTable<T>& table)
{
Info<< table.size() << nl << "(" << nl;
for
(
typename HashPtrTable<T>::const_iterator iter = table.cbegin();
iter != table.cend();
++iter
)
forAllConstIters(table, iter)
{
const T* ptr = *iter;
const T* ptr = iter.object();
Info<< iter.key() << " = ";
if (ptr)
{
......@@ -57,6 +52,22 @@ void printTable(const HashPtrTable<T>& table)
}
Info<< ")" << endl;
// Values only, with for-range
Info<< "values (";
for (auto val : table)
{
Info<< ' ';
if (val)
{
Info<< *val;
}
else
{
Info<< "nullptr";
}
}
Info<< " )" << nl;
}
......@@ -68,7 +79,9 @@ int main()
HashPtrTable<double> myTable;
myTable.insert("abc", new double(42.1));
myTable.insert("def", nullptr);
myTable.insert("ghi", new double(3.14159));
myTable.insert("pi", new double(3.14159));
myTable.insert("natlog", new double(2.718282));
myTable.insert("sqrt2", new double(1.414214));
// Info<< myTable << endl;
printTable(myTable);
......@@ -79,8 +92,20 @@ int main()
printTable(copy);
Info<< copy << endl;
Info<<"\nerase some existing and non-existing entries" << nl;
auto iter = myTable.find("pi");
myTable.erase(iter);
iter = myTable.find("unknownKey");
myTable.erase(iter);
myTable.erase("abc");
myTable.erase("unknownKey");
printTable(myTable);
return 0;
}
// ************************************************************************* //
......@@ -197,8 +197,12 @@ int main(int argc, char *argv[])
Info<< "setD has no 11" << endl;
}
Info<< "setB : " << flatOutput(setB) << endl;
Info<< "setD : " << flatOutput(setD) << endl;
setD -= setB;
Info<< "setD -= setB : " << flatOutput(setD) << endl;
// This should not work (yet?)
// setD[12] = true;
......
......@@ -25,6 +25,9 @@ License
#include "HashTable.H"
#include "List.H"
#include "SortableList.H"
#include "DynamicList.H"
#include "FlatOutput.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "OStringStream.H"
......@@ -163,15 +166,15 @@ int main()
<< "\ntable2" << table2 << nl;
Info<< "\ntable3" << table3
<< "\nclearStorage table3 ... ";
table3.clearStorage();
Info<< table3 << nl;
Info<< "\ntable3" << table2
<< "\nclearStorage table2 ... ";
table2.clearStorage();
Info<< table2 << nl;
table1 =
{
{"aca", 3.0},
{"aaw", 6.0},
{"abc", 3.0},
{"def", 6.0},
{"acr", 8.0},
{"aec", 10.0}
};
......@@ -193,7 +196,43 @@ int main()
// These do not yet work. Issues resolving the distance.
//
// List<scalar> table1vals(table1.begin(), table1.end());
// wordList table1keys(table1.begin(), table1.end());
{
Info<<"distance/size: "
<< std::distance(table1.begin(), table1.end())
<< "/" << table1.size()
<< " and "
<< std::distance(table1.keys().begin(), table1.keys().end())
<< "/" << table1.keys().size()
<< nl;
SortableList<word> sortKeys
// DynamicList<word> sortKeys
(
table1.keys().begin(),
table1.keys().end()
);
Info<<"sortKeys: " << flatOutput(sortKeys) << nl;
}
Info<< "\nFrom table1: " << flatOutput(table1.sortedToc()) << nl
<< "retain keys: " << flatOutput(table3.sortedToc()) << nl;
table1.retain(table3);
Info<< "-> " << flatOutput(table1.sortedToc()) << nl;
Info<< "Lookup non-existent" << nl;
Info<< table1.lookup("missing-const", 1.2345e+6)
<< " // const-access" << nl;
Info<< table1("missing-inadvertent", 3.14159)
<< " // (inadvertent?) non-const access" << nl;
Info<< table1("missing-autovivify")
<< " // Known auto-vivification (non-const access)" << nl;
Info<<"\ntable1: " << table1 << endl;
Info<< "\nDone\n";
......
......@@ -42,6 +42,7 @@ See also
#include "vector.H"
#include "labelRange.H"
#include "scalarList.H"
#include "ListOps.H"
#include "SubList.H"
......@@ -144,6 +145,18 @@ int main(int argc, char *argv[])
labelList longLabelList = identity(15);
// This does not work:
// scalarList slist = identity(15);
//
// More writing, but does work:
scalarList slist
(
labelRange::null.begin(),
labelRange::identity(15).end()
);
Info<<"scalar identity:" << flatOutput(slist) << endl;
Info<< "labels (contiguous=" << contiguous<label>() << ")" << nl;
Info<< "normal: " << longLabelList << nl;
......@@ -220,7 +233,32 @@ int main(int argc, char *argv[])
}
Info<< "sub-sorted: " << flatOutput(longLabelList) << nl;
// Info<<"Slice=" << longLabelList[labelRange(23,5)] << nl;
// construct from a label-range
labelRange range(25,15);
labelList ident(range.begin(), range.end());
Info<<"range-list (label)=" << ident << nl;
List<scalar> sident(range.begin(), range.end());
Info<<"range-list (scalar)=" << sident << nl;
// Sub-ranges also work
List<scalar> sident2(range(3), range(10));
Info<<"range-list (scalar)=" << sident2 << nl;
// VERY BAD IDEA: List<scalar> sident3(range(10), range(3));
// This doesn't work, and don't know what it should do anyhow
// List<vector> vident(range.begin(), range.end());
// Info<<"range-list (vector)=" << vident << nl;
// Even weird things like this
List<scalar> sident4
(
labelRange().begin(),
labelRange::identity(8).end()
);
Info<<"range-list (scalar)=" << sident4 << nl;
}
wordReList reLst;
......
......@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
Info<<"test sorting" << endl;
DynamicList<labelRange> list1(10);
list1.append(labelRange(25, 8));
list1.append(labelRange(0, 10));
list1.append(labelRange::identity(8));
list1.append(labelRange(15, 5));
list1.append(labelRange(50, -10));
......
......@@ -72,30 +72,44 @@ Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
template<class T, class Key, class Hash>
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
{
T* ptr = iter.object();
this->parent_type::erase(iter);
return ptr;
if (iter.found())
{
T* ptr = iter.object();
this->parent_type::erase(iter);
return ptr;
}
return nullptr;
}
template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
{
T* ptr = iter.object();
if (this->parent_type::erase(iter))
if (iter.found())
{
if (ptr)
T* ptr = iter.object();
if (this->parent_type::erase(iter))
{
delete ptr;
}
if (ptr)
{
delete ptr;
}
return true;
}
else
{
return false;
return true;
}
}
return false;
}
template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(const Key& key)
{
auto iter = this->find(key);
return this->erase(iter);
}
......
......@@ -116,12 +116,17 @@ public:
// Edit
//- Remove and return the pointer specified by given iterator
//- Remove and return the pointer specified by given iterator.
// Includes a safeguard against the end-iterator.
T* remove(iterator& iter);
//- Erase an hashedEntry specified by given iterator
//- Erase an entry specified by given iterator
// Includes a safeguard against the end-iterator.
bool erase(iterator& iter);
//- Erase an entry specified by the given key
bool erase(const Key& key);
//- Clear all entries from table
void clear();
......
......@@ -227,16 +227,9 @@ void Foam::HashSet<Key, Hash>::operator|=(const HashSet<Key, Hash>& rhs)
template<class Key, class Hash>
void Foam::HashSet<Key, Hash>::operator&=(const HashSet<Key, Hash>& rhs)
inline void Foam::HashSet<Key, Hash>::operator&=(const HashSet<Key, Hash>& rhs)
{
// Remove elements not also found in rhs
for (iterator iter = this->begin(); iter != this->end(); ++iter)
{
if (!rhs.found(iter.key()))
{
this->erase(iter);
}
}
this->parent_type::retain(rhs);
}
......@@ -259,13 +252,9 @@ void Foam::HashSet<Key, Hash>::operator^=(const HashSet<Key, Hash>& rhs)
template<class Key, class Hash>
void Foam::HashSet<Key, Hash>::operator-=(const HashSet<Key, Hash>& rhs)
inline void Foam::HashSet<Key, Hash>::operator-=(const HashSet<Key, Hash>& rhs)
{
// Remove rhs elements from lhs
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
{
this->erase(iter.key());
}
this->parent_type::erase(rhs);
}
......
......@@ -277,7 +277,7 @@ public:
void operator|=(const HashSet<Key, Hash>& rhs);
//- Only retain entries found in both HashSets
void operator&=(const HashSet<Key, Hash>& rhs);
inline void operator&=(const HashSet<Key, Hash>& rhs);
//- Only retain unique entries (xor)
void operator^=(const HashSet<Key, Hash>& rhs);
......@@ -289,7 +289,7 @@ public:
}
//- Remove entries listed in the given HashSet from this HashSet
void operator-=(const HashSet<Key, Hash>& rhs);
inline void operator-=(const HashSet<Key, Hash>& rhs);
// IOstream Operator
......
......@@ -257,7 +257,7 @@ template<class T, class Key, class Hash>
bool Foam::HashTable<T, Key, Hash>::set
(
const Key& key,
const T& newEntry,
const T& obj,
const bool protect
)
{
......@@ -284,7 +284,7 @@ bool Foam::HashTable<T, Key, Hash>::set
if (!existing)
{
// Not found, insert it at the head
table_[hashIdx] = new hashedEntry(key, newEntry, table_[hashIdx]);
table_[hashIdx] = new hashedEntry(key, obj, table_[hashIdx]);
nElmts_++;
if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize)
......@@ -316,7 +316,7 @@ bool Foam::HashTable<T, Key, Hash>::set
{
// Found - overwrite existing entry
// this corresponds to the Perl convention
hashedEntry* ep = new hashedEntry(key, newEntry, existing->next_);
hashedEntry* ep = new hashedEntry(key, obj, existing->next_);
// Replace existing element - within list or insert at the head
if (prev)
......@@ -411,7 +411,8 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
template<class T, class Key, class Hash>
bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
{
return erase(find(key));
auto iter = find(key);
return erase(iter);
}
......@@ -450,15 +451,15 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
const HashTable<AnyType, Key, AnyHash>& other
)
{
// Remove other keys from this table
const label nTotal = this->size();
label changed = 0;
if (other.size() < nTotal)
using other_iter =
typename HashTable<AnyType, Key, AnyHash>::const_iterator;
if (other.size() <= nTotal)
{
// other is smaller, use its keys for removal
using other_iter =
typename HashTable<AnyType, Key, AnyHash>::const_iterator;
// The other is smaller/same-size, use its keys for removal
for
(
......@@ -475,7 +476,7 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
}
else
{
// other is same/larger: iterate ourselves and check for key in other
// We are smaller: remove if found in the other hash
for
(
iterator iter = begin();
......@@ -494,6 +495,39 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
}
template<class T, class Key, class Hash>
template<class AnyType, class AnyHash>
Foam::label Foam::HashTable<T, Key, Hash>::retain
(
const HashTable<AnyType, Key, AnyHash>& other
)
{
const label nTotal = this->size();
label changed = 0;
if (other.empty())
{
// Trivial case
changed = nTotal;
this->clear();
}
else
{
// Inverted logic: remove if *not* found in the other hash
for (iterator iter = begin(); iter != end(); ++iter)
{
if (!other.found(iter.key()) && erase(iter))
{
++changed;
}
}
}
return changed;
}
template<class T, class Key, class Hash>
void Foam::HashTable<T, Key, Hash>::resize(const label sz)
{
......
......@@ -44,6 +44,7 @@ Note
SourceFiles
HashTableI.H
HashTable.C
HashTableCoreI.H
HashTableCore.C
HashTableIO.C
......@@ -60,6 +61,7 @@ SourceFiles
#include "nullObject.H"
#include <initializer_list>
#include <iterator>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -178,10 +180,17 @@ public:
//- Type of values that the HashTable contains.
typedef T value_type;
//- The type used for storing into value_type objects.
// This type is usually value_type&.
typedef T* pointer;
//- The type used for storing into value_type objects.
// This type is usually value_type&.
typedef T& reference;
//- The type used for reading from constant value_type objects.
typedef const T* const_pointer;
//- The type used for reading from constant value_type objects.
typedef const T& const_reference;
......@@ -247,7 +256,7 @@ private:
//- Assign a new hash-entry to a possibly already existing key.
// Return true if the new entry was set.
bool set(const Key& key, const T& newEntry, const bool protect);
bool set(const Key& key, const T& obj, const bool protect);
protected:
......@@ -307,17 +316,20 @@ public:
//- Return true if the hash table is empty
inline bool empty() const;
//- Return true if hashedEntry is found in table
//- Return true if hashed entry is found in table
bool found(const Key& key) const;
//- Find and return an iterator set at the hashedEntry
//- Find and return an iterator set at the hashed entry
// If not found iterator = end()
iterator find(const Key& key);
//- Find and return an const_iterator set at the hashedEntry
//- Find and return an const_iterator set at the hashed entry
// If not found iterator = end()
const_iterator find(const Key& key) const;
//- Return hashed entry if it exists, or return the given default
inline const T& lookup(const Key& key, const T& deflt) const;
//- Return the table of contents
List<Key> toc() const;
......@@ -327,42 +339,58 @@ public:
// Edit
//- Insert a new hashedEntry
//- Insert a new entry
// Return true if the entry inserted, which means that it did
// not previously exist in the table.
inline bool insert(const Key& key, const T& newEntry);
inline bool insert(const Key& key, const T& obj);
//- Assign a new hashedEntry, overwriting existing entries.
//- Assign a new entry, overwriting existing entries.
// Returns true.
inline bool set(const Key& key, const T& newEntry);
//- Erase a hashedEntry specified by given iterator
// This invalidates the iterator until the next ++ operation
inline bool set(const Key& key, const T& obj);
//- Erase an entry specified by given iterator
// This invalidates the iterator until the next ++ operation.
//
// Includes a safeguard against the end-iterator such that the
// following is safe:
// \code
// auto iter = table.find(unknownKey);
// table.erase(iter);
// \endcode
// which is what \code table.erase(unknownKey) \endcode does anyhow
bool erase(const iterator& iter);
//- Erase a hashedEntry specified by the given key
//- Erase an entry specified by the given key
bool erase(const Key& key);
//- Remove entries given by the listed keys from this HashTable
//- Remove table entries given by the listed keys
// Return the number of elements removed
label erase(const UList<Key>& keys);
//- Remove entries given by the listed keys from this HashTable
//- Remove table entries given by the listed keys
// Return the number of elements removed
template<unsigned Size>
label erase(const FixedList<Key, Size>& keys);
//- Remove entries given by the listed keys from this HashTable
//- Remove table entries given by the listed keys
// Return the number of elements removed
label erase(std::initializer_list<Key> keys);
//- Remove entries given by the given keys from this HashTable
//- Remove table entries given by keys of the other hash-table.
// Return the number of elements removed.
// The parameter HashTable needs the same type of key, but the
//
// The other hash-table must have the same type of key, but the
// type of values held and the hashing function are arbitrary.