objectRegistryTemplates.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-2019 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 #include "objectRegistry.H"
30 #include "predicates.H"
31 #include <type_traits>
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 // Templated implementation for classes()
36 template<class MatchPredicate>
37 Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classesImpl
38 (
39  const objectRegistry& list,
40  const MatchPredicate& matchName
41 )
42 {
43  HashTable<wordHashSet> summary(2*list.size());
44 
45  // Summary (key,val) = (class-name, object-names)
46  forAllConstIters(list, iter)
47  {
48  const regIOobject* obj = iter.val();
49 
50  if (matchName(obj->name()))
51  {
52  // Create entry (if needed) and insert
53  summary(obj->type()).insert(obj->name());
54  }
55  }
56 
57  return summary;
58 }
59 
60 
61 // Templated implementation for count()
62 template<class MatchPredicate1, class MatchPredicate2>
63 Foam::label Foam::objectRegistry::countImpl
64 (
65  const objectRegistry& list,
66  const MatchPredicate1& matchClass,
67  const MatchPredicate2& matchName
68 )
69 {
70  label count = 0;
71 
72  forAllConstIters(list, iter)
73  {
74  const regIOobject* obj = iter.val();
75 
76  if (matchClass(obj->type()) && matchName(obj->name()))
77  {
78  ++count;
79  }
80  }
81 
82  return count;
83 }
84 
85 
86 // Templated implementation for count()
87 template<class Type, class MatchPredicate>
88 Foam::label Foam::objectRegistry::countTypeImpl
89 (
90  const objectRegistry& list,
91  const MatchPredicate& matchName
92 )
93 {
94  label count = 0;
95 
96  forAllConstIters(list, iter)
97  {
98  const regIOobject* obj = iter.val();
99 
100  if
101  (
102  (std::is_void<Type>::value || Foam::isA<Type>(*obj))
103  && matchName(obj->name())
104  )
105  {
106  ++count;
107  }
108  }
109 
110  return count;
111 }
112 
113 
114 // Templated implementation for names(), sortedNames()
115 template<class MatchPredicate1, class MatchPredicate2>
116 Foam::wordList Foam::objectRegistry::namesImpl
117 (
118  const objectRegistry& list,
119  const MatchPredicate1& matchClass,
120  const MatchPredicate2& matchName,
121  const bool doSort
122 )
123 {
124  wordList objNames(list.size());
125 
126  label count=0;
127  forAllConstIters(list, iter)
128  {
129  const regIOobject* obj = iter.val();
130 
131  if (matchClass(obj->type()) && matchName(obj->name()))
132  {
133  objNames[count] = obj->name();
134  ++count;
135  }
136  }
137 
138  objNames.resize(count);
139 
140  if (doSort)
141  {
142  Foam::sort(objNames);
143  }
144 
145  return objNames;
146 }
147 
148 
149 // Templated implementation for names(), sortedNames()
150 template<class Type, class MatchPredicate>
151 Foam::wordList Foam::objectRegistry::namesTypeImpl
152 (
153  const objectRegistry& list,
154  const MatchPredicate& matchName,
155  const bool doSort
156 )
157 {
158  wordList objNames(list.size());
159 
160  label count = 0;
161  forAllConstIters(list, iter)
162  {
163  const regIOobject* obj = iter.val();
164 
165  if
166  (
167  (std::is_void<Type>::value || Foam::isA<Type>(*obj))
168  && matchName(obj->name())
169  )
170  {
171  objNames[count] = obj->name();
172  ++count;
173  }
174  }
175 
176  objNames.resize(count);
177 
178  if (doSort)
179  {
180  Foam::sort(objNames);
181  }
182 
183  return objNames;
184 }
185 
186 
187 // Templated implementation for cobjects()/objects(), csorted()/sorted()
188 template<class Type, class MatchPredicate>
190 Foam::objectRegistry::objectsTypeImpl
191 (
192  const bool strict,
193  const objectRegistry& list,
194  const MatchPredicate& matchName,
195  const bool doSort
196 )
197 {
198  typedef typename std::remove_cv<Type>::type BaseType;
199 
200  UPtrList<Type> result(list.size());
201 
202  label count = 0;
203  forAllConstIters(list, iter)
204  {
205  const regIOobject* obj = iter.val();
206  const BaseType* ptr = dynamic_cast<const BaseType*>(obj);
207 
208  if
209  (
210  ptr
211  && (!strict || Foam::isType<BaseType>(*obj))
212  && matchName(obj->name())
213  )
214  {
215  result.set(count, const_cast<BaseType*>(ptr));
216  ++count;
217  }
218  }
219 
220  result.resize(count);
221 
222  if (doSort)
223  {
224  Foam::sort(result, nameOp<Type>()); // Sort by object name()
225  }
226 
227  return result;
228 }
229 
230 
231 // Templated implementation for lookupClass()
232 template<class Type>
234 Foam::objectRegistry::lookupClassTypeImpl
235 (
236  const bool strict,
237  const objectRegistry& list
238 )
239 {
240  typedef typename std::remove_cv<Type>::type BaseType;
241 
242  HashTable<Type*> result(list.capacity());
243 
244  forAllConstIters(list, iter)
245  {
246  const regIOobject* obj = iter.val();
247  const BaseType* ptr = dynamic_cast<const BaseType*>(obj);
248 
249  if
250  (
251  ptr
252  && (!strict || Foam::isType<BaseType>(*obj))
253  )
254  {
255  result.insert(obj->name(), const_cast<BaseType*>(ptr));
256  }
257  }
258 
259  return result;
260 }
262 
263 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
264 
265 template<class MatchPredicate>
268 (
269  const MatchPredicate& matchName
270 ) const
271 {
272  return classesImpl(*this, matchName);
273 }
274 
275 
276 template<class MatchPredicate>
277 Foam::label Foam::objectRegistry::count
278 (
279  const MatchPredicate& matchClass
280 ) const
281 {
282  return countImpl(*this, matchClass, predicates::always());
283 }
284 
285 
286 template<class MatchPredicate1, class MatchPredicate2>
287 Foam::label Foam::objectRegistry::count
288 (
289  const MatchPredicate1& matchClass,
290  const MatchPredicate2& matchName
291 ) const
292 {
293  return countImpl(*this, matchClass, matchName);
294 }
295 
296 
297 template<class Type, class MatchPredicate>
298 Foam::label Foam::objectRegistry::count
299 (
300  const MatchPredicate& matchName
301 ) const
302 {
303  return countTypeImpl<Type>(*this, matchName);
304 }
305 
306 
307 template<class Type>
308 Foam::label Foam::objectRegistry::count
309 (
310  const bool strict
311 ) const
312 {
313  label nObjects = 0;
314 
315  forAllConstIters(*this, iter)
316  {
317  const regIOobject* obj = iter.val();
318 
319  if
320  (
321  std::is_void<Type>::value
322  ||
323  (
324  strict
325  ? bool(Foam::isType<Type>(*obj))
326  : bool(Foam::isA<Type>(*obj))
327  )
328  )
329  {
330  ++nObjects;
331  }
332  }
333 
334  return nObjects;
335 }
336 
337 
338 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
339 
340 template<class Type, bool Strict>
343 {
344  return objectsTypeImpl<const Type>
345  (
346  Strict, *this, predicates::always(), false // doSort = false
347  );
348 }
349 
350 
351 template<class Type, bool Strict>
354 {
355  return objectsTypeImpl<Type>
356  (
357  Strict, *this, predicates::always(), false // doSort = false
358  );
359 }
360 
361 
362 template<class Type, bool Strict>
365 {
366  return objectsTypeImpl<const Type>
367  (
368  Strict, *this, predicates::always(), true // doSort = true
369  );
370 }
371 
372 
373 template<class Type, bool Strict>
376 {
377  return objectsTypeImpl<Type>
378  (
379  Strict, *this, predicates::always(), true // doSort = false
380  );
381 }
382 
383 
384 template<class Type, class MatchPredicate>
387 (
388  const MatchPredicate& matchName
389 ) const
390 {
391  // doSort = false
392  return objectsTypeImpl<const Type>(false, *this, matchName, false);
393 }
394 
395 
396 template<class Type, class MatchPredicate>
399 (
400  const MatchPredicate& matchName
401 )
402 {
403  // doSort = false
404  return objectsTypeImpl<Type>(false, *this, matchName, false);
405 }
406 
407 
408 template<class Type, class MatchPredicate>
411 (
412  const MatchPredicate& matchName
413 ) const
414 {
415  return objectsTypeImpl<const Type>(false, *this, matchName, true);
416 }
417 
418 
419 template<class Type, class MatchPredicate>
422 (
423  const MatchPredicate& matchName
424 )
425 {
426  return objectsTypeImpl<Type>(false, *this, matchName, true);
427 }
428 
429 
430 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
431 
432 template<class MatchPredicate>
434 (
435  const MatchPredicate& matchClass
436 ) const
437 {
438  return namesImpl(*this, matchClass, predicates::always(), false);
439 }
440 
441 
442 template<class MatchPredicate1, class MatchPredicate2>
444 (
445  const MatchPredicate1& matchClass,
446  const MatchPredicate2& matchName
447 ) const
448 {
449  return namesImpl(*this, matchClass, matchName, false);
450 }
451 
452 
453 template<class Type>
455 {
456  return namesTypeImpl<Type>(*this, predicates::always(), false);
457 }
458 
459 
460 template<class Type, class MatchPredicate>
462 (
463  const MatchPredicate& matchName
464 ) const
465 {
466  return namesTypeImpl<Type>(*this, matchName, false);
467 }
468 
469 
470 template<class MatchPredicate>
472 (
473  const MatchPredicate& matchClass
474 ) const
475 {
476  return namesImpl(*this, matchClass, predicates::always(), true);
477 }
478 
479 
480 template<class MatchPredicate1, class MatchPredicate2>
482 (
483  const MatchPredicate1& matchClass,
484  const MatchPredicate2& matchName
485 ) const
486 {
487  return namesImpl(*this, matchClass, matchName, true);
488 }
489 
490 
491 template<class Type>
493 {
494  return namesTypeImpl<Type>(*this, predicates::always(), true);
495 }
496 
497 
498 template<class Type, class MatchPredicate>
500 (
501  const MatchPredicate& matchName
502 ) const
503 {
504  return namesTypeImpl<Type>(*this, matchName, true);
505 }
506 
507 
508 template<class Type, bool Strict>
510 {
511  return lookupClassTypeImpl<const Type>(Strict, *this);
512 }
513 
514 
515 template<class Type, bool Strict>
517 {
518  return lookupClassTypeImpl<Type>(Strict, *this);
519 }
520 
521 
522 template<class Type>
524 (
525  const bool strict
526 ) const
527 {
528  return lookupClassTypeImpl<const Type>(strict, *this);
529 }
530 
531 
532 template<class Type>
534 (
535  const bool strict
536 )
537 {
538  return lookupClassTypeImpl<Type>(strict, *this);
539 }
540 
541 
542 template<class Type>
544 (
545  const word& name,
546  const bool recursive
547 ) const
548 {
549  return this->cfindObject<Type>(name, recursive);
550 }
551 
552 
553 template<class Type>
555 (
556  const word& name,
557  const bool recursive
558 ) const
559 {
560  return dynamic_cast<const Type*>(this->cfindIOobject(name, recursive));
561 }
562 
563 
564 template<class Type>
566 (
567  const word& name,
568  const bool recursive
569 ) const
570 {
571  return this->cfindObject<Type>(name, recursive);
572 }
573 
574 
575 template<class Type>
577 (
578  const word& name,
579  const bool recursive
580 )
581 {
582  return const_cast<Type*>(this->cfindObject<Type>(name, recursive));
583 }
584 
585 
586 template<class Type>
588 (
589  const word& name,
590  const bool recursive
591 ) const
592 {
593  return const_cast<Type*>(this->cfindObject<Type>(name, recursive));
594 }
595 
596 
597 template<class Type>
599 (
600  const word& name,
601  const bool recursive
602 ) const
603 {
604  const_iterator iter = cfind(name);
605 
606  if (iter.good())
607  {
608  const Type* ptr = dynamic_cast<const Type*>(iter.val());
609 
610  if (ptr)
611  {
612  return *ptr;
613  }
614 
616  << nl
617  << " bad lookup of " << name << " (objectRegistry "
618  << this->name()
619  << ")\n expected a " << Type::typeName
620  << ", found a " << (*iter)->type() << nl
621  << exit(FatalError);
622  }
623  else if (recursive && this->parentNotTime())
624  {
625  return parent_.lookupObject<Type>(name, recursive);
626  }
627 
629  << nl
630  << " failed lookup of " << name << " (objectRegistry "
631  << this->name()
632  << ")\n available objects of type " << Type::typeName
633  << ':' << nl
634  << names<Type>() << nl
635  << exit(FatalError);
637  return NullObjectRef<Type>();
638 }
639 
640 
641 template<class Type>
643 (
644  const word& name,
645  const bool recursive
646 ) const
647 {
648  const Type& ref = this->lookupObject<Type>(name, recursive);
649  // The above will already fail if things didn't work
650 
651  return const_cast<Type&>(ref);
652 }
653 
654 
655 template<class Type>
656 bool Foam::objectRegistry::cacheTemporaryObject(Type& obj) const
657 {
658  bool ok = false;
659 
660  readCacheTemporaryObjects();
661 
662  if (cacheTemporaryObjects_.size())
663  {
664  temporaryObjects_.insert(obj.name());
665 
666  auto iter = cacheTemporaryObjects_.find(obj.name());
667 
668  // Cache object if is in the cacheTemporaryObjects list
669  // and hasn't been cached yet
670  if (iter.good() && iter.val().first() == false)
671  {
672  iter.val().first() = true;
673  iter.val().second() = true;
674 
675  Type* cachedPtr = obj.db().template getObjectPtr<Type>(obj.name());
676 
677  // Remove any name collisions from the cache
678  if (cachedPtr && cachedPtr != &obj && cachedPtr->ownedByRegistry())
679  {
680  deleteCachedObject(cachedPtr);
681  }
682 
683  if (debug)
684  {
685  Info<< "Caching " << obj.name()
686  << " of type " << obj.type() << endl;
687  }
688 
689  obj.release();
690  obj.checkOut();
691  regIOobject::store(new Type(std::move(obj)));
692 
693  ok = true;
694  }
695  }
696 
697  return ok;
698 }
699 
700 
701 // ************************************************************************* //
bool cacheTemporaryObject(Type &obj) const
Cache the given object. Moves content and stores.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
type
Types of root.
Definition: Roots.H:52
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Type & lookupObjectRef(const word &name, const bool recursive=false) const
Lookup and return non-const reference to the object of the given Type. Fatal if not found or the wron...
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
UPtrList< const Type > csorted() const
Return sorted list of objects with a class satisfying isA<Type> or isType<Type> (with Strict) ...
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
wordList names() const
The unsorted names of all objects.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
const Type * cfindObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
HashTable< const Type * > lookupClass() const
Return all objects with a class satisfying isA<Type> or isType<Type> (with Strict) ...
UPtrList< Type > sorted()
Return sorted list of objects with a class satisfying isA<Type> or isType<Type> (with Strict) ...
bool insert(const word &key, const regIOobject * &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:342
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
Unary and binary predicates that always return true, useful for templating.
Definition: predicates.H:53
label count(const char *clsName) const
The number of objects of the given class name.
label capacity() const noexcept
The size of the underlying table (the number of buckets)
Definition: HashTable.H:347
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
Type * getObjectPtr(const word &name, const bool recursive=false) const
Return non-const pointer to the object of the given Type, using a const-cast to have it behave like a...
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
wordList sortedNames() const
The sorted names of all objects.
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
rDeltaT ref()
int debug
Static debugging option.
UPtrList< const Type > cobjects() const
Return unsorted list of objects with a class satisfying isA<Type> or isType<Type> (with Strict) ...
UPtrList< Type > objects()
Return unsorted list of objects with a class satisfying isA<Type> or isType<Type> (with Strict) ...
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:66
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool foundObject(const word &name, const bool recursive=false) const
Is the named Type found?
Registry of regIOobjects.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.