Skip to content

Commit 532b006

Browse files
committed
[ntuple] fix TClass initializatin in RField<UserClass>
In the templated version of the RClassField, the type name passed to TClass::GetClass() must not use the RNTuple normalized name but the demangled name or the meta normalized name. Otherwise, RNTuple may normalize, e.g., `long long` to `std::int64_t`, which in turn gets normalized by Meta to `unsigned long`. (cherry picked from commit 4a789b0)
1 parent 5fac194 commit 532b006

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

tree/ntuple/inc/ROOT/RField.hxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ public:
197197
size_t GetAlignment() const final { return fMaxAlignment; }
198198
std::uint32_t GetTypeVersion() const final;
199199
std::uint32_t GetTypeChecksum() const final;
200+
/// Return the TClass instance backing this field.
201+
const TClass *GetClass() const { return fClass; }
200202
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
201203
};
202204

@@ -285,7 +287,7 @@ template <typename T, typename = void>
285287
class RField final : public RClassField {
286288
public:
287289
static std::string TypeName() { return ROOT::Internal::GetRenormalizedDemangledTypeName(typeid(T)); }
288-
RField(std::string_view name) : RClassField(name, TypeName())
290+
RField(std::string_view name) : RClassField(name, Internal::GetDemangledTypeName(typeid(T)))
289291
{
290292
static_assert(std::is_class_v<T>, "no I/O support for this basic C++ type");
291293
}

tree/ntuple/test/CustomStruct.hxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ public:
9595
T fMember;
9696
};
9797

98+
class EdmContainer {
99+
public:
100+
// Used to test that the streamer info for fWrapper will use long long
101+
EdmWrapper<long long> fWrapper;
102+
};
103+
98104
template <typename T>
99105
struct EdmHashTrait {
100106
using value_type = T;

tree/ntuple/test/CustomStructLinkDef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#pragma link C++ class EdmWrapper<CustomStruct> +;
2727
#pragma link C++ class EdmHash < 1> + ;
28+
#pragma link C++ class EdmWrapper<long long>+;
29+
#pragma link C++ class EdmContainer;
2830

2931
#pragma link C++ class DataVector < int, double> + ;
3032
#pragma link C++ class DataVector < int, float> + ;

tree/ntuple/test/rfield_class.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,19 @@ TEST(RNTuple, TClassInnerReadRule)
344344
reader->LoadEntry(1);
345345
EXPECT_TRUE(f->empty());
346346
}
347+
348+
TEST(RNTuple, TClassMetaName)
349+
{
350+
auto f1 = ROOT::RClassField("f", "EdmWrapper<long long>");
351+
EXPECT_STREQ("EdmWrapper<Long64_t>", f1.GetClass()->GetName());
352+
353+
auto f2 = std::make_unique<ROOT::RField<EdmWrapper<long long>>>("f");
354+
EXPECT_STREQ("EdmWrapper<Long64_t>", static_cast<ROOT::RClassField *>(f2.get())->GetClass()->GetName());
355+
356+
auto f3 = RFieldBase::Create("f", "EdmWrapper<long long>").Unwrap();
357+
EXPECT_STREQ("EdmWrapper<Long64_t>", static_cast<ROOT::RClassField *>(f3.get())->GetClass()->GetName());
358+
359+
auto f4 = RFieldBase::Create("f", "EdmContainer").Unwrap();
360+
EXPECT_STREQ("EdmWrapper<Long64_t>",
361+
static_cast<const ROOT::RClassField *>(f4->GetConstSubfields()[0])->GetClass()->GetName());
362+
}

0 commit comments

Comments
 (0)