Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
843644c
NOT READY: [tree] Fix handling of poorly cluster file in the retain p…
pcanal Jun 2, 2025
ad482ee
io: Improve ByteCountStack assert
pcanal Apr 7, 2026
954b4f0
io: TBufferClass fix handling of large bytecount.
pcanal Apr 7, 2026
380beb0
WIP: for debugging ByteCountStack - Consider REVERTing
pcanal Feb 16, 2026
6d94995
io: Improve ByteCountStack error message
pcanal Apr 9, 2026
fc5c15c
io/meta: Ensure NewArray* takes a 64 bit integer.
pcanal Feb 9, 2026
78b24e8
WIP io: Lift size limit on TBufferFile .. is this temporary?
pcanal Feb 12, 2026
150a1b3
WIP: Update type to ULong64_t
pcanal Apr 3, 2026
69c0ce1
WIP-io: Read/WriteFastArray Float to Long64_t
pcanal Apr 6, 2026
efae37b
io: Relax TBuffer::AutoExpand to 64bits
pcanal Apr 10, 2026
2b97bf9
io: 64bits TVirtualCollectionProxy
pcanal Apr 10, 2026
ebe288f
io: Read TStreamerInfo version to 11, 64bits collection size in old code
pcanal Apr 10, 2026
d7fecbe
io: (for) TStreamerInfo version to 11, 64bits collection size
pcanal Apr 10, 2026
a0cc53a
WIP-io: Extent TVirtualCollection to 64bits.
pcanal Apr 6, 2026
425e636
io: TStreamerInfo version to 11, 64bits collection size
pcanal Apr 10, 2026
09c719b
To Review: io: Address warning after signature changes
pcanal Apr 8, 2026
c5ce2a6
io: Address warning after signature changes
pcanal Apr 8, 2026
1687042
WIP-io: TBuffer ctor and SetBuffer 64bits:
pcanal Apr 9, 2026
f45e056
io: test long range Read/WriteObjectAny
pcanal Feb 11, 2026
8dc3a46
io: Add test for ByteCount for 4GB+ objects
pcanal Apr 7, 2026
0ccb835
net: Keep TMessage to 32 bits (no real enforcement yet)
pcanal Apr 9, 2026
138f23d
io: old StreamerInfo read/write 64 bit collections
pcanal Apr 9, 2026
47f8daa
io: add unit test infrastructure for streaming large objects
jblomer Dec 2, 2025
c364f50
io: test very large collections
pcanal Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions core/base/inc/TBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ class TBuffer : public TObject {

protected:
typedef std::vector<TVirtualArray*> CacheList_t;
// FIXME: decide if this is signed or unsigned.
using Size_t = std::size_t;

Bool_t fMode; //Read or write mode
Int_t fVersion; //Buffer format version
Int_t fBufSize; //Size of buffer
Size_t fBufSize; //Size of buffer
char *fBuffer; //Buffer used to store objects
char *fBufCur; //Current position in buffer
char *fBufMax; //End of buffer
Expand Down Expand Up @@ -88,29 +90,29 @@ class TBuffer : public TObject {
enum { kInitialSize = 1024, kMinimalSize = 128 };

TBuffer(EMode mode);
TBuffer(EMode mode, Long64_t bufsize);
TBuffer(EMode mode, Long64_t bufsize, void *buf, Bool_t adopt = kTRUE, ReAllocCharFun_t reallocfunc = nullptr);
TBuffer(EMode mode, ULong64_t bufsize);
TBuffer(EMode mode, ULong64_t bufsize, void *buf, Bool_t adopt = kTRUE, ReAllocCharFun_t reallocfunc = nullptr);
virtual ~TBuffer();

Int_t GetBufferVersion() const { return fVersion; }
Bool_t IsReading() const { return (fMode & kWrite) == 0; }
Bool_t IsWriting() const { return (fMode & kWrite) != 0; }
void SetReadMode();
void SetWriteMode();
void SetBuffer(void *buf, Long64_t bufsize = 0, Bool_t adopt = kTRUE, ReAllocCharFun_t reallocfunc = nullptr);
void SetBuffer(void *buf, ULong64_t bufsize = 0, Bool_t adopt = kTRUE, ReAllocCharFun_t reallocfunc = nullptr);
ReAllocCharFun_t GetReAllocFunc() const;
void SetReAllocFunc(ReAllocCharFun_t reallocfunc = nullptr);
void SetBufferOffset(Long64_t offset = 0) { fBufCur = fBuffer+offset; }
void SetBufferOffset(ULong64_t offset = 0) { fBufCur = fBuffer+offset; }
void SetParent(TObject *parent);
TObject *GetParent() const;
char *Buffer() const { return fBuffer; }
char *GetCurrent() const { return fBufCur; }
Int_t BufferSize() const { return fBufSize; }
Size_t BufferSize() const { return fBufSize; }
void DetachBuffer() { fBuffer = nullptr; }
Int_t Length() const { return (Int_t)(fBufCur - fBuffer); }
void Expand(Long64_t newsize, Bool_t copy = kTRUE); // expand buffer to newsize
void AutoExpand(Long64_t size_needed); // expand buffer to newsize
Bool_t ByteSwapBuffer(Long64_t n, EDataType type); // Byte-swap N primitive-elements in the buffer
Size_t Length() const { return (Size_t)(fBufCur - fBuffer); }
void Expand(ULong64_t newsize, Bool_t copy = kTRUE); // expand buffer to newsize
void AutoExpand(ULong64_t size_needed); // expand buffer to newsize
Bool_t ByteSwapBuffer(ULong64_t n, EDataType type); // Byte-swap N primitive-elements in the buffer

virtual Bool_t CheckObject(const TObject *obj) = 0;
virtual Bool_t CheckObject(const void *obj, const TClass *ptrClass) = 0;
Expand Down Expand Up @@ -320,7 +322,7 @@ class TBuffer : public TObject {
virtual void ReadFastArray(ULong_t *l, Int_t n) = 0;
virtual void ReadFastArray(Long64_t *l, Int_t n) = 0;
virtual void ReadFastArray(ULong64_t *l, Int_t n) = 0;
virtual void ReadFastArray(Float_t *f, Int_t n) = 0;
virtual void ReadFastArray(Float_t *f, Long64_t n) = 0;
virtual void ReadFastArray(Double_t *d, Int_t n) = 0;
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele = nullptr) = 0;
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele = nullptr) = 0;
Expand Down
84 changes: 44 additions & 40 deletions core/base/src/TBuffer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ Buffer base class used for serializing objects.
#include "TClass.h"
#include "TProcessID.h"

constexpr Int_t kExtraSpace = 8; // extra space at end of buffer (used for free block count)
constexpr Int_t kMaxBufferSize = 0x7FFFFFFE; // largest possible size.
constexpr UInt_t kExtraSpace = 8; // extra space at end of buffer (used for free block count)
constexpr UInt_t kMaxBufferSize = 0x7FFFFFFE; // largest possible size before we need to switch to the large buffer format (see TBufferFile::SetByteCount).
constexpr ULong64_t kMaxLargeBufferSize = 0x7FFFFFFFFFFFFFFE; // largest possible size.



Expand Down Expand Up @@ -69,7 +70,7 @@ TBuffer::TBuffer(EMode mode)
/// Create an I/O buffer object. Mode should be either TBuffer::kRead or
/// TBuffer::kWrite.

TBuffer::TBuffer(EMode mode, Long64_t bufsize)
TBuffer::TBuffer(EMode mode, ULong64_t bufsize)
{
if (bufsize > kMaxBufferSize)
Fatal("TBuffer","Request to create a too large buffer: 0x%llx for a max of 0x%x.", bufsize, kMaxBufferSize);
Expand Down Expand Up @@ -100,23 +101,31 @@ TBuffer::TBuffer(EMode mode, Long64_t bufsize)
/// is provided, a Fatal error will be issued if the Buffer attempts to
/// expand.

TBuffer::TBuffer(EMode mode, Long64_t bufsize, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc)
TBuffer::TBuffer(EMode mode, ULong64_t bufsize, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc)
{
if (bufsize > kMaxBufferSize)
Fatal("TBuffer","Request to create a too large buffer: 0x%llx for a max of 0x%x.", bufsize, kMaxBufferSize);
if (bufsize > kMaxLargeBufferSize)
Fatal("TBuffer","Request to create a too large buffer: 0x%llx for a max of 0x%llx.", bufsize, kMaxLargeBufferSize);
fBufSize = bufsize;
fMode = mode;
fVersion = 0;
fParent = nullptr;

SetBit(kIsOwner);

if (buf && !adopt)
ResetBit(kIsOwner);

SetReAllocFunc( reallocfunc );

if (buf) {
fBuffer = (char *)buf;
if ( (fMode&kWrite)!=0 ) {
fBufSize -= kExtraSpace;
if (fBufSize < kExtraSpace) {
Expand( kMinimalSize );
} else {
fBufSize -= kExtraSpace;
}
}
if (!adopt) ResetBit(kIsOwner);
} else {
if (fBufSize < kMinimalSize) {
fBufSize = kMinimalSize;
Expand All @@ -125,12 +134,6 @@ TBuffer::TBuffer(EMode mode, Long64_t bufsize, void *buf, Bool_t adopt, ReAllocC
}
fBufCur = fBuffer;
fBufMax = fBuffer + fBufSize;

SetReAllocFunc( reallocfunc );

if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
Expand( kMinimalSize );
}
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -154,15 +157,15 @@ TBuffer::~TBuffer()
/// If the size_needed is larger than the current size, the policy
/// is to expand to double the current size or the size_needed which ever is largest.

void TBuffer::AutoExpand(Long64_t size_needed)
void TBuffer::AutoExpand(ULong64_t size_needed)
{
if (size_needed > kMaxBufferSize) {
Fatal("AutoExpand","Request to expand a too large buffer: 0x%llx for a max of 0x%x.", size_needed, kMaxBufferSize);
if (size_needed > kMaxLargeBufferSize) {
Fatal("AutoExpand","Request to expand a too large buffer: 0x%llx for a max of 0x%llx.", size_needed, kMaxLargeBufferSize);
}
if (size_needed > fBufSize) {
Long64_t doubling = 2LLU * fBufSize;
if (doubling > kMaxBufferSize)
doubling = kMaxBufferSize;
ULong64_t doubling = 2LLU * fBufSize;
if (doubling > kMaxLargeBufferSize)
doubling = kMaxLargeBufferSize;
if (size_needed > doubling) {
Expand(size_needed);
} else {
Expand All @@ -183,7 +186,7 @@ void TBuffer::AutoExpand(Long64_t size_needed)
/// is provided, a Fatal error will be issued if the Buffer attempts to
/// expand.

void TBuffer::SetBuffer(void *buf, Long64_t newsiz, Bool_t adopt, ReAllocCharFun_t reallocfunc)
void TBuffer::SetBuffer(void *buf, ULong64_t newsiz, Bool_t adopt, ReAllocCharFun_t reallocfunc)
{
if (newsiz > kMaxBufferSize)
Fatal("SetBuffer","Request to create a too large buffer: 0x%llx for a max of 0x%x.", newsiz, kMaxBufferSize);
Expand All @@ -195,22 +198,22 @@ void TBuffer::SetBuffer(void *buf, Long64_t newsiz, Bool_t adopt, ReAllocCharFun
else
ResetBit(kIsOwner);

SetReAllocFunc( reallocfunc );

fBuffer = (char *)buf;
fBufCur = fBuffer;
if (newsiz > 0) {
if ( (fMode&kWrite)!=0 ) {
fBufSize = newsiz - kExtraSpace;
if (newsiz >= kExtraSpace) {
fBufSize = newsiz - kExtraSpace;
} else {
Expand( kMinimalSize );
}
} else {
fBufSize = newsiz;
}
}
fBufMax = fBuffer + fBufSize;

SetReAllocFunc( reallocfunc );

if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
Expand( kMinimalSize );
}
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -221,22 +224,23 @@ void TBuffer::SetBuffer(void *buf, Long64_t newsiz, Bool_t adopt, ReAllocCharFun
/// In order to avoid losing data, if the current length is greater than
/// the requested size, we only shrink down to the current length.

void TBuffer::Expand(Long64_t newsize, Bool_t copy)
void TBuffer::Expand(ULong64_t newsize, Bool_t copy)
{
Int_t l = Length();
if ( (Long64_t(l) > newsize) && copy ) {
ULong64_t l = Length();
if ( l > newsize && copy ) {
newsize = l;
}
const Int_t extraspace = (fMode&kWrite)!=0 ? kExtraSpace : 0;
const ULong64_t extraspace = (fMode&kWrite)!=0 ? kExtraSpace : 0;

if ( newsize > kMaxBufferSize - kExtraSpace) {
if (l < kMaxBufferSize) {
newsize = kMaxBufferSize - extraspace;
if ( newsize > kMaxLargeBufferSize - kExtraSpace) {
if (l < kMaxLargeBufferSize) {
newsize = kMaxLargeBufferSize - extraspace;
} else {
Fatal("Expand","Requested size (%lld) is too large (max is %d).", newsize, kMaxBufferSize);
Fatal("Expand","Requested size (%llu) is too large (max is %llu).", newsize, kMaxLargeBufferSize);
}
}
if ( (fMode&kWrite)!=0 ) {
// FIXME-LARGE: The size can overflow and the signature of fReAllocFunc is not large enough to handle the size of the buffer.
fBuffer = fReAllocFunc(fBuffer, newsize+kExtraSpace,
copy ? fBufSize+kExtraSpace : 0);
} else {
Expand Down Expand Up @@ -390,13 +394,13 @@ TVirtualArray *TBuffer::PopDataCache()
/// Byte-swap N primitive-elements in the buffer.
/// Bulk API relies on this function.

Bool_t TBuffer::ByteSwapBuffer(Long64_t n, EDataType type)
Bool_t TBuffer::ByteSwapBuffer(ULong64_t n, EDataType type)
{
char *input_buf = GetCurrent();
if ((type == EDataType::kShort_t) || (type == EDataType::kUShort_t)) {
#ifdef R__BYTESWAP
Short_t *buf __attribute__((aligned(8))) = reinterpret_cast<Short_t*>(input_buf);
for (int idx=0; idx<n; idx++) {
for (unsigned int idx=0; idx<n; idx++) {
Short_t tmp = *reinterpret_cast<Short_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
char *tmp_ptr = reinterpret_cast<char *>(&tmp);
frombuf(tmp_ptr, buf + idx);
Expand All @@ -405,7 +409,7 @@ Bool_t TBuffer::ByteSwapBuffer(Long64_t n, EDataType type)
} else if ((type == EDataType::kFloat_t) || (type == EDataType::kInt_t) || (type == EDataType::kUInt_t)) {
#ifdef R__BYTESWAP
Float_t *buf __attribute__((aligned(8))) = reinterpret_cast<Float_t*>(input_buf);
for (int idx=0; idx<n; idx++) {
for (unsigned int idx=0; idx<n; idx++) {
Float_t tmp = *reinterpret_cast<Float_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
char *tmp_ptr = reinterpret_cast<char *>(&tmp);
frombuf(tmp_ptr, buf + idx);
Expand All @@ -414,7 +418,7 @@ Bool_t TBuffer::ByteSwapBuffer(Long64_t n, EDataType type)
} else if ((type == EDataType::kDouble_t) || (type == EDataType::kLong64_t) || (type == EDataType::kULong64_t)) {
#ifdef R__BYTESWAP
Double_t *buf __attribute__((aligned(8))) = reinterpret_cast<Double_t*>(input_buf);
for (int idx=0; idx<n; idx++) {
for (unsigned int idx=0; idx<n; idx++) {
Double_t tmp = *reinterpret_cast<Double_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
char *tmp_ptr = reinterpret_cast<char*>(&tmp);
frombuf(tmp_ptr, buf + idx);
Expand Down
20 changes: 11 additions & 9 deletions core/cont/inc/TVirtualCollectionProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class TVirtualCollectionProxy {
kCustomAlloc = BIT(5) ///< The collection has a custom allocator.
};

using size_type = ULong64_t;

/// RAII helper class that ensures that `PushProxy()` / `PopProxy()` are called when entering / leaving a C++ context
class TPushPop {
public:
Expand Down Expand Up @@ -123,19 +125,19 @@ class TVirtualCollectionProxy {
}

/// Construct an array of `nElements` container objects and return the base address of the array
virtual void *NewArray(Int_t nElements) const { return !fClass.GetClass() ? nullptr : fClass->NewArray(nElements); }
virtual void *NewArray(Long64_t nElements) const { return !fClass.GetClass() ? nullptr : fClass->NewArray(nElements); }
/// Construct an array of `nElements` container objects at the address given by `arena`
virtual void *NewArray(Int_t nElements, void *arena) const
virtual void *NewArray(Long64_t nElements, void *arena) const
{
return !fClass.GetClass() ? nullptr : fClass->NewArray(nElements, arena);
}
/// Construct an array of `nElements` container objects and return the base address of the array
virtual TClass::ObjectPtr NewObjectArray(Int_t nElements) const
virtual TClass::ObjectPtr NewObjectArray(Long64_t nElements) const
{
return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObjectArray(nElements);
}
/// Construct an array of `nElements` container objects at the address given by `arena`
virtual TClass::ObjectPtr NewObjectArray(Int_t nElements, void *arena) const
virtual TClass::ObjectPtr NewObjectArray(Long64_t nElements, void *arena) const
{
return !fClass.GetClass() ? TClass::ObjectPtr{} : fClass->NewObjectArray(nElements, arena);
}
Expand All @@ -155,7 +157,7 @@ class TVirtualCollectionProxy {
}

/// Return the `sizeof()` of the collection object
virtual UInt_t Sizeof() const = 0;
virtual size_type Sizeof() const = 0;

/// Set the address of the container being proxied and keep track of the previous one
virtual void PushProxy(void *objectstart) = 0;
Expand All @@ -174,19 +176,19 @@ class TVirtualCollectionProxy {
virtual EDataType GetType() const = 0;

/// Return the address of the value at index `idx`
virtual void *At(UInt_t idx) = 0;
virtual void *At(size_type idx) = 0;

/// Clear the container
virtual void Clear(const char *opt = "") = 0;

/// Return the current number of elements in the container
virtual UInt_t Size() const = 0;
virtual size_type Size() const = 0;

/// Allocates space for storing at least `n` elements. This function returns a pointer to the actual object on
/// which insertions should take place. For associative collections, this function returns a pointer to a temporary
/// buffer known as the staging area. If the insertion happened in a staging area (i.e. the returned pointer !=
/// proxied object), `Commit()` should be called on the value returned by this function.
virtual void* Allocate(UInt_t n, Bool_t forceDelete) = 0;
virtual void* Allocate(size_type n, Bool_t forceDelete) = 0;

/// Commits pending elements in a staging area (see Allocate() for more information).
virtual void Commit(void*) = 0;
Expand All @@ -196,7 +198,7 @@ class TVirtualCollectionProxy {
virtual void Insert(const void *data, void *container, size_t size) = 0;

/// Return the address of the value at index `idx`
char *operator[](UInt_t idx) const { return (char *)(const_cast<TVirtualCollectionProxy *>(this))->At(idx); }
char *operator[](size_type idx) const { return (char *)(const_cast<TVirtualCollectionProxy *>(this))->At(idx); }

// Functions related to member-wise actions
virtual TStreamerInfoActions::TActionSequence *GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version) = 0;
Expand Down
8 changes: 4 additions & 4 deletions core/meta/inc/TClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,12 @@ friend class TStreamerInfo;
void Move(void *arenaFrom, void *arenaTo) const;
void *New(ENewType defConstructor = kClassNew, Bool_t quiet = kFALSE) const;
void *New(void *arena, ENewType defConstructor = kClassNew) const;
void *NewArray(Long_t nElements, ENewType defConstructor = kClassNew) const;
void *NewArray(Long_t nElements, void *arena, ENewType defConstructor = kClassNew) const;
void *NewArray(Long64_t nElements, ENewType defConstructor = kClassNew) const;
void *NewArray(Long64_t nElements, void *arena, ENewType defConstructor = kClassNew) const;
ObjectPtr NewObject(ENewType defConstructor = kClassNew, Bool_t quiet = kFALSE) const;
ObjectPtr NewObject(void *arena, ENewType defConstructor = kClassNew) const;
ObjectPtr NewObjectArray(Long_t nElements, ENewType defConstructor = kClassNew) const;
ObjectPtr NewObjectArray(Long_t nElements, void *arena, ENewType defConstructor = kClassNew) const;
ObjectPtr NewObjectArray(Long64_t nElements, ENewType defConstructor = kClassNew) const;
ObjectPtr NewObjectArray(Long64_t nElements, void *arena, ENewType defConstructor = kClassNew) const;
virtual void PostLoadCheck();
Long_t Property() const override;
Int_t ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count);
Expand Down
12 changes: 8 additions & 4 deletions core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5245,8 +5245,9 @@ TClass::ObjectPtr TClass::NewObject(void *arena, ENewType defConstructor) const
/// The class must have a default constructor. For meaning of
/// defConstructor, see TClass::IsCallingNew().

void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
void *TClass::NewArray(Long64_t nElements, ENewType defConstructor) const
{
R__ASSERT(nElements >= 0 && "Possible corruption of the heap: negative number of elements requested in TClass::NewObjectArray");
auto obj = NewObjectArray(nElements, defConstructor);
if (obj.GetPtr() && obj.GetAllocator()) {
// Register the object for special handling in the destructor.
Expand All @@ -5261,8 +5262,9 @@ void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
/// The class must have a default constructor. For meaning of
/// defConstructor, see TClass::IsCallingNew().

TClass::ObjectPtr TClass::NewObjectArray(Long_t nElements, ENewType defConstructor) const
TClass::ObjectPtr TClass::NewObjectArray(Long64_t nElements, ENewType defConstructor) const
{
R__ASSERT(nElements >= 0 && "Possible corruption of the heap: negative number of elements requested in TClass::NewObjectArray");
ObjectPtr p;

if (fNewArray) {
Expand Down Expand Up @@ -5347,8 +5349,9 @@ TClass::ObjectPtr TClass::NewObjectArray(Long_t nElements, ENewType defConstruct
/// The class must have a default constructor. For meaning of
/// defConstructor, see TClass::IsCallingNew().

void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) const
void *TClass::NewArray(Long64_t nElements, void *arena, ENewType defConstructor) const
{
R__ASSERT(nElements >= 0 && "Possible corruption of the heap: negative number of elements requested in TClass::NewObjectArray");
auto obj = NewObjectArray(nElements, arena, defConstructor);
if (obj.GetPtr() && obj.GetAllocator()) {
// Register the object for special handling in the destructor.
Expand All @@ -5362,8 +5365,9 @@ void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) c
/// The class must have a default constructor. For meaning of
/// defConstructor, see TClass::IsCallingNew().

TClass::ObjectPtr TClass::NewObjectArray(Long_t nElements, void *arena, ENewType defConstructor) const
TClass::ObjectPtr TClass::NewObjectArray(Long64_t nElements, void *arena, ENewType defConstructor) const
{
R__ASSERT(nElements >= 0 && "Possible corruption of the heap: negative number of elements requested in TClass::NewObjectArray");
ObjectPtr p;

if (fNewArray) {
Expand Down
Loading
Loading