HashSet.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #ifndef HashSet_C
30 #define HashSet_C
31 
32 #include "HashSet.H"
33 #include "FixedList.H"
34 
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 
37 template<class Key, class Hash>
38 template<class InputIter>
39 inline Foam::label Foam::HashSet<Key, Hash>::assignMany
40 (
41  const label nItems,
42  InputIter first,
43  InputIter last
44 )
45 {
46  this->clear();
47  this->reserve(nItems);
48 
49  return insert(first, last);
50 }
51 
52 
53 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 
55 template<class Key, class Hash>
56 template<unsigned N>
58 :
59  parent_type(2*list.size())
60 {
61  insert(list.begin(), list.end());
62 }
63 
64 
65 template<class Key, class Hash>
67 :
68  parent_type(2*list.size())
69 {
70  insert(list.begin(), list.end());
71 }
72 
73 
74 template<class Key, class Hash>
75 template<class Addr>
77 :
78  parent_type(2*list.size())
79 {
80  insert(list.begin(), list.end());
81 }
82 
83 
84 template<class Key, class Hash>
85 Foam::HashSet<Key, Hash>::HashSet(std::initializer_list<Key> list)
86 :
87  parent_type(2*list.size())
88 {
89  insert(list.begin(), list.end());
90 }
91 
92 
93 template<class Key, class Hash>
94 template<class AnyType, class AnyHash>
96 (
98 )
99 :
100  parent_type(2*tbl.size())
101 {
102  for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
103  {
104  this->insert(iter.key());
105  }
106 }
108 
109 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
110 
111 template<class Key, class Hash>
112 template<class InputIter>
113 inline Foam::label Foam::HashSet<Key, Hash>::insert
114 (
115  InputIter first,
116  InputIter last
117 )
118 {
119  label changed = 0;
120  while (first != last)
121  {
122  if (insert(*first))
123  {
124  ++changed;
125  }
126  ++first;
127  }
128  return changed;
129 }
130 
131 
132 template<class Key, class Hash>
133 inline Foam::label Foam::HashSet<Key, Hash>::insert
134 (
135  std::initializer_list<Key> list
136 )
137 {
138  return insert(list.begin(), list.end());
139 }
140 
141 
142 template<class Key, class Hash>
143 template<unsigned N>
144 inline Foam::label Foam::HashSet<Key, Hash>::insert
145 (
146  const FixedList<Key, N>& list
147 )
148 {
149  return insert(list.begin(), list.end());
150 }
151 
152 
153 template<class Key, class Hash>
154 inline Foam::label Foam::HashSet<Key, Hash>::insert
155 (
156  const UList<Key>& list
157 )
158 {
159  return insert(list.begin(), list.end());
160 }
161 
162 
163 template<class Key, class Hash>
164 template<class Addr>
165 inline Foam::label Foam::HashSet<Key, Hash>::insert
166 (
167  const IndirectListBase<Key, Addr>& list
168 )
169 {
170  return insert(list.begin(), list.end());
171 }
172 
173 
174 template<class Key, class Hash>
175 template<class InputIter>
176 inline Foam::label Foam::HashSet<Key, Hash>::unset
177 (
178  InputIter first,
179  InputIter last
180 )
181 {
182  return this->parent_type::erase(first, last);
183 }
184 
185 
186 template<class Key, class Hash>
187 inline Foam::label Foam::HashSet<Key, Hash>::unset
188 (
189  std::initializer_list<Key> list
190 )
191 {
192  return unset(list.begin(), list.end());
193 }
194 
195 
196 template<class Key, class Hash>
197 template<unsigned N>
198 inline Foam::label Foam::HashSet<Key, Hash>::unset
199 (
200  const FixedList<Key, N>& list
201 )
202 {
203  return unset(list.begin(), list.end());
204 }
205 
206 
207 template<class Key, class Hash>
208 inline Foam::label Foam::HashSet<Key, Hash>::unset
209 (
210  const UList<Key>& list
211 )
212 {
213  return unset(list.begin(), list.end());
214 }
215 
216 
217 template<class Key, class Hash>
218 template<class Addr>
219 inline Foam::label Foam::HashSet<Key, Hash>::unset
220 (
221  const IndirectListBase<Key, Addr>& list
222 )
223 {
224  return unset(list.begin(), list.end());
225 }
226 
227 
228 template<class Key, class Hash>
230 {
231  parent_type::merge(source);
232 }
233 
234 
235 template<class Key, class Hash>
237 {
238  parent_type::merge(source);
239 }
240 
241 
242 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
243 
244 template<class Key, class Hash>
245 inline bool Foam::HashSet<Key, Hash>::operator()(const Key& key) const noexcept
246 {
247  return this->contains(key);
248 }
249 
250 
251 template<class Key, class Hash>
252 inline bool Foam::HashSet<Key, Hash>::operator[](const Key& key) const noexcept
253 {
254  return this->contains(key);
255 }
256 
257 
258 template<class Key, class Hash>
259 template<unsigned N>
261 {
262  assignMany(rhs.size(), rhs.begin(), rhs.end());
263 }
264 
265 
266 template<class Key, class Hash>
268 {
269  assignMany(rhs.size(), rhs.begin(), rhs.end());
270 }
271 
272 
273 template<class Key, class Hash>
274 void Foam::HashSet<Key, Hash>::operator=(std::initializer_list<Key> rhs)
275 {
276  assignMany(rhs.size(), rhs.begin(), rhs.end());
277 }
278 
279 
280 template<class Key, class Hash>
282 {
283  // Trivial checks first
284  if (this == &rhs)
285  {
286  return true;
287  }
288  else if (this->size() != rhs.size())
289  {
290  return false;
291  }
292 
293  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
294  {
295  if (!this->contains(iter.key()))
296  {
297  return false;
298  }
299  }
300 
301  return true;
302 }
303 
304 
305 template<class Key, class Hash>
306 bool Foam::HashSet<Key, Hash>::operator!=(const HashSet<Key, Hash>& rhs) const
307 {
308  return !operator==(rhs);
309 }
310 
311 
312 template<class Key, class Hash>
315 {
316  // Add rhs elements into lhs - avoid no-ops
317  if (this != &rhs)
318  {
319  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
320  {
321  this->insert(iter.key());
322  }
323  }
324 
325  return *this;
326 }
327 
328 
329 template<class Key, class Hash>
331 Foam::HashSet<Key, Hash>::operator&=(const HashSet<Key, Hash>& rhs)
332 {
333  this->parent_type::retain(rhs);
334  return *this;
335 }
336 
337 
338 template<class Key, class Hash>
341 {
342  // Add missed rhs elements, remove duplicate elements
343  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
344  {
345  if (this->contains(iter.key()))
346  {
347  this->erase(iter.key());
348  }
349  else
350  {
351  this->insert(iter.key());
352  }
353  }
355  return *this;
356 }
357 
358 
359 template<class Key, class Hash>
362 {
363  return this->operator|=(rhs);
364 }
365 
366 
367 template<class Key, class Hash>
370 {
371  this->parent_type::erase(rhs);
372 
373  return *this;
374 }
375 
376 
377 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
378 
379 template<class Key, class Hash>
380 Foam::Ostream& Foam::operator<<(Ostream& os, const HashSet<Key, Hash>& rhs)
381 {
382  return rhs.writeKeys(os, Detail::ListPolicy::short_length<Key>::value);
383 }
384 
385 
386 /* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */
387 
388 template<class Key, class Hash>
389 Foam::HashSet<Key, Hash> Foam::operator|
390 (
391  const HashSet<Key, Hash>& a,
392  const HashSet<Key, Hash>& b
393 )
394 {
395  HashSet<Key, Hash> result(a);
396  result |= b;
397  return result;
398 }
399 
400 
401 template<class Key, class Hash>
402 Foam::HashSet<Key, Hash> Foam::operator&
403 (
404  const HashSet<Key, Hash>& a,
405  const HashSet<Key, Hash>& b
406 )
407 {
408  HashSet<Key, Hash> result(a.capacity());
409 
410  for (const Key& k : a)
411  {
412  if (b.contains(k))
413  {
414  result.insert(k);
415  }
416  }
417 
418  return result;
419 }
420 
421 
422 template<class Key, class Hash>
423 Foam::HashSet<Key, Hash> Foam::operator^
424 (
425  const HashSet<Key, Hash>& a,
426  const HashSet<Key, Hash>& b
427 )
428 {
429  HashSet<Key, Hash> result(a);
430  result ^= b;
431  return result;
432 }
433 
434 
435 template<class Key, class Hash>
436 Foam::HashSet<Key, Hash> Foam::operator-
437 (
438  const HashSet<Key, Hash>& a,
439  const HashSet<Key, Hash>& b
440 )
441 {
442  HashSet<Key, Hash> result(a.capacity());
443 
444  for (const Key& k : a)
445  {
446  if (!b.contains(k))
447  {
448  result.insert(k);
449  }
450  }
451 
452  return result;
453 }
454 
455 
456 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
457 
458 template<class Key, class Hash>
461 {
462  return iterator
463  (
464  static_cast<parent_type&>(*this).begin()
465  );
466 }
467 
468 
469 template<class Key, class Hash>
472 {
473  return const_iterator
474  (
475  static_cast<const parent_type&>(*this).begin()
476  );
477 }
478 
479 
480 template<class Key, class Hash>
483 {
484  return const_iterator
485  (
486  static_cast<const parent_type&>(*this).cbegin()
487  );
488 }
489 
490 
491 template<class Key, class Hash>
494 {
495  return iterator();
496 }
497 
498 
499 template<class Key, class Hash>
502 {
503  return const_iterator();
504 }
505 
506 
507 template<class Key, class Hash>
508 inline constexpr typename Foam::HashSet<Key, Hash>::const_iterator
510 {
511  return const_iterator();
512 }
513 
514 
515 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
516 
517 #endif
518 
519 // ************************************************************************* //
A HashTable with keys but without contents that is similar to std::unordered_set. ...
Definition: HashSet.H:73
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
this_type & operator^=(const this_type &rhs)
Only retain unique entries (xor)
Definition: HashSet.C:333
iterator begin()
Definition: HashSet.C:453
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
iterator begin() noexcept
Return an iterator to begin traversing the FixedList.
Definition: FixedListI.H:482
srcOptions erase("case")
bool operator()(const Key &key) const noexcept
Return true if the entry exists, same as contains()
Definition: HashSet.C:238
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
bool operator==(const this_type &rhs) const
Sets are equal if all keys are equal, independent of order or underlying storage size.
Definition: HashSet.C:274
this_type & operator|=(const this_type &rhs)
Add entries to this HashSet.
Definition: HashSet.C:307
iterator end() noexcept
Return an iterator to end traversing the FixedList.
Definition: FixedListI.H:506
void operator=(const this_type &rhs)
Copy assign.
Definition: HashSet.H:445
constexpr const_iterator cend() const noexcept
Definition: HashSet.C:502
label k
Boltzmann constant.
void merge(HashSet< Key, Hash > &source)
Attempts to extract entries from source parameter and insert them into this, does not overwrite exist...
Definition: HashSet.C:222
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:232
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
void unset(List< bool > &bools, const labelUList &locations)
Unset the listed locations (assign &#39;false&#39;).
Definition: BitOps.C:99
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition: FixedList.H:600
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:342
HashSet() noexcept=default
Default construct: empty without allocation (capacity=0)
bool unset(const Key &key)
Unset the specified key - same as erase.
Definition: HashSet.H:250
label capacity() const noexcept
The size of the underlying table (the number of buckets)
Definition: HashTable.H:347
Ostream & writeKeys(Ostream &os, const label shortLen=0) const
Write unordered keys (list), with line-breaks when length exceeds shortLen.
Definition: HashTableIO.C:77
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
this_type & operator-=(const this_type &rhs)
Remove entries from this HashSet. Uses erase()
Definition: HashSet.C:362
patchWriters clear()
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:391
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
OBJstream os(runTime.globalPath()/outputName)
iterator begin()
Return an iterator at begin of list.
iterator end() noexcept
Definition: HashSet.C:486
iterator end()
Return an iterator at end of list.
this_type & operator &=(const this_type &rhs)
Only retain entries contained in both HashSets.
typename parent_type::key_iterator iterator
An iterator, returning reference to the key.
Definition: HashSet.H:126
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
triangles reserve(surf.size())
bool operator[](const Key &key) const noexcept
Return true if the entry exists, same as contains().
Definition: HashSet.C:245
this_type & operator+=(const this_type &rhs)
Add entries to this HashSet. Same as the &#39;|=&#39; operator.
Definition: HashSet.C:354
typename parent_type::const_key_iterator const_iterator
A const_iterator, returning reference to the key.
Definition: HashSet.H:131
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:435
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
const_iterator cbegin() const
Definition: HashSet.C:475
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
bool operator!=(const this_type &rhs) const
The opposite of the equality operation.
Definition: HashSet.C:299
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)