Skip to content

Commit dc4dd71

Browse files
vepadulanohahnjo
andcommitted
[ntuple] Ensure type name given by RField<T> is renormalized
To avoid inconsistencies between the full type name of a custom class reported by the RNTuple IO and the type name reported by ROOT meta. The commit adds a unittest. Previously, the test would fail with exceptions such as: ``` 321: unknown file: Failure 321: C++ exception with description "type mismatch for field f2: DataVector<std::int32_t,std::vector<CustomStruct>> vs. DataVector<int,vector<CustomStruct> > 321: At: 321: void ROOT::Experimental::REntry::EnsureMatchingType(RFieldToken) const [with T = DataVector<int, std::vector<CustomStruct> >] 321: " thrown in the test body. ``` Co-authored-by: Jonas Hahnfeld <[email protected]>
1 parent 18621e4 commit dc4dd71

File tree

6 files changed

+20
-2
lines changed

6 files changed

+20
-2
lines changed

tree/ntuple/v7/inc/ROOT/RField.hxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <ROOT/RError.hxx>
2020
#include <ROOT/RFieldBase.hxx>
21+
#include <ROOT/RFieldUtils.hxx>
2122
#include <ROOT/RNTupleSerialize.hxx>
2223
#include <ROOT/RNTupleUtil.hxx>
2324
#include <ROOT/RSpan.hxx>
@@ -290,7 +291,7 @@ public:
290291
template <typename T, typename = void>
291292
class RField final : public RClassField {
292293
public:
293-
static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
294+
static std::string TypeName() { return ROOT::Internal::GetRenormalizedDemangledTypeName(typeid(T)); }
294295
RField(std::string_view name) : RClassField(name, TypeName())
295296
{
296297
static_assert(std::is_class_v<T>, "no I/O support for this basic C++ type");

tree/ntuple/v7/inc/ROOT/RField/RFieldProxiedCollection.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ struct IsCollectionProxy : HasCollectionProxyMemberType<T> {
265265
template <typename T>
266266
class RField<T, typename std::enable_if<IsCollectionProxy<T>::value>::type> final : public RProxiedCollectionField {
267267
public:
268-
static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
268+
static std::string TypeName() { return ROOT::Internal::GetRenormalizedDemangledTypeName(typeid(T)); }
269269
RField(std::string_view name) : RProxiedCollectionField(name, TypeName())
270270
{
271271
static_assert(std::is_class<T>::value, "collection proxy unsupported for fundamental types");

tree/ntuple/v7/inc/ROOT/RFieldUtils.hxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <string>
1212
#include <string_view>
13+
#include <typeinfo>
1314
#include <tuple>
1415
#include <vector>
1516

@@ -26,6 +27,10 @@ std::string GetCanonicalTypePrefix(const std::string &typeName);
2627
/// Given a type name normalized by ROOT meta, renormalize it for RNTuple. E.g., insert std::prefix.
2728
std::string GetRenormalizedTypeName(const std::string &metaNormalizedName);
2829

30+
/// Given a type info ask ROOT meta to demangle it, then renormalize the resulting type name for RNTuple. Useful to
31+
/// ensure that e.g. fundamental types are normalized to the type used by RNTuple (e.g. int -> std::int32_t).
32+
std::string GetRenormalizedDemangledTypeName(const std::type_info &ti);
33+
2934
/// Applies all RNTuple type normalization rules except typedef resolution.
3035
std::string GetNormalizedUnresolvedTypeName(const std::string &origName);
3136

tree/ntuple/v7/src/RFieldUtils.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,8 @@ std::vector<std::string> ROOT::Internal::TokenizeTypeList(std::string_view templ
463463
result.push_back(std::string(typeBegin, typeCursor - typeBegin));
464464
return result;
465465
}
466+
467+
std::string ROOT::Internal::GetRenormalizedDemangledTypeName(const std::type_info &ti)
468+
{
469+
return ROOT::Internal::GetRenormalizedTypeName(ROOT::Internal::GetDemangledTypeName(ti));
470+
}

tree/ntuple/v7/test/CustomStructLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#pragma link C++ class DataVector < int, double> + ;
2929
#pragma link C++ class DataVector < int, float> + ;
3030
#pragma link C++ class DataVector < bool, std::vector < unsigned int>> + ;
31+
#pragma link C++ class DataVector < StructUsingCollectionProxy < int>, double> + ;
3132
#pragma link C++ class DataVector < int, double> ::Inner + ;
3233
#pragma link C++ class DataVector < int, double> ::Inner + ;
3334
#pragma link C++ class DataVector < int, float> ::Inner + ;

tree/ntuple/v7/test/ntuple_type_name.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ TEST(RNTuple, TClassDefaultTemplateParameter)
7070
model->AddField(RFieldBase::Create("f4", "struct DataVector<bool,vector<unsigned>>").Unwrap());
7171
model->AddField(RFieldBase::Create("f5", "DataVector<Double32_t>").Unwrap());
7272
model->AddField(RFieldBase::Create("f6", "DataVector<int, double>").Unwrap());
73+
model->MakeField<DataVector<StructUsingCollectionProxy<int>>>("f7");
7374
auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath());
7475
}
7576

@@ -99,6 +100,11 @@ TEST(RNTuple, TClassDefaultTemplateParameter)
99100
auto v1 = reader->GetView<DataVector<int>>("f1");
100101
auto v3 = reader->GetView<DataVector<int>>("f3");
101102
EXPECT_THROW(reader->GetView<DataVector<int>>("f2"), ROOT::RException);
103+
104+
// Ensure the typed API does not throw an exception
105+
auto f1 = reader->GetModel().GetDefaultEntry().GetPtr<DataVector<int>>("f1");
106+
auto f4 = reader->GetModel().GetDefaultEntry().GetPtr<DataVector<bool, std::vector<unsigned int>>>("f4");
107+
auto f7 = reader->GetModel().GetDefaultEntry().GetPtr<DataVector<StructUsingCollectionProxy<int>>>("f7");
102108
}
103109

104110
TEST(RNTuple, TemplateArgIntegerNormalization)

0 commit comments

Comments
 (0)