diff --git a/tree/ntuple/test/CustomStruct.hxx b/tree/ntuple/test/CustomStruct.hxx index 0cde0ccb3e091..350305a28fc6c 100644 --- a/tree/ntuple/test/CustomStruct.hxx +++ b/tree/ntuple/test/CustomStruct.hxx @@ -497,8 +497,4 @@ struct AlignmentEnvelope { std::array fArr; }; -struct VersionedStreamerField { - ClassDefNV(VersionedStreamerField, 2); -}; - #endif diff --git a/tree/ntuple/test/CustomStructLinkDef.h b/tree/ntuple/test/CustomStructLinkDef.h index c8e6ec796cad9..4786ce21e2860 100644 --- a/tree/ntuple/test/CustomStructLinkDef.h +++ b/tree/ntuple/test/CustomStructLinkDef.h @@ -185,6 +185,5 @@ #pragma link C++ class AlignedAs+; #pragma link C++ class OverAligned+; #pragma link C++ class AlignmentEnvelope+; -#pragma link C++ class VersionedStreamerField+; #endif diff --git a/tree/ntuple/test/StreamerField.hxx b/tree/ntuple/test/StreamerField.hxx index cf5d29d4d26bc..dbf957d96cce4 100644 --- a/tree/ntuple/test/StreamerField.hxx +++ b/tree/ntuple/test/StreamerField.hxx @@ -101,4 +101,8 @@ struct TemperatureKelvin { float fValue; }; +struct VersionedStreamerField { + ClassDefNV(VersionedStreamerField, 2); +}; + #endif // ROOT_RNTuple_Test_StreamerField diff --git a/tree/ntuple/test/StreamerFieldLinkDef.h b/tree/ntuple/test/StreamerFieldLinkDef.h index 59010c53264e4..4d5b33de2e90e 100644 --- a/tree/ntuple/test/StreamerFieldLinkDef.h +++ b/tree/ntuple/test/StreamerFieldLinkDef.h @@ -26,5 +26,6 @@ #pragma link C++ options = rntupleStreamerMode(true) class TemperatureCelsius + ; #pragma link C++ options = rntupleStreamerMode(true) class TemperatureKelvin + ; +#pragma link C++ options = rntupleStreamerMode(true) class VersionedStreamerField + ; #endif diff --git a/tree/ntuple/test/rfield_streamer.cxx b/tree/ntuple/test/rfield_streamer.cxx index 1a331b5b195fb..41137cedad18e 100644 --- a/tree/ntuple/test/rfield_streamer.cxx +++ b/tree/ntuple/test/rfield_streamer.cxx @@ -412,10 +412,26 @@ namespace { /// Used to create on-disk streamer fields with different field versions class RVersionedStreamerField : public RFieldBase { +private: + class RVersionedStreamerFieldDeleter : public RDeleter { + private: + TClass *fClass = nullptr; + + public: + explicit RVersionedStreamerFieldDeleter(TClass *cl) : RDeleter(cl->GetClassAlignment()), fClass(cl) {} + void operator()(void *objPtr, bool dtorOnly) final + { + fClass->Destructor(objPtr, true /* dtorOnly */); + RDeleter::operator()(objPtr, dtorOnly); + } + }; + + TClass *fClass = nullptr; + protected: std::unique_ptr CloneImpl(std::string_view newName) const final { - return std::make_unique(newName, fCustomVersion); + return std::make_unique(newName, fClass->GetName(), fCustomVersion); } const RColumnRepresentations &GetColumnRepresentations() const final @@ -428,23 +444,27 @@ class RVersionedStreamerField : public RFieldBase { void GenerateColumns() final { GenerateColumnsImpl(); } void GenerateColumns(const ROOT::RNTupleDescriptor &) final {} - void ConstructValue(void *) const final {} + void ConstructValue(void *where) const final { fClass->New(where); } + std::unique_ptr GetDeleter() const final + { + return std::make_unique(fClass); + } std::size_t AppendImpl(const void *) final { return 0; } public: std::uint32_t fCustomVersion = 0; - RVersionedStreamerField(std::string_view name, std::uint32_t version) - : RFieldBase(name, "VersionedStreamerField", ROOT::ENTupleStructure::kStreamer, /*isSimple=*/false), - fCustomVersion(version) + RVersionedStreamerField(std::string_view name, std::string_view classname, std::uint32_t version) + : RFieldBase(name, classname, ROOT::ENTupleStructure::kStreamer, /*isSimple=*/false), + fClass(TClass::GetClass(std::string(classname).c_str())), fCustomVersion(version) { } std::uint32_t GetFieldVersion() const final { return fCustomVersion; } std::uint32_t GetTypeVersion() const final { return 137; } - std::size_t GetValueSize() const final { return 0; } - std::size_t GetAlignment() const final { return 0; } + std::size_t GetValueSize() const final { return fClass->GetClassSize(); } + std::size_t GetAlignment() const final { return fClass->GetClassAlignment(); } }; } // anonymous namespace @@ -455,7 +475,7 @@ TEST(RField, StreamerFieldVersion) FileRaii fileGuard("test_ntuple_rfield_streamer_version.root"); { auto model = RNTupleModel::Create(); - model->AddField(std::make_unique("f", version)); + model->AddField(std::make_unique("f", "VersionedStreamerField", version)); auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath()); } auto reader = RNTupleReader::Open("ntpl", fileGuard.GetPath());