@@ -665,6 +665,7 @@ ROOT::Experimental::RSoAField::RSoAField(std::string_view fieldName, const RSoAF
665665 fRecordMemberDeleters .reserve (fRecordMemberFields .size ());
666666 for (const auto f : fRecordMemberFields )
667667 fRecordMemberDeleters .emplace_back (GetDeleterOf (*f));
668+ fLockSplitFields = std::make_unique<std::mutex>();
668669}
669670
670671ROOT ::Experimental::RSoAField::RSoAField(std::string_view fieldName, std::string_view className)
@@ -777,6 +778,7 @@ ROOT::Experimental::RSoAField::RSoAField(std::string_view fieldName, TClass *clS
777778 fTypeAlias = renormalizedAlias;
778779
779780 fTraits |= kTraitSoACollection | kTraitTypeChecksum ;
781+ fLockSplitFields = std::make_unique<std::mutex>();
780782}
781783
782784std::unique_ptr<ROOT ::RFieldBase> ROOT::Experimental::RSoAField::CloneImpl (std::string_view newName) const
@@ -881,10 +883,31 @@ void ROOT::Experimental::RSoAField::RSoADeleter::operator()(void *objPtr, bool d
881883 RDeleter::operator ()(objPtr, dtorOnly);
882884}
883885
884- std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue & /* value */ ) const
886+ std::vector<ROOT ::RFieldBase::RValue> ROOT::Experimental::RSoAField::SplitValue (const RValue &value) const
885887{
886- throw RException (R__FAIL (" not yet implemented" ));
887- return std::vector<RValue>();
888+ const auto nSoAMembers = fSoAMemberOffsets .size ();
889+
890+ {
891+ std::lock_guard<std::mutex> lockGuard (*fLockSplitFields );
892+ if (!fSplitFields ) {
893+ fSplitFields = std::make_unique<std::vector<std::unique_ptr<ROOT ::RRVecField>>>();
894+ fSplitFields ->reserve (nSoAMembers);
895+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
896+ const auto itemField = fRecordMemberFields [i];
897+ fSplitFields ->emplace_back (std::make_unique<RRVecField>(itemField->GetFieldName (), itemField->Clone (" _0" )));
898+ }
899+ }
900+ }
901+
902+ auto valuePtr = value.GetPtr <void >();
903+ auto soaPtr = static_cast <unsigned char *>(valuePtr.get ());
904+ std::vector<RValue> values;
905+ values.reserve (nSoAMembers);
906+ for (std::size_t i = 0 ; i < nSoAMembers; ++i) {
907+ values.emplace_back (
908+ (*fSplitFields )[i]->BindValue (std::shared_ptr<void >(valuePtr, soaPtr + fSoAMemberOffsets [i])));
909+ }
910+ return values;
888911}
889912
890913size_t ROOT::Experimental::RSoAField::GetValueSize () const
0 commit comments