source: ThirdParty/mpqc_open/src/lib/util/class/class.h@ bbc982

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since bbc982 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 11.3 KB
Line 
1//
2// class.h
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifdef __GNUG__
29#pragma interface
30#endif
31
32#ifndef _util_class_class_h
33#define _util_class_class_h
34
35#include <map>
36#include <set>
37#include <string>
38
39#include <stdio.h>
40#include <string.h>
41#include <stdarg.h>
42#include <iostream>
43#include <iomanip>
44#include <typeinfo>
45#include <util/ref/ref.h>
46#include <util/misc/exenv.h>
47
48namespace sc {
49
50template <class T, class C>
51class DescribedMemberDatum {
52 private:
53 T C::*member_;
54 public:
55 DescribedMemberDatum(T C::*member): member_(member) {}
56 //T &member(C *c) { return c->*member_; }
57};
58
59class DescribedClass;
60class ClassDesc;
61typedef ClassDesc* ClassDescP;
62typedef const ClassDesc* CClassDescP;
63
64class ClassDesc;
65
66/// Gives one parent class of a class.
67class ParentClass
68{
69 public:
70 enum Access { Private, Protected, Public };
71 private:
72 Access _access;
73 int _is_virtual;
74 ClassDesc* _classdesc;
75 public:
76 ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
77 ParentClass(const ParentClass&);
78 ~ParentClass();
79 int is_virtual() const;
80 Access access() const { return _access; }
81 const ClassDesc* classdesc() const;
82 void change_classdesc(ClassDesc*n);
83};
84
85/// Gives a list of parent classes of a class.
86class ParentClasses
87{
88 private:
89 int _n;
90 ParentClass** _classes;
91 void add(ParentClass*);
92 // do not allow copy constructor or assignment
93 ParentClasses(const ParentClasses&);
94 void operator=(const ParentClasses&);
95 public:
96 ParentClasses();
97 void init(const char*);
98 ~ParentClasses();
99 ParentClass& parent(int i) { return *_classes[i]; }
100 const ParentClass& parent(int i) const { return *_classes[i]; }
101 ParentClass& operator[](int i) { return *_classes[i]; }
102 const ParentClass& operator[](int i) const { return *_classes[i]; }
103 int n() const { return _n; }
104 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
105};
106
107
108class KeyVal;
109class StateIn;
110
111/** This is used to pass a function that make void constructor calls to the
112 ClassDesc constructor. */
113template <class T>
114DescribedClass* create()
115{
116 return new T;
117}
118
119/** This is used to pass a function that make KeyVal constructor calls to
120 the ClassDesc constructor. */
121template <class T>
122DescribedClass* create(const Ref<KeyVal>& keyval)
123{
124 return new T(keyval);
125}
126
127/** This is used to pass a function that make StateIn constructor calls to
128 the ClassDesc constructor. */
129template <class T>
130DescribedClass* create(StateIn& statein)
131{
132 return new T(statein);
133}
134
135class type_info_key {
136 private:
137 const std::type_info *ti_;
138 public:
139 type_info_key(): ti_(0) {}
140 type_info_key(const std::type_info *ti): ti_(ti) {}
141 type_info_key& operator=(const type_info_key&);
142 int operator==(const type_info_key&) const;
143 int operator<(const type_info_key&) const;
144 int cmp(const type_info_key&) const;
145};
146
147/** This class is used to contain information about classes.
148 Each DescribedClass type has a static ClassDesc
149 member. This member has lists of the parents, children
150 and virtual parents for each class. The
151 ClassDesc class also has a static member that is
152 a list of all described classes in the system. These
153 lists are constructed as the constructors for the static
154 ClassDesc members for each class are called and
155 are completed before main is entered. See \ref class for
156 more information.
157*/
158class ClassDesc: public Identity {
159 friend class ParentClasses;
160 private:
161 static std::map<std::string,ClassDescP> *all_;
162 static std::map<type_info_key,ClassDescP> *type_info_all_;
163 static char * classlib_search_path_;
164 static std::set<std::string> *unresolved_parents_;
165
166 char* classname_;
167 int version_;
168 ParentClasses parents_;
169 std::set<std::string> *children_;
170 DescribedClass* (*ctor_)();
171 DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
172 DescribedClass* (*stateinctor_)(StateIn&);
173 const std::type_info *ti_;
174
175 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
176
177 // do not allow copy constructor or assignment
178 ClassDesc(const ClassDesc&);
179 void operator=(const ClassDesc&);
180
181 // this is used for temporary parent class descriptors
182 ClassDesc(const char*);
183 void init(const char*,int=1,const char* p=0,
184 const std::type_info *ti=0,
185 DescribedClass* (*ctor)()=0,
186 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
187 DescribedClass* (*stateinctor)(StateIn&)=0);
188 public:
189 ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
190 DescribedClass* (*ctor)()=0,
191 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
192 DescribedClass* (*stateinctor)(StateIn&)=0);
193 ~ClassDesc();
194
195 static std::map<std::string,ClassDescP>& all();
196 const ParentClasses& parents() const { return parents_; }
197
198 /// Writes a list of all of the classes to ExEnv::out0().
199 static void list_all_classes();
200 /** Given the name of the class, return a pointer to the
201 class descriptor. */
202 static ClassDesc* name_to_class_desc(const char*);
203 /** Given a type_info object return a pointer to the ClassDesc. */
204 static ClassDesc *class_desc(const std::type_info &);
205 /// Returns the name of the class.
206 const char* name() const { return classname_; }
207 /// Returns the version number of the class.
208 int version() const { return version_; }
209 /// This member has been replaced by create().
210 DescribedClass* create_described_class() const;
211 /** Create an instance of DescribedClass with
212 exact type equal to the class to which this class
213 descriptor belongs. The constructor which takes no
214 arguments is used. If this constructor doesn't exist or
215 a static function that calls it with new wasn't
216 given to this ClassDesc when it was created, then
217 0 will be returned. */
218 virtual DescribedClass* create() const;
219 /** Create an instance of DescribedClass with exact type equal to the
220 class to which this class descriptor belongs. The KeyVal&
221 constructor is used. If this constructor doesn't exist or a static
222 function that calls it with new wasn't passed to this ClassDesc,
223 then 0 will be returned. */
224 virtual DescribedClass* create(const Ref<KeyVal>&) const;
225 /** Create an instance of DescribedClass with exact type equal to the
226 class to which this class descriptor belongs. The StateIn&
227 constructor is used. If this constructor doesn't exist or a static
228 function that calls it with new wasn't passed to this ClassDesc,
229 then 0 will be returned. */
230 virtual DescribedClass* create(StateIn&) const;
231
232 /** Attempt to dynamically load the shared object file for
233 classname. */
234 static int load_class(const char* classname);
235};
236
237/** Classes which need runtime information about themselves and their
238 relationship to other classes can virtually inherit from
239 DescribedClass. This will provide the class with the ability to query
240 its name and its version.
241 Furthermore, the class's static ClassDesc can be obtained
242 which permits several other operations. See \ref class for
243 more information. */
244class DescribedClass : public RefCount {
245 public:
246 DescribedClass();
247 DescribedClass(const DescribedClass&);
248 DescribedClass& operator=(const DescribedClass&);
249 virtual ~DescribedClass();
250 /** This returns the unique pointer to the ClassDesc corresponding
251 to the given type_info object. Null is returned if it fails. */
252 ClassDesc* class_desc() const throw();
253 /// Return the name of the object's exact type.
254 const char* class_name() const;
255 /// Return the version of the class.
256 int class_version() const;
257 /// Print the object.
258 virtual void print(std::ostream& = ExEnv::out0()) const;
259 };
260
261/** Return the ClassDesc corresponding to template argument. */
262template <class T>
263inline ClassDesc *
264class_desc()
265{
266 return ClassDesc::class_desc(typeid(T));
267}
268
269/** Return the ClassDesc corresponding to the exact type for the
270 argument. */
271inline ClassDesc *
272class_desc(DescribedClass *d)
273{
274 return ClassDesc::class_desc(typeid(*d));
275}
276
277/** Attempt to cast a DescribedClass pointer to a DescribedClass
278 descendent. It is an error for the result to be a null pointer. */
279template<class T>
280inline T
281require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
282{
283 T t = dynamic_cast<T>(p);
284 if (p && !t) {
285 va_list args;
286 va_start(args,errmsg);
287 fprintf(stderr,"A required dynamic_cast failed in: ");
288 vfprintf(stderr,errmsg,args);
289 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
290 typeid(T).name(),p->class_desc()->name());
291 fflush(stderr);
292 va_end(args);
293 abort();
294 }
295 return t;
296}
297
298/** Attempt to cast a const DescribedClass pointer to a DescribedClass
299 descendent. It is an error for the result to be a null pointer. */
300template<class T>
301inline T
302require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
303{
304 T t = dynamic_cast<T>(p);
305 if (p && !t) {
306 va_list args;
307 va_start(args,errmsg);
308 fprintf(stderr,"A required dynamic_cast failed in: ");
309 vfprintf(stderr,errmsg,args);
310 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
311 typeid(T).name(),p->class_desc()->name());
312 fflush(stderr);
313 va_end(args);
314 abort();
315 }
316 return t;
317}
318
319/** This, together with ForceLink, is used to force code for particular
320 classes to be linked into executables. */
321template <class A>
322class ForceLinkBase {
323 public:
324 ForceLinkBase() {};
325 virtual ~ForceLinkBase() {};
326 virtual DescribedClass *create(A) = 0;
327};
328
329/** This, together with ForceLinkBase, is used to force code for particular
330classes to be linked into executables. Objects are created from input and
331checkpoint files by using class name lookup to find that class's ClassDesc
332object. The ClassDesc object has members that can create the class.
333Unfortunately, linking in a library doesn't cause code for the the
334ClassDesc, and thus the class itself, to be linked. ForceLink objects are
335created in linkage.h files for each library. The code containing the main
336routine for an executable can include these linkage files to force code for
337that library's classes to be linked. */
338template <class T, class A = const Ref<KeyVal> &>
339class ForceLink: public ForceLinkBase<A> {
340 public:
341 ForceLink() {};
342 virtual ~ForceLink() {};
343 DescribedClass *create(A a) { return new T(a); }
344};
345
346}
347
348#endif
349
350// Local Variables:
351// mode: c++
352// c-file-style: "CLJ"
353// End:
Note: See TracBrowser for help on using the repository browser.