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