2121#include < ROOT/RNTupleRange.hxx>
2222#include < ROOT/RNTupleTypes.hxx>
2323
24+ #include < atomic>
2425#include < cstddef>
2526#include < functional>
2627#include < iterator>
@@ -710,15 +711,29 @@ private:
710711 RFieldBase *fField = nullptr ; // /< The field that created the RValue
711712 // / Set by Bind() or by RFieldBase::CreateValue(), RFieldBase::SplitValue() or RFieldBase::BindValue()
712713 std::shared_ptr<void > fObjPtr ;
713- mutable const std::type_info *fTypeInfo = nullptr ;
714+ mutable std::atomic< const std::type_info *> fTypeInfo = nullptr ;
714715
715716 RValue (RFieldBase *field, std::shared_ptr<void > objPtr) : fField (field), fObjPtr (objPtr) {}
716717
717718public:
718- RValue (const RValue &) = default ;
719- RValue &operator =(const RValue &) = default ;
720- RValue (RValue &&other) = default ;
721- RValue &operator =(RValue &&other) = default ;
719+ RValue (const RValue &other) : fField (other.fField ), fObjPtr (other.fObjPtr ) {}
720+ RValue &operator =(const RValue &other)
721+ {
722+ fField = other.fField ;
723+ fObjPtr = other.fObjPtr ;
724+ // We could copy over the cached type info, or just start with a fresh state...
725+ fTypeInfo = nullptr ;
726+ return *this ;
727+ }
728+ RValue (RValue &&other) : fField (other.fField ), fObjPtr (other.fObjPtr ) {}
729+ RValue &operator =(RValue &&other)
730+ {
731+ fField = other.fField ;
732+ fObjPtr = other.fObjPtr ;
733+ // We could copy over the cached type info, or just start with a fresh state...
734+ fTypeInfo = nullptr ;
735+ return *this ;
736+ }
722737 ~RValue () = default ;
723738
724739private:
@@ -729,12 +744,13 @@ private:
729744 const std::type_info &ti = typeid (T);
730745 // Fast path: if we had a matching type before, try comparing the type_info's. This may still fail in case the
731746 // type has a suppressed template argument that may change the typeid.
732- if (fTypeInfo != nullptr && *fTypeInfo == ti) {
747+ auto *cachedTypeInfo = fTypeInfo .load ();
748+ if (cachedTypeInfo != nullptr && *cachedTypeInfo == ti) {
733749 return ;
734750 }
735751 std::string renormalizedTypeName = Internal::GetRenormalizedTypeName (ti);
736752 if (Internal::IsMatchingFieldType (fField ->GetTypeName (), renormalizedTypeName, ti)) {
737- fTypeInfo = &ti;
753+ fTypeInfo . store ( &ti) ;
738754 return ;
739755 }
740756 throw RException (R__FAIL (" type mismatch for field \" " + fField ->GetFieldName () + " \" : expected " +
0 commit comments