Skip to content

Commit

Permalink
[ntuple] streamline field's CloneImpl() implementation
Browse files Browse the repository at this point in the history
Non-trivial clones go through a special constructor that resembles a
copy constructor.
  • Loading branch information
jblomer committed Oct 22, 2024
1 parent 91d697a commit d26c795
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 23 deletions.
22 changes: 12 additions & 10 deletions tree/ntuple/v7/inc/ROOT/RField/RFieldFundamental.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,13 @@ class RRealField : public RSimpleField<T> {
double fValueMax = std::numeric_limits<T>::max();

protected:
void OnClone(RRealField<T> &cloned) const
/// Called by derived fields' CloneImpl()
RRealField(std::string_view name, const RRealField &source)
: RSimpleField<T>(name, source.GetTypeName()),
fBitWidth(source.fBitWidth),
fValueMin(source.fValueMin),
fValueMax(source.fValueMax)
{
cloned.fBitWidth = fBitWidth;
cloned.fValueMin = fValueMin;
cloned.fValueMax = fValueMax;
}

void GenerateColumns() final
Expand Down Expand Up @@ -474,11 +476,11 @@ template <>
class RField<float> final : public RRealField<float> {
const RColumnRepresentations &GetColumnRepresentations() const final;

RField(std::string_view name, const RField &source) : RRealField<float>(name, source) {}

std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
{
auto cloned = std::make_unique<RField>(newName);
OnClone(*cloned);
return cloned;
return std::unique_ptr<RField>(new RField(newName, *this));
}

public:
Expand All @@ -493,11 +495,11 @@ template <>
class RField<double> final : public RRealField<double> {
const RColumnRepresentations &GetColumnRepresentations() const final;

RField(std::string_view name, const RField &source) : RRealField<double>(name, source) {}

std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
{
auto cloned = std::make_unique<RField>(newName);
OnClone(*cloned);
return cloned;
return std::unique_ptr<RField>(new RField(newName, *this));
}

public:
Expand Down
2 changes: 2 additions & 0 deletions tree/ntuple/v7/inc/ROOT/RField/RFieldRecord.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ private:
void operator()(void *objPtr, bool dtorOnly) final;
};

RRecordField(std::string_view name, const RRecordField &source); // Used by CloneImpl()

protected:
std::size_t fMaxAlignment = 1;
std::size_t fSize = 0;
Expand Down
2 changes: 2 additions & 0 deletions tree/ntuple/v7/inc/ROOT/RField/RFieldSTLMisc.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ private:
static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset);
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag);

RVariantField(std::string_view name, const RVariantField &source); // Used by CloneImpl()

protected:
std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;

Expand Down
39 changes: 26 additions & 13 deletions tree/ntuple/v7/src/RField.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2498,6 +2498,17 @@ void ROOT::Experimental::RProxiedCollectionField::AcceptVisitor(Detail::RFieldVi

//------------------------------------------------------------------------------

ROOT::Experimental::RRecordField::RRecordField(std::string_view name, const RRecordField &source)
: ROOT::Experimental::RFieldBase(name, source.GetTypeName(), ENTupleStructure::kRecord, false /* isSimple */),
fMaxAlignment(source.fMaxAlignment),
fSize(source.fSize),
fOffsets(source.fOffsets)
{
for (const auto &f : source.GetSubFields())
Attach(f->Clone(f->GetFieldName()));
fTraits = source.fTraits;
}

ROOT::Experimental::RRecordField::RRecordField(std::string_view fieldName,
std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
const std::vector<std::size_t> &offsets, std::string_view typeName)
Expand Down Expand Up @@ -2551,11 +2562,7 @@ std::size_t ROOT::Experimental::RRecordField::GetItemPadding(std::size_t baseOff
std::unique_ptr<ROOT::Experimental::RFieldBase>
ROOT::Experimental::RRecordField::CloneImpl(std::string_view newName) const
{
std::vector<std::unique_ptr<RFieldBase>> cloneItems;
cloneItems.reserve(fSubFields.size());
for (auto &item : fSubFields)
cloneItems.emplace_back(item->Clone(item->GetFieldName()));
return std::unique_ptr<RRecordField>(new RRecordField(newName, std::move(cloneItems), fOffsets, GetTypeName()));
return std::unique_ptr<RRecordField>(new RRecordField(newName, *this));
}

std::size_t ROOT::Experimental::RRecordField::AppendImpl(const void *from)
Expand Down Expand Up @@ -3436,6 +3443,19 @@ std::string ROOT::Experimental::RVariantField::GetTypeList(const std::vector<RFi
return result;
}

ROOT::Experimental::RVariantField::RVariantField(std::string_view name, const RVariantField &source)
: ROOT::Experimental::RFieldBase(name, source.GetTypeName(), ENTupleStructure::kVariant, false /* isSimple */),
fMaxItemSize(source.fMaxItemSize),
fMaxAlignment(source.fMaxAlignment),
fTagOffset(source.fTagOffset),
fVariantOffset(source.fVariantOffset),
fNWritten(source.fNWritten.size(), 0)
{
for (const auto &f : source.GetSubFields())
Attach(f->Clone(f->GetFieldName()));
fTraits = source.fTraits;
}

ROOT::Experimental::RVariantField::RVariantField(std::string_view fieldName,
const std::vector<RFieldBase *> &itemFields)
: ROOT::Experimental::RFieldBase(fieldName, "std::variant<" + GetTypeList(itemFields) + ">",
Expand Down Expand Up @@ -3472,14 +3492,7 @@ ROOT::Experimental::RVariantField::RVariantField(std::string_view fieldName,
std::unique_ptr<ROOT::Experimental::RFieldBase>
ROOT::Experimental::RVariantField::CloneImpl(std::string_view newName) const
{
auto nFields = fSubFields.size();
std::vector<RFieldBase *> itemFields;
itemFields.reserve(nFields);
for (unsigned i = 0; i < nFields; ++i) {
// TODO(jblomer): use unique_ptr in RVariantField constructor
itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetFieldName()).release());
}
return std::make_unique<RVariantField>(newName, itemFields);
return std::unique_ptr<RVariantField>(new RVariantField(newName, *this));
}

std::uint8_t ROOT::Experimental::RVariantField::GetTag(const void *variantPtr, std::size_t tagOffset)
Expand Down

0 comments on commit d26c795

Please sign in to comment.