File indexing completed on 2025-01-18 10:04:17
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
0037 NCollection_AliasedArray (Standard_Integer theStride)
0038 : myData (NULL), myStride (theStride), mySize (0), myDeletable (false)
0039 {
0040 if (theStride <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, stride should be positive"); }
0041 }
0042
0043
0044 NCollection_AliasedArray (Standard_Integer theStride,
0045 Standard_Integer theLength)
0046 : myData (NULL), myStride (theStride), mySize (theLength), myDeletable (true)
0047 {
0048 if (theLength <= 0 || myStride <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, stride and length should be positive"); }
0049 myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
0050 if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
0051 }
0052
0053
0054 NCollection_AliasedArray (const NCollection_AliasedArray& theOther)
0055 : myData (NULL), myStride (theOther.myStride), mySize (theOther.mySize), myDeletable (false)
0056 {
0057 if (mySize != 0)
0058 {
0059 myDeletable = true;
0060 myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
0061 if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
0062 Assign (theOther);
0063 }
0064 }
0065
0066
0067 NCollection_AliasedArray (NCollection_AliasedArray&& theOther) Standard_Noexcept
0068 : myData (theOther.myData), myStride (theOther.myStride), mySize (theOther.mySize), myDeletable (theOther.myDeletable)
0069 {
0070 theOther.myDeletable = false;
0071 }
0072
0073
0074 template<typename Type_t>
0075 NCollection_AliasedArray (const Type_t& theBegin,
0076 Standard_Integer theLength)
0077 : myData ((Standard_Byte* )&theBegin), myStride ((int )sizeof(Type_t)), mySize (theLength), myDeletable (false)
0078 {
0079 if (theLength <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, length should be positive"); }
0080 }
0081
0082
0083 Standard_Integer Stride() const { return myStride; }
0084
0085
0086 Standard_Integer Size() const { return mySize; }
0087
0088
0089 Standard_Integer Length() const { return mySize; }
0090
0091
0092 Standard_Boolean IsEmpty() const { return mySize == 0; }
0093
0094
0095 Standard_Integer Lower() const { return 0; }
0096
0097
0098 Standard_Integer Upper() const { return mySize - 1; }
0099
0100
0101 Standard_Boolean IsDeletable() const { return myDeletable; }
0102
0103
0104 Standard_Boolean IsAllocated() const { return myDeletable; }
0105
0106
0107 Standard_Size SizeBytes() const { return size_t(myStride) * size_t(mySize); }
0108
0109
0110
0111
0112 NCollection_AliasedArray& Assign (const NCollection_AliasedArray& theOther)
0113 {
0114 if (&theOther != this)
0115 {
0116 if (myStride != theOther.myStride || mySize != theOther.mySize)
0117 {
0118 throw Standard_DimensionMismatch ("NCollection_AliasedArray::Assign(), arrays have different size");
0119 }
0120 if (myData != NULL)
0121 {
0122 memcpy (myData, theOther.myData, SizeBytes());
0123 }
0124 }
0125 return *this;
0126 }
0127
0128
0129
0130
0131
0132 NCollection_AliasedArray& Move (NCollection_AliasedArray& theOther)
0133 {
0134 if (&theOther != this)
0135 {
0136 if (myDeletable)
0137 {
0138 Standard::FreeAligned (myData);
0139 }
0140 myStride = theOther.myStride;
0141 mySize = theOther.mySize;
0142 myDeletable = theOther.myDeletable;
0143 myData = theOther.myData;
0144 theOther.myDeletable = false;
0145 }
0146 return *this;
0147 }
0148
0149
0150 NCollection_AliasedArray& operator= (const NCollection_AliasedArray& theOther)
0151 {
0152 return Assign (theOther);
0153 }
0154
0155
0156 NCollection_AliasedArray& operator= (NCollection_AliasedArray&& theOther)
0157 {
0158 return Move (theOther);
0159 }
0160
0161
0162
0163
0164
0165
0166 void Resize (Standard_Integer theLength,
0167 Standard_Boolean theToCopyData)
0168 {
0169 if (theLength <= 0) { throw Standard_RangeError ("NCollection_AliasedArray::Resize, length should be positive"); }
0170 if (mySize == theLength)
0171 {
0172 return;
0173 }
0174
0175 const Standard_Integer anOldLen = mySize;
0176 const Standard_Byte* anOldData = myData;
0177 mySize = theLength;
0178 if (!theToCopyData && myDeletable)
0179 {
0180 Standard::FreeAligned (myData);
0181 }
0182 myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
0183 if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
0184 if (!theToCopyData)
0185 {
0186 myDeletable = true;
0187 return;
0188 }
0189
0190 const size_t aLenCopy = size_t(Min (anOldLen, theLength)) * size_t(myStride);
0191 memcpy (myData, anOldData, aLenCopy);
0192 if (myDeletable)
0193 {
0194 Standard::FreeAligned (anOldData);
0195 }
0196 myDeletable = true;
0197 }
0198
0199
0200 ~NCollection_AliasedArray()
0201 {
0202 if (myDeletable)
0203 {
0204 Standard::FreeAligned (myData);
0205 }
0206 }
0207
0208 public:
0209
0210
0211 const Standard_Byte* value (Standard_Integer theIndex) const
0212 {
0213 Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= mySize, "NCollection_AliasedArray::value(), out of range index");
0214 return myData + size_t(myStride) * size_t(theIndex);
0215 }
0216
0217
0218 Standard_Byte* changeValue (Standard_Integer theIndex)
0219 {
0220 Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= mySize, "NCollection_AliasedArray::changeValue(), out of range index");
0221 return myData + size_t(myStride) * size_t(theIndex);
0222 }
0223
0224
0225 template<typename Type_t> void Init (const Type_t& theValue)
0226 {
0227 for (Standard_Integer anIter = 0; anIter < mySize; ++anIter)
0228 {
0229 ChangeValue<Type_t> (anIter) = theValue;
0230 }
0231 }
0232
0233
0234
0235 template<typename Type_t> const Type_t& Value (Standard_Integer theIndex) const
0236 {
0237 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::Value(), wrong type");
0238 return *reinterpret_cast<const Type_t*>(value (theIndex));
0239 }
0240
0241
0242
0243 template<typename Type_t> void Value (Standard_Integer theIndex, Type_t& theValue) const
0244 {
0245 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::Value(), wrong type");
0246 theValue = *reinterpret_cast<const Type_t*>(value (theIndex));
0247 }
0248
0249
0250
0251 template<typename Type_t> Type_t& ChangeValue (Standard_Integer theIndex)
0252 {
0253 Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::ChangeValue(), wrong type");
0254 return *reinterpret_cast<Type_t* >(changeValue (theIndex));
0255 }
0256
0257
0258
0259 template<typename Type_t> const Type_t& Value2 (Standard_Integer theIndex) const
0260 {
0261 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::Value2(), wrong type");
0262 return *reinterpret_cast<const Type_t*>(value (theIndex));
0263 }
0264
0265
0266
0267 template<typename Type_t> void Value2 (Standard_Integer theIndex, Type_t& theValue) const
0268 {
0269 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::Value2(), wrong type");
0270 theValue = *reinterpret_cast<const Type_t*>(value (theIndex));
0271 }
0272
0273
0274
0275 template<typename Type_t>
0276 Type_t& ChangeValue2 (Standard_Integer theIndex)
0277 {
0278 Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::ChangeValue2(), wrong type");
0279 return *reinterpret_cast<Type_t* >(changeValue (theIndex));
0280 }
0281
0282
0283 template<typename Type_t> const Type_t& First() const { return Value<Type_t> (0); }
0284
0285
0286 template<typename Type_t> Type_t& ChangeFirst() { return ChangeValue<Type_t> (0); }
0287
0288
0289 template<typename Type_t> const Type_t& Last() const { return Value<Type_t> (mySize - 1); }
0290
0291
0292 template<typename Type_t> Type_t& ChangeLast() { return Value<Type_t> (mySize - 1); }
0293
0294 protected:
0295
0296 Standard_Byte* myData;
0297 Standard_Integer myStride;
0298 Standard_Integer mySize;
0299 Standard_Boolean myDeletable;
0300
0301 };
0302
0303 #endif