Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-08 10:29:12

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