File indexing completed on 2025-01-30 10:26:04
0001
0002
0003
0004 #ifndef VECGEOM_VARIABLESIZEOBJ_H
0005 #define VECGEOM_VARIABLESIZEOBJ_H
0006
0007
0008 #include "VecGeom/base/Global.h"
0009
0010
0011 #include <string.h>
0012
0013 class TRootIOCtor;
0014
0015 namespace vecgeom {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 template <typename V>
0026 class VariableSizeObj {
0027 public:
0028 using Index_t = unsigned int;
0029
0030 bool fSelfAlloc : 1;
0031 const Index_t fN : 31;
0032 V fRealArray[1];
0033
0034 VariableSizeObj(TRootIOCtor *) : fSelfAlloc(false), fN(0) {}
0035
0036 VECGEOM_FORCE_INLINE
0037 VECCORE_ATT_HOST_DEVICE
0038 VariableSizeObj(unsigned int nvalues) : fSelfAlloc(false), fN(nvalues) {}
0039
0040 VECGEOM_FORCE_INLINE
0041 VECCORE_ATT_HOST_DEVICE
0042 VariableSizeObj(const VariableSizeObj &other) : fSelfAlloc(false), fN(other.fN)
0043 {
0044 if (other.fN) memcpy(GetValues(), other.GetValues(), (other.fN) * sizeof(V));
0045 }
0046
0047 VECGEOM_FORCE_INLINE
0048 VECCORE_ATT_HOST_DEVICE
0049 VariableSizeObj(size_t new_size, const VariableSizeObj &other) : fSelfAlloc(false), fN(new_size)
0050 {
0051 if (other.fN) memcpy(GetValues(), other.GetValues(), (other.fN) * sizeof(V));
0052 }
0053
0054 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE V *GetValues() { return &fRealArray[0]; }
0055 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE const V *GetValues() const { return &fRealArray[0]; }
0056
0057 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE V &operator[](Index_t index) { return GetValues()[index]; };
0058 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE const V &operator[](Index_t index) const { return GetValues()[index]; };
0059
0060 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE VariableSizeObj &operator=(const VariableSizeObj &rhs)
0061 {
0062
0063
0064
0065
0066 if (rhs.fN == fN) {
0067 memcpy(GetValues(), rhs.GetValues(), rhs.fN * sizeof(V));
0068 } else if (rhs.fN < fN) {
0069 memcpy(GetValues(), rhs.GetValues(), rhs.fN * sizeof(V));
0070 memset(GetValues() + rhs.fN, 0, (fN - rhs.fN) * sizeof(V));
0071 } else {
0072
0073 memcpy(GetValues(), rhs.GetValues(), fN * sizeof(V));
0074 }
0075 return *this;
0076 }
0077 };
0078
0079 template <typename Cont, typename V>
0080 class VariableSizeObjectInterface {
0081 protected:
0082 VariableSizeObjectInterface() = default;
0083 ~VariableSizeObjectInterface() = default;
0084
0085 public:
0086
0087
0088 template <typename... T>
0089 VECCORE_ATT_HOST_DEVICE
0090 static Cont *MakeInstance(size_t nvalues, const T &... params)
0091 {
0092
0093
0094 size_t needed = SizeOf(nvalues);
0095 char *ptr = new char[needed];
0096 if (!ptr) return 0;
0097 assert((((unsigned long long)ptr) % alignof(Cont)) == 0 && "alignment error");
0098 Cont *obj = new (ptr) Cont(nvalues, params...);
0099 obj->GetVariableData().fSelfAlloc = true;
0100 return obj;
0101 }
0102
0103 template <typename... T>
0104 VECCORE_ATT_HOST_DEVICE
0105 static Cont *MakeInstanceAt(size_t nvalues, void *addr, const T &... params)
0106 {
0107
0108
0109
0110 if (!addr) {
0111 return MakeInstance(nvalues, params...);
0112 } else {
0113 assert((((unsigned long long)addr) % alignof(Cont)) == 0 && "addr does not satisfy alignment");
0114 Cont *obj = new (addr) Cont(nvalues, params...);
0115 obj->GetVariableData().fSelfAlloc = false;
0116 return obj;
0117 }
0118 }
0119
0120
0121 VECCORE_ATT_HOST_DEVICE
0122 static Cont *MakeCopy(const Cont &other)
0123 {
0124
0125
0126 size_t needed = SizeOf(other.GetVariableData().fN);
0127 char *ptr = new char[needed];
0128 if (!ptr) return 0;
0129 Cont *copy = new (ptr) Cont(other);
0130 copy->GetVariableData().fSelfAlloc = true;
0131 return copy;
0132 }
0133
0134 VECCORE_ATT_HOST_DEVICE
0135 static Cont *MakeCopy(size_t new_size, const Cont &other)
0136 {
0137
0138
0139
0140 size_t needed = SizeOf(new_size);
0141 char *ptr = new char[needed];
0142 if (!ptr) return 0;
0143 Cont *copy = new (ptr) Cont(new_size, other);
0144 copy->GetVariableData().fSelfAlloc = true;
0145 return copy;
0146 }
0147
0148
0149 VECCORE_ATT_HOST_DEVICE
0150 static Cont *MakeCopyAt(const Cont &other, void *addr)
0151 {
0152
0153 if (addr) {
0154 Cont *copy = new (addr) Cont(other);
0155 copy->GetVariableData().fSelfAlloc = false;
0156 return copy;
0157 } else {
0158 return MakeCopy(other);
0159 }
0160 }
0161
0162
0163 VECCORE_ATT_HOST_DEVICE
0164 static Cont *MakeCopyAt(size_t new_size, const Cont &other, void *addr)
0165 {
0166
0167 if (addr) {
0168 Cont *copy = new (addr) Cont(new_size, other);
0169 copy->GetVariableData().fSelfAlloc = false;
0170 return copy;
0171 } else {
0172 return MakeCopy(new_size, other);
0173 }
0174 }
0175
0176
0177 VECCORE_ATT_HOST_DEVICE
0178 static void ReleaseInstance(Cont *obj)
0179 {
0180
0181 obj->~Cont();
0182 if (obj->GetVariableData().fSelfAlloc) delete[](char *) obj;
0183 }
0184
0185
0186 VECCORE_ATT_HOST_DEVICE
0187 static constexpr size_t SizeOf(size_t nvalues)
0188 {
0189 return (sizeof(Cont) + Cont::SizeOfExtra(nvalues) + sizeof(V) * (nvalues - 1));
0190 }
0191
0192
0193 VECCORE_ATT_HOST_DEVICE
0194 static constexpr size_t SizeOfExtra(size_t nvalues) { return 0; }
0195
0196
0197
0198 VECCORE_ATT_HOST_DEVICE
0199 static constexpr size_t SizeOfAlignAware(size_t nvalues) { return SizeOf(nvalues) + RealFillUp(nvalues); }
0200
0201 private:
0202 VECCORE_ATT_HOST_DEVICE
0203 static constexpr size_t FillUp(size_t nvalues) { return alignof(Cont) - SizeOf(nvalues) % alignof(Cont); }
0204
0205 VECCORE_ATT_HOST_DEVICE
0206 static constexpr size_t RealFillUp(size_t nvalues)
0207 {
0208 return (FillUp(nvalues) == alignof(Cont)) ? 0 : FillUp(nvalues);
0209 }
0210 };
0211 }
0212
0213 #endif