File indexing completed on 2026-09-04 09:21:27
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
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
0028
0029
0030
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
0037
0038 template <SupportedUserDataType BasicType>
0039 consteval const char* userDataTypeName();
0040
0041
0042
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
0059
0060
0061
0062
0063
0064
0065 template <typename BasicType, typename = EnableIfSupportedUserType<BasicType>>
0066 class UserDataCollection : public CollectionBase {
0067
0068 private:
0069 std::vector<BasicType> _vec{};
0070
0071
0072
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
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 #if defined(__cpp_lib_containers_ranges)
0098
0099 template <detail::RangeConvertibleTo<BasicType> R>
0100 UserDataCollection(std::from_range_t, R&& range) : UserDataCollection() {
0101 _vec = detail::to_vector<BasicType>(std::forward<R>(range));
0102 }
0103 #endif
0104
0105
0106
0107
0108
0109
0110
0111 template <detail::RangeConvertibleTo<BasicType> R>
0112 static UserDataCollection from(R&& range) {
0113 UserDataCollection coll;
0114 coll._vec = detail::to_vector<BasicType>(std::forward<R>(range));
0115 return coll;
0116 }
0117
0118
0119 static constexpr SchemaVersionT schemaVersion = 1;
0120
0121 static constexpr std::string_view typeName = userDataCollTypeName<BasicType>();
0122 static constexpr std::string_view valueTypeName = userDataTypeName<BasicType>();
0123 static constexpr std::string_view dataTypeName = userDataTypeName<BasicType>();
0124
0125
0126 void prepareForWrite() const override {
0127 }
0128
0129
0130 void prepareAfterRead() override {
0131 }
0132
0133
0134 bool setReferences(const ICollectionProvider*) override {
0135 return true;
0136 }
0137
0138
0139 void setID(uint32_t id) override {
0140 m_collectionID = id;
0141 }
0142
0143
0144 uint32_t getID() const override {
0145 return m_collectionID;
0146 }
0147
0148
0149 podio::CollectionWriteBuffers getBuffers() override {
0150 _vecPtr = &_vec;
0151 return {&_vecPtr, _vecPtr, &m_refCollections, &m_vecmem_info};
0152 }
0153
0154
0155 bool hasID() const override {
0156 return getID() != static_cast<uint32_t>(podio::ObjectID::untracked) &&
0157 getID() != static_cast<uint32_t>(podio::ObjectID::invalid);
0158 }
0159
0160 [[deprecated("isValid will be removed, use hasID() if you want to check if it has an ID, otherwise assume the "
0161 "collection is valid")]]
0162 bool isValid() const override {
0163 return hasID();
0164 }
0165
0166
0167 size_t size() const override {
0168 return _vec.size();
0169 }
0170
0171
0172 size_t max_size() const override {
0173 return _vec.max_size();
0174 }
0175
0176
0177 bool empty() const override {
0178 return _vec.empty();
0179 }
0180
0181
0182 const std::string_view getTypeName() const override {
0183 return typeName;
0184 }
0185
0186
0187 const std::string_view getValueTypeName() const override {
0188 return valueTypeName;
0189 }
0190
0191
0192 const std::string_view getDataTypeName() const override {
0193 return dataTypeName;
0194 }
0195
0196
0197 static void __cppyy_pythonize__(PyObject* klass, const std::string& name) {
0198 podio::detail::pythonizations::pythonize_subscript(klass, name);
0199 }
0200
0201
0202 void clear() override {
0203 _vec.clear();
0204 }
0205
0206
0207 bool isSubsetCollection() const override {
0208 return false;
0209 }
0210
0211
0212 void setSubsetCollection(bool) override {
0213 }
0214
0215
0216 SchemaVersionT getSchemaVersion() const final {
0217 return schemaVersion;
0218 }
0219
0220
0221 void print(std::ostream& os = std::cout, bool flush = true) const override {
0222 os << "[";
0223 if (!_vec.empty()) {
0224 os << _vec[0];
0225 for (size_t i = 1; i < _vec.size(); ++i) {
0226 os << ", " << _vec[i];
0227 }
0228 }
0229 os << "]";
0230
0231 if (flush) {
0232 os.flush();
0233 }
0234 }
0235
0236 size_t getDatamodelRegistryIndex() const override {
0237 return DatamodelRegistry::NoDefinitionNecessary;
0238 }
0239
0240
0241
0242 typename std::vector<BasicType>::reference create() {
0243 return _vec.emplace_back();
0244 }
0245
0246 iterator begin() {
0247 return _vec.begin();
0248 }
0249 iterator end() {
0250 return _vec.end();
0251 }
0252 const_iterator begin() const {
0253 return _vec.begin();
0254 }
0255 const_iterator end() const {
0256 return _vec.end();
0257 }
0258 const_iterator cbegin() const {
0259 return _vec.cbegin();
0260 }
0261 const_iterator cend() const {
0262 return _vec.cend();
0263 }
0264
0265 reverse_iterator rbegin() {
0266 return _vec.rbegin();
0267 }
0268 const_reverse_iterator rbegin() const {
0269 return _vec.rbegin();
0270 }
0271 const_reverse_iterator crbegin() const {
0272 return _vec.crbegin();
0273 }
0274 reverse_iterator rend() {
0275 return _vec.rend();
0276 }
0277 const_reverse_iterator rend() const {
0278 return _vec.rend();
0279 }
0280 const_reverse_iterator crend() const {
0281 return _vec.crend();
0282 }
0283
0284 typename std::vector<BasicType>::reference operator[](size_t idx) {
0285 return _vec[idx];
0286 }
0287 typename std::vector<BasicType>::const_reference operator[](size_t idx) const {
0288 return _vec[idx];
0289 }
0290
0291 typename std::vector<BasicType>::reference at(size_t idx) {
0292 return _vec.at(idx);
0293 }
0294 typename std::vector<BasicType>::const_reference at(size_t idx) const {
0295 return _vec.at(idx);
0296 }
0297
0298 void resize(size_t count) {
0299 _vec.resize(count);
0300 }
0301 void push_back(const BasicType& value) {
0302 _vec.push_back(value);
0303 }
0304
0305
0306 typename std::vector<BasicType>& vec() {
0307 return _vec;
0308 }
0309
0310
0311 const typename std::vector<BasicType>& vec() const {
0312 return _vec;
0313 }
0314 };
0315
0316 using UserDataCollectionTypes = decltype(std::apply(
0317 []<typename... Ts>(Ts...) { return utils::TypeList<UserDataCollection<Ts>...>{}; }, SupportedUserDataTypes{}));
0318
0319
0320 #undef PODIO_ADD_USER_TYPE
0321
0322 template <SupportedUserDataType BasicType>
0323 std::ostream& operator<<(std::ostream& o, const podio::UserDataCollection<BasicType>& coll) {
0324 coll.print(o);
0325 return o;
0326 }
0327
0328
0329
0330
0331 #if defined(__clang__)
0332 #pragma clang diagnostic push
0333 #pragma clang diagnostic ignored "-Wunknown-warning-option"
0334 #pragma clang diagnostic ignored "-Wdeprecated-redundant-constexpr-static-def"
0335 #pragma clang diagnostic ignored "-Wdeprecated"
0336 template <typename BasicType, typename U>
0337 constexpr std::string_view UserDataCollection<BasicType, U>::typeName;
0338 template <typename BasicType, typename U>
0339 constexpr std::string_view UserDataCollection<BasicType, U>::valueTypeName;
0340 template <typename BasicType, typename U>
0341 constexpr std::string_view UserDataCollection<BasicType, U>::dataTypeName;
0342 #pragma clang diagnostic pop
0343 #elif defined(__GNUC__)
0344 #pragma GCC diagnostic push
0345 #pragma GCC diagnostic ignored "-Wdeprecated"
0346 template <typename BasicType, typename U>
0347 constexpr std::string_view UserDataCollection<BasicType, U>::typeName;
0348 template <typename BasicType, typename U>
0349 constexpr std::string_view UserDataCollection<BasicType, U>::valueTypeName;
0350 template <typename BasicType, typename U>
0351 constexpr std::string_view UserDataCollection<BasicType, U>::dataTypeName;
0352 #pragma GCC diagnostic pop
0353 #endif
0354
0355 }
0356
0357 #endif