1919#include < TString.h>
2020#include < TTree.h>
2121#include < vector>
22+ #include < type_traits>
23+ #include < concepts>
2224#include " GPUCommonDef.h"
2325
2426class TBranch ;
@@ -39,10 +41,79 @@ namespace utils
3941// /
4042// / See testTreeStream.cxx for functional example
4143// /
44+ namespace details
45+ {
46+ template <typename T>
47+ struct IsTrivialRootType {
48+ static constexpr bool value =
49+ std::is_same_v<T, Float_t> || // Float_t
50+ std::is_same_v<T, Double_t> || // Double_t
51+ std::is_same_v<T, ULong64_t> || std::is_same_v<T, ULong_t> || // ULong64_t or ULong_t
52+ std::is_same_v<T, Long64_t> || std::is_same_v<T, Long_t> || // Long64_t or Long_t
53+ std::is_same_v<T, UInt_t> || // UInt_t
54+ std::is_same_v<T, Int_t> || // Int_t
55+ std::is_same_v<T, UShort_t> || // UShort_t
56+ std::is_same_v<T, Short_t> || // Short_t
57+ std::is_same_v<T, UChar_t> || // UChar_t
58+ std::is_same_v<T, Char_t> || std::is_same_v<T, int8_t > || std::is_same_v<T, Bool_t>; // Char_t, int8_t, or Bool_t
59+ };
60+
61+ template <typename T>
62+ struct IsTrivialRootType <T[]> {
63+ static constexpr bool value = IsTrivialRootType<T>::value;
64+ };
65+
66+ template <typename T, std::size_t N>
67+ struct IsTrivialRootType <T[N]> {
68+ static constexpr bool value = IsTrivialRootType<T>::value;
69+ };
70+
71+ template <typename T>
72+ concept TrivialRootType = IsTrivialRootType<T>::value;
73+
74+ template <typename T>
75+ concept ComplexRootType = !IsTrivialRootType<T>::value;
76+
77+ template <TrivialRootType T>
78+ static constexpr char getRootTypeCode ()
79+ {
80+ if constexpr (std::is_array_v<T>) {
81+ return getRootTypeCode<std::remove_all_extents_t <T>>();
82+ } else if constexpr (std::is_same_v<T, Float_t>) {
83+ return ' F' ;
84+ } else if constexpr (std::is_same_v<T, Double_t>) {
85+ return ' D' ;
86+ } else if constexpr (std::is_same_v<T, ULong64_t> ||
87+ std::is_same_v<T, ULong_t>) {
88+ return ' l' ;
89+ } else if constexpr (std::is_same_v<T, Long64_t> ||
90+ std::is_same_v<T, Long_t>) {
91+ return ' L' ;
92+ } else if constexpr (std::is_same_v<T, UInt_t>) {
93+ return ' i' ;
94+ } else if constexpr (std::is_same_v<T, Int_t>) {
95+ return ' I' ;
96+ } else if constexpr (std::is_same_v<T, UShort_t>) {
97+ return ' s' ;
98+ } else if constexpr (std::is_same_v<T, Short_t>) {
99+ return ' S' ;
100+ } else if constexpr (std::is_same_v<T, UChar_t>) {
101+ return ' b' ;
102+ } else if constexpr (std::is_same_v<T, Char_t> ||
103+ std::is_same_v<T, int8_t > ||
104+ std::is_same_v<T, Bool_t>) {
105+ return ' B' ;
106+ } else {
107+ static_assert (false , " unsupported type!" );
108+ }
109+ }
110+ } // namespace details
111+
42112class TreeStream
43113{
44114 public:
45115 struct TreeDataElement {
116+ int arsize = 1 ; // /< size of array
46117 char type = 0 ; // /< type of data element
47118 const TClass* cls = nullptr ; // /< data type pointer
48119 const void * ptr = nullptr ; // /< pointer to element
@@ -64,87 +135,10 @@ class TreeStream
64135 void setID (int id) { mID = id; }
65136 int getID () const { return mID ; }
66137
67- TreeStream& operator <<(const Bool_t& b)
68- {
69- CheckIn (' B' , &b);
70- return *this ;
71- }
72-
73- TreeStream& operator <<(const Char_t& c)
74- {
75- CheckIn (' B' , &c);
76- return *this ;
77- }
78-
79- TreeStream& operator <<(const int8_t & i)
80- {
81- CheckIn (' B' , &i);
82- return *this ;
83- }
84-
85- TreeStream& operator <<(const UChar_t& c)
86- {
87- CheckIn (' b' , &c);
88- return *this ;
89- }
90-
91- TreeStream& operator <<(const Short_t& h)
92- {
93- CheckIn (' S' , &h);
94- return *this ;
95- }
96-
97- TreeStream& operator <<(const UShort_t& h)
98- {
99- CheckIn (' s' , &h);
100- return *this ;
101- }
102-
103- TreeStream& operator <<(const Int_t& i)
104- {
105- CheckIn (' I' , &i);
106- return *this ;
107- }
108-
109- TreeStream& operator <<(const UInt_t& i)
110- {
111- CheckIn (' i' , &i);
112- return *this ;
113- }
114-
115- TreeStream& operator <<(const Long_t& l)
116- {
117- CheckIn (' L' , &l);
118- return *this ;
119- }
120-
121- TreeStream& operator <<(const ULong_t& l)
122- {
123- CheckIn (' l' , &l);
124- return *this ;
125- }
126-
127- TreeStream& operator <<(const Long64_t& l)
128- {
129- CheckIn (' L' , &l);
130- return *this ;
131- }
132-
133- TreeStream& operator <<(const ULong64_t& l)
134- {
135- CheckIn (' l' , &l);
136- return *this ;
137- }
138-
139- TreeStream& operator <<(const Float_t& f)
140- {
141- CheckIn (' F' , &f);
142- return *this ;
143- }
144-
145- TreeStream& operator <<(const Double_t& d)
138+ template <details::TrivialRootType T>
139+ TreeStream& operator <<(const T& t)
146140 {
147- CheckIn (' D ' , &d );
141+ CheckIn (details::getRootTypeCode<T>() , &t );
148142 return *this ;
149143 }
150144
@@ -157,7 +151,7 @@ class TreeStream
157151 return *this ;
158152 }
159153
160- template <class T , typename std::enable_if<!std::is_pointer<GPUgeneric() T>::value, bool >::type* = nullptr >
154+ template <details::ComplexRootType T, typename std::enable_if<!std::is_pointer<GPUgeneric() T>::value, bool >::type* = nullptr >
161155 TreeStream& operator <<(const T& obj)
162156 {
163157 CheckIn (&obj);
@@ -175,6 +169,7 @@ class TreeStream
175169 int mCurrentIndex = 0 ; // /< index of current element
176170 int mID = -1 ; // /< identifier of layout
177171 int mNextNameCounter = 0 ; // /< next name counter
172+ int mNextArraySize = 0 ; // /< next array size
178173 int mStatus = 0 ; // /< status of the layout
179174 TString mNextName ; // /< name for next entry
180175
@@ -191,8 +186,7 @@ Int_t TreeStream::CheckIn(const T* obj)
191186 }
192187
193188 if (mCurrentIndex >= static_cast <int >(mElements .size ())) {
194- mElements .emplace_back ();
195- auto & element = mElements .back ();
189+ auto & element = mElements .emplace_back ();
196190 element.cls = pClass;
197191 TString name = mNextName ;
198192 if (name.Length ()) {
@@ -204,6 +198,8 @@ Int_t TreeStream::CheckIn(const T* obj)
204198 }
205199 element.name = name.Data ();
206200 element.ptr = obj;
201+ element.arsize = mNextArraySize ;
202+ mNextArraySize = 1 ; // reset
207203 } else {
208204 auto & element = mElements [mCurrentIndex ];
209205 if (!element.cls ) {
0 commit comments