Skip to content

Commit 629a497

Browse files
committed
Support IO of forward_list as a proxied collection
1 parent e530c2e commit 629a497

20 files changed

+189
-90
lines changed

core/cont/inc/TCollectionProxyInfo.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "TError.h"
2424
#endif
2525
#include <vector>
26+
#include <forward_list>
2627

2728
#if defined(_WIN32)
2829
#if _MSC_VER<1300
@@ -250,6 +251,19 @@ namespace ROOT {
250251
}
251252
};
252253

254+
struct SfinaeHelper {
255+
// Use SFINAE to get the size of the container
256+
257+
// In general we get the size of the container with the size method
258+
template <class T>
259+
static size_t GetContainerSize(const T& c) {return c.size();}
260+
261+
// Since forward_list does not provide a size operator, we have to
262+
// use an alternative. This has a cost of course.
263+
template <class T, class ALLOCATOR>
264+
static size_t GetContainerSize(const std::forward_list<T,ALLOCATOR>& c) {return std::distance(c.begin(),c.end());}
265+
};
266+
253267
/** @class TCollectionProxyInfo::Type TCollectionProxyInfo.h TCollectionProxyInfo.h
254268
*
255269
* Small helper to encapsulate basic data accesses for
@@ -277,7 +291,7 @@ namespace ROOT {
277291
}
278292
static void* size(void* env) {
279293
PEnv_t e = PEnv_t(env);
280-
e->fSize = PCont_t(e->fObject)->size();
294+
e->fSize = SfinaeHelper::GetContainerSize(*PCont_t(e->fObject));
281295
return &e->fSize;
282296
}
283297
static void* clear(void* env) {
@@ -292,7 +306,7 @@ namespace ROOT {
292306
::new(e->buff) Iter_t(c->begin());
293307
#endif
294308
e->fIterator = c->begin();
295-
e->fSize = c->size();
309+
e->fSize = SfinaeHelper::GetContainerSize(*c);
296310
if ( 0 == e->fSize ) return e->fStart = 0;
297311
TYPENAME T::const_reference ref = *(e->iter());
298312
return e->fStart = Type<T>::address(ref);
@@ -363,6 +377,42 @@ namespace ROOT {
363377
}
364378
};
365379

380+
/** @class TCollectionProxyInfo::Pushfront TCollectionProxyInfo.h TCollectionProxyInfo.h
381+
*
382+
* Small helper to encapsulate all necessary data accesses for
383+
* containers like forward_list
384+
*
385+
* @author D.Piparo
386+
* @version 1.0
387+
* @date 26/02/2015
388+
*/
389+
template <class T> struct Pushfront : public Type<T> {
390+
typedef T Cont_t;
391+
typedef typename T::iterator Iter_t;
392+
typedef typename T::value_type Value_t;
393+
typedef Environ<Iter_t> Env_t;
394+
typedef Env_t *PEnv_t;
395+
typedef Cont_t *PCont_t;
396+
typedef Value_t *PValue_t;
397+
static void resize(void* obj, size_t n) {
398+
PCont_t c = PCont_t(obj);
399+
c->resize(n);
400+
}
401+
static void* feed(void *from, void *to, size_t size) {
402+
PCont_t c = PCont_t(to);
403+
if (size==0) return 0;
404+
PValue_t m = &(PValue_t(from)[size-1]); // Take the last item
405+
// Iterate backwards not to revert ordering
406+
for (size_t i=0; i<size; ++i, --m){
407+
c->push_front(*m);
408+
}
409+
return 0;
410+
}
411+
static int value_offset() {
412+
return 0;
413+
}
414+
};
415+
366416
/** @class TCollectionProxyInfo::Map TCollectionProxyInfo.h TCollectionProxyInfo.h
367417
*
368418
* Small helper to encapsulate all necessary data accesses for

core/meta/inc/TDictionary.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,16 @@ class TDictionary : public TNamed {
190190

191191
// Type of STL container (returned by IsSTLContainer).
192192
enum ESTLType {
193-
kNone = ROOT::kNotSTL,
194-
kVector = ROOT::kSTLvector,
195-
kList = ROOT::kSTLlist,
196-
kDeque = ROOT::kSTLdeque,
197-
kMap = ROOT::kSTLmap,
198-
kMultimap = ROOT::kSTLmultimap,
199-
kSet = ROOT::kSTLset,
200-
kMultiset = ROOT::kSTLmultiset,
201-
kBitset = ROOT::kSTLbitset
193+
kNone = ROOT::kNotSTL,
194+
kVector = ROOT::kSTLvector,
195+
kList = ROOT::kSTLlist,
196+
kForwardlist = ROOT::kSTLforwardlist,
197+
kDeque = ROOT::kSTLdeque,
198+
kMap = ROOT::kSTLmap,
199+
kMultimap = ROOT::kSTLmultimap,
200+
kSet = ROOT::kSTLset,
201+
kMultiset = ROOT::kSTLmultiset,
202+
kBitset = ROOT::kSTLbitset
202203
};
203204

204205
typedef const void *DeclId_t;

core/meta/inc/TStreamerElement.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ class TStreamerElement : public TNamed {
5959
public:
6060

6161
enum ESTLtype {
62-
kSTL = ROOT::kSTLany,
63-
kSTLstring = ROOT::kSTLstring,
64-
kSTLvector = ROOT::kSTLvector,
65-
kSTLlist = ROOT::kSTLlist,
66-
kSTLdeque = ROOT::kSTLdeque,
67-
kSTLmap = ROOT::kSTLmap,
68-
kSTLmultimap = ROOT::kSTLmultimap,
69-
kSTLset = ROOT::kSTLset,
70-
kSTLmultiset = ROOT::kSTLmultiset,
71-
kSTLbitset = ROOT::kSTLbitset
62+
kSTL = ROOT::kSTLany,
63+
kSTLstring = ROOT::kSTLstring,
64+
kSTLvector = ROOT::kSTLvector,
65+
kSTLlist = ROOT::kSTLlist,
66+
kSTLforwardlist = ROOT::kSTLforwardlist,
67+
kSTLdeque = ROOT::kSTLdeque,
68+
kSTLmap = ROOT::kSTLmap,
69+
kSTLmultimap = ROOT::kSTLmultimap,
70+
kSTLset = ROOT::kSTLset,
71+
kSTLmultiset = ROOT::kSTLmultiset,
72+
kSTLbitset = ROOT::kSTLbitset
7273
};
7374
// TStreamerElement status bits
7475
enum {

core/meta/src/TBaseClass.cxx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,16 @@ ROOT::ESTLType TBaseClass::IsSTLContainer()
110110
fSTLType = -2;
111111
} else {
112112
const char *type = gCling->BaseClassInfo_TmpltName(fInfo);
113-
if (!type) fSTLType = ROOT::kNotSTL;
114-
else if (!strcmp(type, "vector")) fSTLType = ROOT::kSTLvector;
115-
else if (!strcmp(type, "list")) fSTLType = ROOT::kSTLlist;
116-
else if (!strcmp(type, "deque")) fSTLType = ROOT::kSTLdeque;
117-
else if (!strcmp(type, "map")) fSTLType = ROOT::kSTLmap;
118-
else if (!strcmp(type, "multimap")) fSTLType = ROOT::kSTLmultimap;
119-
else if (!strcmp(type, "set")) fSTLType = ROOT::kSTLset;
120-
else if (!strcmp(type, "multiset")) fSTLType = ROOT::kSTLmultiset;
121-
else fSTLType = ROOT::kNotSTL;
113+
if (!type) fSTLType = ROOT::kNotSTL;
114+
else if (!strcmp(type, "vector")) fSTLType = ROOT::kSTLvector;
115+
else if (!strcmp(type, "list")) fSTLType = ROOT::kSTLlist;
116+
else if (!strcmp(type, "forward_list"))fSTLType = ROOT::kSTLforwardlist;
117+
else if (!strcmp(type, "deque")) fSTLType = ROOT::kSTLdeque;
118+
else if (!strcmp(type, "map")) fSTLType = ROOT::kSTLmap;
119+
else if (!strcmp(type, "multimap")) fSTLType = ROOT::kSTLmultimap;
120+
else if (!strcmp(type, "set")) fSTLType = ROOT::kSTLset;
121+
else if (!strcmp(type, "multiset")) fSTLType = ROOT::kSTLmultiset;
122+
else fSTLType = ROOT::kNotSTL;
122123
}
123124
}
124125
if (fSTLType == -2) return ROOT::kNotSTL;

core/meta/src/TCling.cxx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ bool TCling::LoadPCM(TString pcmFileName,
12141214
}
12151215

12161216
TDirectory::TContext ctxt(0);
1217-
1217+
12181218
TFile *pcmFile = new TFile(pcmFileName+"?filetype=pcm","READ");
12191219

12201220
auto listOfKeys = pcmFile->GetListOfKeys();
@@ -1227,9 +1227,9 @@ bool TCling::LoadPCM(TString pcmFileName,
12271227
}
12281228

12291229
TObjArray *protoClasses;
1230-
if (gDebug > 1)
1230+
if (gDebug > 1)
12311231
::Info("TCling::LoadPCM","reading protoclasses for %s \n",pcmFileName.Data());
1232-
1232+
12331233
pcmFile->GetObject("__ProtoClasses", protoClasses);
12341234

12351235
if (protoClasses) {
@@ -1607,7 +1607,8 @@ void TCling::RegisterModule(const char* modulename,
16071607
if (strcmp(modulename,"libCore")!=0 && strcmp(modulename,"libRint")!=0
16081608
&& strcmp(modulename,"libThread")!=0 && strcmp(modulename,"libRIO")!=0
16091609
&& strcmp(modulename,"libcomplexDict")!=0 && strcmp(modulename,"libdequeDict")!=0
1610-
&& strcmp(modulename,"liblistDict")!=0 && strcmp(modulename,"libvectorDict")!=0
1610+
&& strcmp(modulename,"liblistDict")!=0 && strcmp(modulename,"libforward_listDict")!=0
1611+
&& strcmp(modulename,"libvectorDict")!=0
16111612
&& strcmp(modulename,"libmapDict")!=0 && strcmp(modulename,"libmultimap2Dict")!=0
16121613
&& strcmp(modulename,"libmap2Dict")!=0 && strcmp(modulename,"libmultimapDict")!=0
16131614
&& strcmp(modulename,"libsetDict")!=0 && strcmp(modulename,"libmultisetDict")!=0

core/meta/src/TStreamerElement.cxx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,14 +1693,15 @@ TStreamerSTL::TStreamerSTL(const char *name, const char *title, Int_t offset,
16931693
fCtype = 0;
16941694
// Any class name that 'contains' the word will be counted
16951695
// as a STL container. Is that really what we want.
1696-
if (strstr(s,"vector")) fSTLtype = ROOT::kSTLvector;
1697-
else if (strstr(s,"list")) fSTLtype = ROOT::kSTLlist;
1698-
else if (strstr(s,"deque")) fSTLtype = ROOT::kSTLdeque;
1699-
else if (strstr(s,"multimap")) fSTLtype = ROOT::kSTLmultimap;
1700-
else if (strstr(s,"multiset")) fSTLtype = ROOT::kSTLmultiset;
1701-
else if (strstr(s,"bitset")) fSTLtype = ROOT::kSTLbitset;
1702-
else if (strstr(s,"map")) fSTLtype = ROOT::kSTLmap;
1703-
else if (strstr(s,"set")) fSTLtype = ROOT::kSTLset;
1696+
if (strstr(s,"vector")) fSTLtype = ROOT::kSTLvector;
1697+
else if (strstr(s,"list")) fSTLtype = ROOT::kSTLlist;
1698+
else if (strstr(s,"forward_list")) fSTLtype = ROOT::kSTLforwardlist;
1699+
else if (strstr(s,"deque")) fSTLtype = ROOT::kSTLdeque;
1700+
else if (strstr(s,"multimap")) fSTLtype = ROOT::kSTLmultimap;
1701+
else if (strstr(s,"multiset")) fSTLtype = ROOT::kSTLmultiset;
1702+
else if (strstr(s,"bitset")) fSTLtype = ROOT::kSTLbitset;
1703+
else if (strstr(s,"map")) fSTLtype = ROOT::kSTLmap;
1704+
else if (strstr(s,"set")) fSTLtype = ROOT::kSTLset;
17041705
if (fSTLtype == 0) { delete [] s; return;}
17051706
if (dmPointer) fSTLtype += TVirtualStreamerInfo::kOffsetP;
17061707

@@ -1852,14 +1853,15 @@ const char *TStreamerSTL::GetInclude() const
18521853
{
18531854
// Return the proper include for this element.
18541855

1855-
if (fSTLtype == ROOT::kSTLvector) IncludeNameBuffer().Form("<%s>","vector");
1856-
else if (fSTLtype == ROOT::kSTLlist) IncludeNameBuffer().Form("<%s>","list");
1857-
else if (fSTLtype == ROOT::kSTLdeque) IncludeNameBuffer().Form("<%s>","deque");
1858-
else if (fSTLtype == ROOT::kSTLmap) IncludeNameBuffer().Form("<%s>","map");
1859-
else if (fSTLtype == ROOT::kSTLset) IncludeNameBuffer().Form("<%s>","set");
1860-
else if (fSTLtype == ROOT::kSTLmultimap) IncludeNameBuffer().Form("<%s>","map");
1861-
else if (fSTLtype == ROOT::kSTLmultiset) IncludeNameBuffer().Form("<%s>","set");
1862-
else if (fSTLtype == ROOT::kSTLbitset) IncludeNameBuffer().Form("<%s>","bitset");
1856+
if (fSTLtype == ROOT::kSTLvector) IncludeNameBuffer().Form("<%s>","vector");
1857+
else if (fSTLtype == ROOT::kSTLlist) IncludeNameBuffer().Form("<%s>","list");
1858+
else if (fSTLtype == ROOT::kSTLforwardlist) IncludeNameBuffer().Form("<%s>","forward_list");
1859+
else if (fSTLtype == ROOT::kSTLdeque) IncludeNameBuffer().Form("<%s>","deque");
1860+
else if (fSTLtype == ROOT::kSTLmap) IncludeNameBuffer().Form("<%s>","map");
1861+
else if (fSTLtype == ROOT::kSTLset) IncludeNameBuffer().Form("<%s>","set");
1862+
else if (fSTLtype == ROOT::kSTLmultimap) IncludeNameBuffer().Form("<%s>","map");
1863+
else if (fSTLtype == ROOT::kSTLmultiset) IncludeNameBuffer().Form("<%s>","set");
1864+
else if (fSTLtype == ROOT::kSTLbitset) IncludeNameBuffer().Form("<%s>","bitset");
18631865
return IncludeNameBuffer();
18641866
}
18651867

core/metautils/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ ROOT_INSTALL_HEADERS()
3030

3131
#### STL dictionary (replacement for cintdlls)##############################
3232

33-
set(stldicts vector list deque map map2 set multimap multimap2 multiset complex)
33+
set(stldicts vector list forward_list deque map map2 set multimap multimap2 multiset complex)
3434
if(NOT WIN32)
3535
list(APPEND stldicts valarray)
3636
endif()

core/metautils/Module.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ INCLUDEFILES += $(METAUTILSDEP)
5454
STLDICTS =
5555
STLDICTS += lib/libvectorDict.$(SOEXT)
5656
STLDICTS += lib/liblistDict.$(SOEXT)
57+
STLDICTS += lib/libforward_listDict.$(SOEXT)
5758
STLDICTS += lib/libdequeDict.$(SOEXT)
5859
STLDICTS += lib/libmapDict.$(SOEXT)
5960
STLDICTS += lib/libmap2Dict.$(SOEXT)
@@ -91,7 +92,7 @@ STLDICTSMAPS = $(STLDICTS:.$(SOEXT)=.rootmap)
9192
# used in the main Makefile
9293
ALLLIBS += $(STLDICTS)
9394
ALLMAPS += $(STLDICTSMAPS)
94-
95+
9596
##### local rules #####
9697
.PHONY: all-$(MODNAME) clean-$(MODNAME) distclean-$(MODNAME)
9798

core/metautils/inc/ESTLType.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@
2626
namespace ROOT {
2727

2828
enum ESTLType {
29-
kNotSTL = 0,
30-
kSTLvector = 1,
31-
kSTLlist = 2,
32-
kSTLdeque = 3,
33-
kSTLmap = 4,
34-
kSTLmultimap = 5,
35-
kSTLset = 6,
36-
kSTLmultiset = 7,
37-
kSTLbitset = 8,
38-
kSTLend = 9,
39-
kSTLany = 300 /* TVirtualStreamerInfo::kSTL */,
40-
kSTLstring = 365 /* TVirtualStreamerInfo::kSTLstring */
29+
kNotSTL = 0,
30+
kSTLvector = 1,
31+
kSTLlist = 2,
32+
kSTLforwardlist = 3,
33+
kSTLdeque = 4,
34+
kSTLmap = 5,
35+
kSTLmultimap = 6,
36+
kSTLset = 7,
37+
kSTLmultiset = 8,
38+
kSTLbitset = 9,
39+
kSTLend = 10,
40+
kSTLany = 300 /* TVirtualStreamerInfo::kSTL */,
41+
kSTLstring = 365 /* TVirtualStreamerInfo::kSTLstring */
4142
};
4243

