runTimeSelectionTables.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) 2019-2021 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  Macros to ease declaration of run-time selection tables.
29 
30  declareRunTimeSelectionTable is used to create a run-time selection table
31  for a base-class which holds constructor pointers on the table.
32 
33  declareRunTimeNewSelectionTable is used to create a run-time selection
34  table for a derived-class which holds "New" pointers on the table.
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #include "token.H"
39 
40 #ifndef runTimeSelectionTables_H
41 #define runTimeSelectionTables_H
42 
43 #include <memory> // For std::unique_ptr
44 #include <utility> // For std::pair
45 
46 #include "autoPtr.H"
47 #include "HashTable.H"
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 
51 // Common infrastructure
52 
53 // Not used directly: declare run-time selection (variables and methods)
54 #define declareRunTimeSelectionTableBase(returnType,prefix,argList) \
55  \
56  /* Function pointer type: construct from argList */ \
57  typedef returnType (*prefix##Ptr)argList; \
58  \
59  /* Function table type: construct from argList */ \
60  typedef ::Foam::HashTable \
61  < \
62  prefix##Ptr, \
63  ::Foam::word, \
64  ::Foam::Hash<::Foam::word> \
65  > prefix##TableType; \
66  \
67  /* Lookup aliases for constructors */ \
68  typedef ::Foam::HashTable \
69  < \
70  std::pair<::Foam::word,int>, \
71  ::Foam::word, \
72  ::Foam::Hash<::Foam::word> \
73  > prefix##CompatTableType; \
74  \
75  /* Table singleton (storage) */ \
76  static prefix##TableType* prefix##TablePtr_; \
77  \
78  /* Lookup aliases singleton (storage) */ \
79  static std::unique_ptr<prefix##CompatTableType> prefix##CompatTablePtr_; \
80  \
81  /* Aliases singleton (access) */ \
82  static prefix##CompatTableType& prefix##CompatTable(); \
83  \
84  /* Table construct/destruct helper */ \
85  static void prefix##TablePtr_construct(bool load); \
86  \
87  /* Lookup function pointer from singleton, nullptr if not found */ \
88  static prefix##Ptr prefix##Table(const ::Foam::word& k)
89 
90 
91 // Not used directly: storage and helper methods for runtime tables
92 #define defineRunTimeSelectionTableBase(baseType,prefix,Tspecialize) \
93  \
94  /* Define table singleton (storage) */ \
95  Tspecialize prefix##TableType* prefix##TablePtr_(nullptr); \
96  \
97  /* Define aliases singleton (storage) */ \
98  Tspecialize \
99  std::unique_ptr<prefix##CompatTableType> prefix##CompatTablePtr_(nullptr); \
100  \
101  /* Define table singleton (access) for aliases */ \
102  Tspecialize prefix##CompatTableType& prefix##CompatTable() \
103  { \
104  if (!prefix##CompatTablePtr_) \
105  { \
106  prefix##CompatTablePtr_.reset(new prefix##CompatTableType(16)); \
107  } \
108  return *(prefix##CompatTablePtr_); \
109  } \
110  \
111  /* Table construct/destruct helper */ \
112  Tspecialize void prefix##TablePtr_construct(bool load) \
113  { \
114  static bool constructed = false; \
115  if (load) \
116  { \
117  if (!constructed) \
118  { \
119  prefix##TablePtr_ = new prefix##TableType; \
120  constructed = true; \
121  } \
122  } \
123  else if (prefix##TablePtr_) \
124  { \
125  delete prefix##TablePtr_; \
126  prefix##TablePtr_ = nullptr; \
127  prefix##CompatTablePtr_.reset(nullptr); \
128  constructed = false; \
129  } \
130  } \
131  \
132  /* Define lookup function pointer (singleton) */ \
133  Tspecialize prefix##Ptr prefix##Table(const ::Foam::word& k) \
134  { \
135  if (prefix##TablePtr_) \
136  { \
137  const auto& tbl = *prefix##TablePtr_; \
138  auto iter = tbl.cfind(k); \
139  if (!iter.found() && prefix##CompatTablePtr_) \
140  { \
141  const auto altIter = prefix##CompatTablePtr_->cfind(k); \
142  if (altIter.found()) \
143  { \
144  const auto& alt = altIter.val(); /* <word,int> */ \
145  iter = tbl.cfind(alt.first); \
146  if (::Foam::error::warnAboutAge(alt.second)) \
147  { \
148  std::cerr \
149  << "Using [v" << alt.second << "] '" << k \
150  << "' instead of '" << alt.first \
151  << " in runtime selection table: " \
152  << #baseType << '\n' << std::endl; \
153  ::Foam::error::warnAboutAge("lookup", alt.second); \
154  } \
155  } \
156  } \
157  if (iter.found()) \
158  { \
159  return iter.val(); \
160  } \
161  } \
162  return nullptr; \
163  }
164 
165 
166 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
167 
168 //
169 // Declaration Macros
170 //
171 
172 //- Declare a run-time selection (variables and adder classes)
173 // The ptrWrapper is typically a Foam::autoPtr or a Foam::tmp container.
174 #define declareRunTimeSelectionTable\
175 (ptrWrapper,baseType,argNames,argList,parList) \
176  \
177  declareRunTimeSelectionTableBase( \
178  ptrWrapper<baseType>, argNames##Constructor, argList); \
179  \
180  /* Helper to add compatibility/alias for runtime selection table */ \
181  template<class baseType##Type> \
182  struct addAlias##argNames##ConstructorToTable \
183  { \
184  explicit addAlias##argNames##ConstructorToTable \
185  ( \
186  const ::Foam::word& k, \
187  const ::Foam::word& alias, \
188  const int ver \
189  ) \
190  { \
191  argNames##ConstructorCompatTable() \
192  .set(alias, std::pair<::Foam::word,int>(k,ver)); \
193  } \
194  }; \
195  \
196  /* Helper to add constructor from argList to table */ \
197  template<class baseType##Type> \
198  struct add##argNames##ConstructorToTable \
199  { \
200  static ptrWrapper<baseType> New argList \
201  { \
202  return ptrWrapper<baseType>(new baseType##Type parList); \
203  } \
204  \
205  explicit add##argNames##ConstructorToTable \
206  ( \
207  const ::Foam::word& k = baseType##Type::typeName \
208  ) \
209  { \
210  argNames##ConstructorTablePtr_construct(true); \
211  if (!argNames##ConstructorTablePtr_->insert(k, New)) \
212  { \
213  std::cerr \
214  << "Duplicate entry " << k << " in runtime table " \
215  << #baseType << std::endl; \
216  ::Foam::error::safePrintStack(std::cerr); \
217  } \
218  } \
219  \
220  ~add##argNames##ConstructorToTable() \
221  { \
222  argNames##ConstructorTablePtr_construct(false); \
223  } \
224  \
225  add##argNames##ConstructorToTable \
226  (const add##argNames##ConstructorToTable&) = delete; \
227  \
228  void operator= \
229  (const add##argNames##ConstructorToTable&) = delete; \
230  }; \
231  \
232  /* Helper to add constructor from argList to table */ \
233  /* Remove only the entry (not the table) upon destruction */ \
234  template<class baseType##Type> \
235  struct addRemovable##argNames##ConstructorToTable \
236  { \
237  const ::Foam::word name; /* Lookup name for later removal */ \
238  \
239  static ptrWrapper<baseType> New argList \
240  { \
241  return ptrWrapper<baseType>(new baseType##Type parList); \
242  } \
243  \
244  explicit addRemovable##argNames##ConstructorToTable \
245  ( \
246  const ::Foam::word& k = baseType##Type::typeName \
247  ) \
248  : \
249  name(k) \
250  { \
251  argNames##ConstructorTablePtr_construct(true); \
252  argNames##ConstructorTablePtr_->set(k, New); \
253  } \
254  \
255  ~addRemovable##argNames##ConstructorToTable() \
256  { \
257  if (argNames##ConstructorTablePtr_) \
258  { \
259  argNames##ConstructorTablePtr_->erase(name); \
260  } \
261  } \
262  \
263  addRemovable##argNames##ConstructorToTable \
264  (const addRemovable##argNames##ConstructorToTable&) = delete; \
265  \
266  void operator= \
267  (const addRemovable##argNames##ConstructorToTable&) = delete; \
268  };
269 
270 
271 //- Declare a run-time selection for derived classes
272 #define declareRunTimeNewSelectionTable\
273 (ptrWrapper,baseType,argNames,argList,parList) \
274  \
275  declareRunTimeSelectionTableBase( \
276  ptrWrapper<baseType>,argNames##Constructor,argList); \
277  \
278  /* Helper to add compatibility/alias for runtime selection table */ \
279  template<class baseType##Type> \
280  struct addAlias##argNames##ConstructorToTable \
281  { \
282  explicit addAlias##argNames##ConstructorToTable \
283  ( \
284  const ::Foam::word& k, \
285  const ::Foam::word& alias, \
286  const int ver \
287  ) \
288  { \
289  argNames##ConstructorCompatTable() \
290  .set(alias, std::pair<::Foam::word,int>(k,ver)); \
291  } \
292  }; \
293  \
294  /* Helper to add constructor from argList to table */ \
295  template<class baseType##Type> \
296  struct add##argNames##ConstructorToTable \
297  { \
298  static ptrWrapper<baseType> New##baseType argList \
299  { \
300  return ptrWrapper<baseType>(baseType##Type::New parList.ptr()); \
301  } \
302  \
303  explicit add##argNames##ConstructorToTable \
304  ( \
305  const ::Foam::word& k = baseType##Type::typeName \
306  ) \
307  { \
308  argNames##ConstructorTablePtr_construct(true); \
309  if (!argNames##ConstructorTablePtr_->insert(k, New##baseType)) \
310  { \
311  std::cerr \
312  << "Duplicate entry " << k << " in runtime table " \
313  << #baseType << std::endl; \
314  ::Foam::error::safePrintStack(std::cerr); \
315  } \
316  } \
317  \
318  ~add##argNames##ConstructorToTable() \
319  { \
320  argNames##ConstructorTablePtr_construct(false); \
321  } \
322  \
323  add##argNames##ConstructorToTable \
324  (const add##argNames##ConstructorToTable&) = delete; \
325  \
326  void operator= \
327  (const add##argNames##ConstructorToTable&) = delete; \
328  }; \
329  \
330  /* Helper to add constructor from argList to table */ \
331  template<class baseType##Type> \
332  struct addRemovable##argNames##ConstructorToTable \
333  { \
334  const ::Foam::word name; /* Retain name for later removal */ \
335  \
336  static ptrWrapper<baseType> New##baseType argList \
337  { \
338  return ptrWrapper<baseType>(baseType##Type::New parList.ptr()); \
339  } \
340  \
341  explicit addRemovable##argNames##ConstructorToTable \
342  ( \
343  const ::Foam::word& k = baseType##Type::typeName \
344  ) \
345  : \
346  name(k) \
347  { \
348  argNames##ConstructorTablePtr_construct(true); \
349  argNames##ConstructorTablePtr_->set(k, New##baseType); \
350  } \
351  \
352  ~addRemovable##argNames##ConstructorToTable() \
353  { \
354  if (argNames##ConstructorTablePtr_) \
355  { \
356  argNames##ConstructorTablePtr_->erase(name); \
357  } \
358  } \
359  \
360  addRemovable##argNames##ConstructorToTable \
361  (const addRemovable##argNames##ConstructorToTable&) = delete; \
362  \
363  void operator= \
364  (const addRemovable##argNames##ConstructorToTable&) = delete; \
365  };
366 
367 
368 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
369 
370 //
371 // Definition Macros
372 //
373 
374 //- Define run-time selection table
375 #define defineRunTimeSelectionTable(baseType,argNames) \
376  \
377  defineRunTimeSelectionTableBase( \
378  baseType,baseType::argNames##Constructor,)
379 
380 
381 //- Define run-time selection table for template classes
382 // use when baseType doesn't need a template argument (eg, is a typedef)
383 #define defineTemplateRunTimeSelectionTable(baseType,argNames) \
384  \
385  defineRunTimeSelectionTableBase( \
386  baseType,baseType::argNames##Constructor,template<>)
387 
388 
389 //- Define run-time selection table for template classes
390 // use when baseType requires the Targ template argument
391 #define defineTemplatedRunTimeSelectionTable(baseType,argNames,Targ) \
392  \
393  defineRunTimeSelectionTableBase( \
394  baseType,baseType<Targ>::argNames##Constructor,template<>)
395 
396 
397 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
398 
399 #endif
400 
401 // ************************************************************************* //
token.H
HashTable.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
declareRunTimeSelectionTableBase
#define declareRunTimeSelectionTableBase(returnType, prefix, argList)
Definition: runTimeSelectionTables.H:54
declareRunTimeSelectionTable
#define declareRunTimeSelectionTable(ptrWrapper, baseType, argNames, argList, parList)
Declare a run-time selection (variables and adder classes)
Definition: runTimeSelectionTables.H:174
defineTemplateRunTimeSelectionTable
#define defineTemplateRunTimeSelectionTable(baseType, argNames)
Define run-time selection table for template classes.
Definition: runTimeSelectionTables.H:383
Foam::add
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:939
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
defineRunTimeSelectionTableBase
#define defineRunTimeSelectionTableBase(baseType, prefix, Tspecialize)
Definition: runTimeSelectionTables.H:92
Foam::error::safePrintStack
static void safePrintStack(std::ostream &os)
Definition: dummyPrintStack.C:32
autoPtr.H