Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TListOfFunctionTemplates.cxx
Go to the documentation of this file.
1 // @(#)root/cont
2 // Author: Bianca-Cristina Cristescu March 2014
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TListOfFunctionTemplates
13 A collection of TFunction objects designed for fast access given a
14 DeclId_t and for keep track of TFunction that were described
15 unloaded function.
16 */
17 
19 #include "TClass.h"
20 #include "TExMap.h"
21 #include "TFunction.h"
22 #include "TFunctionTemplate.h"
23 #include "TMethod.h"
24 #include "TInterpreter.h"
25 #include "TVirtualMutex.h"
26 
27 ClassImp(TListOfFunctionTemplates);
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// Constructor.
31 
32 TListOfFunctionTemplates::TListOfFunctionTemplates(TClass *cl) : fClass(cl),fIds(0),
33  fUnloaded(0),fLastLoadMarker(0)
34 {
35  fIds = new TExMap;
36  fUnloaded = new THashList;
37 }
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 /// Destructor.
41 
42 TListOfFunctionTemplates::~TListOfFunctionTemplates()
43 {
44  THashList::Delete();
45  delete fIds;
46  fUnloaded->Delete();
47  delete fUnloaded;
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// Add pair<id, object> to the map of functions and their ids.
52 
53 void TListOfFunctionTemplates::MapObject(TObject *obj)
54 {
55  TFunctionTemplate *f = dynamic_cast<TFunctionTemplate*>(obj);
56  if (f) {
57  fIds->Add((Long64_t)f->GetDeclId(),(Long64_t)f);
58  }
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Add object at the beginning of the list.
63 
64 void TListOfFunctionTemplates::AddFirst(TObject *obj)
65 {
66  THashList::AddFirst(obj);
67  MapObject(obj);
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Add object at the beginning of the list and also store option.
72 /// Storing an option is useful when one wants to change the behaviour
73 /// of an object a little without having to create a complete new
74 /// copy of the object. This feature is used, for example, by the Draw()
75 /// method. It allows the same object to be drawn in different ways.
76 
77 void TListOfFunctionTemplates::AddFirst(TObject *obj, Option_t *opt)
78 {
79  THashList::AddFirst(obj,opt);
80  MapObject(obj);
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Add object at the end of the list.
85 
86 void TListOfFunctionTemplates::AddLast(TObject *obj)
87 {
88  THashList::AddLast(obj);
89  MapObject(obj);
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Add object at the end of the list and also store option.
94 /// Storing an option is useful when one wants to change the behaviour
95 /// of an object a little without having to create a complete new
96 /// copy of the object. This feature is used, for example, by the Draw()
97 /// method. It allows the same object to be drawn in different ways.
98 
99 void TListOfFunctionTemplates::AddLast(TObject *obj, Option_t *opt)
100 {
101  THashList::AddLast(obj, opt);
102  MapObject(obj);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Insert object at location idx in the list.
107 
108 void TListOfFunctionTemplates::AddAt(TObject *obj, Int_t idx)
109 {
110  THashList::AddAt(obj, idx);
111  MapObject(obj);
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Insert object after object after in the list.
116 
117 void TListOfFunctionTemplates::AddAfter(const TObject *after, TObject *obj)
118 {
119  THashList::AddAfter(after, obj);
120  MapObject(obj);
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Insert object after object after in the list.
125 
126 void TListOfFunctionTemplates::AddAfter(TObjLink *after, TObject *obj)
127 {
128  THashList::AddAfter(after, obj);
129  MapObject(obj);
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Insert object before object before in the list.
134 
135 void TListOfFunctionTemplates::AddBefore(const TObject *before, TObject *obj)
136 {
137  THashList::AddBefore(before, obj);
138  MapObject(obj);
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// Insert object before object before in the list.
143 
144 void TListOfFunctionTemplates::AddBefore(TObjLink *before, TObject *obj)
145 {
146  THashList::AddBefore(before, obj);
147  MapObject(obj);
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Remove all objects from the list. Does not delete the objects unless
152 /// the THashList is the owner (set via SetOwner()).
153 
154 void TListOfFunctionTemplates::Clear(Option_t *option)
155 {
156  fUnloaded->Clear(option);
157  fIds->Clear();
158  THashList::Clear(option);
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Delete all TFunction object files.
163 
164 void TListOfFunctionTemplates::Delete(Option_t *option /* ="" */)
165 {
166  fUnloaded->Delete(option);
167  fIds->Clear();
168  THashList::Delete(option);
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Specialize FindObject to do search for the
173 /// a function just by name or create it if its not already in the list
174 
175 TObject *TListOfFunctionTemplates::FindObject(const char *name) const
176 {
177  TObject *result = THashList::FindObject(name);
178  if (!result) {
179 
180  R__LOCKGUARD(gInterpreterMutex);
181 
182  TInterpreter::DeclId_t decl;
183  if (fClass) decl = gInterpreter->GetFunctionTemplate(fClass->GetClassInfo(),name);
184  else decl = gInterpreter->GetFunctionTemplate(0,name);
185  if (decl) result = const_cast<TListOfFunctionTemplates*>(this)->Get(decl);
186  }
187  return result;
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// Return the set of overloads for this name, collecting all available ones.
192 /// Can construct and insert new TFunction-s.
193 
194 TList* TListOfFunctionTemplates::GetListForObjectNonConst(const char* name)
195 {
196  R__LOCKGUARD(gInterpreterMutex);
197 
198  TList* overloads = (TList*)fOverloads.FindObject(name);
199  TExMap overloadsSet;
200  Bool_t wasEmpty = true;
201  if (!overloads) {
202  overloads = new TList();
203  overloads->SetName(name);
204  fOverloads.Add(overloads);
205  } else {
206  TIter iOverload(overloads);
207  while (TFunctionTemplate* over = (TFunctionTemplate*)iOverload()) {
208  wasEmpty = false;
209  overloadsSet.Add((Long64_t)(ULong64_t)over->GetDeclId(),
210  (Long64_t)(ULong64_t)over);
211  }
212  }
213 
214  // Update if needed.
215  std::vector<DeclId_t> overloadDecls;
216  ClassInfo_t* ci = fClass ? fClass->GetClassInfo() : 0;
217  gInterpreter->GetFunctionOverloads(ci, name, overloadDecls);
218  for (std::vector<DeclId_t>::const_iterator iD = overloadDecls.begin(),
219  eD = overloadDecls.end(); iD != eD; ++iD) {
220  TFunctionTemplate* over = Get(*iD);
221  if (wasEmpty || !overloadsSet.GetValue((Long64_t)(ULong64_t)over->GetDeclId())) {
222  overloads->Add(over);
223  }
224  }
225 
226  return overloads;
227 }
228 
229 ////////////////////////////////////////////////////////////////////////////////
230 /// Return the set of overloads for this name, collecting all available ones.
231 /// Can construct and insert new TFunction-s.
232 
233 TList* TListOfFunctionTemplates::GetListForObject(const char* name) const
234 {
235  return const_cast<TListOfFunctionTemplates*>(this)->GetListForObjectNonConst(name);
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Return the set of overloads for function obj, collecting all available ones.
240 /// Can construct and insert new TFunction-s.
241 
242 TList* TListOfFunctionTemplates::GetListForObject(const TObject* obj) const
243 {
244  if (!obj) return 0;
245  return const_cast<TListOfFunctionTemplates*>(this)
246  ->GetListForObjectNonConst(obj->GetName());
247 }
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// Return (after creating it if necessary) the TMethod or TFunction
251 /// describing the function corresponding to the Decl 'id'.
252 
253 TFunctionTemplate *TListOfFunctionTemplates::Get(DeclId_t id)
254 {
255  if (!id) return 0;
256 
257  TFunctionTemplate *f = (TFunctionTemplate*)fIds->GetValue((Long64_t)id);
258  if (!f) {
259  if (fClass) {
260  if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
261  } else {
262  if (!gInterpreter->ClassInfo_Contains(0,id)) return 0;
263  }
264 
265  R__LOCKGUARD(gInterpreterMutex);
266 
267  FuncTempInfo_t *m = gInterpreter->FuncTempInfo_Factory(id);
268 
269  // Let's see if this is a reload ...
270  TString name;
271  gInterpreter->FuncTempInfo_Name(m, name);
272  TFunctionTemplate* update = (TFunctionTemplate*)fUnloaded->FindObject(name);
273  if (update) {
274  fUnloaded->Remove(update);
275  update->Update(m);
276  f = update;
277  }
278  if (!f) {
279  if (fClass) f = new TFunctionTemplate(m, fClass);
280  else f = new TFunctionTemplate(m, 0);
281  }
282  // Calling 'just' THahList::Add would turn around and call
283  // TListOfFunctionTemplates::AddLast which should *also* do the fIds->Add.
284  THashList::AddLast(f);
285  fIds->Add((Long64_t)id,(Long64_t)f);
286  }
287  return f;
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Remove a pair<id, object> from the map of functions and their ids.
292 
293 void TListOfFunctionTemplates::UnmapObject(TObject *obj)
294 {
295  TFunctionTemplate *f = dynamic_cast<TFunctionTemplate*>(obj);
296  if (f) {
297  fIds->Remove((Long64_t)f->GetDeclId());
298  }
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Remove object from this collection and recursively remove the object
303 /// from all other objects (and collections).
304 /// This function overrides TCollection::RecursiveRemove that calls
305 /// the Remove function. THashList::Remove cannot be called because
306 /// it uses the hash value of the hash table. This hash value
307 /// is not available anymore when RecursiveRemove is called from
308 /// the TObject destructor.
309 
310 void TListOfFunctionTemplates::RecursiveRemove(TObject *obj)
311 {
312  if (!obj) return;
313 
314  THashList::RecursiveRemove(obj);
315  fUnloaded->RecursiveRemove(obj);
316  UnmapObject(obj);
317 
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Remove object from the list.
322 
323 TObject* TListOfFunctionTemplates::Remove(TObject *obj)
324 {
325  Bool_t found;
326 
327  found = THashList::Remove(obj);
328  if (!found) {
329  found = fUnloaded->Remove(obj);
330  }
331  UnmapObject(obj);
332  if (found) return obj;
333  else return 0;
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Remove object via its objlink from the list.
338 
339 TObject* TListOfFunctionTemplates::Remove(TObjLink *lnk)
340 {
341  if (!lnk) return 0;
342 
343  TObject *obj = lnk->GetObject();
344 
345  THashList::Remove(lnk);
346  fUnloaded->Remove(obj);
347 
348  UnmapObject(obj);
349  return obj;
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Load all the functions known to the interpreter for the scope 'fClass'
354 /// into this collection.
355 
356 void TListOfFunctionTemplates::Load()
357 {
358  if (fClass && fClass->GetClassInfo() == 0) return;
359 
360  R__LOCKGUARD(gInterpreterMutex);
361 
362  ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
363  if (currentTransaction == fLastLoadMarker) {
364  return;
365  }
366  fLastLoadMarker = currentTransaction;
367 
368  gInterpreter->LoadFunctionTemplates(fClass);
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Mark 'all func' as being unloaded.
373 /// After the unload, the function can no longer be found directly,
374 /// until the decl can be found again in the interpreter (in which
375 /// the func object will be reused.
376 
377 void TListOfFunctionTemplates::Unload()
378 {
379  TObjLink *lnk = FirstLink();
380  while (lnk) {
381  TFunctionTemplate *func = (TFunctionTemplate*)lnk->GetObject();
382 
383  fIds->Remove((Long64_t)func->GetDeclId());
384  fUnloaded->Add(func);
385 
386  lnk = lnk->Next();
387  }
388 
389  THashList::Clear();
390 }
391 
392 ////////////////////////////////////////////////////////////////////////////////
393 /// Mark 'func' as being unloaded.
394 /// After the unload, the function can no longer be found directly,
395 /// until the decl can be found again in the interpreter (in which
396 /// the func object will be reused.
397 
398 void TListOfFunctionTemplates::Unload(TFunctionTemplate *func)
399 {
400  if (THashList::Remove(func)) {
401  // We contains the object, let remove it from the other internal
402  // list and move it to the list of unloaded objects.
403 
404  fIds->Remove((Long64_t)func->GetDeclId());
405  fUnloaded->Add(func);
406  }
407 }