4344
}

core/metautils/inc/TClassEdit.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,17 @@ namespace TClassEdit {
8888
};
8989

9090
enum ESTLType {
91-
kNotSTL = ROOT::kNotSTL,
92-
kVector = ROOT::kSTLvector,
93-
kList = ROOT::kSTLlist,
94-
kDeque = ROOT::kSTLdeque,
95-
kMap = ROOT::kSTLmap,
96-
kMultiMap = ROOT::kSTLmultimap,
97-
kSet = ROOT::kSTLset,
98-
kMultiSet = ROOT::kSTLmultiset,
99-
kBitSet = ROOT::kSTLbitset,
100-
kEnd = ROOT::kSTLend
91+
kNotSTL = ROOT::kNotSTL,
92+
kVector = ROOT::kSTLvector,
93+
kList = ROOT::kSTLlist,
94+
kForwardist = ROOT::kSTLforwardlist,
95+
kDeque = ROOT::kSTLdeque,
96+
kMap = ROOT::kSTLmap,
97+
kMultiMap = ROOT::kSTLmultimap,
98+
kSet = ROOT::kSTLset,
99+
kMultiSet = ROOT::kSTLmultiset,
100+
kBitSet = ROOT::kSTLbitset,
101+
kEnd = ROOT::kSTLend
101102
};
102103

