These are bit-compatible with equivalent structs in the GSL library (gsl_block and gsl_vector). Originally the class member was a gsl_vector* pointer; but since I could not get genreflex to build dictionaries for these foreign structs (and since I later recognized I would have to add the annotations //[size]) I created these bit-compatible structs, which can be converted back and forth via reinterpret_cast-ing. However, there are remaining problems with persistency — I get the following errors:
Error in TStreamerInfo::Build: epm_gsl_block, discarding: double* data, illegal [size] (must be Int_t)
Error in TStreamerInfo::Build: epm_gsl_vector, discarding: double* data, illegal [size] (must be Int_t)
The underlying type of size_t is typically an unsigned long, rather than an unsigned int. The relevant code that restricts of the counter to be integer is found in TStreamerInfo.cxx (from ROOT: io/io/src/TStreamerInfo.cxx Source File, starting at line 447):
Types 3 and 13 are Int_t and UInt_t, while 4 and 14 are Long_t and ULong_t. I cannot think of a reason why it shouldn’t be possible to to allow the dtCounter to be a long type integer (especially since size_t is the canonical type for the size of an array in modern C/C++). Is there are workaround for this issue, or would it be possible to extend TStreamerInfo to allow long types for the counter?
Could you elaborate? For one, I see that the code in TStreamerInfo.cxx accepts a signed int or an unsigned int, thus ((dtCounter->GetType() == 3) || (dtCounter->GetType() == 13), so is it it really true that the size variable must be signed? And second, the fact that only types 3 and 13, and not 4 and 14, are accepted in TStreamerInfo is clearly a ROOT limitation. Is this all you mean, or do you mean that if accepting types 4 and 14 were added here, code would break somewhere else?
Yes, other place in the code currently assume that the index is 32bits and thus adding support for 64bits is possible but not trivial (one part is hunting all the places that make this assumptions.
More work would be required for me to flesh this out, of course, but my idea is that the values of array_size and size will always be forced to be equal – in practice the size never gets greater than O(10) so there will be no overflow problems. Will Reflex be able to parse this structure, with array_size, a member of the outer struct, representing the size of data in the inner struct?
Also, might I suggest that support for 64 bit indices be considered in the future? The pay-off for my single use-case is probably not worth the large amount of work you indicate would be necessary, but perhaps others might find benefit – especially since std::size_t is nowadays promoted as the canonical index type for people learning C++?