Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 09:05:05

0001 #ifndef PODIO_USERDATACOLLECTION_H
0002 #define PODIO_USERDATACOLLECTION_H
0003 
0004 #include "podio/CollectionBase.h"
0005 #include "podio/CollectionBuffers.h"
0006 #include "podio/DatamodelRegistry.h"
0007 #include "podio/SchemaEvolution.h"
0008 #include "podio/utilities/TypeHelpers.h"
0009 
0010 #define PODIO_ADD_USER_TYPE(type)                                                                                      \
0011   template <>                                                                                                          \
0012   consteval const char* userDataTypeName<type>() {                                                                     \
0013     return #type;                                                                                                      \
0014   }                                                                                                                    \
0015   template <>                                                                                                          \
0016   consteval const char* userDataCollTypeName<type>() {                                                                 \
0017     return "podio::UserDataCollection<" #type ">";                                                                     \
0018   }
0019 
0020 namespace podio {
0021 
0022 /// tuple of basic types supported in user vector
0023 using SupportedUserDataTypes =
0024     std::tuple<float, double, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t>;
0025 
0026 /// Alias template to be used to enable template specializations only for the types listed in the
0027 /// SupportedUserDataTypes list
0028 /// EnableIfSupportedUserType is kept because cppyy does not seem to like
0029 /// when UsedDataCollection is used with the concept
0030 template <typename T>
0031 concept SupportedUserDataType = detail::isInTuple<T, SupportedUserDataTypes>;
0032 template <typename T>
0033 using EnableIfSupportedUserType = std::enable_if_t<detail::isInTuple<T, SupportedUserDataTypes>>;
0034 
0035 /// helper template to provide readable type names for basic types with macro
0036 /// PODIO_ADD_USER_TYPE(type)
0037 template <SupportedUserDataType BasicType>
0038 consteval const char* userDataTypeName();
0039 
0040 /// Helper template to provide the fully qualified name of a UserDataCollection.
0041 /// Implementations are populated by the PODIO_ADD_USER_TYPE macro.
0042 template <SupportedUserDataType BasicType>
0043 consteval const char* userDataCollTypeName();
0044 
0045 PODIO_ADD_USER_TYPE(float)
0046 PODIO_ADD_USER_TYPE(double)
0047 
0048 PODIO_ADD_USER_TYPE(int8_t)
0049 PODIO_ADD_USER_TYPE(int16_t)
0050 PODIO_ADD_USER_TYPE(int32_t)
0051 PODIO_ADD_USER_TYPE(int64_t)
0052 PODIO_ADD_USER_TYPE(uint8_t)
0053 PODIO_ADD_USER_TYPE(uint16_t)
0054 PODIO_ADD_USER_TYPE(uint32_t)
0055 PODIO_ADD_USER_TYPE(uint64_t)
0056 
0057 /// Collection of basic types for additional user data not defined in the EDM.
0058 /// The data is stored in an std::vector<basic_type>. Supported are all basic
0059 /// types supported in PODIO, i.e. float, double and 8-64 bit fixed size signed
0060 /// and unsigned integers - @see SupportedUserDataTypes.
0061 ///
0062 /// @author F.Gaede, DESY
0063 /// @date Sep 2021
0064 template <typename BasicType, typename = EnableIfSupportedUserType<BasicType>>
0065 class UserDataCollection : public CollectionBase {
0066 
0067 private:
0068   std::vector<BasicType> _vec{};
0069   // Pointer to the actual storage, necessary for I/O. In order to have
0070   // simpler move-semantics this will be set and properly initialized on
0071   // demand during the call to getBuffers
0072   std::vector<BasicType>* _vecPtr{nullptr};
0073   uint32_t m_collectionID{0};
0074   CollRefCollection m_refCollections{};
0075   VectorMembersInfo m_vecmem_info{};
0076 
0077 public:
0078   using value_type = typename std::vector<BasicType>::value_type;
0079   using mutable_type = value_type;
0080   using const_iterator = typename std::vector<BasicType>::const_iterator;
0081   using iterator = typename std::vector<BasicType>::iterator;
0082   using difference_type = typename std::vector<BasicType>::difference_type;
0083   using size_type = typename std::vector<BasicType>::size_type;
0084   using const_reverse_iterator = typename std::vector<BasicType>::const_reverse_iterator;
0085   using reverse_iterator = typename std::vector<BasicType>::reverse_iterator;
0086 
0087   UserDataCollection() = default;
0088   /// Constructor from an existing vector (which will be moved from!)
0089   UserDataCollection(std::vector<BasicType>&& vec) : _vec(std::move(vec)) {
0090   }
0091   UserDataCollection(const UserDataCollection&) = delete;
0092   UserDataCollection& operator=(const UserDataCollection&) = delete;
0093   UserDataCollection(UserDataCollection&&) = default;
0094   UserDataCollection& operator=(UserDataCollection&&) = default;
0095   ~UserDataCollection() = default;
0096 
0097   /// The schema version of UserDataCollections
0098   static constexpr SchemaVersionT schemaVersion = 1;
0099 
0100   constexpr static auto typeName = userDataCollTypeName<BasicType>();
0101   constexpr static auto valueTypeName = userDataTypeName<BasicType>();
0102   constexpr static auto dataTypeName = userDataTypeName<BasicType>();
0103 
0104   /// prepare buffers for serialization
0105   void prepareForWrite() const override {
0106   }
0107 
0108   /// re-create collection from buffers after read
0109   void prepareAfterRead() override {
0110   }
0111 
0112   /// initialize references after read
0113   bool setReferences(const ICollectionProvider*) override {
0114     return true;
0115   }
0116 
0117   /// set collection ID
0118   void setID(uint32_t id) override {
0119     m_collectionID = id;
0120   }
0121 
0122   /// get collection ID
0123   uint32_t getID() const override {
0124     return m_collectionID;
0125   }
0126 
0127   /// Get the collection buffers for this collection
0128   podio::CollectionWriteBuffers getBuffers() override {
0129     _vecPtr = &_vec; // Set the pointer to the correct internal vector
0130     return {&_vecPtr, _vecPtr, &m_refCollections, &m_vecmem_info};
0131   }
0132 
0133   /// check for validity of the container after read
0134   bool isValid() const override {
0135     return true;
0136   }
0137 
0138   /// number of elements in the collection
0139   size_t size() const override {
0140     return _vec.size();
0141   }
0142 
0143   /// maximal number of elements in the collection
0144   size_t max_size() const override {
0145     return _vec.max_size();
0146   }
0147 
0148   /// Is the collection empty
0149   bool empty() const override {
0150     return _vec.empty();
0151   }
0152 
0153   /// fully qualified type name
0154   const std::string_view getTypeName() const override {
0155     return typeName;
0156   }
0157 
0158   /// fully qualified type name of elements - with namespace
0159   const std::string_view getValueTypeName() const override {
0160     return valueTypeName;
0161   }
0162 
0163   /// fully qualified type name of stored POD elements - with namespace
0164   const std::string_view getDataTypeName() const override {
0165     return dataTypeName;
0166   }
0167 
0168   /// clear the collection and all internal states
0169   void clear() override {
0170     _vec.clear();
0171   }
0172 
0173   /// check if this collection is a subset collection - no subset possible
0174   bool isSubsetCollection() const override {
0175     return false;
0176   }
0177 
0178   /// declare this collection to be a subset collection - no effect
0179   void setSubsetCollection(bool) override {
0180   }
0181 
0182   /// The schema version is fixed manually
0183   SchemaVersionT getSchemaVersion() const final {
0184     return schemaVersion;
0185   }
0186 
0187   /// Print this collection to the passed stream
0188   void print(std::ostream& os = std::cout, bool flush = true) const override {
0189     os << "[";
0190     if (!_vec.empty()) {
0191       os << _vec[0];
0192       for (size_t i = 1; i < _vec.size(); ++i) {
0193         os << ", " << _vec[i];
0194       }
0195     }
0196     os << "]";
0197 
0198     if (flush) {
0199       os.flush(); // Necessary for python
0200     }
0201   }
0202 
0203   size_t getDatamodelRegistryIndex() const override {
0204     return DatamodelRegistry::NoDefinitionNecessary;
0205   }
0206 
0207   // ----- some wrappers for std::vector and access to the complete std::vector (if really needed)
0208 
0209   typename std::vector<BasicType>::reference create() {
0210     return _vec.emplace_back();
0211   }
0212 
0213   iterator begin() {
0214     return _vec.begin();
0215   }
0216   iterator end() {
0217     return _vec.end();
0218   }
0219   const_iterator begin() const {
0220     return _vec.begin();
0221   }
0222   const_iterator end() const {
0223     return _vec.end();
0224   }
0225   const_iterator cbegin() const {
0226     return _vec.cbegin();
0227   }
0228   const_iterator cend() const {
0229     return _vec.cend();
0230   }
0231   // reverse iterators
0232   reverse_iterator rbegin() {
0233     return _vec.rbegin();
0234   }
0235   const_reverse_iterator rbegin() const {
0236     return _vec.rbegin();
0237   }
0238   const_reverse_iterator crbegin() const {
0239     return _vec.crbegin();
0240   }
0241   reverse_iterator rend() {
0242     return _vec.rend();
0243   }
0244   const_reverse_iterator rend() const {
0245     return _vec.rend();
0246   }
0247   const_reverse_iterator crend() const {
0248     return _vec.crend();
0249   }
0250 
0251   typename std::vector<BasicType>::reference operator[](size_t idx) {
0252     return _vec[idx];
0253   }
0254   typename std::vector<BasicType>::const_reference operator[](size_t idx) const {
0255     return _vec[idx];
0256   }
0257 
0258   typename std::vector<BasicType>::reference at(size_t idx) {
0259     return _vec.at(idx);
0260   }
0261   typename std::vector<BasicType>::const_reference at(size_t idx) const {
0262     return _vec.at(idx);
0263   }
0264 
0265   void resize(size_t count) {
0266     _vec.resize(count);
0267   }
0268   void push_back(const BasicType& value) {
0269     _vec.push_back(value);
0270   }
0271 
0272   /// access to the actual data vector
0273   typename std::vector<BasicType>& vec() {
0274     return _vec;
0275   }
0276 
0277   /// const access to the actual data vector
0278   const typename std::vector<BasicType>& vec() const {
0279     return _vec;
0280   }
0281 };
0282 
0283 // don't make this macro public as it should only be used internally here...
0284 #undef PODIO_ADD_USER_TYPE
0285 
0286 template <SupportedUserDataType BasicType>
0287 std::ostream& operator<<(std::ostream& o, const podio::UserDataCollection<BasicType>& coll) {
0288   coll.print(o);
0289   return o;
0290 }
0291 
0292 } // namespace podio
0293 
0294 #endif