103104
class TInterpreterLookupHelper {

core/metautils/src/TClassEdit.cxx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ int TClassEdit::TSplitType::IsSTLCont(int testAlloc) const
138138

139139
int kind = STLKind(fElements[0].c_str());
140140

141-
if (kind==ROOT::kSTLvector || kind==ROOT::kSTLlist ) {
141+
if (kind==ROOT::kSTLvector || kind==ROOT::kSTLlist || kind==ROOT::kSTLforwardlist) {
142142

143143
int nargs = STLArgs(kind);
144144
if (testAlloc && (numb-1 > nargs) && !IsDefAlloc(fElements[numb-1].c_str(),fElements[1].c_str())) {
@@ -244,6 +244,7 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
244244
switch (kind) {
245245
case ROOT::kSTLvector:
246246
case ROOT::kSTLlist:
247+
case ROOT::kSTLforwardlist:
247248
case ROOT::kSTLdeque:
248249
case ROOT::kSTLset:
249250
case ROOT::kSTLmultiset:
@@ -277,6 +278,7 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
277278
switch (kind) {
278279
case ROOT::kSTLvector:
279280
case ROOT::kSTLlist:
281+
case ROOT::kSTLforwardlist:
280282
case ROOT::kSTLdeque:
281283
break;
282284
case ROOT::kSTLset:
@@ -410,12 +412,13 @@ ROOT::ESTLType TClassEdit::STLKind(const char *type, size_t len)
410412

411413
//container names
412414
static const char *stls[] =
413-
{ "any", "vector", "list", "deque", "map", "multimap", "set", "multiset", "bitset", 0};
415+
{ "any", "vector", "list", "forward_list", "deque", "map", "multimap", "set", "multiset", "bitset", 0};
414416
static const size_t stllen[] =
415-
{ 3, 6, 4, 5, 3, 8, 3, 8, 6, 0};
417+
{ 3, 6, 4, 12, 5, 3, 8, 3, 8, 6, 0};
416418
static const ROOT::ESTLType values[] =
417419
{ ROOT::kNotSTL, ROOT::kSTLvector,
418-
ROOT::kSTLlist, ROOT::kSTLdeque,
420+
ROOT::kSTLlist, ROOT::kSTLforwardlist,
421+
ROOT::kSTLdeque,
419422
ROOT::kSTLmap, ROOT::kSTLmultimap,
420423
ROOT::kSTLset, ROOT::kSTLmultiset,
421424
ROOT::kSTLbitset, ROOT::kNotSTL

0 commit comments

Comments
 (0)