mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve HashTable iterator access and management
- provide key_iterator/const_key_iterator for all hashes,
reuse directly for HashSet as iterator/const_iterator, respectively.
- additional keys() method for HashTable that returns a wrapped to
a pair of begin/end const_iterators with additional size/empty
information that allows these to be used directly by anything else
expecting things with begin/end/size. Unfortunately does not yet
work with std::distance().
Example,
for (auto& k : labelHashTable.keys())
{
...
}
This commit is contained in:
@ -69,6 +69,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "tableA keys: "; tableA.writeKeys(Info) << endl;
|
Info<< "tableA keys: "; tableA.writeKeys(Info) << endl;
|
||||||
|
|
||||||
|
auto keyIterPair = tableA.keys();
|
||||||
|
for (const auto& i : keyIterPair)
|
||||||
|
{
|
||||||
|
Info<<" keys: " << i << endl;
|
||||||
|
}
|
||||||
|
|
||||||
Map<label> mapA
|
Map<label> mapA
|
||||||
{
|
{
|
||||||
{ 1, 1 },
|
{ 1, 1 },
|
||||||
@ -193,7 +199,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "setD : " << flatOutput(setD) << endl;
|
Info<< "setD : " << flatOutput(setD) << endl;
|
||||||
|
|
||||||
// this doesn't work (yet?)
|
// This should not work (yet?)
|
||||||
// setD[12] = true;
|
// setD[12] = true;
|
||||||
|
|
||||||
List<label> someLst(10);
|
List<label> someLst(10);
|
||||||
|
|||||||
@ -24,6 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "HashTable.H"
|
#include "HashTable.H"
|
||||||
|
#include "List.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "IStringStream.H"
|
#include "IStringStream.H"
|
||||||
#include "OStringStream.H"
|
#include "OStringStream.H"
|
||||||
@ -177,12 +178,23 @@ int main()
|
|||||||
|
|
||||||
Info<< "\ntable1" << table1 << nl;
|
Info<< "\ntable1" << table1 << nl;
|
||||||
|
|
||||||
Info<< "\nrange-for(table1)" << nl;
|
Info<< "\nrange-for(table1) - returns values" << nl;
|
||||||
for (auto const& it : table1)
|
for (const auto& it : table1)
|
||||||
{
|
{
|
||||||
Info<< " " << it << nl;
|
Info<< "val:" << it << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< "\nrange-for(table1.keys()) - returns keys" << nl;
|
||||||
|
for (const auto& k : table1.keys())
|
||||||
|
{
|
||||||
|
Info<< "key:" << k << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These do not yet work. Issues resolving the distance.
|
||||||
|
//
|
||||||
|
// List<scalar> table1vals(table1.begin(), table1.end());
|
||||||
|
// wordList table1keys(table1.begin(), table1.end());
|
||||||
|
|
||||||
Info<< "\nDone\n";
|
Info<< "\nDone\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
3
applications/test/cplusplus1/Make/files
Normal file
3
applications/test/cplusplus1/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-cpluplus1.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-cpluplus1
|
||||||
2
applications/test/cplusplus1/Make/options
Normal file
2
applications/test/cplusplus1/Make/options
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
|
||||||
|
/* EXE_LIBS = -lfiniteVolume */
|
||||||
88
applications/test/cplusplus1/Test-cpluplus1.C
Normal file
88
applications/test/cplusplus1/Test-cpluplus1.C
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test miscellaneous C++ templates/functionality.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "string.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
#include "UList.H"
|
||||||
|
#include "HashSet.H"
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// Macros to stringify macro contents.
|
||||||
|
#define STRINGIFY(content) #content
|
||||||
|
#define STRING_QUOTE(input) STRINGIFY(input)
|
||||||
|
|
||||||
|
#define PRINT_TYPEID(arg) \
|
||||||
|
Info<< typeid(arg).name() << " <= typeid of " << STRING_QUOTE(arg) << nl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
Info<< "various declaration types" << nl << nl;
|
||||||
|
|
||||||
|
PRINT_TYPEID(label);
|
||||||
|
PRINT_TYPEID(decltype(UList<label>::value_type()));
|
||||||
|
PRINT_TYPEID(decltype(std::declval<UList<label>>().cbegin()));
|
||||||
|
PRINT_TYPEID(decltype(*(std::declval<UList<label>>().cbegin())));
|
||||||
|
Info<< nl;
|
||||||
|
|
||||||
|
PRINT_TYPEID(decltype(HashTable<label>::key_type()));
|
||||||
|
PRINT_TYPEID(decltype(HashTable<label>::value_type()));
|
||||||
|
// Not yet: PRINT_TYPEID(decltype(HashTable<label>::mapped_type()));
|
||||||
|
PRINT_TYPEID(decltype(std::declval<HashTable<label>>().begin()));
|
||||||
|
PRINT_TYPEID(decltype(std::declval<const HashTable<label>>().begin()));
|
||||||
|
PRINT_TYPEID(decltype(*(std::declval<HashTable<label>>().begin())));
|
||||||
|
PRINT_TYPEID(decltype(*(std::declval<const HashTable<label>>().begin())));
|
||||||
|
|
||||||
|
PRINT_TYPEID(decltype(std::declval<const HashTable<label>>().keys()));
|
||||||
|
Info<< nl;
|
||||||
|
|
||||||
|
PRINT_TYPEID(decltype(HashSet<label>::key_type()));
|
||||||
|
PRINT_TYPEID(decltype(HashSet<label>::value_type()));
|
||||||
|
// Not yet: PRINT_TYPEID(decltype(HashSet<label>::mapped_type()));
|
||||||
|
PRINT_TYPEID(decltype(std::declval<HashSet<label>>().begin()));
|
||||||
|
PRINT_TYPEID(decltype(std::declval<const HashSet<label>>().begin()));
|
||||||
|
PRINT_TYPEID(decltype(*(std::declval<HashSet<label>>().begin())));
|
||||||
|
PRINT_TYPEID(decltype(*(std::declval<const HashSet<label>>().begin())));
|
||||||
|
Info<< nl;
|
||||||
|
|
||||||
|
Info << "\nEnd\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -29,6 +29,9 @@ Description
|
|||||||
#include "pTraits.H"
|
#include "pTraits.H"
|
||||||
#include "vector.H"
|
#include "vector.H"
|
||||||
#include "tensor.H"
|
#include "tensor.H"
|
||||||
|
#include "uLabel.H"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -40,7 +43,10 @@ void printTraits()
|
|||||||
{
|
{
|
||||||
Info<< pTraits<T>::typeName
|
Info<< pTraits<T>::typeName
|
||||||
<< ": zero=" << pTraits<T>::zero
|
<< ": zero=" << pTraits<T>::zero
|
||||||
<< " one=" << pTraits<T>::one << endl;
|
<< " one=" << pTraits<T>::one
|
||||||
|
<< " integral=" << std::is_integral<T>::value
|
||||||
|
<< " floating=" << std::is_floating_point<T>::value
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,6 +86,21 @@ int main()
|
|||||||
label def = label();
|
label def = label();
|
||||||
Info<< "intialized primitive:"<< def << endl;
|
Info<< "intialized primitive:"<< def << endl;
|
||||||
|
|
||||||
|
Info<< nl << "some interesting label limits:" << nl;
|
||||||
|
std::cout<< "sizeof = " << sizeof(label) << nl;
|
||||||
|
std::cout<< "min = " << pTraits<label>::min << nl;
|
||||||
|
std::cout<< "max = " << pTraits<label>::max << nl;
|
||||||
|
std::cout<< "umax = " << pTraits<uLabel>::max << nl;
|
||||||
|
|
||||||
|
std::cout<< "max_2 = " << pTraits<label>::max/2 << " == "
|
||||||
|
<< (1 << (sizeof(label)*8-2)) << nl;
|
||||||
|
|
||||||
|
std::cout<< "max_4 = " << pTraits<label>::max/4 << " == "
|
||||||
|
<< (1 << (sizeof(label)*8-3)) << nl;
|
||||||
|
|
||||||
|
std::cout<< "max_8 = " << pTraits<label>::max/8 << " == "
|
||||||
|
<< (1 << (sizeof(label)*8-4)) << nl;
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -140,6 +140,7 @@ Foam::label Foam::HashSet<Key, Hash>::insert(const UList<Key>& lst)
|
|||||||
return insertMultiple(lst.begin(), lst.end());
|
return insertMultiple(lst.begin(), lst.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
template<unsigned Size>
|
template<unsigned Size>
|
||||||
Foam::label Foam::HashSet<Key, Hash>::insert(const FixedList<Key, Size>& lst)
|
Foam::label Foam::HashSet<Key, Hash>::insert(const FixedList<Key, Size>& lst)
|
||||||
@ -147,6 +148,7 @@ Foam::label Foam::HashSet<Key, Hash>::insert(const FixedList<Key, Size>& lst)
|
|||||||
return insertMultiple(lst.begin(), lst.end());
|
return insertMultiple(lst.begin(), lst.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
Foam::label Foam::HashSet<Key, Hash>::insert(std::initializer_list<Key> lst)
|
Foam::label Foam::HashSet<Key, Hash>::insert(std::initializer_list<Key> lst)
|
||||||
{
|
{
|
||||||
@ -209,7 +211,7 @@ bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const
|
|||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
bool Foam::HashSet<Key, Hash>::operator!=(const HashSet<Key, Hash>& rhs) const
|
bool Foam::HashSet<Key, Hash>::operator!=(const HashSet<Key, Hash>& rhs) const
|
||||||
{
|
{
|
||||||
return !(operator==(rhs));
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -319,51 +321,63 @@ Foam::operator^
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline typename Foam::HashSet<Key, Hash>::iterator
|
inline typename Foam::HashSet<Key, Hash>::iterator
|
||||||
Foam::HashSet<Key, Hash>::begin()
|
Foam::HashSet<Key, Hash>::begin()
|
||||||
{
|
{
|
||||||
return iterator(this->ParentClass::begin());
|
return HashTableCore::iterator_begin<iterator>
|
||||||
|
(
|
||||||
|
static_cast<parent_type&>(*this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline typename Foam::HashSet<Key, Hash>::const_iterator
|
inline typename Foam::HashSet<Key, Hash>::const_iterator
|
||||||
Foam::HashSet<Key, Hash>::begin() const
|
Foam::HashSet<Key, Hash>::begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(this->ParentClass::cbegin());
|
return HashTableCore::iterator_begin<const_iterator>
|
||||||
|
(
|
||||||
|
static_cast<const parent_type&>(*this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline typename Foam::HashSet<Key, Hash>::const_iterator
|
inline typename Foam::HashSet<Key, Hash>::const_iterator
|
||||||
Foam::HashSet<Key, Hash>::cbegin() const
|
Foam::HashSet<Key, Hash>::cbegin() const
|
||||||
{
|
{
|
||||||
return this->begin();
|
return HashTableCore::iterator_begin<const_iterator>
|
||||||
|
(
|
||||||
|
static_cast<const parent_type&>(*this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline const typename Foam::HashSet<Key, Hash>::iterator&
|
inline const typename Foam::HashSet<Key, Hash>::iterator&
|
||||||
Foam::HashSet<Key, Hash>::end()
|
Foam::HashSet<Key, Hash>::end()
|
||||||
{
|
{
|
||||||
using iter_type = typename HashSet<Key, Hash>::iterator;
|
return HashTableCore::iterator_end<iterator>();
|
||||||
return HashTableCore::endIteratorRef<iter_type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline const typename Foam::HashSet<Key, Hash>::const_iterator&
|
inline const typename Foam::HashSet<Key, Hash>::const_iterator&
|
||||||
Foam::HashSet<Key, Hash>::end() const
|
Foam::HashSet<Key, Hash>::end() const
|
||||||
{
|
{
|
||||||
using iter_type = typename HashSet<Key, Hash>::const_iterator;
|
return HashTableCore::iterator_end<const_iterator>();
|
||||||
return HashTableCore::endIteratorRef<iter_type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
inline const typename Foam::HashSet<Key, Hash>::const_iterator&
|
inline const typename Foam::HashSet<Key, Hash>::const_iterator&
|
||||||
Foam::HashSet<Key, Hash>::cend() const
|
Foam::HashSet<Key, Hash>::cend() const
|
||||||
{
|
{
|
||||||
using iter_type = typename HashSet<Key, Hash>::const_iterator;
|
return HashTableCore::iterator_cend<const_iterator>();
|
||||||
return HashTableCore::endIteratorRef<iter_type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -68,8 +68,6 @@ class HashSet
|
|||||||
:
|
:
|
||||||
public HashTable<nil, Key, Hash>
|
public HashTable<nil, Key, Hash>
|
||||||
{
|
{
|
||||||
typedef HashTable<nil, Key, Hash> ParentClass;
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Insert values, using begin/end iterators.
|
//- Insert values, using begin/end iterators.
|
||||||
@ -92,18 +90,31 @@ class HashSet
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//- The template instance used for this HashSet
|
||||||
|
typedef HashSet<Key, Hash> this_type;
|
||||||
|
|
||||||
|
//- The template instance used for the parent HashTable
|
||||||
|
typedef HashTable<nil, Key, Hash> parent_type;
|
||||||
|
|
||||||
|
//- An iterator, returning reference to the key
|
||||||
|
using iterator = typename parent_type::key_iterator;
|
||||||
|
|
||||||
|
//- A const_iterator, returning reference to the key
|
||||||
|
using const_iterator = typename parent_type::const_key_iterator;
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct given initial size
|
//- Construct given initial size
|
||||||
HashSet(const label size = 128)
|
HashSet(const label size = 128)
|
||||||
:
|
:
|
||||||
ParentClass(size)
|
parent_type(size)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct from Istream
|
//- Construct from Istream
|
||||||
HashSet(Istream& is)
|
HashSet(Istream& is)
|
||||||
:
|
:
|
||||||
ParentClass(is)
|
parent_type(is)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct from UList of Key
|
//- Construct from UList of Key
|
||||||
@ -119,19 +130,19 @@ public:
|
|||||||
//- Construct as copy
|
//- Construct as copy
|
||||||
HashSet(const HashSet<Key, Hash>& hs)
|
HashSet(const HashSet<Key, Hash>& hs)
|
||||||
:
|
:
|
||||||
ParentClass(hs)
|
parent_type(hs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct by transferring the parameter contents
|
//- Construct by transferring the parameter contents
|
||||||
HashSet(const Xfer<HashSet<Key, Hash>>& hs)
|
HashSet(const Xfer<HashSet<Key, Hash>>& hs)
|
||||||
:
|
:
|
||||||
ParentClass(hs)
|
parent_type(hs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct by transferring the parameter contents
|
//- Construct by transferring the parameter contents
|
||||||
HashSet(const Xfer<HashTable<nil, Key, Hash>>& hs)
|
HashSet(const Xfer<HashTable<nil, Key, Hash>>& hs)
|
||||||
:
|
:
|
||||||
HashTable<nil, Key, Hash>(hs)
|
parent_type(hs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct from the keys of another HashTable,
|
//- Construct from the keys of another HashTable,
|
||||||
@ -147,7 +158,7 @@ public:
|
|||||||
//- Insert a new entry
|
//- Insert a new entry
|
||||||
bool insert(const Key& key)
|
bool insert(const Key& key)
|
||||||
{
|
{
|
||||||
return this->ParentClass::insert(key, nil());
|
return this->parent_type::insert(key, nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Insert keys from the list of Key
|
//- Insert keys from the list of Key
|
||||||
@ -191,77 +202,38 @@ public:
|
|||||||
//- Unset the specified key - same as erase
|
//- Unset the specified key - same as erase
|
||||||
bool unset(const Key& key)
|
bool unset(const Key& key)
|
||||||
{
|
{
|
||||||
return this->ParentClass::erase(key);
|
return this->parent_type::erase(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Unset the listed keys - same as erase
|
//- Unset the listed keys - same as erase
|
||||||
label unset(const UList<Key>& lst)
|
label unset(const UList<Key>& lst)
|
||||||
{
|
{
|
||||||
return this->ParentClass::erase(lst);
|
return this->parent_type::erase(lst);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Unset the listed keys - same as erase
|
//- Unset the listed keys - same as erase
|
||||||
template<unsigned Size>
|
template<unsigned Size>
|
||||||
label unset(const FixedList<Key, Size>& lst)
|
label unset(const FixedList<Key, Size>& lst)
|
||||||
{
|
{
|
||||||
return this->ParentClass::erase(lst);
|
return this->parent_type::erase(lst);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Unset the listed keys - same as erase
|
//- Unset the listed keys - same as erase
|
||||||
label unset(std::initializer_list<Key> lst)
|
label unset(std::initializer_list<Key> lst)
|
||||||
{
|
{
|
||||||
return this->ParentClass::erase(lst);
|
return this->parent_type::erase(lst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// STL iterator
|
// STL iterators
|
||||||
|
|
||||||
//- An STL-conforming iterator
|
iterator begin();
|
||||||
struct iterator
|
const_iterator begin() const;
|
||||||
:
|
const_iterator cbegin() const;
|
||||||
public ParentClass::iterator
|
|
||||||
{
|
|
||||||
using parent = typename ParentClass::iterator;
|
|
||||||
|
|
||||||
//- Implicit conversion
|
const iterator& end();
|
||||||
iterator(const parent& iter)
|
const const_iterator& end() const;
|
||||||
:
|
const const_iterator& cend() const;
|
||||||
parent(iter)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//- Return the key
|
|
||||||
auto operator*() const -> const Key&
|
|
||||||
{
|
|
||||||
return this->key();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//- An STL-conforming const_iterator
|
|
||||||
struct const_iterator
|
|
||||||
:
|
|
||||||
public ParentClass::const_iterator
|
|
||||||
{
|
|
||||||
using parent = typename ParentClass::const_iterator;
|
|
||||||
|
|
||||||
//- Implicit conversion
|
|
||||||
const_iterator(const parent& iter)
|
|
||||||
:
|
|
||||||
parent(iter)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//- Return the key
|
|
||||||
auto operator*() const -> const Key&
|
|
||||||
{
|
|
||||||
return this->key();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto begin() -> iterator;
|
|
||||||
auto begin() const -> const_iterator;
|
|
||||||
auto cbegin() const -> const_iterator;
|
|
||||||
auto end() -> const iterator&;
|
|
||||||
auto end() const -> const const_iterator&;
|
|
||||||
auto cend() const -> const const_iterator&;
|
|
||||||
|
|
||||||
|
|
||||||
// Writing
|
// Writing
|
||||||
@ -276,15 +248,18 @@ public:
|
|||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
|
//- This operation doesn't make much sense for a hash-set
|
||||||
|
void operator()(const Key& key) = delete;
|
||||||
|
|
||||||
//- Return true if the entry exists, same as found()
|
//- Return true if the entry exists, same as found()
|
||||||
inline bool operator[](const Key& key) const;
|
inline bool operator[](const Key& key) const;
|
||||||
|
|
||||||
//- Equality. Two hashset are equal when they have the same keys.
|
//- Equality. Two hashset are equal when they have the same keys.
|
||||||
// Independent of table size or order.
|
// Independent of table size or order.
|
||||||
bool operator==(const HashSet<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 HashSet<Key, Hash>& rhs) const;
|
bool operator!=(const this_type& rhs) const;
|
||||||
|
|
||||||
|
|
||||||
//- Assignment from a UList of keys
|
//- Assignment from a UList of keys
|
||||||
|
|||||||
@ -3,7 +3,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) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -336,7 +336,7 @@ bool Foam::HashTable<T, Key, Hash>::set
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
bool Foam::HashTable<T, Key, Hash>::iteratorBase::erase()
|
bool Foam::HashTable<T, Key, Hash>::iterator_base::erase()
|
||||||
{
|
{
|
||||||
// Note: entryPtr_ is nullptr for end(), so this catches that too
|
// Note: entryPtr_ is nullptr for end(), so this catches that too
|
||||||
if (entryPtr_)
|
if (entryPtr_)
|
||||||
@ -515,7 +515,7 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz)
|
|||||||
|
|
||||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||||
{
|
{
|
||||||
tmpTable->insert(iter.key(), *iter);
|
tmpTable->insert(iter.key(), iter.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
const label oldSize = tableSize_;
|
const label oldSize = tableSize_;
|
||||||
@ -645,7 +645,7 @@ void Foam::HashTable<T, Key, Hash>::operator=
|
|||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Tuple2<Key, T>& pair : lst)
|
for (const auto& pair : lst)
|
||||||
{
|
{
|
||||||
insert(pair.first(), pair.second());
|
insert(pair.first(), pair.second());
|
||||||
}
|
}
|
||||||
@ -684,7 +684,7 @@ bool Foam::HashTable<T, Key, Hash>::operator!=
|
|||||||
const HashTable<T, Key, Hash>& rhs
|
const HashTable<T, Key, Hash>& rhs
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return !(operator==(rhs));
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,13 @@ Note
|
|||||||
often result in a different hash order. Use a sorted table-of-contents
|
often result in a different hash order. Use a sorted table-of-contents
|
||||||
when the hash order is important.
|
when the hash order is important.
|
||||||
|
|
||||||
|
The end iterator of all hash-tables has a nullptr to the hash entry.
|
||||||
|
Thus avoid separate allocation for each table and use a single one with
|
||||||
|
a nullptr. The hash-table iterators always have an entry-pointer as the
|
||||||
|
first member data, which allows reinterpret_cast from anything else with
|
||||||
|
a nullptr as its first data member.
|
||||||
|
The nullObject is such an item (with a nullptr data member).
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
HashTableI.H
|
HashTableI.H
|
||||||
HashTable.C
|
HashTable.C
|
||||||
@ -78,25 +85,15 @@ Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
|
|||||||
Class HashTableCore Declaration
|
Class HashTableCore Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//- Template-invariant bits for HashTable.
|
//- Bits that are independent of the HashTable template parameters.
|
||||||
// This also includes a global end-iterator.
|
struct HashTableCore
|
||||||
//
|
|
||||||
// The end iterator of all hash-tables has a nullptr to the hash entry.
|
|
||||||
// Thus avoid separate allocation for each table and use a single one with
|
|
||||||
// a nullptr.
|
|
||||||
// The hash-table iterators always have this as its first member data,
|
|
||||||
// so we can reinterpret_cast from anything else that has a nullptr for its
|
|
||||||
// first data member. This is now also the case for the NullObject.
|
|
||||||
class HashTableCore
|
|
||||||
{
|
{
|
||||||
public:
|
//- Maximum allowable internal table size. Approximately labelMax/4
|
||||||
|
|
||||||
//- Return a canonical (power-of-two) size
|
|
||||||
static label canonicalSize(const label size);
|
|
||||||
|
|
||||||
//- Maximum allowable table size
|
|
||||||
static const label maxTableSize;
|
static const label maxTableSize;
|
||||||
|
|
||||||
|
//- Return a canonical (power-of-two) of the requested size.
|
||||||
|
static label canonicalSize(const label requested_size);
|
||||||
|
|
||||||
//- Construct null
|
//- Construct null
|
||||||
HashTableCore()
|
HashTableCore()
|
||||||
{}
|
{}
|
||||||
@ -104,21 +101,57 @@ public:
|
|||||||
//- Define template name and debug
|
//- Define template name and debug
|
||||||
ClassName("HashTable");
|
ClassName("HashTable");
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
static_assert
|
static_assert
|
||||||
(
|
(
|
||||||
sizeof(NullObject) >= sizeof(void*),
|
sizeof(NullObject) >= sizeof(void*),
|
||||||
"NullObject is too small to reinterpret_cast as HashTable::iterator"
|
"NullObject is too small to reinterpret_cast as HashTable::iterator"
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Reinterpret a NullObject as a hash-table iterator.
|
|
||||||
template<class Iterator>
|
//- Factory method to create a non-const iterator begin
|
||||||
inline static const Iterator& endIteratorRef()
|
template<class IteratorType, class TableType>
|
||||||
|
inline static IteratorType iterator_begin(TableType& table);
|
||||||
|
|
||||||
|
//- Factory method to create a const iterator begin
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline static IteratorType iterator_begin(const TableType& table);
|
||||||
|
|
||||||
|
//- Factory method to create a const iterator begin
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline static IteratorType iterator_cbegin(const TableType& table);
|
||||||
|
|
||||||
|
//- Factory method to create a non-const iterator end
|
||||||
|
// Simply reinterprets a NullObject as a hash-table iterator.
|
||||||
|
template<class IteratorType>
|
||||||
|
inline static const IteratorType& iterator_end();
|
||||||
|
|
||||||
|
//- Factory method to create a const iterator cend
|
||||||
|
// Simply reinterprets a NullObject as a hash-table iterator.
|
||||||
|
template<class IteratorType>
|
||||||
|
inline static const IteratorType& iterator_cend();
|
||||||
|
|
||||||
|
|
||||||
|
//- Factory class for creating a begin/end pair for any const iterator.
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
class const_iterator_pair
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const Iterator*>(nullObjectPtr);
|
label size_;
|
||||||
}
|
IteratorType iter_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline const_iterator_pair(const TableType& tbl);
|
||||||
|
|
||||||
|
inline label size() const;
|
||||||
|
inline bool empty() const;
|
||||||
|
|
||||||
|
inline IteratorType begin() const;
|
||||||
|
inline IteratorType cbegin() const;
|
||||||
|
|
||||||
|
inline const IteratorType& end() const;
|
||||||
|
inline const IteratorType& cend() const;
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -131,6 +164,43 @@ class HashTable
|
|||||||
:
|
:
|
||||||
public HashTableCore
|
public HashTableCore
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- The template instance used for this HashTable
|
||||||
|
typedef HashTable<T, Key, Hash> this_type;
|
||||||
|
|
||||||
|
|
||||||
|
// STL type definitions
|
||||||
|
|
||||||
|
//- Type of keys that the HashTable uses.
|
||||||
|
typedef Key key_type;
|
||||||
|
|
||||||
|
//- 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& reference;
|
||||||
|
|
||||||
|
//- The type used for reading from constant value_type objects.
|
||||||
|
typedef const T& const_reference;
|
||||||
|
|
||||||
|
//- The type to represent the difference between two iterators
|
||||||
|
typedef label difference_type;
|
||||||
|
|
||||||
|
//- The type that can represent the size of a HashTable.
|
||||||
|
typedef label size_type;
|
||||||
|
|
||||||
|
|
||||||
|
//- Forward iterator with non-const access
|
||||||
|
class iterator;
|
||||||
|
|
||||||
|
//- Forward iterator with const access
|
||||||
|
class const_iterator;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// Private data type for table entries
|
// Private data type for table entries
|
||||||
|
|
||||||
//- Structure to hold a hashed entry, with a SLList for collisions
|
//- Structure to hold a hashed entry, with a SLList for collisions
|
||||||
@ -148,7 +218,6 @@ class HashTable
|
|||||||
//- Construct from key, next pointer and object
|
//- Construct from key, next pointer and object
|
||||||
inline hashedEntry(const Key& key, const T& obj, hashedEntry* next);
|
inline hashedEntry(const Key& key, const T& obj, hashedEntry* next);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
hashedEntry(const hashedEntry&) = delete;
|
hashedEntry(const hashedEntry&) = delete;
|
||||||
@ -183,6 +252,13 @@ class HashTable
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//- Internally used base for iterator and const_iterator
|
||||||
|
class iterator_base;
|
||||||
|
|
||||||
|
//- Friendship with the iterator_base is required.
|
||||||
|
friend class iterator_base;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Remove using begin/end iterators of listed keys
|
//- Remove using begin/end iterators of listed keys
|
||||||
@ -196,16 +272,6 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Forward declaration of iterators
|
|
||||||
|
|
||||||
class iteratorBase;
|
|
||||||
class iterator;
|
|
||||||
class const_iterator;
|
|
||||||
|
|
||||||
//- Declare friendship with the iteratorBase
|
|
||||||
friend class iteratorBase;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct given initial table size
|
//- Construct given initial table size
|
||||||
@ -230,92 +296,92 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
//- The size of the underlying table
|
//- The size of the underlying table
|
||||||
inline label capacity() const;
|
inline label capacity() const;
|
||||||
|
|
||||||
//- Return number of elements in table
|
//- Return number of elements in table
|
||||||
inline label size() const;
|
inline label size() const;
|
||||||
|
|
||||||
//- Return true if the hash table is empty
|
//- Return true if the hash table is empty
|
||||||
inline bool empty() const;
|
inline bool empty() const;
|
||||||
|
|
||||||
//- Return true if hashedEntry is found in table
|
//- Return true if hashedEntry is found in table
|
||||||
bool found(const Key& key) const;
|
bool found(const Key& key) const;
|
||||||
|
|
||||||
//- Find and return an iterator set at the hashedEntry
|
//- Find and return an iterator set at the hashedEntry
|
||||||
// If not found iterator = end()
|
// If not found iterator = end()
|
||||||
iterator find(const Key& key);
|
iterator find(const Key& key);
|
||||||
|
|
||||||
//- Find and return an const_iterator set at the hashedEntry
|
//- Find and return an const_iterator set at the hashedEntry
|
||||||
// If not found iterator = end()
|
// If not found iterator = end()
|
||||||
const_iterator find(const Key& key) const;
|
const_iterator find(const Key& key) const;
|
||||||
|
|
||||||
//- Return the table of contents
|
//- Return the table of contents
|
||||||
List<Key> toc() const;
|
List<Key> toc() const;
|
||||||
|
|
||||||
//- Return the table of contents as a sorted list
|
//- Return the table of contents as a sorted list
|
||||||
List<Key> sortedToc() const;
|
List<Key> sortedToc() const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
//- Insert a new hashedEntry
|
//- Insert a new hashedEntry
|
||||||
// Return true if the entry inserted, which means that it did
|
// Return true if the entry inserted, which means that it did
|
||||||
// not previously exist in the table.
|
// not previously exist in the table.
|
||||||
inline bool insert(const Key& key, const T& newEntry);
|
inline bool insert(const Key& key, const T& newEntry);
|
||||||
|
|
||||||
//- Assign a new hashedEntry, overwriting existing entries.
|
//- Assign a new hashedEntry, overwriting existing entries.
|
||||||
// Returns true.
|
// Returns true.
|
||||||
inline bool set(const Key& key, const T& newEntry);
|
inline bool set(const Key& key, const T& newEntry);
|
||||||
|
|
||||||
//- Erase a hashedEntry specified by given iterator
|
//- Erase a hashedEntry specified by given iterator
|
||||||
// This invalidates the iterator until the next operator++
|
// This invalidates the iterator until the next ++ operation
|
||||||
bool erase(const iterator& iter);
|
bool erase(const iterator& iter);
|
||||||
|
|
||||||
//- Erase a hashedEntry specified by the given key
|
//- Erase a hashedEntry specified by the given key
|
||||||
bool erase(const Key& key);
|
bool erase(const Key& key);
|
||||||
|
|
||||||
//- Remove entries given by the listed keys from this HashTable
|
//- Remove entries given by the listed keys from this HashTable
|
||||||
// Return the number of elements removed
|
// Return the number of elements removed
|
||||||
label erase(const UList<Key>& keys);
|
label erase(const UList<Key>& keys);
|
||||||
|
|
||||||
//- Remove entries given by the listed keys from this HashTable
|
//- Remove entries given by the listed keys from this HashTable
|
||||||
// Return the number of elements removed
|
// Return the number of elements removed
|
||||||
template<unsigned Size>
|
template<unsigned Size>
|
||||||
label erase(const FixedList<Key, Size>& keys);
|
label erase(const FixedList<Key, Size>& keys);
|
||||||
|
|
||||||
//- Remove entries given by the listed keys from this HashTable
|
//- Remove entries given by the listed keys from this HashTable
|
||||||
// Return the number of elements removed
|
// Return the number of elements removed
|
||||||
label erase(std::initializer_list<Key> keys);
|
label erase(std::initializer_list<Key> keys);
|
||||||
|
|
||||||
//- Remove entries given by the given keys from this HashTable
|
//- Remove entries given by the given keys from this HashTable
|
||||||
// Return the number of elements removed.
|
// Return the number of elements removed.
|
||||||
// The parameter HashTable needs the same type of key, but the
|
// The parameter HashTable needs the same type of key, but the
|
||||||
// type of values held and the hashing function are arbitrary.
|
// type of values held and the hashing function are arbitrary.
|
||||||
template<class AnyType, class AnyHash>
|
template<class AnyType, class AnyHash>
|
||||||
label erase(const HashTable<AnyType, Key, AnyHash>& other);
|
label erase(const HashTable<AnyType, Key, AnyHash>& other);
|
||||||
|
|
||||||
//- Resize the hash table for efficiency
|
//- Resize the hash table for efficiency
|
||||||
void resize(const label sz);
|
void resize(const label sz);
|
||||||
|
|
||||||
//- Clear all entries from table
|
//- Clear all entries from table
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
//- Clear the table entries and the table itself.
|
//- Clear the table entries and the table itself.
|
||||||
// Equivalent to clear() followed by resize(0)
|
// Equivalent to clear() followed by resize(0)
|
||||||
void clearStorage();
|
void clearStorage();
|
||||||
|
|
||||||
//- Shrink the allocated table to approx. twice number of elements
|
//- Shrink the allocated table to approx. twice number of elements
|
||||||
void shrink();
|
void shrink();
|
||||||
|
|
||||||
//- Transfer the contents of the argument table into this table
|
//- Transfer the contents of the argument table into this table
|
||||||
// and annul the argument table.
|
// and annul the argument table.
|
||||||
void transfer(HashTable<T, Key, Hash>& ht);
|
void transfer(HashTable<T, Key, Hash>& ht);
|
||||||
|
|
||||||
//- Transfer contents to the Xfer container
|
//- Transfer contents to the Xfer container
|
||||||
inline Xfer<HashTable<T, Key, Hash>> xfer();
|
inline Xfer<HashTable<T, Key, Hash>> xfer();
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -345,65 +411,25 @@ public:
|
|||||||
bool operator!=(const HashTable<T, Key, Hash>& rhs) const;
|
bool operator!=(const HashTable<T, Key, Hash>& rhs) const;
|
||||||
|
|
||||||
|
|
||||||
// STL type definitions
|
protected:
|
||||||
|
|
||||||
//- Type of keys that the HashTable uses.
|
|
||||||
typedef Key key_type;
|
|
||||||
|
|
||||||
//- Type of values that the HashTable contains.
|
|
||||||
typedef T value_type;
|
|
||||||
|
|
||||||
//- Type that can be used for storing into HashTable::value_type
|
|
||||||
// objects. This type is usually List::value_type&.
|
|
||||||
typedef T& reference;
|
|
||||||
|
|
||||||
//- Type that can be used for storing into constant
|
|
||||||
// HashTable::value_type objects. This type is usually const
|
|
||||||
// HashTable::value_type&.
|
|
||||||
typedef const T& const_reference;
|
|
||||||
|
|
||||||
//- The type that can represent the size of a HashTable.
|
|
||||||
typedef label size_type;
|
|
||||||
|
|
||||||
|
|
||||||
// Iterator access
|
|
||||||
|
|
||||||
//- Iterator set to the beginning of the HashTable
|
|
||||||
inline iterator begin();
|
|
||||||
|
|
||||||
//- const_iterator set to the beginning of the HashTable
|
|
||||||
inline const_iterator begin() const;
|
|
||||||
|
|
||||||
//- const_iterator set to the beginning of the HashTable
|
|
||||||
inline const_iterator cbegin() const;
|
|
||||||
|
|
||||||
//- iterator to signal the end for any HashTable
|
|
||||||
inline const iterator& end();
|
|
||||||
|
|
||||||
//- const_iterator to signal the end for any HashTable
|
|
||||||
inline const const_iterator& end() const;
|
|
||||||
|
|
||||||
//- const_iterator to signal the end for any HashTable
|
|
||||||
inline const const_iterator& cend() const;
|
|
||||||
|
|
||||||
|
|
||||||
// Iterators and helpers
|
// Iterators and helpers
|
||||||
|
|
||||||
//- The iterator base for HashTable
|
//- The iterator base for HashTable (internal use only).
|
||||||
// Note: data and functions are protected, to allow reuse by iterator
|
// Note: data and functions are protected, to allow reuse by iterator
|
||||||
// and prevent most external usage.
|
// and prevent most external usage.
|
||||||
// iterator and const_iterator have the same size, allowing
|
// iterator and const_iterator have the same size, allowing
|
||||||
// us to reinterpret_cast between them (if desired)
|
// us to reinterpret_cast between them (if desired)
|
||||||
class iteratorBase
|
class iterator_base
|
||||||
{
|
{
|
||||||
using entry_type = hashedEntry;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Public typedefs
|
// Public typedefs
|
||||||
using table_type = HashTable<T, Key, Hash>;
|
using table_type = this_type;
|
||||||
using key_type = HashTable<T, Key, Hash>::key_type;
|
using key_type = this_type::key_type;
|
||||||
|
using difference_type = this_type::difference_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using entry_type = hashedEntry;
|
||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
@ -428,25 +454,25 @@ public:
|
|||||||
//- Increment to the next position
|
//- Increment to the next position
|
||||||
inline void increment();
|
inline void increment();
|
||||||
|
|
||||||
//- Erase the entry at the current position
|
|
||||||
bool erase();
|
|
||||||
|
|
||||||
//- The referenced object/value element
|
//- The referenced object/value element
|
||||||
inline T& element() const;
|
inline T& element() const;
|
||||||
|
|
||||||
|
//- Erase the entry at the current position
|
||||||
|
bool erase();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct null (end iterator)
|
//- Construct null (end iterator)
|
||||||
inline iteratorBase();
|
inline iterator_base();
|
||||||
|
|
||||||
//- Construct from begin of hash-table
|
//- Construct from begin of hash-table
|
||||||
inline explicit iteratorBase(const table_type* hashTbl);
|
inline explicit iterator_base(const table_type* hashTbl);
|
||||||
|
|
||||||
//- Construct from hash table, element and hash index
|
//- Construct from hash table, element and hash index
|
||||||
inline iteratorBase
|
inline iterator_base
|
||||||
(
|
(
|
||||||
const table_type* hashTbl,
|
const table_type* hashTbl,
|
||||||
const entry_type* elmt,
|
const entry_type* elmt,
|
||||||
@ -463,27 +489,49 @@ public:
|
|||||||
inline const Key& key() const;
|
inline const Key& key() const;
|
||||||
|
|
||||||
//- Compare hash-entry element pointers
|
//- Compare hash-entry element pointers
|
||||||
inline bool operator==(const iteratorBase& iter) const;
|
inline bool operator==(const iterator_base& iter) const;
|
||||||
inline bool operator!=(const iteratorBase& iter) const;
|
inline bool operator!=(const iterator_base& iter) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- An iterator wrapper for returning a reference to the key
|
||||||
|
template<class WrappedIterator>
|
||||||
|
class key_iterator_base
|
||||||
|
:
|
||||||
|
public WrappedIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using reference = const Key&;
|
||||||
|
using difference_type = typename WrappedIterator::difference_type;
|
||||||
|
|
||||||
|
//- Implicit conversion
|
||||||
|
inline key_iterator_base(const WrappedIterator& iter);
|
||||||
|
|
||||||
|
//- Return the key
|
||||||
|
inline reference operator*() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// STL iterator
|
// STL iterator
|
||||||
|
|
||||||
//- An STL-conforming iterator
|
//- Forward iterator with non-const access
|
||||||
class iterator
|
class iterator
|
||||||
:
|
:
|
||||||
public iteratorBase
|
public iterator_base
|
||||||
{
|
{
|
||||||
friend class HashTable; // uses iterator::erase() method
|
friend class HashTable; // Uses iterator::erase() method
|
||||||
using entry_type = hashedEntry;
|
using entry_type = hashedEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Public typedefs
|
// Public typedefs
|
||||||
using table_type = HashTable<T, Key, Hash>;
|
using table_type = this_type;
|
||||||
using key_type = HashTable<T, Key, Hash>::key_type;
|
using key_type = this_type::key_type;
|
||||||
using reference = HashTable<T, Key, Hash>::reference;
|
using reference = this_type::reference;
|
||||||
|
using difference_type = typename iterator_base::difference_type;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
@ -518,19 +566,20 @@ public:
|
|||||||
|
|
||||||
// STL const_iterator
|
// STL const_iterator
|
||||||
|
|
||||||
//- An STL-conforming const_iterator
|
//- Forward iterator with const access
|
||||||
class const_iterator
|
class const_iterator
|
||||||
:
|
:
|
||||||
public iteratorBase
|
public iterator_base
|
||||||
{
|
{
|
||||||
using entry_type = const hashedEntry;
|
using entry_type = const hashedEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Public typedefs
|
// Public typedefs
|
||||||
using table_type = const HashTable<T, Key, Hash>;
|
using table_type = const this_type;
|
||||||
using key_type = HashTable<T, Key, Hash>::key_type;
|
using key_type = this_type::key_type;
|
||||||
using reference = HashTable<T, Key, Hash>::const_reference;
|
using reference = this_type::const_reference;
|
||||||
|
using difference_type = typename iterator_base::difference_type;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
@ -566,6 +615,43 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//- Iterating over keys only
|
||||||
|
|
||||||
|
//- Forward iterator returning the key
|
||||||
|
using key_iterator = key_iterator_base<iterator>;
|
||||||
|
|
||||||
|
//- Forward const iterator returning the key
|
||||||
|
using const_key_iterator = key_iterator_base<const_iterator>;
|
||||||
|
|
||||||
|
//- A const iterator begin/end pair for iterating over keys
|
||||||
|
const_iterator_pair<const_key_iterator, this_type> keys() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
const_iterator_pair<const_key_iterator,this_type>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Iterator access
|
||||||
|
|
||||||
|
//- Iterator set to the beginning of the HashTable
|
||||||
|
inline iterator begin();
|
||||||
|
|
||||||
|
//- const_iterator set to the beginning of the HashTable
|
||||||
|
inline const_iterator begin() const;
|
||||||
|
|
||||||
|
//- const_iterator set to the beginning of the HashTable
|
||||||
|
inline const_iterator cbegin() const;
|
||||||
|
|
||||||
|
//- iterator to signal the end for any HashTable
|
||||||
|
inline const iterator& end();
|
||||||
|
|
||||||
|
//- const_iterator to signal the end for any HashTable
|
||||||
|
inline const const_iterator& end() const;
|
||||||
|
|
||||||
|
//- const_iterator to signal the end for any HashTable
|
||||||
|
inline const const_iterator& cend() const;
|
||||||
|
|
||||||
|
|
||||||
// Writing
|
// Writing
|
||||||
|
|
||||||
//- Print information
|
//- Print information
|
||||||
@ -598,6 +684,7 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "HashTableCoreI.H"
|
||||||
#include "HashTableI.H"
|
#include "HashTableI.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -3,7 +3,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) 2011-2012 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -33,38 +33,53 @@ namespace Foam
|
|||||||
defineTypeNameAndDebug(HashTableCore, 0);
|
defineTypeNameAndDebug(HashTableCore, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Foam::label Foam::HashTableCore::maxTableSize
|
|
||||||
(
|
// Approximately labelMax/4
|
||||||
Foam::HashTableCore::canonicalSize
|
const Foam::label Foam::HashTableCore::maxTableSize(1 << (sizeof(label)*8-3));
|
||||||
(
|
|
||||||
Foam::labelMax/2
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::label Foam::HashTableCore::canonicalSize(const label size)
|
Foam::label Foam::HashTableCore::canonicalSize(const label requested_size)
|
||||||
{
|
{
|
||||||
if (size < 1)
|
if (requested_size < 1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforce power of two
|
// Enforce power of two - makes for a vey fast modulus etc.
|
||||||
uLabel goodSize = size;
|
// Use unsigned for these calculations.
|
||||||
|
//
|
||||||
|
// - The lower limit (8) is somewhat arbitrary, but if the hash table
|
||||||
|
// is too small, there will be many direct table collisions.
|
||||||
|
// - The uper limit (approx. labelMax/4) must be a power of two,
|
||||||
|
// need not be extremely large for hashing.
|
||||||
|
|
||||||
if (goodSize & (goodSize - 1))
|
uLabel powerOfTwo = 8; // lower-limit
|
||||||
|
|
||||||
|
const uLabel size = requested_size;
|
||||||
|
if (size < powerOfTwo)
|
||||||
{
|
{
|
||||||
// brute-force is fast enough
|
return powerOfTwo;
|
||||||
goodSize = 1;
|
|
||||||
while (goodSize < unsigned(size))
|
|
||||||
{
|
|
||||||
goodSize <<= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (requested_size >= maxTableSize)
|
||||||
|
{
|
||||||
|
return maxTableSize;
|
||||||
|
}
|
||||||
|
else if (size & (size-1)) // <- Modulus of i^2
|
||||||
|
{
|
||||||
|
// Determine power-of-two. Brute-force is fast enough.
|
||||||
|
while (powerOfTwo < size)
|
||||||
|
{
|
||||||
|
powerOfTwo <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
return goodSize;
|
return powerOfTwo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
146
src/OpenFOAM/containers/HashTables/HashTable/HashTableCoreI.H
Normal file
146
src/OpenFOAM/containers/HashTables/HashTable/HashTableCoreI.H
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * helper methods * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline IteratorType Foam::HashTableCore::iterator_begin
|
||||||
|
(
|
||||||
|
TableType& table
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return IteratorType(table.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline IteratorType Foam::HashTableCore::iterator_begin
|
||||||
|
(
|
||||||
|
const TableType& table
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return IteratorType(table.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline IteratorType Foam::HashTableCore::iterator_cbegin
|
||||||
|
(
|
||||||
|
const TableType& table
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return IteratorType(table.cbegin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType>
|
||||||
|
inline const IteratorType& Foam::HashTableCore::iterator_end()
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const IteratorType*>(nullObjectPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType>
|
||||||
|
inline const IteratorType& Foam::HashTableCore::iterator_cend()
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const IteratorType*>(nullObjectPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * const iterator pair * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline Foam::HashTableCore::const_iterator_pair<IteratorType, TableType>
|
||||||
|
::const_iterator_pair
|
||||||
|
(
|
||||||
|
const TableType& tbl
|
||||||
|
)
|
||||||
|
:
|
||||||
|
size_(tbl.size()),
|
||||||
|
iter_(tbl.begin())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline Foam::label
|
||||||
|
Foam::HashTableCore::const_iterator_pair<IteratorType, TableType>::size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline bool
|
||||||
|
Foam::HashTableCore::const_iterator_pair<IteratorType, TableType>::empty() const
|
||||||
|
{
|
||||||
|
return !size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline IteratorType Foam::HashTableCore::const_iterator_pair
|
||||||
|
<
|
||||||
|
IteratorType,
|
||||||
|
TableType
|
||||||
|
>::begin() const
|
||||||
|
{
|
||||||
|
return iter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline IteratorType Foam::HashTableCore::const_iterator_pair
|
||||||
|
<
|
||||||
|
IteratorType,
|
||||||
|
TableType
|
||||||
|
>::cbegin() const
|
||||||
|
{
|
||||||
|
return iter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline const IteratorType& Foam::HashTableCore::const_iterator_pair
|
||||||
|
<
|
||||||
|
IteratorType,
|
||||||
|
TableType
|
||||||
|
>::end() const
|
||||||
|
{
|
||||||
|
return HashTableCore::iterator_cend<IteratorType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class IteratorType, class TableType>
|
||||||
|
inline const IteratorType& Foam::HashTableCore::const_iterator_pair
|
||||||
|
<
|
||||||
|
IteratorType,
|
||||||
|
TableType
|
||||||
|
>::cend() const
|
||||||
|
{
|
||||||
|
return HashTableCore::iterator_cend<IteratorType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -159,7 +159,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
|
|||||||
// * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase()
|
inline Foam::HashTable<T, Key, Hash>::iterator_base::iterator_base()
|
||||||
:
|
:
|
||||||
entryPtr_(nullptr),
|
entryPtr_(nullptr),
|
||||||
hashTable_(nullptr),
|
hashTable_(nullptr),
|
||||||
@ -168,7 +168,7 @@ inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase()
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
inline Foam::HashTable<T, Key, Hash>::iterator_base::iterator_base
|
||||||
(
|
(
|
||||||
const table_type* hashTbl,
|
const table_type* hashTbl,
|
||||||
const entry_type* elmt,
|
const entry_type* elmt,
|
||||||
@ -182,7 +182,7 @@ inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
inline Foam::HashTable<T, Key, Hash>::iterator_base::iterator_base
|
||||||
(
|
(
|
||||||
const table_type* hashTbl
|
const table_type* hashTbl
|
||||||
)
|
)
|
||||||
@ -213,7 +213,7 @@ inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
|||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline void
|
inline void
|
||||||
Foam::HashTable<T, Key, Hash>::iteratorBase::increment()
|
Foam::HashTable<T, Key, Hash>::iterator_base::increment()
|
||||||
{
|
{
|
||||||
// A negative index is a special value from erase
|
// A negative index is a special value from erase
|
||||||
if (hashIndex_ < 0)
|
if (hashIndex_ < 0)
|
||||||
@ -257,30 +257,30 @@ Foam::HashTable<T, Key, Hash>::iteratorBase::increment()
|
|||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline bool
|
inline bool
|
||||||
Foam::HashTable<T, Key, Hash>::iteratorBase::found() const
|
Foam::HashTable<T, Key, Hash>::iterator_base::found() const
|
||||||
{
|
{
|
||||||
return entryPtr_;
|
return entryPtr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline const Key& Foam::HashTable<T, Key, Hash>::iteratorBase::key() const
|
inline const Key& Foam::HashTable<T, Key, Hash>::iterator_base::key() const
|
||||||
{
|
{
|
||||||
return entryPtr_->key_;
|
return entryPtr_->key_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline T& Foam::HashTable<T, Key, Hash>::iteratorBase::element() const
|
inline T& Foam::HashTable<T, Key, Hash>::iterator_base::element() const
|
||||||
{
|
{
|
||||||
return entryPtr_->obj_;
|
return entryPtr_->obj_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator==
|
inline bool Foam::HashTable<T, Key, Hash>::iterator_base::operator==
|
||||||
(
|
(
|
||||||
const iteratorBase& iter
|
const iterator_base& iter
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return entryPtr_ == iter.entryPtr_;
|
return entryPtr_ == iter.entryPtr_;
|
||||||
@ -288,21 +288,45 @@ inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator==
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!=
|
inline bool Foam::HashTable<T, Key, Hash>::iterator_base::operator!=
|
||||||
(
|
(
|
||||||
const iteratorBase& iter
|
const iterator_base& iter
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return entryPtr_ != iter.entryPtr_;
|
return entryPtr_ != iter.entryPtr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * key iterator base * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
template<class WrappedIterator>
|
||||||
|
inline Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
|
||||||
|
::key_iterator_base
|
||||||
|
(
|
||||||
|
const WrappedIterator& iter
|
||||||
|
)
|
||||||
|
:
|
||||||
|
WrappedIterator(iter)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
template<class WrappedIterator>
|
||||||
|
inline const Key&
|
||||||
|
Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
|
||||||
|
::operator*() const
|
||||||
|
{
|
||||||
|
return this->key();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator()
|
inline Foam::HashTable<T, Key, Hash>::iterator::iterator()
|
||||||
:
|
:
|
||||||
iteratorBase()
|
iterator_base()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -312,7 +336,7 @@ inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
|||||||
table_type* hashTbl
|
table_type* hashTbl
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
iteratorBase(hashTbl)
|
iterator_base(hashTbl)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -324,7 +348,7 @@ inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
|||||||
const label hashIndex
|
const label hashIndex
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
iteratorBase(hashTbl, elmt, hashIndex)
|
iterator_base(hashTbl, elmt, hashIndex)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -371,12 +395,12 @@ Foam::HashTable<T, Key, Hash>::iterator::operator++(int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator()
|
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator()
|
||||||
:
|
:
|
||||||
iteratorBase()
|
iterator_base()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -386,7 +410,7 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
|||||||
const HashTable<T, Key, Hash>::iterator& iter
|
const HashTable<T, Key, Hash>::iterator& iter
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
iteratorBase(iter)
|
iterator_base(iter)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -396,7 +420,7 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
|||||||
table_type* hashTbl
|
table_type* hashTbl
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
iteratorBase(hashTbl)
|
iterator_base(hashTbl)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -408,7 +432,7 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
|||||||
const label hashIndex
|
const label hashIndex
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
iteratorBase(hashTbl, elmt, hashIndex)
|
iterator_base(hashTbl, elmt, hashIndex)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -467,7 +491,7 @@ Foam::HashTable<T, Key, Hash>::begin()
|
|||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
||||||
Foam::HashTable<T, Key, Hash>::cbegin() const
|
Foam::HashTable<T, Key, Hash>::begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(this);
|
return const_iterator(this);
|
||||||
}
|
}
|
||||||
@ -475,7 +499,7 @@ Foam::HashTable<T, Key, Hash>::cbegin() const
|
|||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
||||||
Foam::HashTable<T, Key, Hash>::begin() const
|
Foam::HashTable<T, Key, Hash>::cbegin() const
|
||||||
{
|
{
|
||||||
return const_iterator(this);
|
return const_iterator(this);
|
||||||
}
|
}
|
||||||
@ -485,19 +509,7 @@ template<class T, class Key, class Hash>
|
|||||||
inline const typename Foam::HashTable<T, Key, Hash>::iterator&
|
inline const typename Foam::HashTable<T, Key, Hash>::iterator&
|
||||||
Foam::HashTable<T, Key, Hash>::end()
|
Foam::HashTable<T, Key, Hash>::end()
|
||||||
{
|
{
|
||||||
using iter_type = typename HashTable<T, Key, Hash>::iterator;
|
return iterator_end<iterator>();
|
||||||
|
|
||||||
return endIteratorRef<iter_type>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
|
||||||
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
|
||||||
Foam::HashTable<T, Key, Hash>::cend() const
|
|
||||||
{
|
|
||||||
using iter_type = typename HashTable<T, Key, Hash>::const_iterator;
|
|
||||||
|
|
||||||
return endIteratorRef<iter_type>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -505,9 +517,15 @@ template<class T, class Key, class Hash>
|
|||||||
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
||||||
Foam::HashTable<T, Key, Hash>::end() const
|
Foam::HashTable<T, Key, Hash>::end() const
|
||||||
{
|
{
|
||||||
using iter_type = typename HashTable<T, Key, Hash>::const_iterator;
|
return iterator_end<const_iterator>();
|
||||||
|
}
|
||||||
|
|
||||||
return endIteratorRef<iter_type>();
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
||||||
|
Foam::HashTable<T, Key, Hash>::cend() const
|
||||||
|
{
|
||||||
|
return iterator_cend<const_iterator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -130,7 +130,7 @@ Foam::Ostream& Foam::HashTable<T, Key, Hash>::writeKeys
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check state of IOstream
|
// Check state of IOstream
|
||||||
os.check("HashSet<Key>::writeList(Ostream&)");
|
os.check(FUNCTION_NAME);
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ Foam::Ostream& Foam::operator<<
|
|||||||
os << token::END_LIST;
|
os << token::END_LIST;
|
||||||
|
|
||||||
// Check state of IOstream
|
// Check state of IOstream
|
||||||
os.check("Ostream& operator<<(Ostream&, const HashTable&)");
|
os.check(FUNCTION_NAME);
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,8 +78,8 @@ template<class T, class Key, class Hash> Ostream& operator<<
|
|||||||
//- Template-invariant bits for StaticHashTable
|
//- Template-invariant bits for StaticHashTable
|
||||||
struct StaticHashTableCore
|
struct StaticHashTableCore
|
||||||
{
|
{
|
||||||
//- Return a canonical (power-of-two) size
|
//- Return a canonical (power-of-two) of the requested size.
|
||||||
static label canonicalSize(const label size);
|
static label canonicalSize(const label requested_size);
|
||||||
|
|
||||||
//- Construct null
|
//- Construct null
|
||||||
StaticHashTableCore()
|
StaticHashTableCore()
|
||||||
|
|||||||
@ -34,30 +34,42 @@ defineTypeNameAndDebug(StaticHashTableCore, 0);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Approximately labelMax/4
|
||||||
|
static const Foam::label maxTableSize(1 << (sizeof(Foam::label)*8-3));
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::label Foam::StaticHashTableCore::canonicalSize(const label size)
|
Foam::label Foam::StaticHashTableCore::canonicalSize(const label requested_size)
|
||||||
{
|
{
|
||||||
if (size < 1)
|
if (requested_size < 1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce power of two - makes for a vey fast modulus etc.
|
// Enforce power of two - makes for a vey fast modulus etc.
|
||||||
// The value '8' is some arbitrary lower limit.
|
// Use unsigned for these calculations.
|
||||||
// If the hash table is too small, there will be many table collisions!
|
//
|
||||||
|
// - The lower limit (8) is somewhat arbitrary, but if the hash table
|
||||||
|
// is too small, there will be many direct table collisions.
|
||||||
|
// - The uper limit (approx. labelMax/4) must be a power of two,
|
||||||
|
// need not be extremely large for hashing.
|
||||||
|
|
||||||
const uLabel unsigned_size = size;
|
uLabel powerOfTwo = 8; // lower-limit
|
||||||
uLabel powerOfTwo = 8;
|
|
||||||
|
|
||||||
|
const uLabel size = requested_size;
|
||||||
if (size < powerOfTwo)
|
if (size < powerOfTwo)
|
||||||
{
|
{
|
||||||
return powerOfTwo;
|
return powerOfTwo;
|
||||||
}
|
}
|
||||||
else if (unsigned_size & (unsigned_size-1)) // <- Modulus of i^2
|
else if (requested_size >= maxTableSize)
|
||||||
|
{
|
||||||
|
return maxTableSize;
|
||||||
|
}
|
||||||
|
else if (size & (size-1)) // <- Modulus of i^2
|
||||||
{
|
{
|
||||||
// Determine power-of-two. Brute-force is fast enough.
|
// Determine power-of-two. Brute-force is fast enough.
|
||||||
while (powerOfTwo < unsigned_size)
|
while (powerOfTwo < size)
|
||||||
{
|
{
|
||||||
powerOfTwo <<= 1;
|
powerOfTwo <<= 1;
|
||||||
}
|
}
|
||||||
@ -66,7 +78,7 @@ Foam::label Foam::StaticHashTableCore::canonicalSize(const label size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return unsigned_size;
|
return size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user