diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index ab35d1b5a9a5c..69e450627eb9c 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -4433,6 +4433,11 @@ void TCling::CreateListOfBaseClasses(TClass *cl) const if (cl->fBase) { return; } + // Ignore the base class (e.g. `std::_Complex_base` on Windows) + if (TClassEdit::GetComplexType(cl->GetName()) != TClassEdit::EComplexType::kNone) { + cl->fBase = new TList(); + return; + } TClingClassInfo *tci = (TClingClassInfo *)cl->GetClassInfo(); if (!tci) return; TClingBaseClassInfo t(GetInterpreterImpl(), tci); diff --git a/roottest/root/io/complex/CMakeLists.txt b/roottest/root/io/complex/CMakeLists.txt index 993beb33ca882..6c61abbad0a86 100644 --- a/roottest/root/io/complex/CMakeLists.txt +++ b/roottest/root/io/complex/CMakeLists.txt @@ -6,20 +6,17 @@ ROOTTEST_GENERATE_REFLEX_DICTIONARY(classWithComplex ROOTTEST_ADD_TEST(writeClassWithComplex MACRO execwriteClassWithComplex.C OUTREF execwriteClassWithComplex.ref - ${WILLFAIL_ON_WIN32} FIXTURES_REQUIRED root-io-complex-dict-fixture FIXTURES_SETUP root-io-complex-writeClassWithComplex-fixture) ROOTTEST_ADD_TEST(readClassWithComplex MACRO execreadClassWithComplex.C OUTREF execreadClassWithComplex.ref - ${WILLFAIL_ON_WIN32} FIXTURES_REQUIRED root-io-complex-writeClassWithComplex-fixture) ROOTTEST_ADD_TEST(writecomplex MACRO execwritecomplex.C - ${WILLFAIL_ON_WIN32} OUTREF execwritecomplex.ref FIXTURES_SETUP root-io-complex-writecomplex-fixture) @@ -27,5 +24,4 @@ ROOTTEST_ADD_TEST(readcomplex COPY_TO_BUILDDIR complexOfilekubuntuROOT5.root complexOfilekubuntuROOT6.root complexOfileslc6ROOT5.xml complexOfilekubuntuROOT5.xml complexOfilekubuntuROOT6.xml complexOfileslc6ROOT5.root MACRO execreadcomplex.C OUTREF execreadcomplex.ref - ${WILLFAIL_ON_WIN32} FIXTURES_REQUIRED root-io-complex-writecomplex-fixture) diff --git a/roottest/root/io/complex/execreadcomplex.C b/roottest/root/io/complex/execreadcomplex.C index 66f1df5abec84..55e163d9dde98 100644 --- a/roottest/root/io/complex/execreadcomplex.C +++ b/roottest/root/io/complex/execreadcomplex.C @@ -1,15 +1,16 @@ // This macro must be v5/v6 executable! -void compareValues(const char* filename, - complex cFloat, complex cFloatRef, - complex cDouble, complex cDoubleRef){ +void compareValues(const char *filename, const char *where, complex cFloat, complex cFloatRef, + complex cDouble, complex cDoubleRef) +{ if (cFloatRef != cFloat) { - cout << "ERROR complex on file " << filename << " numbers differ! Reference: " << cFloatRef << " on disk " << cFloat << endl; + cout << "ERROR complex on file " << filename << " numbers differ for " << where + << " ! Reference: " << cFloatRef << " on disk " << cFloat << endl; } if (cDoubleRef != cDouble) { - cout << "ERROR complex on file " << filename << " numbers differ! Reference: " << cDoubleRef << " on disk " << cDouble << endl; + cout << "ERROR complex on file " << filename << " numbers differ for " << where + << " ! Reference: " << cDoubleRef << " on disk " << cDouble << endl; } - } void readcomplex(const std::string base) @@ -46,8 +47,14 @@ void readcomplex(const std::string base) for (int j = 0; j < nIters; ++j) { // Re-generate values - std::complex cFloatRef(rndm.Uniform(theMin, theMax), rndm.Uniform(theMin, theMax)); - std::complex cDoubleRef(rndm.Uniform(theMin, theMax), rndm.Uniform(theMin, theMax)); + // Since the order of execution of function arguments are not guarantees by the standard, + // don't pass TRandom3 methods as function arguments, to avoid potential cross-platform differences + auto rnd1 = rndm.Uniform(theMin, theMax); + auto rnd2 = rndm.Uniform(theMin, theMax); + auto rnd3 = rndm.Uniform(theMin, theMax); + auto rnd4 = rndm.Uniform(theMin, theMax); + std::complex cFloatRef(rnd1, rnd2); + std::complex cDoubleRef(rnd3, rnd4); // read them TString cFloatName(TString::Format("cFloat_%i", j)); @@ -63,14 +70,12 @@ void readcomplex(const std::string base) cout << "ERROR Cannot get " << cDoubleName << " from file " << ifilename << endl; continue; } - // compare them bit-by-bit - compareValues(ifilename, *cFloatPtr, cFloatRef, *cDoublePtr, cDoubleRef); - + compareValues(ifilename, TString::Format("cFloat/cDouble #%i", j), *cFloatPtr, cFloatRef, *cDoublePtr, + cDoubleRef); } if (iFile != 1) { - // Now the tree TTreeReader reader ("t",ifile); TTreeReaderValue> cFloat_split(reader, "cFloat_split"); @@ -78,21 +83,26 @@ void readcomplex(const std::string base) TTreeReaderValue> cDouble_split(reader, "cDouble_split"); TTreeReaderValue> cDouble(reader, "cDouble"); + int e = 0; while (reader.Next()) { - std::complex cFloatn(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); - std::complex cDoublen(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); - compareValues(ifilename, *cFloat_split, cFloatn, *cDouble_split, cDoublen); - compareValues(ifilename, *cFloat, cFloatn, *cDouble, cDoublen); + auto rnd11 = rndm.Uniform(theMin, theMax); + auto rnd12 = rndm.Uniform(theMin, theMax); + auto rnd13 = rndm.Uniform(theMin, theMax); + auto rnd14 = rndm.Uniform(theMin, theMax); + std::complex cFloatn(rnd11, rnd12); + std::complex cDoublen(rnd13, rnd14); + compareValues(ifilename, TString::Format("Split branch entry #%i", e), *cFloat_split, cFloatn, + *cDouble_split, cDoublen); + compareValues(ifilename, TString::Format("Streamed branch entry #%i", e), *cFloat, cFloatn, *cDouble, + cDoublen); + ++e; } - } - } } void execreadcomplex() { - // Files produced on this very platform readcomplex("complexOfileROOT6"); @@ -100,5 +110,4 @@ void execreadcomplex() readcomplex("complexOfilekubuntuROOT5"); readcomplex("complexOfilekubuntuROOT6"); readcomplex("complexOfileslc6ROOT5"); - } diff --git a/roottest/root/io/complex/execwritecomplex.C b/roottest/root/io/complex/execwritecomplex.C index 6cde2da4732f3..bfae38f32c7e1 100644 --- a/roottest/root/io/complex/execwritecomplex.C +++ b/roottest/root/io/complex/execwritecomplex.C @@ -1,7 +1,7 @@ // This macro must be v5/v6 executable! -void writecomplex(const std::string base){ - +void writecomplex(const std::string base) +{ const int nentries = 1000; const double theMax = 1000.; @@ -9,14 +9,14 @@ void writecomplex(const std::string base){ // The two formats std::string rVersion = "ROOT6"; - if (gROOT->GetVersionInt()<60000) + if (gROOT->GetVersionInt() < 60000) rVersion = "ROOT5"; std::vector ofileNames; - ofileNames.push_back(base+rVersion+".xml"); - ofileNames.push_back(base+rVersion+".root"); + ofileNames.push_back(base + rVersion + ".xml"); + ofileNames.push_back(base + rVersion + ".root"); - for (int iFile=0;iFile cFloatrw(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); - std::complex cDoublerw(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); + for (int j = 0; j < nentries; ++j) { + // Since the order of execution of function arguments are not guarantees by the standard, + // don't pass TRandom3 methods as function arguments, to avoid potential cross-platform differences + auto rnd1 = rndm.Uniform(theMin, theMax); + auto rnd2 = rndm.Uniform(theMin, theMax); + auto rnd3 = rndm.Uniform(theMin, theMax); + auto rnd4 = rndm.Uniform(theMin, theMax); + std::complex cFloatrw(rnd1, rnd2); + std::complex cDoublerw(rnd3, rnd4); - ofile->WriteObjectAny(&cFloatrw,"complex",TString::Format("cFloat_%i",j)); - ofile->WriteObjectAny(&cDoublerw,"complex",TString::Format("cDouble_%i",j)); + ofile->WriteObjectAny(&cFloatrw, "complex", TString::Format("cFloat_%i", j)); + ofile->WriteObjectAny(&cDoublerw, "complex", TString::Format("cDouble_%i", j)); } if (iFile != 0) { // tree not supported on xml // Now write a tree with nentries events with one branch per type, split and unsplit - std::complex* cFloat = new std::complex(0.f,0.f); - std::complex* cDouble = new std::complex(0.,0.); - TTree t("t","Test Tree"); - t.Branch("cFloat_split", &cFloat,16000,99); - t.Branch("cFloat", &cFloat,16000,0); - t.Branch("cDouble_split", &cDouble,16000,99); - t.Branch("cDouble", &cDouble,16000,0); - for (int j=0;j cFloatVol(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); - std::complex cDoubleVol(rndm.Uniform(theMin,theMax),rndm.Uniform(theMin,theMax)); - *cFloat=cFloatVol; - *cDouble=cDoubleVol; + std::complex *cFloat = new std::complex(0.f, 0.f); + std::complex *cDouble = new std::complex(0., 0.); + TTree t("t", "Test Tree"); + t.Branch("cFloat_split", &cFloat, 16000, 99); + t.Branch("cFloat", &cFloat, 16000, 0); + t.Branch("cDouble_split", &cDouble, 16000, 99); + t.Branch("cDouble", &cDouble, 16000, 0); + for (int j = 0; j < nentries; ++j) { + auto rnd11 = rndm.Uniform(theMin, theMax); + auto rnd12 = rndm.Uniform(theMin, theMax); + auto rnd13 = rndm.Uniform(theMin, theMax); + auto rnd14 = rndm.Uniform(theMin, theMax); + std::complex cFloatVol(rnd11, rnd12); + std::complex cDoubleVol(rnd13, rnd14); + *cFloat = cFloatVol; + *cDouble = cDoubleVol; t.Fill(); } t.Write(); @@ -57,6 +67,7 @@ void writecomplex(const std::string base){ } } -void execwritecomplex(){ +void execwritecomplex() +{ writecomplex("complexOfile"); } diff --git a/roottest/root/io/newstl/CMakeLists.txt b/roottest/root/io/newstl/CMakeLists.txt index 7b95839fb5086..9fb01172db3a5 100644 --- a/roottest/root/io/newstl/CMakeLists.txt +++ b/roottest/root/io/newstl/CMakeLists.txt @@ -52,7 +52,7 @@ endif() ROOTTEST_ADD_TEST(ComplexTest MACRO runComplexTest.C ROOTEXE_OPTS ${_complextest_load} - OUTREF ComplexTest${ref_suffix} + OUTREF ComplexTest.ref FIXTURES_REQUIRED root-io-newstl-ComplexTest_h-fixture) ROOTTEST_ADD_TEST(SampleFile diff --git a/roottest/root/io/newstl/ComplexTest.h b/roottest/root/io/newstl/ComplexTest.h index d853262680aa0..3b012c8823083 100644 --- a/roottest/root/io/newstl/ComplexTest.h +++ b/roottest/root/io/newstl/ComplexTest.h @@ -24,9 +24,4 @@ class Test: public TObject ClassDefOverride(Test, 1); }; -#ifdef __ROOTCLING__ -#pragma link C++ class std::complex+; -#pragma link C++ class Test+; -#endif - #endif /* Test_hh */