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 | Copyright (C) 2011-2012 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Macros to ease declaration of run-time selection tables.
26 
27  declareRunTimeSelectionTable is used to create a run-time selection table
28  for a base-class which holds constructor pointers on the table.
29 
30  declareRunTimeNewSelectionTable is used to create a run-time selection
31  table for a derived-class which holds "New" pointers on the table.
32 
33 \*---------------------------------------------------------------------------*/
34 
35 #include "token.H"
36 
37 #ifndef runTimeSelectionTables_H
38 #define runTimeSelectionTables_H
39 
40 #include "autoPtr.H"
41 #include "HashTable.H"
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
45 
46 // external use:
47 // ~~~~~~~~~~~~~
48 // declare a run-time selection:
49 #define declareRunTimeSelectionTable\
50 (autoPtr,baseType,argNames,argList,parList) \
51  \
52  /* Construct from argList function pointer type */ \
53  typedef autoPtr< baseType > (*argNames##ConstructorPtr)argList; \
54  \
55  /* Construct from argList function table type */ \
56  typedef HashTable< argNames##ConstructorPtr, word, string::hash > \
57  argNames##ConstructorTable; \
58  \
59  /* Construct from argList function pointer table pointer */ \
60  static argNames##ConstructorTable* argNames##ConstructorTablePtr_; \
61  \
62  /* Table constructor called from the table add function */ \
63  static void construct##argNames##ConstructorTables(); \
64  \
65  /* Table destructor called from the table add function destructor */ \
66  static void destroy##argNames##ConstructorTables(); \
67  \
68  /* Class to add constructor from argList to table */ \
69  template< class baseType##Type > \
70  class add##argNames##ConstructorToTable \
71  { \
72  public: \
73  \
74  static autoPtr< baseType > New argList \
75  { \
76  return autoPtr< baseType >(new baseType##Type parList); \
77  } \
78  \
79  add##argNames##ConstructorToTable \
80  ( \
81  const word& lookup = baseType##Type::typeName \
82  ) \
83  { \
84  construct##argNames##ConstructorTables(); \
85  if (!argNames##ConstructorTablePtr_->insert(lookup, New)) \
86  { \
87  std::cerr<< "Duplicate entry " << lookup \
88  << " in runtime selection table " << #baseType \
89  << std::endl; \
90  error::safePrintStack(std::cerr); \
91  } \
92  } \
93  \
94  ~add##argNames##ConstructorToTable() \
95  { \
96  destroy##argNames##ConstructorTables(); \
97  } \
98  }; \
99  \
100  /* Class to add constructor from argList to table */ \
101  /* Remove only the entry (not the table) upon destruction */ \
102  template< class baseType##Type > \
103  class addRemovable##argNames##ConstructorToTable \
104  { \
105  /* retain lookup name for later removal */ \
106  const word& lookup_; \
107  \
108  public: \
109  \
110  static autoPtr< baseType > New argList \
111  { \
112  return autoPtr< baseType >(new baseType##Type parList); \
113  } \
114  \
115  addRemovable##argNames##ConstructorToTable \
116  ( \
117  const word& lookup = baseType##Type::typeName \
118  ) \
119  : \
120  lookup_(lookup) \
121  { \
122  construct##argNames##ConstructorTables(); \
123  argNames##ConstructorTablePtr_->set(lookup, New); \
124  } \
125  \
126  ~addRemovable##argNames##ConstructorToTable() \
127  { \
128  if (argNames##ConstructorTablePtr_) \
129  { \
130  argNames##ConstructorTablePtr_->erase(lookup_); \
131  } \
132  } \
133  };
134 
135 
136 
137 // external use:
138 // ~~~~~~~~~~~~~
139 // declare a run-time selection for derived classes:
140 #define declareRunTimeNewSelectionTable\
141 (autoPtr,baseType,argNames,argList,parList) \
142  \
143  /* Construct from argList function pointer type */ \
144  typedef autoPtr< baseType > (*argNames##ConstructorPtr)argList; \
145  \
146  /* Construct from argList function table type */ \
147  typedef HashTable< argNames##ConstructorPtr, word, string::hash > \
148  argNames##ConstructorTable; \
149  \
150  /* Construct from argList function pointer table pointer */ \
151  static argNames##ConstructorTable* argNames##ConstructorTablePtr_; \
152  \
153  /* Table constructor called from the table add function */ \
154  static void construct##argNames##ConstructorTables(); \
155  \
156  /* Table destructor called from the table add function destructor */ \
157  static void destroy##argNames##ConstructorTables(); \
158  \
159  /* Class to add constructor from argList to table */ \
160  template< class baseType##Type > \
161  class add##argNames##ConstructorToTable \
162  { \
163  public: \
164  \
165  static autoPtr< baseType > New##baseType argList \
166  { \
167  return autoPtr< baseType >(baseType##Type::New parList.ptr()); \
168  } \
169  \
170  add##argNames##ConstructorToTable \
171  ( \
172  const word& lookup = baseType##Type::typeName \
173  ) \
174  { \
175  construct##argNames##ConstructorTables(); \
176  if \
177  ( \
178  !argNames##ConstructorTablePtr_->insert \
179  ( \
180  lookup, \
181  New##baseType \
182  ) \
183  ) \
184  { \
185  std::cerr<< "Duplicate entry " << lookup \
186  << " in runtime selection table " << #baseType \
187  << std::endl; \
188  error::safePrintStack(std::cerr); \
189  } \
190  } \
191  \
192  ~add##argNames##ConstructorToTable() \
193  { \
194  destroy##argNames##ConstructorTables(); \
195  } \
196  }; \
197  \
198  /* Class to add constructor from argList to table */ \
199  template< class baseType##Type > \
200  class addRemovable##argNames##ConstructorToTable \
201  { \
202  /* retain lookup name for later removal */ \
203  const word& lookup_; \
204  \
205  public: \
206  \
207  static autoPtr< baseType > New##baseType argList \
208  { \
209  return autoPtr< baseType >(baseType##Type::New parList.ptr()); \
210  } \
211  \
212  addRemovable##argNames##ConstructorToTable \
213  ( \
214  const word& lookup = baseType##Type::typeName \
215  ) \
216  : \
217  lookup_(lookup) \
218  { \
219  construct##argNames##ConstructorTables(); \
220  argNames##ConstructorTablePtr_->set \
221  ( \
222  lookup, \
223  New##baseType \
224  ); \
225  } \
226  \
227  ~addRemovable##argNames##ConstructorToTable() \
228  { \
229  if (argNames##ConstructorTablePtr_) \
230  { \
231  argNames##ConstructorTablePtr_->erase(lookup_); \
232  } \
233  } \
234  };
235 
236 
237 // internal use:
238 // constructor aid
239 #define defineRunTimeSelectionTableConstructor\
240 (baseType,argNames) \
241  \
242  /* Table constructor called from the table add function */ \
243  void baseType::construct##argNames##ConstructorTables() \
244  { \
245  static bool constructed = false; \
246  if (!constructed) \
247  { \
248  constructed = true; \
249  baseType::argNames##ConstructorTablePtr_ \
250  = new baseType::argNames##ConstructorTable; \
251  } \
252  }
253 
254 
255 // internal use:
256 // destructor aid
257 #define defineRunTimeSelectionTableDestructor\
258 (baseType,argNames) \
259  \
260  /* Table destructor called from the table add function destructor */ \
261  void baseType::destroy##argNames##ConstructorTables() \
262  { \
263  if (baseType::argNames##ConstructorTablePtr_) \
264  { \
265  delete baseType::argNames##ConstructorTablePtr_; \
266  baseType::argNames##ConstructorTablePtr_ = NULL; \
267  } \
268  }
269 
270 
271 // internal use:
272 // create pointer to hash-table of functions
273 #define defineRunTimeSelectionTablePtr\
274 (baseType,argNames) \
275  \
276  /* Define the constructor function table */ \
277  baseType::argNames##ConstructorTable* \
278  baseType::argNames##ConstructorTablePtr_ = NULL
279 
280 
281 // not much in use:
282 #define defineTemplateRunTimeSelectionTablePtr(baseType,argNames) \
283  \
284  /* Define the constructor function table */ \
285  typename baseType::argNames##ConstructorTable* \
286  baseType::argNames##ConstructorTablePtr_ = NULL
287 
288 
289 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
290 
291 
292 // external use:
293 // ~~~~~~~~~~~~~
294 // define run-time selection table
295 #define defineRunTimeSelectionTable\
296 (baseType,argNames) \
297  \
298  defineRunTimeSelectionTablePtr(baseType,argNames); \
299  defineRunTimeSelectionTableConstructor(baseType,argNames); \
300  defineRunTimeSelectionTableDestructor(baseType,argNames)
301 
302 
303 // external use:
304 // ~~~~~~~~~~~~~
305 // define run-time selection table for template classes
306 // use when baseType doesn't need a template argument (eg, is a typedef)
307 #define defineTemplateRunTimeSelectionTable\
308 (baseType,argNames) \
309  \
310  template<> \
311  defineRunTimeSelectionTablePtr(baseType,argNames); \
312  template<> \
313  defineRunTimeSelectionTableConstructor(baseType,argNames); \
314  template<> \
315  defineRunTimeSelectionTableDestructor(baseType,argNames)
316 
317 
318 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
319 
320 
321 // internal use:
322 // constructor aid
323 // use when baseType requires the Targ template argument
324 #define defineTemplatedRunTimeSelectionTableConstructor\
325 (baseType,argNames,Targ) \
326  \
327  /* Table constructor called from the table add function */ \
328  void baseType< Targ >::construct##argNames##ConstructorTables() \
329  { \
330  static bool constructed = false; \
331  if (!constructed) \
332  { \
333  constructed = true; \
334  baseType< Targ >::argNames##ConstructorTablePtr_ \
335  = new baseType< Targ >::argNames##ConstructorTable; \
336  } \
337  }
338 
339 
340 // internal use:
341 // destructor aid
342 // use when baseType requires the Targ template argument
343 #define defineTemplatedRunTimeSelectionTableDestructor\
344 (baseType,argNames,Targ) \
345  \
346  /* Table destructor called from the table add function destructor */ \
347  void baseType< Targ >::destroy##argNames##ConstructorTables() \
348  { \
349  if (baseType< Targ >::argNames##ConstructorTablePtr_) \
350  { \
351  delete baseType< Targ >::argNames##ConstructorTablePtr_; \
352  baseType< Targ >::argNames##ConstructorTablePtr_ = NULL; \
353  } \
354  }
355 
356 
357 // internal use:
358 // create pointer to hash-table of functions
359 // use when baseType requires the Targ template argument
360 #define defineTemplatedRunTimeSelectionTablePtr\
361 (baseType,argNames,Targ) \
362  \
363  /* Define the constructor function table */ \
364  baseType< Targ >::argNames##ConstructorTable* \
365  baseType< Targ >::argNames##ConstructorTablePtr_ = NULL
366 
367 
368 // external use:
369 // ~~~~~~~~~~~~~
370 // define run-time selection table for template classes
371 // use when baseType requires the Targ template argument
372 #define defineTemplatedRunTimeSelectionTable\
373 (baseType,argNames,Targ) \
374  \
375  template<> \
376  defineTemplatedRunTimeSelectionTablePtr(baseType,argNames,Targ); \
377  template<> \
378  defineTemplatedRunTimeSelectionTableConstructor(baseType,argNames,Targ); \
379  template<> \
380  defineTemplatedRunTimeSelectionTableDestructor(baseType,argNames,Targ)
381 
382 
383 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
384 
385 #endif
386 
387 // ************************************************************************* //