29 #define MESSAGE(which,text) 
   41 class TGenVectorProxy : 
public TGenCollectionProxy {
 
   44    TGenVectorProxy(
const TGenCollectionProxy& c) : TGenCollectionProxy(c)
 
   48    virtual ~TGenVectorProxy()
 
   52    virtual void* At(UInt_t idx)
 
   54       if ( fEnv && fEnv->fObject ) {
 
   58             return fEnv->fStart = fFirst.invoke(fEnv);
 
   60             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
   61             return ((
char*)fEnv->fStart) + fValDiff*idx;
 
   64       Fatal(
"TGenVectorProxy",
"At> Logic error - no proxy object set.");
 
   68    virtual void DeleteItem(Bool_t force, 
void* ptr)
 const 
   71          if ( fVal->fProperties&kNeedDelete) {
 
   72             TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
   73             TPushPop helper(proxy,ptr);
 
   74             proxy->Clear(
"force");
 
   76          fVal->DeleteItem(ptr);
 
   90 class TGenVectorBoolProxy : 
public TGenCollectionProxy {
 
   94    TGenVectorBoolProxy(
const TGenCollectionProxy& c) : TGenCollectionProxy(c), fLastValue(false)
 
   98    virtual ~TGenVectorBoolProxy()
 
  102    virtual void* At(UInt_t idx)
 
  107       if ( fEnv && fEnv->fObject ) {
 
  108          auto vec = (std::vector<bool> *)(fEnv->fObject);
 
  109          fLastValue = (*vec)[idx];
 
  113       Fatal(
"TGenVectorProxy",
"At> Logic error - no proxy object set.");
 
  117    virtual void DeleteItem(Bool_t force, 
void* ptr)
 const 
  120       if ( force && ptr ) {
 
  121          fVal->DeleteItem(ptr);
 
  137 class TGenBitsetProxy : 
public TGenCollectionProxy {
 
  140    TGenBitsetProxy(
const TGenCollectionProxy& c) : TGenCollectionProxy(c)
 
  144    virtual ~TGenBitsetProxy()
 
  148    virtual void* At(UInt_t idx)
 
  153       if ( fEnv && fEnv->fObject ) {
 
  156                fEnv->fStart = fFirst.invoke(fEnv);
 
  160                fEnv->fIdx = idx - fEnv->fIdx;
 
  161                if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
  166          typedef ROOT::TCollectionProxyInfo::Environ<std::pair<size_t,Bool_t> > EnvType_t;
 
  167          EnvType_t *e = (EnvType_t*)fEnv;
 
  168          return &(e->fIterator.second);
 
  170       Fatal(
"TGenVectorProxy",
"At> Logic error - no proxy object set.");
 
  174    virtual void DeleteItem(Bool_t force, 
void* ptr)
 const 
  177       if ( force && ptr ) {
 
  178          fVal->DeleteItem(ptr);
 
  193 class TGenListProxy : 
public TGenVectorProxy {
 
  196    TGenListProxy(
const TGenCollectionProxy& c) : TGenVectorProxy(c)
 
  200    virtual ~TGenListProxy()
 
  206       if ( fEnv && fEnv->fObject ) {
 
  210             return fEnv->fStart = fFirst.invoke(fEnv);
 
  212             fEnv->fIdx = idx - fEnv->fIdx;
 
  213             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
  214             void* result = fNext.invoke(fEnv);
 
  220       Fatal(
"TGenListProxy",
"At> Logic error - no proxy object set.");
 
  235 class TGenSetProxy : 
public TGenVectorProxy {
 
  238    TGenSetProxy(
const TGenCollectionProxy& c) : TGenVectorProxy(c)
 
  242    virtual ~TGenSetProxy()
 
  248       if ( fEnv && fEnv->fObject ) {
 
  249          if ( fEnv->fUseTemp ) {
 
  250             return (((
char*)fEnv->fTemp)+idx*fValDiff);
 
  255             return fEnv->fStart = fFirst.invoke(fEnv);
 
  257             fEnv->fIdx = idx - fEnv->fIdx;
 
  258             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
  259             void* result = fNext.invoke(fEnv);
 
  265       Fatal(
"TGenSetProxy",
"At> Logic error - no proxy object set.");
 
  280 class TGenMapProxy : 
public TGenSetProxy {
 
  283    TGenMapProxy(
const TGenCollectionProxy& c) : TGenSetProxy(c)
 
  287    virtual ~TGenMapProxy()
 
  291    virtual void DeleteItem(Bool_t force, 
void* ptr)
 const 
  294          if ( fKey->fProperties&kNeedDelete) {
 
  295             TVirtualCollectionProxy *proxy = fKey->fType->GetCollectionProxy();
 
  296             TPushPop helper(proxy,fKey->fCase&kIsPointer ? *(
void**)ptr : ptr);
 
  297             proxy->Clear(
"force");
 
  299          if ( fVal->fProperties&kNeedDelete) {
 
  300             TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
  301             char *addr = ((
char*)ptr)+fValOffset;
 
  302             TPushPop helper(proxy,fVal->fCase&kIsPointer ? *(
void**)addr : addr);
 
  303             proxy->Clear(
"force");
 
  306       if ( fKey->fCase&kIsPointer ) {
 
  307          fKey->DeleteItem(*(
void**)ptr);
 
  309       if ( fVal->fCase&kIsPointer ) {
 
  310          char *addr = ((
char*)ptr)+fValOffset;
 
  311          fVal->DeleteItem(*(
void**)addr);
 
  319 TGenCollectionProxy::Value::Value(
const std::string& inside_type, Bool_t silent)
 
  321    std::string inside = (inside_type.find(
"const ")==0) ? inside_type.substr(6) : inside_type;
 
  327    fSize = std::string::npos;
 
  331    bool nameChanged = 
false;
 
  332    std::string intype = TClassEdit::GetNameForIO(inside.c_str(), TClassEdit::EModType::kNone, &nameChanged);
 
  334    bool isPointer = nameChanged; 
 
  337    if (!nameChanged && intype[intype.length()-1] == 
'*') {
 
  340       if (intype[intype.length()-1] == 
'*') {
 
  343             Warning(
"TGenCollectionProxy::Value::Value", 
"I/O not supported for collection of pointer to pointer: %s", inside_type.c_str());
 
  344          fSize = 
sizeof(
void*);
 
  350    if ( intype.substr(0,6) == 
"string" || intype.substr(0,11) == 
"std::string" ) {
 
  351       fCase = kBIT_ISSTRING;
 
  352       fType = TClass::GetClass(
"string");
 
  353       fCtor = fType->GetNew();
 
  354       fDtor = fType->GetDestructor();
 
  355       fDelete = fType->GetDelete();
 
  358          fSize = 
sizeof(
void*);
 
  360          fSize = 
sizeof(std::string);
 
  370       fType = TClass::GetClass(intype.c_str(),kTRUE,silent);
 
  375             fSize = 
sizeof(
void*);
 
  376             if (fType == TString::Class()) {
 
  377                fCase |= kBIT_ISTSTRING;
 
  381          fCtor   = fType->GetNew();
 
  382          fDtor   = fType->GetDestructor();
 
  383          fDelete = fType->GetDelete();
 
  385          R__LOCKGUARD(gInterpreterMutex);
 
  389          THashTable *typeTable = 
dynamic_cast<THashTable*
>( gROOT->GetListOfTypes() );
 
  390          THashList *enumTable = 
dynamic_cast<THashList*
>( gROOT->GetListOfEnums() );
 
  392          assert(typeTable && 
"The type of the list of type has changed");
 
  393          assert(enumTable && 
"The type of the list of enum has changed");
 
  395          TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( intype.c_str() );
 
  396          if (fundType && fundType->GetType() < 0x17 && fundType->GetType() > 0) {
 
  397             fKind = (EDataType)fundType->GetType();
 
  400             fCase |= kIsFundamental;
 
  403                fSize = 
sizeof(
void*);
 
  405                fSize = fundType->Size();
 
  407          } 
else if (enumTable->THashList::FindObject( intype.c_str() ) ) {
 
  410             fSize = 
sizeof(Int_t);
 
  414                fSize = 
sizeof(
void*);
 
  428             TypeInfo_t *ti = gCling->TypeInfo_Factory();
 
  429             gCling->TypeInfo_Init(ti,inside.c_str());
 
  430             if ( !gCling->TypeInfo_IsValid(ti) ) {
 
  433                   fSize = 
sizeof(
void*);
 
  448                   fSize = 
sizeof(Int_t);
 
  453                Long_t prop = gCling->TypeInfo_Property(ti);
 
  454                if ( prop&kIsPointer ) {
 
  455                   fSize = 
sizeof(
void*);
 
  457                if ( prop&kIsStruct ) {
 
  462                R__ASSERT(! (prop&kIsClass) && 
"Impossible code path" );
 
  471                if ( prop&kIsFundamental ) {
 
  472                   fundType = gROOT->GetType( intype.c_str() );
 
  474                      if (intype != 
"long double") {
 
  475                         Error(
"TGenCollectionProxy",
"Unknown fundamental type %s",intype.c_str());
 
  480                      fKind = (EDataType)fundType->GetType();
 
  481                      fSize = gCling->TypeInfo_Size(ti);
 
  482                      R__ASSERT((fKind>0 && fKind<0x17) || (fKind==-1&&(prop&kIsPointer)) );
 
  485                else if ( prop&kIsEnum ) {
 
  489                fCase = prop & (kIsPointer|kIsFundamental|kIsEnum|kIsClass);
 
  490                if (fType == TString::Class() && (fCase&kIsPointer)) {
 
  491                   fCase |= kBIT_ISTSTRING;
 
  494             gCling->TypeInfo_Delete(ti);
 
  498          TVirtualCollectionProxy *proxy = fType->GetCollectionProxy();
 
  499          if (proxy && (proxy->GetProperties() & kNeedDelete)) {
 
  500             fProperties |= kNeedDelete;
 
  504    if ( fSize == std::string::npos ) {
 
  508          fSize = fType->Size();
 
  516 Bool_t TGenCollectionProxy::Value::IsValid()
 
  520    return fSize != std::string::npos;
 
  523 void TGenCollectionProxy::Value::DeleteItem(
void* ptr)
 
  527    if ( ptr && fCase&kIsPointer ) {
 
  532          fType->Destructor(ptr);
 
  535          ::operator 
delete(ptr);
 
  561 TGenCollectionProxy::TGenCollectionProxy(
const TGenCollectionProxy& copy)
 
  562    : TVirtualCollectionProxy(copy.fClass),
 
  563      fTypeinfo(copy.fTypeinfo)
 
  567    fPointers       = copy.fPointers;
 
  568    fSTL_type       = copy.fSTL_type;
 
  569    fSize.call      = copy.fSize.call;
 
  570    fNext.call      = copy.fNext.call;
 
  571    fFirst.call     = copy.fFirst.call;
 
  572    fClear.call     = copy.fClear.call;
 
  573    fResize         = copy.fResize;
 
  574    fDestruct       = copy.fDestruct;
 
  575    fConstruct      = copy.fConstruct;
 
  577    fCollect        = copy.fCollect;
 
  578    fCreateEnv.call = copy.fCreateEnv.call;
 
  579    fValOffset      = copy.fValOffset;
 
  580    fValDiff        = copy.fValDiff;
 
  581    fValue          = copy.fValue.load() ? 
new Value(*copy.fValue) : 0;
 
  582    fVal            = copy.fVal   ? 
new Value(*copy.fVal)   : 0;
 
  583    fKey            = copy.fKey   ? 
new Value(*copy.fKey)   : 0;
 
  584    fOnFileClass    = copy.fOnFileClass;
 
  585    fReadMemberWise = 
new TObjArray(TCollection::kInitCapacity,-1);
 
  586    fConversionReadMemberWise = 0;
 
  587    fWriteMemberWise = 0;
 
  588    fProperties     = copy.fProperties;
 
  589    fFunctionCreateIterators    = copy.fFunctionCreateIterators;
 
  590    fFunctionCopyIterator       = copy.fFunctionCopyIterator;
 
  591    fFunctionNextIterator       = copy.fFunctionNextIterator;
 
  592    fFunctionDeleteIterator     = copy.fFunctionDeleteIterator;
 
  593    fFunctionDeleteTwoIterators = copy.fFunctionDeleteTwoIterators;
 
  599 TGenCollectionProxy::TGenCollectionProxy(Info_t info, 
size_t iter_size)
 
  600    : TVirtualCollectionProxy(0),
 
  621    fSTL_type        = ROOT::kNotSTL;
 
  623    if ( iter_size > 
sizeof(e.fIterator) ) {
 
  624       Fatal(
"TGenCollectionProxy",
 
  625             "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
 
  626             "Iterators for collection",
 
  629             (Long_t)
sizeof(e.fIterator));
 
  631    fReadMemberWise = 
new TObjArray(TCollection::kInitCapacity,-1);
 
  632    fConversionReadMemberWise   = 0;
 
  633    fWriteMemberWise            = 0;
 
  634    fFunctionCreateIterators    = 0;
 
  635    fFunctionCopyIterator       = 0;
 
  636    fFunctionNextIterator       = 0;
 
  637    fFunctionDeleteIterator     = 0;
 
  638    fFunctionDeleteTwoIterators = 0;
 
  644 TGenCollectionProxy::TGenCollectionProxy(
const ROOT::TCollectionProxyInfo &info, TClass *cl)
 
  645    : TVirtualCollectionProxy(cl),
 
  646      fTypeinfo(info.fInfo), fOnFileClass(0)
 
  649    fValDiff        = info.fValueDiff;
 
  650    fValOffset      = info.fValueOffset;
 
  651    fSize.call      = info.fSizeFunc;
 
  652    fResize         = info.fResizeFunc;
 
  653    fNext.call      = info.fNextFunc;
 
  654    fFirst.call     = info.fFirstFunc;
 
  655    fClear.call     = info.fClearFunc;
 
  656    fConstruct      = info.fConstructFunc;
 
  657    fDestruct       = info.fDestructFunc;
 
  658    fFeed           = info.fFeedFunc;
 
  659    fCollect        = info.fCollectFunc;
 
  660    fCreateEnv.call = info.fCreateEnv;
 
  663       fName = cl->GetName();
 
  671    fSTL_type        = ROOT::kNotSTL;
 
  674    if ( info.fIterSize > 
sizeof(e.fIterator) ) {
 
  675       Fatal(
"TGenCollectionProxy",
 
  676             "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
 
  677             "Iterators for collection",
 
  679             (Long_t)info.fIterSize,
 
  680             (Long_t)
sizeof(e.fIterator));
 
  682    fReadMemberWise = 
new TObjArray(TCollection::kInitCapacity,-1);
 
  683    fConversionReadMemberWise   = 0;
 
  684    fWriteMemberWise            = 0;
 
  685    fFunctionCreateIterators    = info.fCreateIterators;
 
  686    fFunctionCopyIterator       = info.fCopyIterator;
 
  687    fFunctionNextIterator       = info.fNext;
 
  688    fFunctionDeleteIterator     = info.fDeleteSingleIterator;
 
  689    fFunctionDeleteTwoIterators = info.fDeleteTwoIterators;
 
  694    void clearVector(vec& v)
 
  698       for(
typename vec::iterator i=v.begin(); i != v.end(); ++i) {
 
  699          typename vec::value_type e = *i;
 
  710 TGenCollectionProxy::~TGenCollectionProxy()
 
  712    clearVector(fProxyList);
 
  713    clearVector(fProxyKept);
 
  714    clearVector(fStaged);
 
  716    if ( fValue.load() ) 
delete fValue.load();
 
  717    if ( fVal   ) 
delete fVal;
 
  718    if ( fKey   ) 
delete fKey;
 
  720    delete fReadMemberWise;
 
  721    if (fConversionReadMemberWise) {
 
  722       std::map<std::string, TObjArray*>::iterator it;
 
  723       std::map<std::string, TObjArray*>::iterator end = fConversionReadMemberWise->end();
 
  724       for( it = fConversionReadMemberWise->begin(); it != end; ++it ) {
 
  727       delete fConversionReadMemberWise;
 
  728       fConversionReadMemberWise = 0;
 
  730    delete fWriteMemberWise;
 
  736 TVirtualCollectionProxy* TGenCollectionProxy::Generate()
 const 
  738    if ( !fValue.load() ) Initialize(kFALSE);
 
  741       return new TGenCollectionProxy(*
this);
 
  744       case ROOT::kSTLbitset: {
 
  745          return new TGenBitsetProxy(*
this);
 
  747       case ROOT::kSTLvector: {
 
  748          if ((*fValue).fKind == kBool_t) {
 
  749             return new TGenVectorBoolProxy(*
this);
 
  751             return new TGenVectorProxy(*
this);
 
  755       case ROOT::kSTLforwardlist:
 
  756          return new TGenListProxy(*
this);
 
  758       case ROOT::kSTLunorderedmap:
 
  759       case ROOT::kSTLmultimap:
 
  760       case ROOT::kSTLunorderedmultimap:
 
  761          return new TGenMapProxy(*
this);
 
  763       case ROOT::kSTLunorderedset:
 
  764       case ROOT::kSTLmultiset:
 
  765       case ROOT::kSTLunorderedmultiset:
 
  766          return new TGenSetProxy(*
this);
 
  768          return new TGenCollectionProxy(*
this);
 
  775 TGenCollectionProxy *TGenCollectionProxy::Initialize(Bool_t silent)
 const 
  777    TGenCollectionProxy* p = 
const_cast<TGenCollectionProxy*
>(
this);
 
  778    if ( fValue.load() ) 
return p;
 
  779    return p->InitializeEx(silent);
 
  785 void TGenCollectionProxy::CheckFunctions()
 const 
  787    if ( 0 == fSize.call ) {
 
  788       Fatal(
"TGenCollectionProxy",
"No 'size' function pointer for class %s present.",fName.c_str());
 
  790    if ( 0 == fResize ) {
 
  791       Fatal(
"TGenCollectionProxy",
"No 'resize' function for class %s present.",fName.c_str());
 
  793    if ( 0 == fNext.call  ) {
 
  794       Fatal(
"TGenCollectionProxy",
"No 'next' function for class %s present.",fName.c_str());
 
  796    if ( 0 == fFirst.call ) {
 
  797       Fatal(
"TGenCollectionProxy",
"No 'begin' function for class %s present.",fName.c_str());
 
  799    if ( 0 == fClear.call ) {
 
  800       Fatal(
"TGenCollectionProxy",
"No 'clear' function for class %s present.",fName.c_str());
 
  802    if ( 0 == fConstruct ) {
 
  803       Fatal(
"TGenCollectionProxy",
"No 'block constructor' function for class %s present.",fName.c_str());
 
  805    if ( 0 == fDestruct ) {
 
  806       Fatal(
"TGenCollectionProxy",
"No 'block destructor' function for class %s present.",fName.c_str());
 
  809       Fatal(
"TGenCollectionProxy",
"No 'data feed' function for class %s present.",fName.c_str());
 
  811    if ( 0 == fCollect ) {
 
  812       Fatal(
"TGenCollectionProxy",
"No 'data collect' function for class %s present.",fName.c_str());
 
  814    if (0 == fCreateEnv.call ) {
 
  815       Fatal(
"TGenCollectionProxy",
"No 'environment creation' function for class %s present.",fName.c_str());
 
  822 static TGenCollectionProxy::Value *R__CreateValue(
const std::string &name, Bool_t silent)
 
  824    TGenCollectionProxy::Value *val = 
new TGenCollectionProxy::Value( name, silent );
 
  825    if ( !val->IsValid() ) {
 
  826       Fatal(
"TGenCollectionProxy",
"Could not find %s!",name.c_str());
 
  834 TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
 
  836    R__LOCKGUARD(gInterpreterMutex);
 
  837    if (fValue.load()) 
return this;
 
  839    TClass *cl = fClass ? fClass.GetClass() : TClass::GetClass(fTypeinfo,kTRUE,silent);
 
  842       fName   = cl->GetName();
 
  845       std::vector<std::string> inside;
 
  846       int num = TClassEdit::GetSplit(cl->GetName(),inside,nested);
 
  849          Value* newfValue = 
nullptr;
 
  850          if ( inside[0].find(
"stdext::hash_") != std::string::npos )
 
  851             inside[0].replace(3,10,
"::");
 
  852          if ( inside[0].find(
"__gnu_cxx::hash_") != std::string::npos )
 
  853             inside[0].replace(0,16,
"std::");
 
  854          fSTL_type = TClassEdit::STLKind(inside[0]);
 
  855          switch ( fSTL_type ) {
 
  857             case ROOT::kSTLunorderedmap:
 
  858             case ROOT::kSTLmultimap:
 
  859             case ROOT::kSTLunorderedmultimap:
 
  861             case ROOT::kSTLunorderedset:
 
  862             case ROOT::kSTLmultiset:
 
  863             case ROOT::kSTLunorderedmultiset:
 
  864             case ROOT::kSTLbitset: 
 
  865                fProperties |= kIsAssociative;
 
  866                if (num > 3 && !inside[3].empty()) {
 
  867                   if (! TClassEdit::IsDefAlloc(inside[3].c_str(),inside[0].c_str())) {
 
  868                      fProperties |= kCustomAlloc;
 
  874          int slong = 
sizeof(
void*);
 
  875          switch ( fSTL_type ) {
 
  877             case ROOT::kSTLunorderedmap:
 
  878             case ROOT::kSTLmultimap:
 
  879             case ROOT::kSTLunorderedmultimap:
 
  880                nam = 
"pair<"+inside[1]+
","+inside[2];
 
  881                nam += (nam[nam.length()-1]==
'>') ? 
" >" : 
">";
 
  882                newfValue = R__CreateValue(nam, silent);
 
  884                fVal   = R__CreateValue(inside[2], silent);
 
  885                fKey   = R__CreateValue(inside[1], silent);
 
  886                fPointers = (0 != (fKey->fCase&kIsPointer));
 
  887                if (fPointers || (0 != (fKey->fProperties&kNeedDelete))) {
 
  888                   fProperties |= kNeedDelete;
 
  890                if ( 0 == fValDiff ) {
 
  891                   fValDiff = fKey->fSize + fVal->fSize;
 
  892                   fValDiff += (slong - fKey->fSize%slong)%slong;
 
  893                   fValDiff += (slong - fValDiff%slong)%slong;
 
  895                if ( 0 == fValOffset ) {
 
  896                   fValOffset = fKey->fSize;
 
  897                   fValOffset += (slong - fKey->fSize%slong)%slong;
 
  900             case ROOT::kSTLbitset:
 
  904                newfValue = R__CreateValue(inside[1], silent);
 
  906                fVal   = 
new Value(*newfValue);
 
  907                if ( 0 == fValDiff ) {
 
  908                   fValDiff = fVal->fSize;
 
  909                   fValDiff += (slong - fValDiff%slong)%slong;
 
  911                if (num > 2 && !inside[2].empty()) {
 
  912                   if (! TClassEdit::IsDefAlloc(inside[2].c_str(),inside[0].c_str())) {
 
  913                      fProperties |= kCustomAlloc;
 
  919          fPointers = fPointers || (0 != (fVal->fCase&kIsPointer));
 
  920          if (fPointers || (0 != (fVal->fProperties&kNeedDelete))) {
 
  921             fProperties |= kNeedDelete;
 
  928       Fatal(
"TGenCollectionProxy",
"Components of %s not analysed!",cl->GetName());
 
  930    Fatal(
"TGenCollectionProxy",
"Collection class %s not found!",fTypeinfo.name());
 
  937 TClass *TGenCollectionProxy::GetCollectionClass()
 const 
  939    return fClass ? fClass : Initialize(kFALSE)->fClass;
 
  945 Int_t TGenCollectionProxy::GetCollectionType()
 const 
  947    if (!fValue.load()) {
 
  956 ULong_t TGenCollectionProxy::GetIncrement()
 const {
 
  957    if (!fValue.load()) {
 
  966 UInt_t TGenCollectionProxy::Sizeof()
 const 
  968    return fClass->Size();
 
  974 Bool_t TGenCollectionProxy::HasPointers()
 const 
  983    return fPointers && !(fSTL_type == ROOT::kSTLmap || fSTL_type == ROOT::kSTLmultimap ||
 
  984                          fSTL_type == ROOT::kSTLunorderedmap || fSTL_type == ROOT::kSTLunorderedmultimap);
 
  990 TClass *TGenCollectionProxy::GetValueClass()
 const 
  992    if (!fValue.load()) Initialize(kFALSE);
 
  993    return fValue.load() ? (*fValue).fType.GetClass() : 0;
 
 1000 void TGenCollectionProxy::UpdateValueClass(
const TClass *oldValueType, TClass *newValueType)
 
 1005    if (fValue.load() && (*fValue).fType == oldValueType) {
 
 1007       (*fValue).fType = newValueType;
 
 1014 EDataType TGenCollectionProxy::GetType()
 const 
 1016    if ( !fValue.load() ) Initialize(kFALSE);
 
 1017    return (*fValue).fKind;
 
 1023 void* TGenCollectionProxy::At(UInt_t idx)
 
 1025    if ( fEnv && fEnv->fObject ) {
 
 1026       switch (fSTL_type) {
 
 1027       case ROOT::kSTLvector:
 
 1028          if ((*fValue).fKind == kBool_t) {
 
 1029             auto vec = (std::vector<bool> *)(fEnv->fObject);
 
 1030             fEnv->fLastValueVecBool = (*vec)[idx];
 
 1032             return &(fEnv->fLastValueVecBool);
 
 1037             return fEnv->fStart = fFirst.invoke(fEnv);
 
 1039             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
 1040             return ((
char*)fEnv->fStart) + fValDiff*idx;
 
 1042       case ROOT::kSTLbitset: {
 
 1045             fEnv->fStart = fFirst.invoke(fEnv);
 
 1049             fEnv->fIdx = idx - fEnv->fIdx;
 
 1050             if (!fEnv->fStart) fEnv->fStart = fFirst.invoke(fEnv);
 
 1055          typedef ROOT::TCollectionProxyInfo::Environ <std::pair<size_t, Bool_t>> EnvType_t;
 
 1056          EnvType_t *e = (EnvType_t *) fEnv;
 
 1057          return &(e->fIterator.second);
 
 1060       case ROOT::kSTLunorderedset:
 
 1061       case ROOT::kSTLmultiset:
 
 1062       case ROOT::kSTLunorderedmultiset:
 
 1064       case ROOT::kSTLunorderedmap:
 
 1065       case ROOT::kSTLmultimap:
 
 1066       case ROOT::kSTLunorderedmultimap:
 
 1067          if ( fEnv->fUseTemp ) {
 
 1068             return (((
char*)fEnv->fTemp)+idx*fValDiff);
 
 1075             return fEnv->fStart = fFirst.invoke(fEnv);
 
 1077             fEnv->fIdx = idx - fEnv->fIdx;
 
 1078             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
 
 1079             void* result = fNext.invoke(fEnv);
 
 1086    Fatal(
"TGenCollectionProxy",
"At> Logic error - no proxy object set.");
 
 1093 void TGenCollectionProxy::Clear(
const char* opt)
 
 1095    if ( fEnv && fEnv->fObject ) {
 
 1096       if ( (fProperties & kNeedDelete) && opt && *opt==
'f' ) {
 
 1097          size_t i, n = *(
size_t*)fSize.invoke(fEnv);
 
 1100                DeleteItem(
true, TGenCollectionProxy::At(i));
 
 1103       fClear.invoke(fEnv);
 
 1110 UInt_t TGenCollectionProxy::Size()
 const 
 1112    if ( fEnv && fEnv->fObject ) {
 
 1113       if (fEnv->fUseTemp) {
 
 1116          return *(
size_t*)fSize.invoke(fEnv);
 
 1119    Fatal(
"TGenCollectionProxy",
"Size> Logic error - no proxy object set.");
 
 1126 void TGenCollectionProxy::Resize(UInt_t n, Bool_t force)
 
 1128    if ( fEnv && fEnv->fObject ) {
 
 1129       if ( force && fPointers ) {
 
 1130          size_t i, nold = *(
size_t*)fSize.invoke(fEnv);
 
 1132             for (i=n; i<nold; ++i)
 
 1133                DeleteItem(
true, *(
void**)TGenCollectionProxy::At(i));
 
 1136       MESSAGE(3, 
"Resize(n)" );
 
 1138       fResize(fEnv->fObject,fEnv->fSize);
 
 1141    Fatal(
"TGenCollectionProxy",
"Resize> Logic error - no proxy object set.");
 
 1149 void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t  )
 
 1151    if ( fEnv && fEnv->fObject ) {
 
 1152       switch ( fSTL_type ) {
 
 1154          case ROOT::kSTLunorderedset:
 
 1155          case ROOT::kSTLmultiset:
 
 1156          case ROOT::kSTLunorderedmultiset:
 
 1158          case ROOT::kSTLunorderedmap:
 
 1159          case ROOT::kSTLmultimap:
 
 1160          case ROOT::kSTLunorderedmultimap:{
 
 1161             if ( (fProperties & kNeedDelete) )
 
 1164                fClear.invoke(fEnv);
 
 1171             if (fStaged.empty()) {
 
 1172                s = 
new TStaging(n,fValDiff);
 
 1178             fConstruct(s->GetContent(),s->GetSize());
 
 1180             s->SetTarget(fEnv->fObject);
 
 1182             fEnv->fTemp = s->GetContent();
 
 1183             fEnv->fUseTemp = kTRUE;
 
 1184             fEnv->fStart = fEnv->fTemp;
 
 1188          case ROOT::kSTLvector:
 
 1189          case ROOT::kSTLlist:
 
 1190          case ROOT::kSTLforwardlist:
 
 1191          case ROOT::kSTLdeque:
 
 1192             if( (fProperties & kNeedDelete) ) {
 
 1196             fResize(fEnv->fObject,n);
 
 1197             return fEnv->fObject;
 
 1199         case ROOT::kSTLbitset: {
 
 1201             if (fStaged.empty()) {
 
 1202                s = 
new TStaging(n,fValDiff);
 
 1208             s->SetTarget(fEnv->fObject);
 
 1210             fEnv->fTemp = s->GetContent();
 
 1211             fEnv->fUseTemp = kTRUE;
 
 1212             fEnv->fStart = fEnv->fTemp;
 
 1225 void TGenCollectionProxy::Insert(
const void *data, 
void *container, 
size_t size)
 
 1227    fFeed((
void*)data,container,size);
 
 1233 void TGenCollectionProxy::Commit(
void* from)
 
 1235    if (fProperties & kIsAssociative) {
 
 1241          TStaging *s = (TStaging*) from;
 
 1242          if ( s->GetTarget() ) {
 
 1243             fFeed(s->GetContent(),s->GetTarget(),s->GetSize());
 
 1245          fDestruct(s->GetContent(),s->GetSize());
 
 1247          fStaged.push_back(s);
 
 1255 void TGenCollectionProxy::PushProxy(
void *objstart)
 
 1257    if ( !fValue.load() ) Initialize(kFALSE);
 
 1258    if ( !fProxyList.empty() ) {
 
 1259       EnvironBase_t* back = fProxyList.back();
 
 1260       if ( back->fObject == objstart ) {
 
 1262          fProxyList.push_back(back);
 
 1267    EnvironBase_t* e    = 0;
 
 1268    if ( fProxyKept.empty() ) {
 
 1269       e = (EnvironBase_t*)fCreateEnv.invoke();
 
 1271       e->fUseTemp = kFALSE;
 
 1274       e = fProxyKept.back();
 
 1275       fProxyKept.pop_back();
 
 1279    e->fObject   = objstart;
 
 1283    fProxyList.push_back(e);
 
 1290 void TGenCollectionProxy::PopProxy()
 
 1292    if ( !fProxyList.empty() ) {
 
 1293       EnvironBase_t* e = fProxyList.back();
 
 1294       if ( --e->fRefCount <= 0 ) {
 
 1295          fProxyKept.push_back(e);
 
 1296          e->fUseTemp = kFALSE;
 
 1298       fProxyList.pop_back();
 
 1300    fEnv = fProxyList.empty() ? 0 : fProxyList.back();
 
 1306 void TGenCollectionProxy::DeleteItem(Bool_t force, 
void* ptr)
 const 
 1308    if ( force && ptr ) {
 
 1309       switch (fSTL_type) {
 
 1311          case ROOT::kSTLunorderedmap:
 
 1312          case ROOT::kSTLmultimap:
 
 1313          case ROOT::kSTLunorderedmultimap:{
 
 1314             if ( fKey->fCase&kIsPointer ) {
 
 1315                if (fKey->fProperties&kNeedDelete) {
 
 1316                   TVirtualCollectionProxy *proxy = fKey->fType->GetCollectionProxy();
 
 1317                   TPushPop helper(proxy,*(
void**)ptr);
 
 1318                   proxy->Clear(
"force");
 
 1320                fKey->DeleteItem(*(
void**)ptr);
 
 1322                if (fKey->fProperties&kNeedDelete) {
 
 1323                   TVirtualCollectionProxy *proxy = fKey->fType->GetCollectionProxy();
 
 1324                   TPushPop helper(proxy,ptr);
 
 1325                   proxy->Clear(
"force");
 
 1328             char *addr = ((
char*)ptr)+fValOffset;
 
 1329             if ( fVal->fCase&kIsPointer ) {
 
 1330                if ( fVal->fProperties&kNeedDelete) {
 
 1331                   TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
 1332                   TPushPop helper(proxy,*(
void**)addr);
 
 1333                   proxy->Clear(
"force");
 
 1335                fVal->DeleteItem(*(
void**)addr);
 
 1337                if ( fVal->fProperties&kNeedDelete) {
 
 1338                   TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
 1339                   TPushPop helper(proxy,addr);
 
 1340                   proxy->Clear(
"force");
 
 1346             if ( fVal->fCase&kIsPointer ) {
 
 1347                if (fVal->fProperties&kNeedDelete) {
 
 1348                   TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
 1349                   TPushPop helper(proxy,*(
void**)ptr);
 
 1350                   proxy->Clear(
"force");
 
 1352                fVal->DeleteItem(*(
void**)ptr);
 
 1354                if (fVal->fProperties&kNeedDelete) {
 
 1355                   TVirtualCollectionProxy *proxy = fVal->fType->GetCollectionProxy();
 
 1356                   TPushPop helper(proxy,ptr);
 
 1357                   proxy->Clear(
"force");
 
 1368 void TGenCollectionProxy::ReadBuffer(TBuffer & , 
void * , 
const TClass * )
 
 1370    MayNotUse(
"TGenCollectionProxy::ReadBuffer(TBuffer &, void *, const TClass *)");
 
 1375 void TGenCollectionProxy::ReadBuffer(TBuffer & , 
void * )
 
 1377    MayNotUse(
"TGenCollectionProxy::ReadBuffer(TBuffer &, void *)");
 
 1383 void TGenCollectionProxy::Streamer(TBuffer &buff)
 
 1386       GetCollectionClass()->Streamer( fEnv->fObject, buff );
 
 1389    Fatal(
"TGenCollectionProxy",
"Streamer> Logic error - no proxy object set.");
 
 1395 void TGenCollectionProxy::Streamer(TBuffer &buff, 
void *objp, 
int  )
 
 1397    TPushPop env(
this, objp);
 
 1404 void TGenCollectionProxy::operator()(TBuffer &b, 
void *objp)
 
 1406    Streamer(b, objp, 0);
 
 1410 struct TGenCollectionProxy__SlowIterator {
 
 1411    TVirtualCollectionProxy *fProxy;
 
 1413    TGenCollectionProxy__SlowIterator(TVirtualCollectionProxy *proxy) : fProxy(proxy), fIndex(0) {}
 
 1418 void TGenCollectionProxy__SlowCreateIterators(
void * , 
void **begin_arena, 
void **end_arena, TVirtualCollectionProxy *proxy)
 
 1420    new (*begin_arena) TGenCollectionProxy__SlowIterator(proxy);
 
 1421    *(UInt_t*)*end_arena = proxy->Size();
 
 1426 void *TGenCollectionProxy__SlowNext(
void *iter, 
const void *end)
 
 1428    TGenCollectionProxy__SlowIterator *iterator = (TGenCollectionProxy__SlowIterator*)iter;
 
 1429    if (iterator->fIndex != *(UInt_t*)end) {
 
 1430       void *result = iterator->fProxy->At(iterator->fIndex);
 
 1431       ++(iterator->fIndex);
 
 1440 void * TGenCollectionProxy__SlowCopyIterator(
void *dest, 
const void *source)
 
 1442    *(TGenCollectionProxy__SlowIterator*)dest = *(TGenCollectionProxy__SlowIterator*)source;
 
 1449 void TGenCollectionProxy__SlowDeleteSingleIterators(
void *)
 
 1456 void TGenCollectionProxy__SlowDeleteTwoIterators(
void *, 
void *)
 
 1465 void TGenCollectionProxy__VectorCreateIterators(
void *obj, 
void **begin_arena, 
void **end_arena, TVirtualCollectionProxy*)
 
 1467    std::vector<char> *vec = (std::vector<char>*)obj;
 
 1473    *begin_arena = &(*vec->begin());
 
 1474 #ifdef R__VISUAL_CPLUSPLUS 
 1475    *end_arena = &(*(vec->end()-1)) + 1; 
 
 1478    *end_arena = &(*vec->end());
 
 1486 void *TGenCollectionProxy__VectorNext(
void *, 
const void *)
 
 1494 void *TGenCollectionProxy__VectorCopyIterator(
void *dest, 
const void *source)
 
 1496    *(
void**)dest = *(
void**)source;
 
 1503 void TGenCollectionProxy__VectorDeleteSingleIterators(
void *)
 
 1510 void TGenCollectionProxy__VectorDeleteTwoIterators(
void *, 
void *)
 
 1518 void TGenCollectionProxy__StagingCreateIterators(
void *obj, 
void **begin_arena, 
void **end_arena, TVirtualCollectionProxy *)
 
 1520    TGenCollectionProxy::TStaging * s = (TGenCollectionProxy::TStaging*)obj;
 
 1521    *begin_arena = s->GetContent();
 
 1522    *end_arena = s->GetEnd();
 
 1528 void *TGenCollectionProxy__StagingNext(
void *, 
const void *)
 
 1536 void *TGenCollectionProxy__StagingCopyIterator(
void *dest, 
const void *source)
 
 1538    *(
void**)dest = *(
void**)source;
 
 1545 void TGenCollectionProxy__StagingDeleteSingleIterators(
void *)
 
 1552 void TGenCollectionProxy__StagingDeleteTwoIterators(
void *, 
void *)
 
 1563 TVirtualCollectionProxy::CreateIterators_t TGenCollectionProxy::GetFunctionCreateIterators(Bool_t read)
 
 1566       if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1567       if ( (fProperties & kIsAssociative) && read)
 
 1568          return TGenCollectionProxy__StagingCreateIterators;
 
 1571    if ( fFunctionCreateIterators ) 
return fFunctionCreateIterators;
 
 1573    if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1583    if (fSTL_type==ROOT::kSTLvector || (fProperties & kIsEmulated))
 
 1584       return fFunctionCreateIterators = TGenCollectionProxy__VectorCreateIterators;
 
 1585    else if ( (fProperties & kIsAssociative) && read)
 
 1586       return TGenCollectionProxy__StagingCreateIterators;
 
 1588       return fFunctionCreateIterators = TGenCollectionProxy__SlowCreateIterators;
 
 1597 TVirtualCollectionProxy::CopyIterator_t TGenCollectionProxy::GetFunctionCopyIterator(Bool_t read)
 
 1600       if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1601       if ( (fProperties & kIsAssociative) && read)
 
 1602          return TGenCollectionProxy__StagingCopyIterator;
 
 1605    if ( fFunctionCopyIterator ) 
return fFunctionCopyIterator;
 
 1607    if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1609    if (fSTL_type==ROOT::kSTLvector || (fProperties & kIsEmulated))
 
 1610       return fFunctionCopyIterator = TGenCollectionProxy__VectorCopyIterator;
 
 1611    else if ( (fProperties & kIsAssociative) && read)
 
 1612       return TGenCollectionProxy__StagingCopyIterator;
 
 1614       return fFunctionCopyIterator = TGenCollectionProxy__SlowCopyIterator;
 
 1624 TVirtualCollectionProxy::Next_t TGenCollectionProxy::GetFunctionNext(Bool_t read)
 
 1627       if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1628       if ( (fProperties & kIsAssociative) && read)
 
 1629          return TGenCollectionProxy__StagingNext;
 
 1632    if ( fFunctionNextIterator ) 
return fFunctionNextIterator;
 
 1634    if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1636    if (fSTL_type==ROOT::kSTLvector || (fProperties & kIsEmulated))
 
 1637       return fFunctionNextIterator = TGenCollectionProxy__VectorNext;
 
 1638    else if ( (fProperties & kIsAssociative) && read)
 
 1639       return TGenCollectionProxy__StagingNext;
 
 1641       return fFunctionNextIterator = TGenCollectionProxy__SlowNext;
 
 1649 TVirtualCollectionProxy::DeleteIterator_t TGenCollectionProxy::GetFunctionDeleteIterator(Bool_t read)
 
 1652       if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1653       if ( (fProperties & kIsAssociative) && read)
 
 1654          return TGenCollectionProxy__StagingDeleteSingleIterators;
 
 1657    if ( fFunctionDeleteIterator ) 
return fFunctionDeleteIterator;
 
 1659    if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1661    if (fSTL_type==ROOT::kSTLvector || (fProperties & kIsEmulated))
 
 1662       return fFunctionDeleteIterator = TGenCollectionProxy__VectorDeleteSingleIterators;
 
 1663    else if ( (fProperties & kIsAssociative) && read)
 
 1664       return TGenCollectionProxy__StagingDeleteSingleIterators;
 
 1666       return fFunctionDeleteIterator = TGenCollectionProxy__SlowDeleteSingleIterators;
 
 1674 TVirtualCollectionProxy::DeleteTwoIterators_t TGenCollectionProxy::GetFunctionDeleteTwoIterators(Bool_t read)
 
 1677       if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1678       if ( (fProperties & kIsAssociative) && read)
 
 1679          return TGenCollectionProxy__StagingDeleteTwoIterators;
 
 1682    if ( fFunctionDeleteTwoIterators ) 
return fFunctionDeleteTwoIterators;
 
 1684    if ( !fValue.load() ) InitializeEx(kFALSE);
 
 1686    if (fSTL_type==ROOT::kSTLvector || (fProperties & kIsEmulated))
 
 1687       return fFunctionDeleteTwoIterators = TGenCollectionProxy__VectorDeleteTwoIterators;
 
 1688    else if ( (fProperties & kIsAssociative) && read)
 
 1689       return TGenCollectionProxy__StagingDeleteTwoIterators;
 
 1691       return fFunctionDeleteTwoIterators = TGenCollectionProxy__SlowDeleteTwoIterators;
 
 1698 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)
 
 1700    if (oldClass == 0) {
 
 1704    TStreamerInfoActions::TActionSequence *result = 0;
 
 1705    if (fConversionReadMemberWise) {
 
 1706       std::map<std::string, TObjArray*>::iterator it;
 
 1708       it = fConversionReadMemberWise->find( oldClass->GetName() );
 
 1710       if( it != fConversionReadMemberWise->end() ) {
 
 1715          result = (TStreamerInfoActions::TActionSequence *)arr->At(version);
 
 1723    TClass *valueClass = GetValueClass();
 
 1724    if (valueClass == 0) {
 
 1727    TVirtualStreamerInfo *info = valueClass->GetConversionStreamerInfo(oldClass,version);
 
 1731    result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*
this);
 
 1734       arr = 
new TObjArray(version+10, -1);
 
 1735       if (!fConversionReadMemberWise) {
 
 1736          fConversionReadMemberWise = 
new std::map<std::string, TObjArray*>();
 
 1738       (*fConversionReadMemberWise)[oldClass->GetName()] = arr;
 
 1740    arr->AddAtAndExpand( result, version );
 
 1749 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetReadMemberWiseActions(Int_t version)
 
 1751    TStreamerInfoActions::TActionSequence *result = 0;
 
 1752    if (version < (fReadMemberWise->GetSize()-1)) { 
 
 1753       result = (TStreamerInfoActions::TActionSequence *)fReadMemberWise->At(version);
 
 1757       TClass *valueClass = GetValueClass();
 
 1758       TVirtualStreamerInfo *info = 0;
 
 1760          info = valueClass->GetStreamerInfo(version);
 
 1762       result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*
this);
 
 1763       fReadMemberWise->AddAtAndExpand(result,version);
 
 1771 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetWriteMemberWiseActions()
 
 1773   TStreamerInfoActions::TActionSequence *result = fWriteMemberWise;
 
 1776      TClass *valueClass = GetValueClass();
 
 1777      TVirtualStreamerInfo *info = 0;
 
 1779         info = valueClass->GetStreamerInfo();
 
 1781      result = TStreamerInfoActions::TActionSequence::CreateWriteMemberWiseActions(info,*
this);
 
 1782      fWriteMemberWise=result;