@@ -205,43 +205,45 @@ struct HasCollectionProxyMemberType<
205205 : std::true_type {
206206};
207207
208- // / The point here is that we can only tell at run time if a class has an associated collection proxy.
209- // / For compile time, in the first iteration of this PR we had an extra template argument that acted as a "tag" to
210- // / differentiate the RField specialization for classes with an associated collection proxy (inherits
211- // / RProxiedCollectionField) from the RField primary template definition (RClassField-derived), as in:
212- // / ```
213- // / auto field = std::make_unique<RField<MyClass>>("klass");
214- // / // vs
215- // / auto otherField = std::make_unique<RField<MyClass, ROOT::Experimental::TagIsCollectionProxy>>("klass");
216- // / ```
217- // /
218- // / That is convenient only for non-nested types, i.e. it doesn't work with, e.g. `RField<std::vector<MyClass>,
219- // / ROOT::Experimental::TagIsCollectionProxy>`, as the tag is not forwarded to the instantiation of the inner RField
220- // / (that for the value type of the vector). The following two possible solutions were considered:
221- // / - A wrapper type (much like `ntuple/inc/ROOT/RNTupleUtil.hxx:49`), that helps to differentiate both cases.
222- // / There we would have:
223- // / ```
224- // / auto field = std::make_unique<RField<RProxiedCollection<MyClass>>>("klass"); // Using collection proxy
225- // / ```
226- // / - A helper IsCollectionProxy<T> type, that can be used in a similar way to those in the `<type_traits>` header.
227- // / We found this more convenient and is the implemented thing below. Here, classes can be marked as a
228- // / collection proxy with either of the following two forms (whichever is more convenient for the user):
229- // / ```
230- // / template <>
231- // / struct IsCollectionProxy<MyClass> : std::true_type {};
232- // / ```
233- // / or by adding a member type to the class as follows:
234- // / ```
235- // / class MyClass {
236- // / public:
237- // / using IsCollectionProxy = std::true_type;
238- // / };
239- // / ```
240- // /
241- // / Of course, there is another possible solution which is to have a single RClassField that implements both
242- // / the regular-class and the collection-proxy behaviors, and always chooses appropriately at run time.
243- // / We found that less clean and probably has more overhead, as most probably it involves an additional branch + call
244- // / in each of the member functions.
208+ /* The point here is that we can only tell at run time if a class has an associated collection proxy.
209+ For compile time, in the first iteration of this PR we had an extra template argument that acted as a "tag" to
210+ differentiate the RField specialization for classes with an associated collection proxy (inherits
211+ RProxiedCollectionField) from the RField primary template definition (RClassField-derived), as in:
212+ ```
213+ auto field = std::make_unique<RField<MyClass>>("klass");
214+ // vs
215+ auto otherField = std::make_unique<RField<MyClass, ROOT::Experimental::TagIsCollectionProxy>>("klass");
216+ ```
217+
218+ That is convenient only for non-nested types, i.e. it doesn't work with, e.g. `RField<std::vector<MyClass>,
219+ ROOT::Experimental::TagIsCollectionProxy>`, as the tag is not forwarded to the instantiation of the inner RField
220+ (that for the value type of the vector). The following two possible solutions were considered:
221+ - A wrapper type that helps to differentiate both cases.
222+ There we would have:
223+ ```
224+ auto field = std::make_unique<RField<RProxiedCollection<MyClass>>>("klass"); // Using collection proxy
225+ ```
226+ - A helper IsCollectionProxy<T> type, that can be used in a similar way to those in the `<type_traits>` header.
227+ We found this more convenient and is the implemented thing below. Here, classes can be marked as a
228+ collection proxy with either of the following two forms (whichever is more convenient for the user):
229+ ```
230+ template <>
231+ struct IsCollectionProxy<MyClass> : std::true_type {};
232+ ```
233+ or by adding a member type to the class as follows:
234+ ```
235+ class MyClass {
236+ public:
237+ using IsCollectionProxy = std::true_type;
238+ };
239+ ```
240+
241+ Of course, there is another possible solution which is to have a single RClassField that implements both
242+ the regular-class and the collection-proxy behaviors, and always chooses appropriately at run time.
243+ We found that less clean and probably has more overhead, as most probably it involves an additional branch + call
244+ in each of the member functions. */
245+ // / Helper type trait for marking classes as a collection proxy.
246+ // / This type trait must be set for collection proxy-based RNTuple fields created through MakeField<T>.
245247template <typename T, typename = void >
246248struct IsCollectionProxy : HasCollectionProxyMemberType<T> {
247249};
0 commit comments