Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:10

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