File indexing completed on 2026-07-17 08:35:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _NCollection_AliasedArray_HeaderFile
0015 #define _NCollection_AliasedArray_HeaderFile
0016
0017 #include <Standard_DimensionMismatch.hxx>
0018 #include <Standard_OutOfMemory.hxx>
0019 #include <Standard_OutOfRange.hxx>
0020 #include <Standard_TypeMismatch.hxx>
0021 #include <Standard_Macro.hxx>
0022
0023
0024
0025
0026
0027
0028
0029 template <int MyAlignSize = 16>
0030 class NCollection_AliasedArray
0031 {
0032 public:
0033 DEFINE_STANDARD_ALLOC
0034 public:
0035
0036 NCollection_AliasedArray(Standard_Integer theStride)
0037 : myData(NULL),
0038 myStride(theStride),
0039 mySize(0),
0040 myDeletable(false)
0041 {
0042 if (theStride <= 0)
0043 {
0044 throw Standard_RangeError("NCollection_AliasedArray, stride should be positive");
0045 }
0046 }
0047
0048
0049 NCollection_AliasedArray(Standard_Integer theStride, Standard_Integer theLength)
0050 : myData(NULL),
0051 myStride(theStride),
0052 mySize(theLength),
0053 myDeletable(true)
0054 {
0055 if (theLength <= 0 || myStride <= 0)
0056 {
0057 throw Standard_RangeError("NCollection_AliasedArray, stride and length should be positive");
0058 }
0059 myData = (Standard_Byte*)Standard::AllocateAligned(SizeBytes(), MyAlignSize);
0060 if (myData == NULL)
0061 {
0062 throw Standard_OutOfMemory("NCollection_AliasedArray, allocation failed");
0063 }
0064 }
0065
0066
0067 NCollection_AliasedArray(const NCollection_AliasedArray& theOther)
0068 : myData(NULL),
0069 myStride(theOther.myStride),
0070 mySize(theOther.mySize),
0071 myDeletable(false)
0072 {
0073 if (mySize != 0)
0074 {
0075 myDeletable = true;
0076 myData = (Standard_Byte*)Standard::AllocateAligned(SizeBytes(), MyAlignSize);
0077 if (myData == NULL)
0078 {
0079 throw Standard_OutOfMemory("NCollection_AliasedArray, allocation failed");
0080 }
0081 Assign(theOther);
0082 }
0083 }
0084
0085
0086 NCollection_AliasedArray(NCollection_AliasedArray&& theOther) Standard_Noexcept
0087 : myData(theOther.myData),
0088 myStride(theOther.myStride),
0089 mySize(theOther.mySize),
0090 myDeletable(theOther.myDeletable)
0091 {
0092 theOther.myDeletable = false;
0093 }
0094
0095
0096 template <typename Type_t>
0097 NCollection_AliasedArray(const Type_t& theBegin, Standard_Integer theLength)
0098 : myData((Standard_Byte*)&theBegin),
0099 myStride((int)sizeof(Type_t)),
0100 mySize(theLength),
0101 myDeletable(false)
0102 {
0103 if (theLength <= 0)
0104 {
0105 throw Standard_RangeError("NCollection_AliasedArray, length should be positive");
0106 }
0107 }
0108
0109
0110 Standard_Integer Stride() const { return myStride; }
0111
0112
0113 Standard_Integer Size() const { return mySize; }
0114
0115
0116 Standard_Integer Length() const { return mySize; }
0117
0118
0119 Standard_Boolean IsEmpty() const { return mySize == 0; }
0120
0121
0122 Standard_Integer Lower() const { return 0; }
0123
0124
0125 Standard_Integer Upper() const { return mySize - 1; }
0126
0127
0128 Standard_Boolean IsDeletable() const { return myDeletable; }
0129
0130
0131 Standard_Boolean IsAllocated() const { return myDeletable; }
0132
0133
0134 Standard_Size SizeBytes() const { return size_t(myStride) * size_t(mySize); }
0135
0136
0137
0138
0139 NCollection_AliasedArray& Assign(const NCollection_AliasedArray& theOther)
0140 {
0141 if (&theOther != this)
0142 {
0143 if (myStride != theOther.myStride || mySize != theOther.mySize)
0144 {
0145 throw Standard_DimensionMismatch(
0146 "NCollection_AliasedArray::Assign(), arrays have different size");
0147 }
0148 if (myData != NULL)
0149 {
0150 memcpy(myData, theOther.myData, SizeBytes());
0151 }
0152 }
0153 return *this;
0154 }
0155
0156
0157
0158
0159
0160 NCollection_AliasedArray& Move(NCollection_AliasedArray& theOther)
0161 {
0162 if (&theOther != this)
0163 {
0164 if (myDeletable)
0165 {
0166 Standard::FreeAligned(myData);
0167 }
0168 myStride = theOther.myStride;
0169 mySize = theOther.mySize;
0170 myDeletable = theOther.myDeletable;
0171 myData = theOther.myData;
0172 theOther.myDeletable = false;
0173 }
0174 return *this;
0175 }
0176
0177
0178 NCollection_AliasedArray& operator=(const NCollection_AliasedArray& theOther)
0179 {
0180 return Assign(theOther);
0181 }
0182
0183
0184 NCollection_AliasedArray& operator=(NCollection_AliasedArray&& theOther)
0185 {
0186 return Move(theOther);
0187 }
0188
0189
0190
0191
0192
0193
0194 void Resize(Standard_Integer theLength, Standard_Boolean theToCopyData)
0195 {
0196 if (theLength <= 0)
0197 {
0198 throw Standard_RangeError("NCollection_AliasedArray::Resize, length should be positive");
0199 }
0200 if (mySize == theLength)
0201 {
0202 return;
0203 }
0204
0205 const Standard_Integer anOldLen = mySize;
0206 const Standard_Byte* anOldData = myData;
0207 mySize = theLength;
0208 if (!theToCopyData && myDeletable)
0209 {
0210 Standard::FreeAligned(myData);
0211 }
0212 myData = (Standard_Byte*)Standard::AllocateAligned(SizeBytes(), MyAlignSize);
0213 if (myData == NULL)
0214 {
0215 throw Standard_OutOfMemory("NCollection_AliasedArray, allocation failed");
0216 }
0217 if (!theToCopyData)
0218 {
0219 myDeletable = true;
0220 return;
0221 }
0222
0223 const size_t aLenCopy = size_t(Min(anOldLen, theLength)) * size_t(myStride);
0224 memcpy(myData, anOldData, aLenCopy);
0225 if (myDeletable)
0226 {
0227 Standard::FreeAligned(anOldData);
0228 }
0229 myDeletable = true;
0230 }
0231
0232
0233 ~NCollection_AliasedArray()
0234 {
0235 if (myDeletable)
0236 {
0237 Standard::FreeAligned(myData);
0238 }
0239 }
0240
0241 public:
0242
0243 const Standard_Byte* value(Standard_Integer theIndex) const
0244 {
0245 Standard_OutOfRange_Raise_if(theIndex < 0 || theIndex >= mySize,
0246 "NCollection_AliasedArray::value(), out of range index");
0247 return myData + size_t(myStride) * size_t(theIndex);
0248 }
0249
0250
0251 Standard_Byte* changeValue(Standard_Integer theIndex)
0252 {
0253 Standard_OutOfRange_Raise_if(theIndex < 0 || theIndex >= mySize,
0254 "NCollection_AliasedArray::changeValue(), out of range index");
0255 return myData + size_t(myStride) * size_t(theIndex);
0256 }
0257
0258
0259 template <typename Type_t>
0260 void Init(const Type_t& theValue)
0261 {
0262 for (Standard_Integer anIter = 0; anIter < mySize; ++anIter)
0263 {
0264 ChangeValue<Type_t>(anIter) = theValue;
0265 }
0266 }
0267
0268
0269
0270 template <typename Type_t>
0271 const Type_t& Value(Standard_Integer theIndex) const
0272 {
0273 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t),
0274 "NCollection_AliasedArray::Value(), wrong type");
0275 return *reinterpret_cast<const Type_t*>(value(theIndex));
0276 }
0277
0278
0279
0280 template <typename Type_t>
0281 void Value(Standard_Integer theIndex, Type_t& theValue) const
0282 {
0283 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t),
0284 "NCollection_AliasedArray::Value(), wrong type");
0285 theValue = *reinterpret_cast<const Type_t*>(value(theIndex));
0286 }
0287
0288
0289
0290 template <typename Type_t>
0291 Type_t& ChangeValue(Standard_Integer theIndex)
0292 {
0293 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t),
0294 "NCollection_AliasedArray::ChangeValue(), wrong type");
0295 return *reinterpret_cast<Type_t*>(changeValue(theIndex));
0296 }
0297
0298
0299
0300
0301 template <typename Type_t>
0302 const Type_t& Value2(Standard_Integer theIndex) const
0303 {
0304 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t),
0305 "NCollection_AliasedArray::Value2(), wrong type");
0306 return *reinterpret_cast<const Type_t*>(value(theIndex));
0307 }
0308
0309
0310
0311
0312 template <typename Type_t>
0313 void Value2(Standard_Integer theIndex, Type_t& theValue) const
0314 {
0315 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t),
0316 "NCollection_AliasedArray::Value2(), wrong type");
0317 theValue = *reinterpret_cast<const Type_t*>(value(theIndex));
0318 }
0319
0320
0321
0322
0323 template <typename Type_t>
0324 Type_t& ChangeValue2(Standard_Integer theIndex)
0325 {
0326 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t),
0327 "NCollection_AliasedArray::ChangeValue2(), wrong type");
0328 return *reinterpret_cast<Type_t*>(changeValue(theIndex));
0329 }
0330
0331
0332 template <typename Type_t>
0333 const Type_t& First() const
0334 {
0335 return Value<Type_t>(0);
0336 }
0337
0338
0339 template <typename Type_t>
0340 Type_t& ChangeFirst()
0341 {
0342 return ChangeValue<Type_t>(0);
0343 }
0344
0345
0346 template <typename Type_t>
0347 const Type_t& Last() const
0348 {
0349 return Value<Type_t>(mySize - 1);
0350 }
0351
0352
0353 template <typename Type_t>
0354 Type_t& ChangeLast()
0355 {
0356 return Value<Type_t>(mySize - 1);
0357 }
0358
0359 protected:
0360 Standard_Byte* myData;
0361 Standard_Integer myStride;
0362 Standard_Integer mySize;
0363 Standard_Boolean myDeletable;
0364 };
0365
0366 #endif