typeInfo.H
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) 2018-2024 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 Description
28  Basic run-time type information using word as the type's name.
29  Used to enhance the standard RTTI to cover I/O.
30 
31  The user can get the type's type name using the type info access function
32  \code
33  type()
34  \endcode
35 
36  The isA functions:
37  \code
38  isA<Type>(obj)
39  isA_constCast<Type>(obj)
40  \endcode
41  which return const or non-const pointers to the cast object,
42  nullptr if cast is not possible (can be tested as a bool).
43 
44  The reference type cast template function:
45  \code
46  refCast<Type>(obj)
47  refConstCast<Type>(obj)
48  \endcode
49  wraps dynamic_cast to handle failed casts and generate a FatalError.
50 
51 \*---------------------------------------------------------------------------*/
52 
53 #ifndef Foam_typeInfo_H
54 #define Foam_typeInfo_H
55 
56 #include "error.H"
57 #include "className.H"
58 #include <typeinfo>
59 
60 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
61 
62 // Declarations (for use in header files)
63 
64 //- Declare a ClassNameNoDebug() with extra virtual type info
65 #define TypeNameNoDebug(TypeNameString) \
66  ClassNameNoDebug(TypeNameString); \
67  virtual const word& type() const { return typeName; }
68 
69 //- Declare a ClassName() with extra virtual type info
70 #define TypeName(TypeNameString) \
71  ClassName(TypeNameString); \
72  virtual const word& type() const { return typeName; }
73 
74 
75 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
76 
77 namespace Foam
78 {
79 
80 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
81 
82 //- Attempt dynamic_cast to \c Type.
83 // \note The template types should \em not include any \c const qualifier.
84 // \return const pointer to cast object, nullptr if cast is not possible
85 template<class Type, class U>
86 inline const Type* isA(const U& obj)
87 {
88  const U* p = &obj;
89  return dynamic_cast<const Type*>(p);
90 }
91 
92 
93 //- Attempt dynamic_cast to \c Type followed by a const_cast of the result.
94 // \note The template types should \em not include any \c const qualifier.
95 // \return non-const pointer to cast object, nullptr if cast is not possible
96 template<class Type, class U>
97 inline Type* isA_constCast(const U& obj)
98 {
99  const U* p = &obj;
100  return const_cast<Type*>(dynamic_cast<const Type*>(p));
101 }
102 
103 
104 //- Check if typeid of the object and \c Type are identical
105 template<class Type, class U>
106 inline bool isType(const U& obj)
107 {
108  return typeid(Type) == typeid(obj);
109 }
110 
111 
112 //- A dynamic_cast (for references) that generates FatalError on failed casts
113 // Respects the constness of the template types.
114 template<class Type, class U>
115 inline Type& dynamicCast(U& obj)
116 {
117  U* p = &obj;
118  Type* casted = dynamic_cast<Type*>(p);
119 
120  if (!casted)
121  {
123  << "Attempt to cast type " << typeid(U).name()
124  << " to type " << typeid(Type).name()
125  << abort(FatalError);
126  }
127 
128  return *casted;
129 }
130 
131 
132 //- A dynamic_cast (for references) that generates FatalIOError on failed casts
133 // Respects the constness of the template types.
134 template<class Type, class U>
135 inline Type& dynamicCast(U& obj, const dictionary& dict)
136 {
137  U* p = &obj;
138  Type* casted = dynamic_cast<Type*>(p);
139 
140  if (!casted)
141  {
143  << "Attempt to cast type " << typeid(U).name()
144  << " to type " << typeid(Type).name()
145  << abort(FatalIOError);
146  }
148  return *casted;
149 }
150 
151 
152 //- A dynamic_cast (for references) to \c Type reference.
153 // \note Respects the constness of the template types.
154 // \return reference to cast object, or FatalError on failed casts
155 // and use the virtual type() method for error messages.
156 template<class Type, class U>
157 inline Type& refCast(U& obj)
158 {
159  U* p = &obj;
160  Type* casted = dynamic_cast<Type*>(p);
161 
162  if (!casted)
163  {
165  << "Attempt to cast type " << obj.type()
166  << " to type " << Type::typeName
167  << abort(FatalError);
168  }
169 
170  return *casted;
171 }
173 
174 //- A dynamic_cast (for const references) to \c Type reference,
175 //- followed by a const_cast of the result.
176 // \note The template types should \em not include any \c const qualifier.
177 // \return non-const reference to cast object, or FatalError on failed casts
178 // and use the virtual type() method for error messages.
179 template<class Type, class U>
180 inline Type& refConstCast(const U& obj)
181 {
182  const U* p = &obj;
183  const Type* casted = dynamic_cast<const Type*>(p);
184 
185  if (!casted)
186  {
188  << "Attempt to cast type " << obj.type()
189  << " to type " << Type::typeName
190  << abort(FatalError);
191  }
192 
193  return const_cast<Type&>(*casted);
194 }
195 
196 
197 //- A dynamic_cast (for references) that generates FatalIOError on failed casts,
198 //- uses the virtual type() method for error messages.
199 // Respects the constness of the template types.
200 template<class Type, class U>
201 inline Type& refCast(U& obj, const dictionary& dict)
202 {
203  U* p = &obj;
204  Type* casted = dynamic_cast<Type*>(p);
205 
206  if (!casted)
207  {
209  << "Attempt to cast type " << obj.type()
210  << " to type " << Type::typeName
211  << abort(FatalIOError);
212  }
213 
214  return *casted;
215 }
216 
217 
218 //- A dynamic_cast (for references) that generates FatalError on failed casts,
219 //- uses the virtual type() method for error messages.
220 //- The index can be used to convey additional context.
221 // Respects the constness of the template types.
222 template<class Type, class U>
223 inline Type& refCast(U& obj, const label index)
224 {
225  U* p = &obj;
226  Type* casted = dynamic_cast<Type*>(p);
227 
228  if (!casted)
229  {
231  << "Attempt to cast type " << obj.type()
232  << " to type " << Type::typeName
233  << " at index " << index
234  << abort(FatalError);
235  }
236 
237  return *casted;
238 }
239 
240 
241 // * * * * * * * * * * * * * * * * Functors * * * * * * * * * * * * * * * * //
242 
243 //- Test if dynamic_cast to Type is possible, as a functor
244 template<class Type>
245 struct isAOp
246 {
247  template<class U>
248  bool operator()(const U& obj) const
249  {
250  return isA<Type, U>(obj);
251  }
252 };
253 
254 
255 //- Test if typeid is identical to the Type, as a functor
256 template<class Type>
257 struct isTypeOp
258 {
259  template<class U>
260  bool operator()(const U& obj) const
261  {
262  return isType<Type, U>(obj);
263  }
264 };
265 
266 
267 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
268 
269 } // End namespace Foam
270 
271 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
272 
273 #endif
275 // ************************************************************************* //
dictionary dict
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition: typeInfo.H:172
Type * isA_constCast(const U &obj)
Attempt dynamic_cast to Type followed by a const_cast of the result.
Definition: typeInfo.H:101
bool operator()(const U &obj) const
Definition: typeInfo.H:288
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
bool isType(const U &obj)
Check if typeid of the object and Type are identical.
Definition: typeInfo.H:112
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Type & dynamicCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts.
Definition: typeInfo.H:124
Type & refConstCast(const U &obj)
A dynamic_cast (for const references) to Type reference, followed by a const_cast of the result...
Definition: typeInfo.H:198
U
Definition: pEqn.H:72
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:637
Macro definitions for declaring ClassName(), NamespaceName(), etc.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition: typeInfo.H:87
volScalarField & p
bool operator()(const U &obj) const
Definition: typeInfo.H:274
Namespace for OpenFOAM.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...