Thanks @pcanal 
I did an attempt to automate the writing of a std::any
. However I’m not using the STL class because I originally wanted my toolbox to be compatible with C++11 standard (which does not includes std::any yet).
My reimplementation is quite similar, but I had to write additionnal methods to get extra info that std::any
don’t provide. For example, std::any
don’t keep the size of the stored object. The only hair we can rely on to figure out the original data type is to use the .type()
method. But this is not sufficient to automatically know the actual size of the stored object. There was some discussion on Stack Overflow about this.
But I guess it’s ok in our case to make a else if
chain as the data types one can store in TTrees is finite, and we need to figure out the type of the object for the leaf definition string anyway:
size_t getLeafSize(std::any& a_){
if ( a_.type() == typeid(int) ){ return sizeof(int); }
else if( a_.type() == typeid(double) ){ return sizeof(double); }
//...
}
The other concern about the use of std::any
is to find the proper address in memory of the stored object. As memcpy
write the raw data from the address point we provide, it’s necessary to at least know the offset:
root [0] std::any a
(std::any &) @0x1095df0f0
root [1] a = double(1.5)
(std::any &) @0x1095df0f0
root [2] &a
(std::any *) 0x1095df0f0
root [3] double *d = std::any_cast<double>(&a)
(double *) 0x1095df0f8
root [4] sizeof(a)
(unsigned long) 32
root [5] sizeof(*d)
(unsigned long) 8
In that case the overhead size of std::any
seems to be 8 ( = 0x1095df0f8 - 0x1095df0f0
). So if the offset is always the same, we can easily write the data from this starting point.
But for more complicated objects (like TGraph, TSpline3 or TClonesArray), I understand your concern is a more complicated question. In practice how do you write those objects in a TBranch
? If I remember correctly a typical instruction for the user side is:
TTree* t = new TTree();
TSpline3 s;
t->Branch("mySpline", &s);
t->Print();
******************************************************************************
*Tree : : *
*Entries : 0 : Total = 842 bytes File Size = 0 *
* : : Tree compression factor = 1.00 *
******************************************************************************
*Br 0 :mySpline : TSpline3 *
*Entries : 0 : Total Size= 501 bytes One basket in memory *
*Baskets : 0 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
Does it mean each time I call TTree::Fill()
, the size of the defined TLeaf is reset?
Thanks again for this very interesting discussion 
Cheers!