![]() |
|
|||
Warning, file /include/podio/detail/RelationIOHelpers.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef PODIO_DETAIL_RELATIONIOHELPERS_H 0002 #define PODIO_DETAIL_RELATIONIOHELPERS_H 0003 0004 #include "podio/utilities/TypeHelpers.h" 0005 #include <podio/CollectionBase.h> 0006 0007 #include <memory> 0008 #include <tuple> 0009 #include <vector> 0010 0011 namespace podio::detail { 0012 0013 /// Function template for handling interface types in OneToMultiRelations 0014 /// 0015 /// Effectively this function checks whether the passed collection can be 0016 /// dynamically cast to the collection type of the concrete type and if that is 0017 /// true uses it to construct an interface type and add it to relElements. The 0018 /// function on its own doesn't do anything too meaningful, it is meant to be 0019 /// used in a call to std::apply that goes over all the interfaced types of an 0020 /// interface type. 0021 /// 0022 /// @tparam T The concrete type inside the interface that should be checked. 0023 /// This effectively is mainly used for tag-dispatch and overload 0024 /// selection in this context 0025 /// @tparam InterfaceType The interface type (that can be used to interface T) 0026 /// 0027 /// @param relElements The vector to which the interface objects should be added 0028 /// @param coll The collection that holds the actual element 0029 /// @param id The ObjectID of the element that we are currently looking for 0030 template <typename T, typename InterfaceType> 0031 void tryAddTo(T, std::vector<InterfaceType>& relElements, const podio::CollectionBase* coll, const podio::ObjectID id) { 0032 if (auto typedColl = dynamic_cast<const typename T::collection_type*>(coll)) { 0033 const T tmp = (*typedColl)[id.index]; 0034 relElements.emplace_back(tmp); 0035 } 0036 } 0037 0038 /// Helper function for handling interface type relations in OneToManyRelations 0039 /// 0040 /// This function tries all types that are interfaced by the InterfaceType and 0041 /// adds the one that matches to the relations. The main work happens in 0042 /// tryAddTo, this simply wraps everything in a std::apply over all 0043 /// interfaced_types. 0044 /// 0045 /// @tparam InterfaceType The interface type of the Relation 0046 /// 0047 /// @param relElements The vector to which the interface objects should be added 0048 /// @param coll The collection that holds the actual element 0049 /// @param id The ObjectID of the element that we are currently looking for 0050 template <typename InterfaceType> 0051 void addInterfaceToMultiRelation(std::vector<InterfaceType>& relElements, const podio::CollectionBase* coll, 0052 const podio::ObjectID id) { 0053 std::apply([&](auto... t) { (tryAddTo(t, relElements, coll, id), ...); }, typename InterfaceType::interfaced_types{}); 0054 } 0055 0056 /// Helper function for adding an object to the OneToManyRelations container 0057 /// when reading back collections 0058 /// 0059 /// This function does the necessary type casting of the passed collection to 0060 /// retrieve the desired object and also takes care of adding the object to the 0061 /// container that holds them for later usage. It handles relations to regular 0062 /// types as well as interface types. 0063 /// 0064 /// This functionality has been lifted from the jinja2 templates, where we now 0065 /// only call it, because we need a template deduction context for making if 0066 /// constexpr work as expected, such that we can dispatch to different 0067 /// implementatoins depending on whether the relation is to an interface type or 0068 /// to a regular type. 0069 /// 0070 /// @note It is expected that the following pre-conditions are met: 0071 /// - The passed collection is valid (i.e. not a nullptr) 0072 /// - the collectionID of the passed collection is the same as the one in 0073 /// the passed ObjectID 0074 /// - The collection can by casted to the relation type or any of the 0075 /// interfaced types of the relation 0076 /// 0077 /// @tparam RelType The type of the OneToManyRelation 0078 /// 0079 /// @param relElements The container that holds the objects for the relation and 0080 /// which will be used for adding an element from the passed 0081 /// collection 0082 /// @param coll The collection from which the object will be obtained after the 0083 /// necessary type casting 0084 /// @param id The ObjectID of the object that should be retrieved and added. 0085 template <typename RelType> 0086 void addMultiRelation(std::vector<RelType>& relElements, const podio::CollectionBase* coll, const podio::ObjectID id) { 0087 if constexpr (podio::detail::isInterfaceType<RelType>) { 0088 addInterfaceToMultiRelation(relElements, coll, id); 0089 } else { 0090 const auto* typeColl = static_cast<const typename RelType::collection_type*>(coll); 0091 relElements.emplace_back((*typeColl)[id.index]); 0092 } 0093 } 0094 0095 /// Function template for handling interface types in OneToOneRelations 0096 /// 0097 /// Effectively this function checks whether the passed collection can be 0098 /// dynamically cast to the collection type of the concrete type and if that is 0099 /// true uses it to assign to the passed interface object The function on its 0100 /// own doesn't do anything too meaningful, it is meant to be used in a call to 0101 /// std::apply that goes over all the interfaced types of an interface type. 0102 /// 0103 /// @tparam T The concrete type inside the interface that should be checked. 0104 /// This effectively is mainly used for tag-dispatch and overload 0105 /// selection in this context 0106 /// @tparam InterfaceType The interface type (that can be used to interface T) 0107 /// 0108 /// @param relation The object to which the interface object should be assigned 0109 /// to 0110 /// @param coll The collection that holds the actual element 0111 /// @param id The ObjectID of the element that we are currently looking for 0112 template <typename T, typename InterfaceType> 0113 void tryAssignTo(T, std::unique_ptr<InterfaceType>& relation, const podio::CollectionBase* coll, 0114 const podio::ObjectID id) { 0115 if (const auto* typeColl = dynamic_cast<const typename T::collection_type*>(coll)) { 0116 relation = std::make_unique<InterfaceType>((*typeColl)[id.index]); 0117 } 0118 } 0119 0120 /// Helper function for handling interface type relations in OneToOneRelations 0121 /// 0122 /// This function tries all types that are interfaced by the InterfaceType and 0123 /// that assigns the one thta matches to the relation. The main work happens in 0124 /// tryAssignTo, this simply wraps everything in a std::apply over all 0125 /// interfaced_types. 0126 /// 0127 /// @tparam InterfaceType The interface type of the Relation 0128 /// 0129 /// @param relation The object to which the interface object should be assigned 0130 /// to 0131 /// @param coll The collection that holds the actual element 0132 /// @param id The ObjectID of the element that we are currently looking for 0133 template <typename InterfaceType> 0134 void addInterfaceToSingleRelation(std::unique_ptr<InterfaceType>& relation, const podio::CollectionBase* coll, 0135 const podio::ObjectID id) { 0136 std::apply([&](auto... t) { (tryAssignTo(t, relation, coll, id), ...); }, typename InterfaceType::interfaced_types{}); 0137 } 0138 0139 /// Helper function for assigning the related object in a OneToOneRelation 0140 /// 0141 /// This function does the necessary type casting of the passed collection to 0142 /// retrieve the desired object and also takes care of assigning the object to 0143 /// the passed pointer that hold it for later usage. It handles relations 0144 /// to regular types as well as interface types. 0145 /// 0146 /// This functionality has been lifted from the jinja2 templates, where we now 0147 /// only call it, because we need a template deduction context for making if 0148 /// constexpr work as expected, such that we can dispatch to different 0149 /// implementatoins depending on whether the relation is to an interface type or 0150 /// to a regular type. 0151 /// 0152 /// @note It is expected that the following pre-conditions are met: 0153 /// - The passed collection is valid (i.e. not a nullptr) 0154 /// - the collectionID of the passed collection is the same as the one in 0155 /// the passed ObjectID 0156 /// - The collection can by casted to the relation type or any of the 0157 /// interfaced types of the relation 0158 /// 0159 /// @tparam RelType The type of the OneToManyRelation 0160 /// 0161 /// @param relation The pointer to which we should assign the related object 0162 /// that is retrieved from the passed collection 0163 /// @param coll The collection from which the object will be obtained after the 0164 /// necessary type casting 0165 /// @param id The ObjectID of the object that should be retrieved and added. 0166 template <typename RelType> 0167 void addSingleRelation(std::unique_ptr<RelType>& relation, const podio::CollectionBase* coll, 0168 const podio::ObjectID id) { 0169 if constexpr (podio::detail::isInterfaceType<RelType>) { 0170 addInterfaceToSingleRelation(relation, coll, id); 0171 } else { 0172 const auto* typeColl = static_cast<const typename RelType::collection_type*>(coll); 0173 relation = std::make_unique<RelType>((*typeColl)[id.index]); 0174 } 0175 } 0176 0177 } // namespace podio::detail 0178 0179 #endif // PODIO_DETAIL_RELATIONIOHELPERS_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |