Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSeqCollection.cxx
Go to the documentation of this file.
1// @(#)root/cont:$Id$
2// Author: Fons Rademakers 04/08/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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 TSeqCollection
13\ingroup Containers
14Sequenceable collection abstract base class. TSeqCollection's have
15an ordering relation, i.e. there is a first and last element.
16*/
17
18#include "TSeqCollection.h"
19#include "TCollection.h"
20#include "TVirtualMutex.h"
21#include "TClass.h"
22#include "TMethodCall.h"
23
24
25////////////////////////////////////////////////////////////////////////////////
26/// Return index of object in collection. Returns -1 when object not found.
27/// Uses member IsEqual() to find object.
28
30{
31 Int_t idx = 0;
32 TIter next(this);
33 TObject *ob;
34
35 while ((ob = next())) {
36 if (ob->IsEqual(obj)) return idx;
37 idx++;
38 }
39 return -1;
40}
41
42////////////////////////////////////////////////////////////////////////////////
43/// Returns index of last object in collection. Returns -1 when no
44/// objects in collection.
45
47{
48 TObject *tmp = Last();
49 return tmp ? IndexOf(tmp) : -1;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Compare to objects in the collection. Use member Compare() of object a.
54
56{
57 if (!a && !b) return 0;
58 if (!a) return 1;
59 if (!b) return -1;
60 return a->Compare(b);
61}
62
63////////////////////////////////////////////////////////////////////////////////
64/// Sort array of TObject pointers using a quicksort algorithm.
65/// The algorithm used is a non stable sort (i.e. already sorted
66/// elements might switch/change places).
67/// Uses ObjCompare() to compare objects.
68
70{
72
73 static TObject *tmp;
74 static int i; // "static" to save stack space
75 int j;
76
77 while (last - first > 1) {
78 i = first;
79 j = last;
80 for (;;) {
81 while (++i < last && ObjCompare(a[i], a[first]) < 0)
82 ;
83 while (--j > first && ObjCompare(a[j], a[first]) > 0)
84 ;
85 if (i >= j)
86 break;
87
88 tmp = a[i];
89 a[i] = a[j];
90 a[j] = tmp;
91 }
92 if (j == first) {
93 ++first;
94 continue;
95 }
96 tmp = a[first];
97 a[first] = a[j];
98 a[j] = tmp;
99 if (j - first < last - (j + 1)) {
100 QSort(a, first, j);
101 first = j + 1; // QSort(j + 1, last);
102 } else {
103 QSort(a, j + 1, last);
104 last = j; // QSort(first, j);
105 }
106 }
107}
108
109////////////////////////////////////////////////////////////////////////////////
110/// Sort array a of TObject pointers using a quicksort algorithm.
111/// Arrays b will be sorted just like a (a determines the sort).
112/// Argument nBs is the number of TObject** arrays in b.
113/// The algorithm used is a non stable sort (i.e. already sorted
114/// elements might switch/change places).
115/// Uses ObjCompare() to compare objects.
116
118{
120
121 static TObject *tmp1, **tmp2;
122 static int i; // "static" to save stack space
123 int j,k;
124
125 static int depth = 0;
126 if (depth == 0 && nBs > 0) tmp2 = new TObject*[nBs];
127 depth++;
128
129 while (last - first > 1) {
130 i = first;
131 j = last;
132 for (;;) {
133 while (++i < last && ObjCompare(a[i], a[first]) < 0) {}
134 while (--j > first && ObjCompare(a[j], a[first]) > 0) {}
135 if (i >= j) break;
136
137 tmp1 = a[i]; for(k=0;k<nBs;k++) tmp2[k] = b[k][i];
138 a[i] = a[j]; for(k=0;k<nBs;k++) b[k][i] = b[k][j];
139 a[j] = tmp1; for(k=0;k<nBs;k++) b[k][j] = tmp2[k];
140 }
141 if (j == first) {
142 ++first;
143 continue;
144 }
145 tmp1 = a[first]; for(k=0;k<nBs;k++) tmp2[k] = b[k][first];
146 a[first] = a[j]; for(k=0;k<nBs;k++) b[k][first] = b[k][j];
147 a[j] = tmp1; for(k=0;k<nBs;k++) b[k][j] = tmp2[k];
148 if (j - first < last - (j + 1)) {
149 QSort(a, nBs, b, first, j);
150 first = j + 1; // QSort(j + 1, last);
151 } else {
152 QSort(a, nBs, b, j + 1, last);
153 last = j; // QSort(first, j);
154 }
155 }
156 depth--;
157
158 if (depth == 0 && nBs > 0) delete [] tmp2;
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Merge this collection with all collections coming in the input list. The
163/// input list must contain other collections of objects compatible with the
164/// ones in this collection and ordered in the same manner. For example, if this
165/// collection contains a TH1 object and a tree, all collections in the input
166/// list have to contain a histogram and a tree. In case the list contains
167/// collections, the objects in the input lists must also be collections with
168/// the same structure and number of objects.
169/// If some objects inside the collection are instances of a class that do not
170/// have a Merge function (like TObjString), rather than merging, a copy of each
171/// instance (via a call to Clone) is appended to the output.
172///
173/// ### Example
174/// ~~~ {.cpp}
175/// this list
176/// ____________ ---------------------|
177/// | A (TH1F) | __________ | L1 (TSeqCollection)|- [A1, B1(C1,D1,E1)]
178/// | B (TList)|-| C (TTree)| | L1 (TSeqCollection)|- [A2, B2(C2,D2,E2)]
179/// |__________| | D (TH1F) | | ... |- [...]
180/// | E (TH1F) | |____________________|
181/// |__________|
182/// ~~~
183
185{
186 Long64_t nmerged = 0;
187 if (IsEmpty() || !list) {
188 Warning("Merge", "list is empty - nothing to merge");
189 return 0;
190 }
191 if (list->IsEmpty()) {
192 Warning("Merge", "input list is empty - nothing to merge with");
193 return 0;
194 }
195 TIter nextobject(this);
196 TIter nextlist(list);
200 TSeqCollection *templist = nullptr;
202 Int_t indobj = 0;
203 TSeqCollection *notmergeable = nullptr;
205 while ((object = nextobject())) { // loop objects in this collection
207 // If current object has not dictionary just add it
208 if (!object->IsA()) {
210 } else {
211 // If current object is not mergeable just add it
212 callEnv.InitWithPrototype(object->IsA(), "Merge", "TCollection*");
213 if (!callEnv.IsValid()) mergeable = kFALSE;
214 }
215 if (mergeable) {
216 // Current object mergeable - get corresponding objects in input lists
218 // Make sure original objects are not deleted; some containers, e.g. TSelectorList, maybe owners
219 templist->SetOwner(kFALSE);
220 } else {
221 templist = nullptr;
222 }
223 nextlist.Reset();
224 Int_t indcoll = 0;
225 while ((collcrt = nextlist())) { // loop input lists
226 if (!collcrt->InheritsFrom(TSeqCollection::Class())) {
227 Error("Merge", "some objects in the input list are not collections - merging aborted");
229 return 0;
230 }
231 if (indobj > ((TSeqCollection*)collcrt)->LastIndex()) {
232 // We reached the end of this collection.
233 continue;
234 }
235 // The next object to be merged with is a collection
236 // the iterator skips the 'holes' the collections, we also need to do so.
238 if (!objtomerge) {
239 Warning("Merge", "object of type %s (position %d in list) not found in list %d. Continuing...",
240 object->ClassName(), indobj, indcoll);
241 continue;
242 }
243/*
244 // Dangerous - may try to merge non-corresponding histograms (A.G)
245 while (objtomerge == 0
246 && indobj < ((TSeqCollection*)collcrt)->LastIndex()
247 ) {
248 ++indobj;
249 objtomerge = ((TSeqCollection*)collcrt)->At(indobj);
250 }
251*/
252 if (object->IsA() != objtomerge->IsA()) {
253 Error("Merge", "object of type %s at index %d not matching object of type %s in input list",
254 object->ClassName(), indobj, objtomerge->ClassName());
256 return 0;
257 }
258 // Add object at index indobj in the temporary list
259 if (mergeable) {
260 templist->Add(objtomerge);
261 nmerged++;
262 } else {
263 // Just add it to the dedicated temp list for later addition to the current list
264 if (!notmergeable && IsA())
266 if (notmergeable)
268 else
269 Warning("Merge", "temp list for non mergeable objects not created!");
270 }
271 }
272 // Merge current object with objects in the temporary list
273 if (mergeable) {
274 callEnv.SetParam((Longptr_t) templist);
275 callEnv.Execute(object);
277 }
278 indobj++;
279 }
280
281 // Add the non-mergeable objects, if any
282 if (notmergeable && notmergeable->GetSize() > 0) {
284 while (auto onm = nxnm())
285 Add(onm->Clone());
287 }
288
289 return nmerged;
290}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
R__EXTERN TVirtualMutex * gCollectionMutex
Definition TCollection.h:45
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__LOCKGUARD2(mutex)
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5017
Collection abstract base class.
Definition TCollection.h:65
virtual Bool_t IsEmpty() const
Method or function calling interface.
Definition TMethodCall.h:37
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
Sequenceable collection abstract base class.
Int_t LastIndex() const
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
static TClass * Class()
TClass * IsA() const override
virtual TObject * Last() const =0
static void QSort(TObject **a, Int_t first, Int_t last)
Sort array of TObject pointers using a quicksort algorithm.
Long64_t Merge(TCollection *list)
Merge this collection with all collections coming in the input list.
virtual Int_t GetLast() const
Returns index of last object in collection.
static Int_t ObjCompare(TObject *a, TObject *b)
Compare to objects in the collection. Use member Compare() of object a.
void Add(TObject *obj) override