3ds Max C++ API Reference
Array< T > Class Template Reference

A generic array container, with proper support for non-POD types. More...

#include <Array.h>

+ Inheritance diagram for Array< T >:

Public Types

typedef int(__cdecl * CompareFnc) (const void *elem1, const void *elem2)
 Type of function to pass to sort(). More...
 

Public Member Functions

 Array ()
 Initializes an empty array. More...
 
 Array (size_t initUsedLength, const T &defaultVal=T(), size_t initGrowLength=kDefaultGrowthLength)
 Initializes an array with an initial size. More...
 
 Array (const Array< T > &src)
 Copy constructor. More...
 
template<class InputIt >
 Array (InputIt begin, InputIt end)
 Copy constructor. More...
 
 ~Array ()
 Destructor. Destroys every element stored in the array, and frees the allocated storage. More...
 
Array< T > & operator= (const Array< T > &src)
 Copy operator. More...
 
bool operator== (const Array< T > &op) const
 Equality operator. More...
 
Array< T > & setAt (size_t index, const T &value)
 Sets a copy of value at the given index. More...
 
Array< T > & setAll (const T &value)
 Sets all the elements of the array to the given value. More...
 
bool isValidIndex (size_t) const
 Returns whether the given array index is valid for this array. More...
 
T & operator[] (size_t i)
 Subscript operator. More...
 
const T & operator[] (size_t i) const
 Subscript operator. More...
 
const T & at (size_t index) const
 Same as subscript operator. More...
 
T & at (size_t index)
 Same as subscript operator. More...
 
T & first ()
 Accesses the first element in the array. More...
 
const T & first () const
 Accesses the first element in the array. More...
 
T * begin ()
 Accesses the begin iterator, which is a plain pointer in this case. More...
 
const T * begin () const
 Accesses the const begin iterator, which is a plain pointer in this case. More...
 
T & last ()
 Accesses the last element in the array. More...
 
const T & last () const
 Accesses the first element in the array. More...
 
T * end ()
 Accesses the end iterator (one past last valid element). Do not dereference. More...
 
const T * end () const
 Accesses the const end iterator (one past last valid element). Do not dereference. More...
 
size_t append (const T &value)
 Appends a copy of value to the array. More...
 
Array< T > & append (const T *values, size_t count)
 Appends one or more element(s) to the array. More...
 
Array< T > & append (const Array< T > &array)
 Appends the contents of another array to this array. More...
 
Array< T > & insertAt (size_t index, const T &value)
 Inserts a single value, at a given location, into this array. More...
 
Array< T > & insertAt (size_t index, const T *values, size_t count)
 Inserts a one or more value(s), at a given location, into this array. More...
 
Array< T > & removeAt (size_t index)
 Removes a single element from the array. More...
 
bool remove (const T &value, size_t start=0)
 Searches for a value in the array and, if it is found, removes it from the array. More...
 
Array< T > & removeFirst ()
 Removes the first element of the array. More...
 
Array< T > & removeLast ()
 Removes the last element of the array. More...
 
Array< T > & removeAll ()
 Removes all the elements from the array. More...
 
Array< T > & removeSubArray (size_t startIndex, size_t endIndex)
 Removes a subset of the array. More...
 
bool contains (const T &value, size_t start=0) const
 Determines if a value is stored in the array. More...
 
bool find (const T &value, size_t &foundAt, size_t start=0) const
 Searches for a value in the array. More...
 
size_t find (const T &value) const
 Searches for a value in the array. More...
 
size_t findFrom (const T &value, size_t start) const
 Searches for a value in the array, starting at a given index. More...
 
size_t length () const
 Returns the number of used elements (as opposed to simply allocated/reserved) in the array. More...
 
bool isEmpty () const
 Returns true if the number of used elements in the array is 0; returns false otherwise. More...
 
size_t lengthUsed () const
 Returns the number of elements used (as opposed to simply allocated/reserved) in the array. More...
 
Array< T > & setLengthUsed (size_t length, const T &defaultVal=T())
 Sets the number of elements used (as opposed to simply allocated/reserved) in the array. More...
 
size_t lengthReserved () const
 Returns the number of elements allocated/reserved (as opposed to actually used) in the array. More...
 
Array< T > & setLengthReserved (size_t length)
 Sets the number of elements allocated/reserved (as opposed to actually used) in the array. More...
 
void reserve (size_t capacity)
 Alias for setLengthReserved. More...
 
size_t growLength () const
 Returns the growth length of the array. More...
 
Array< T > & setGrowLength (size_t)
 Sets the growth length of the array. More...
 
Array< T > & reverse ()
 Reverses the sequence of elements in the array. More...
 
Array< T > & swap (size_t i1, size_t i2)
 Swaps two elements in this array. More...
 
void sort (CompareFnc cmp)
 Sorts the elements of the array using a custom comparison function. More...
 
const T * asArrayPtr () const
 Returns the array storage as a C-style array pointer. More...
 
T * asArrayPtr ()
 Accesses the first element in the array. More...
 

Protected Types

enum  { kDefaultGrowthLength = 8 }
 

Static Protected Member Functions

static size_t quickSortPartition (T *data, size_t first, size_t last, CompareFnc cmp)
 The partition portion of the QuickSort algorithm. More...
 
static void quickSortRecursive (T *data, size_t first, size_t last, CompareFnc cmp)
 Recursive QuickSort function used to sort the elements of the array. More...
 
static void handleOutOfMemory ()
 Utility function, called when the array fails to allocate memory. More...
 
static T * ArrayAllocate (size_t len)
 Allocates an array of elements without constructing them. More...
 
static void ArrayConstruct (T *arrayBegin, size_t len, const T &defaultVal)
 Constructs an array of elements. More...
 
static void ArrayDeAllocate (T *arrayBegin)
 De-allocates an array of elements without destructing them. More...
 
static void ArrayDestruct (T *arrayBegin, size_t len)
 Destructs an array of elements. More...
 
static void ArrayCopy (T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
 Copies an array of elements to an already-constructed buffer. More...
 
static void ArrayCopyOverlap (T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
 Copies an array of elements when the target and destination memory buffers may overlap. More...
 
static void ArrayCopyConstruct (T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
 Copies and array of elements to a non-constructed. More...
 

Protected Attributes

T * mpArray
 Pointer to the storage buffer. More...
 
size_t mReservedLen
 The reserved length (in number of elements, not bytes). More...
 
size_t mUsedLen
 The used length (in number of elements, not bytes). More...
 
size_t mGrowLen
 The growth length. See setGrowLength(). More...
 

Additional Inherited Members

- Static Public Member Functions inherited from MaxHeapOperators
static UtilExport voidoperator new (size_t size)
 Standard new operator used to allocate objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e)
 Standard new operator used to allocate objects if there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new (size_t size, const char *filename, int line)
 New operator used to allocate objects that takes the filename and line number where the new was called If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, int block_type, const char *filename, int line)
 New operator used to allocate objects that takes the type of memory, filename and line number where the new was called If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e, const char *filename, int line)
 New operator used to allocate objects that takes the filename and line number where the new was called If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new (size_t size, unsigned long flags)
 New operator used to allocate objects that takes extra flags to specify special operations If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e, unsigned long flags)
 New operator used to allocate objects that takes extra flags to specify special operations If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size, const char *filename, int line)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, int block_type, const char *filename, int line)
 New operator used to allocate arrays of objects. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e, const char *filename, int line)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size, unsigned long flags)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e, unsigned long flags)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport void operator delete (void *ptr)
 Standard delete operator used to deallocate an object If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e)
 Standard delete operator used to deallocate an object If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete (void *ptr, const char *filename, int line)
 Delete operator used to deallocate an object that takes the filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, int block_type, const char *filename, int line)
 Delete operator used to deallocate an object that takes the type of memory, filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e, const char *filename, int line)
 Delete operator used to deallocate an object that takes the filename and line number where the delete was called If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete (void *ptr, unsigned long flags)
 Delete operator used to deallocate an object that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e, unsigned long flags)
 Delete operator used to deallocate an object that takes extra flags to specify special operations If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr)
 Standard delete operator used to deallocate an array of objects If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e)
 Standard delete operator used to deallocate an array of objects If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, int block_type, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the type of memory, filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the filename and line number where the delete was called If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr, unsigned long flags)
 Delete operator used to deallocate an array of objects that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e, unsigned long flags)
 Delete operator used to deallocate an array of objects that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, void *placement_ptr)
 Placement new operator. More...
 
static UtilExport void operator delete (void *ptr, void *placement_ptr)
 Placement delete operator. More...
 
static UtilExport voidaligned_malloc (size_t size, size_t alignment)
 Allocates memory on a specified alignment boundary. More...
 
static UtilExport voidaligned_realloc (void *ptr, size_t size, size_t alignment)
 Reallocates memory on a specified alignment boundary. More...
 
static UtilExport void aligned_free (void *ptr)
 Frees a block of memory that was allocated with aligned_malloc/aligned_realloc. More...
 

Detailed Description

template<class T>
class MaxSDK::Array< T >

A generic array container, with proper support for non-POD types.

This template class is a generic, dynamic array container, similar to the STL class "vector". Whereas the classical 3ds Max SDK class Tab supports only POD types, this class supports non-POD types as well.

Note
POD stands for "plain old data", and basically denotes any data type which does not need to be constructed, destructed, and which can be copied with memcpy() rather than requiring a copy operator to be called.

Member Typedef Documentation

◆ CompareFnc

typedef int( __cdecl * CompareFnc) (const void *elem1, const void *elem2)

Type of function to pass to sort().

Must return:
  • < 0 if elem1 is smaller than elem2,
  • > 0 if elem 1 is greater,
  • or 0 if they're equal.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
protected
Enumerator
kDefaultGrowthLength 

The default growth length. See setGrowLength().

338  {
341  };
@ kDefaultGrowthLength
The default growth length. See setGrowLength().
Definition: Array.h:340

Constructor & Destructor Documentation

◆ Array() [1/4]

Initializes an empty array.

22 : mpArray(NULL),
23  mReservedLen(0),
24  mUsedLen(0),
26 {
27  if(mGrowLen < 1) {
28  // Growth length needs to be at least 1.
29  mGrowLen = 1;
30  }
31 }
#define NULL
Definition: autoptr.h:18
T * mpArray
Pointer to the storage buffer.
Definition: Array.h:344
size_t mReservedLen
The reserved length (in number of elements, not bytes).
Definition: Array.h:346
size_t mUsedLen
The used length (in number of elements, not bytes).
Definition: Array.h:348
size_t mGrowLen
The growth length. See setGrowLength().
Definition: Array.h:350

◆ Array() [2/4]

Array ( size_t  initUsedLength,
const T &  defaultVal = T(),
size_t  initGrowLength = kDefaultGrowthLength 
)

Initializes an array with an initial size.

Parameters
[in]initUsedLength- Number of elements initially allocated in the array.
[in]defaultVal- The default value for the elements initially allocated.
[in]initGrowLength- The initial growth length of the array. For more information on the growth length, see setGrowLength().
34 : mpArray(NULL),
35  mReservedLen(0),
36  mUsedLen(0),
38 {
39  if(mGrowLen < 1) {
40  // Growth length needs to be at least 1.
41  mGrowLen = 1;
42  }
43 
44  // Re-size the array if a non-zero length was specified.
45  if(usedLength > 0) {
46  mpArray = ArrayAllocate(usedLength);
47  if (mpArray == NULL) {
49  }
50  else {
51 
52  // Initialize the new elements
53  ArrayConstruct(mpArray, usedLength, defaultVal);
54 
55  mReservedLen = usedLength;
56  mUsedLen = usedLength;
57  }
58  }
59 }
size_t growLength() const
Returns the growth length of the array.
Definition: Array.inline.h:179
static T * ArrayAllocate(size_t len)
Allocates an array of elements without constructing them.
Definition: Array.inline.h:21
static void ArrayConstruct(T *arrayBegin, size_t len, const T &defaultVal)
Constructs an array of elements.
Definition: Array.inline.h:34
static void handleOutOfMemory()
Utility function, called when the array fails to allocate memory.
Definition: Array.inline.h:359

◆ Array() [3/4]

Array ( const Array< T > &  src)

Copy constructor.

Copies the contents of another array.

Parameters
[in]src- Array from which the elements are copied.
69 : mpArray(NULL),
70  mReservedLen(src.mUsedLen),
71  mUsedLen(src.mUsedLen),
72  mGrowLen(src.mGrowLen)
73 {
74  if (mReservedLen > 0) {
76  if (mpArray == NULL) {
78  mReservedLen = 0;
79  mUsedLen = 0;
80  }
81  else {
83  }
84  }
85 }
static void ArrayCopyConstruct(T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
Copies and array of elements to a non-constructed.
Definition: Array.inline.h:128

◆ Array() [4/4]

Array ( InputIt  begin,
InputIt  end 
)

Copy constructor.

Copies the contents values between 2 iterators.

Parameters
[in]begin- iterator that defines where to start copying from
[in]end- iterator that defines when to stop copying
90  : mpArray(nullptr)
91  , mReservedLen(0)
92  , mUsedLen(0)
94 {
95  size_t count = end - begin;
96 
97  mpArray = ArrayAllocate(count);
98  if (mpArray == nullptr)
99  {
101  }
102 
103  mReservedLen = count;
104  mUsedLen = count;
105 
106  // todo trivially copyable
107  T* place = mpArray;
108  for (; begin != end; ++begin) {
109  new(place) T(*begin);
110  ++place;
111  }
112 }
T * begin()
Accesses the begin iterator, which is a plain pointer in this case.
Definition: Array.inline.h:274
T * end()
Accesses the end iterator (one past last valid element). Do not dereference.
Definition: Array.inline.h:304

◆ ~Array()

Destructor. Destroys every element stored in the array, and frees the allocated storage.

115 {
116  // The type stored by MaxSDK::Array must be trivial or it must have a copy constructor and a copy assignment operator
117  // for ArrayCopyConstruct, ArrayCopy and ArrayCopyOverlap to work
118  static_assert(std::is_trivial<T>::value || (std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value),
119  "The type stored by MaxSDK::Array must be trivial or it must have a copy constructor and a copy assignment operator.");
120 
121  if (mpArray != NULL) {
124  }
125 }
static void ArrayDeAllocate(T *arrayBegin)
De-allocates an array of elements without destructing them.
Definition: Array.inline.h:43
static void ArrayDestruct(T *arrayBegin, size_t len)
Destructs an array of elements.
Definition: Array.inline.h:50

Member Function Documentation

◆ operator=()

Array< T > & operator= ( const Array< T > &  src)

Copy operator.

Copies the contents of another array.

Parameters
[in]src- Array from which the elements are copied.
Returns
A reference to 'this'.
137 {
138  if (this != &src) {
139  // Re-allocate the buffer if necessary
140  if (mReservedLen < src.mUsedLen) {
141  // Destroy the existing list
142  if (mpArray != NULL) {
145  }
146  // Allocate a new buffer
147  mReservedLen = src.mUsedLen;
149  if (mpArray == NULL) { // ...so this only happens if failure.
151  mReservedLen = 0;
152  mUsedLen = 0;
153  return *this;
154  }
155  // Copy the list
156  mUsedLen = src.mUsedLen;
158  }
159  else if(mUsedLen < src.mUsedLen) {
160  // The entire destination list is to be overwritten
161  ArrayCopy(mpArray, mUsedLen, src.mpArray, mUsedLen);
162  // Remaining elements need to be added to the list
163  ArrayCopyConstruct(mpArray + mUsedLen, mReservedLen - mUsedLen, src.mpArray + mUsedLen, src.mUsedLen - mUsedLen);
164  mUsedLen = src.mUsedLen;
165  }
166  else if(mUsedLen > src.mUsedLen) {
167  // Copy the entire source list.
168  ArrayCopy(mpArray, mUsedLen, src.mpArray, src.mUsedLen);
169  // Truncate unused elements in the destination list.
170  ArrayDestruct(mpArray + src.mUsedLen, mUsedLen - src.mUsedLen);
171  mUsedLen = src.mUsedLen;
172  }
173  else {
174  // Lists are of identical size; simply copy the entire contents
175  ArrayCopy(mpArray, mReservedLen, src.mpArray, mUsedLen);
176  }
177  }
178  return *this;
179 }
static void ArrayCopy(T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
Copies an array of elements to an already-constructed buffer.
Definition: Array.inline.h:62

◆ operator==()

bool operator== ( const Array< T > &  op) const

Equality operator.

Parameters
[in]op- Array to be compared to 'this'.
Returns
true if and only if both arrays contain the same number of elements and each of these elements if equal to the corresponding element from the other Array.
189 {
190  if (mUsedLen == cpr.mUsedLen)
191  {
192  for (size_t i = 0; i < mUsedLen; i++)
193  if (mpArray[i] != cpr.mpArray[i])
194  return false;
195  return true;
196  }
197  return false;
198 }

◆ operator[]() [1/2]

T & operator[] ( size_t  i)
inline

Subscript operator.

Parameters
[in]i- Index of array element to access. This index must be within the array bounds. If the index is out of bounds it will throw a MaxSDK::Util::MaxOutOfRangeException exception.
Returns
A reference to the array element at the specified index.
Remarks
Does implement bounds checking.
201 {
202  if (!isValidIndex(i))
203  {
204  DbgAssert(false);
205  throw MaxSDK::Util::OutOfRangeException(_M("Argument index out of bounds, passed into a MaxSDK::Array::operator[]"));
206  }
207  return mpArray[i];
208 }
bool isValidIndex(size_t) const
Returns whether the given array index is valid for this array.
Definition: Array.inline.h:194
Thrown when an out of bounds index is detected.
Definition: MaxExceptions.h:53
#define DbgAssert(expr)
Definition: assert1.h:82
#define _M(x)
Used to wrap string literals.
Definition: strbasic.h:67

◆ operator[]() [2/2]

const T & operator[] ( size_t  i) const
inline

Subscript operator.

Parameters
[in]i- Index of array element to access. This index must be within the array bounds. If the index is out of bounds it will throw a MaxSDK::Util::MaxOutOfRangeException exception.
Returns
A reference to the array element at the specified index.
Remarks
Does implement bounds checking.
211 {
212  if (!isValidIndex(i))
213  {
214  DbgAssert(false);
215  throw MaxSDK::Util::OutOfRangeException(_M("Argument index out of bounds, passed into a MaxSDK::Array::operator[]"));
216  }
217  return mpArray[i];
218 }

◆ at() [1/2]

const T & at ( size_t  index) const
inline

Same as subscript operator.

Parameters
[in]index- Index of array element to access. This index must be within the array bounds.
Returns
A reference to the array element at the specified index.
Remarks
Does not implement bounds checking.
231 {
232  if (!isValidIndex(i))
233  {
234  DbgAssert(false);
235  throw MaxSDK::Util::OutOfRangeException(_M("Argument index out of bounds, passed into a MaxSDK::Array::at()"));
236  }
237  return mpArray[i];
238 }

◆ at() [2/2]

T & at ( size_t  index)
inline

Same as subscript operator.

Parameters
[in]index- Index of array element to access. This index must be within the array bounds.
Returns
A reference to the array element at the specified index.
Remarks
Does not implement bounds checking.
221 {
222  if (!isValidIndex(i))
223  {
224  DbgAssert(false);
225  throw MaxSDK::Util::OutOfRangeException(_M("Argument index out of bounds, passed into a MaxSDK::Array::at()"));
226  }
227  return mpArray[i];
228 }

◆ setAt()

Array< T > & setAt ( size_t  index,
const T &  value 
)
inline

Sets a copy of value at the given index.

Parameters
[in]index- The position in the array where a copy of value is placed. This index must be within the array bounds.
[in]value- a reference to the original object.
Returns
A reference to 'this'.
Remarks
Does not implement bounds checking.
241 {
242  if (!isValidIndex(i))
243  {
244  DbgAssert(false);
245  throw MaxSDK::Util::OutOfRangeException(_M("Argument index out of bounds, passed into a MaxSDK::Array::setAt()"));
246  }
247  mpArray[i] = value;
248  return *this;
249 }

◆ setAll()

Array< T > & setAll ( const T &  value)

Sets all the elements of the array to the given value.

Parameters
[in]value- The value to which the elements of the array are set.
Returns
A reference to 'this'.
204 {
205  for (size_t i = 0; i < mUsedLen; i++) {
206  mpArray[i] = value;
207  }
208  return *this;
209 }

◆ first() [1/2]

T & first
inline

Accesses the first element in the array.

Returns
A reference to the first element of the array.
Remarks
It is invalid to call this on an empty array.
252 {
253  DbgAssert(!this->isEmpty());
254  DbgAssert(mpArray != nullptr);
255  if (this->isEmpty() || (nullptr == mpArray))
256  {
257  throw MaxSDK::Util::RunTimeException(_M("Attempting to call MaxSDK::Array::first() on an empty array"));
258  }
259  return mpArray[0];
260 }
bool isEmpty() const
Returns true if the number of used elements in the array is 0; returns false otherwise.
Definition: Array.inline.h:164
General multi-purpose exception for runtime errors.
Definition: MaxExceptions.h:69

◆ first() [2/2]

const T & first
inline

Accesses the first element in the array.

Returns
A reference to the first element of the array.
Remarks
It is invalid to call this on an empty array.
263 {
264  DbgAssert(!this->isEmpty());
265  DbgAssert(mpArray != nullptr);
266  if (this->isEmpty() || (nullptr == mpArray))
267  {
268  throw MaxSDK::Util::RunTimeException(_M("Attempting to call MaxSDK::Array::first() on an empty array"));
269  }
270  return mpArray[0];
271 }

◆ begin() [1/2]

T * begin

Accesses the begin iterator, which is a plain pointer in this case.

274  {
275  return mpArray;
276 }

◆ begin() [2/2]

const T * begin

Accesses the const begin iterator, which is a plain pointer in this case.

278  {
279  return mpArray;
280 }

◆ last() [1/2]

T & last
inline

Accesses the last element in the array.

Returns
A reference to the last element of the array.
Remarks
It is invalid to call this on an empty array.
283 {
284  DbgAssert(!this->isEmpty());
285  DbgAssert(mpArray != nullptr);
286  if (this->isEmpty() || (nullptr == mpArray))
287  {
288  throw MaxSDK::Util::RunTimeException(_M("Attempting to call MaxSDK::Array::last() on an empty array"));
289  }
290  return mpArray[mUsedLen-1];
291 }

◆ last() [2/2]

const T & last
inline

Accesses the first element in the array.

Returns
A reference to the first element of the array.
Remarks
It is invalid to call this on an empty array.
294 {
295  DbgAssert(!this->isEmpty());
296  DbgAssert(mpArray != nullptr);
297  if (this->isEmpty() || (nullptr == mpArray))
298  {
299  throw MaxSDK::Util::RunTimeException(_M("Attempting to call MaxSDK::Array::last() on an empty array"));
300  }
301  return mpArray[mUsedLen-1];
302 }

◆ end() [1/2]

T * end

Accesses the end iterator (one past last valid element). Do not dereference.

304  {
305  return mpArray + mUsedLen;
306 }

◆ end() [2/2]

const T * end

Accesses the const end iterator (one past last valid element). Do not dereference.

308  {
309  return mpArray + mUsedLen;
310 }

◆ append() [1/3]

size_t append ( const T &  value)
inline

Appends a copy of value to the array.

Parameters
[in]value- A reference to the original value.
Returns
The number of elements in the array prior to the append operation.
313 {
314  insertAt(mUsedLen, value);
315  return mUsedLen-1;
316 }
Array< T > & insertAt(size_t index, const T &value)
Inserts a single value, at a given location, into this array.
Definition: Array.imp.h:241

◆ append() [2/3]

Array< T > & append ( const T *  values,
size_t  count 
)

Appends one or more element(s) to the array.

Parameters
[in]values- A pointer to a C-style array of elements, from which the appended elements will be copied.
[in]count- The number of elements to be appended.
Returns
A reference to 'this'.
319 {
320  return insertAt(mUsedLen, values, count);
321 }

◆ append() [3/3]

Array< T > & append ( const Array< T > &  array)

Appends the contents of another array to this array.

Parameters
[in]array- The array from which elements are to be appended.
Returns
A reference to 'this'.
218 {
219  size_t otherLen = otherArray.length();
220  if (otherLen == 0) {
221  return *this;
222  }
223  size_t newLen = mUsedLen + otherLen;
224  if (newLen > mReservedLen) {
225  setLengthReserved(newLen);
226  }
227 
228  ArrayCopyConstruct(mpArray + mUsedLen, mReservedLen - mUsedLen, otherArray.mpArray, otherLen);
229 
230  mUsedLen = newLen;
231  return *this;
232 }
Array< T > & setLengthReserved(size_t length)
Sets the number of elements allocated/reserved (as opposed to actually used) in the array.
Definition: Array.imp.h:461

◆ insertAt() [1/2]

Array< T > & insertAt ( size_t  index,
const T &  value 
)

Inserts a single value, at a given location, into this array.

Parameters
[in]index- The index at which the element is to be inserted. This index must be smaller or equal to the used length of the array.
[in]value- The value to be inserted.
Returns
A reference to 'this'.
242 {
243  DbgAssert(index >= 0 && index <= mUsedLen);
244 
245  if (mUsedLen >= mReservedLen) {
247  }
248 
249  if (index != mUsedLen) {
250 
251  // Initialize the new member of the array
253 
254  // Copy the remainder of the list that needs to be shifted
255  for(size_t i = mUsedLen - 1; i > index; --i) {
256  mpArray[i] = mpArray[i-1];
257  }
258 
259  // Now copy the new element into the array
260  mpArray[index] = value;
261  }
262  else {
263  // Add the new value to the end of the list
265  }
266 
267  mUsedLen++;
268  return *this;
269 }

◆ insertAt() [2/2]

Array< T > & insertAt ( size_t  index,
const T *  values,
size_t  count 
)

Inserts a one or more value(s), at a given location, into this array.

Parameters
[in]index- The index at which the element is to be inserted. This index must be smaller or equal to the used length of the array.
[in]values- A pointer to a C-style array of elements, from which the inserted elements will be copied.
[in]count- The number of elements to be inserted.
Returns
A reference to 'this'.
272 {
273  DbgAssert(index >= 0 && index <= mUsedLen);
274 
275  if(index <= mUsedLen) {
276 
277  size_t lastInsertIndex = index + count - 1;
278 
279  // Increase the allocated memory if necessary
280  size_t newUsedLen = mUsedLen + count;
281  if(newUsedLen > mReservedLen) {
282 
283  // Allocate a new buffer
284  T* newArray = ArrayAllocate(newUsedLen);
285  if(newArray == NULL) {
286  // Can't insert the new element since the allocation failed.
288  return *this;
289  }
290 
291  // Copy existing elements located to the left of the insertion range
292  ArrayCopyConstruct(newArray, newUsedLen, mpArray, index);
293 
294  // Copy the inserted elements
295  ArrayCopyConstruct(newArray + index, newUsedLen - index, values, count);
296 
297  // Copy existing elements located to the right of the insertion range
298  if(index < mUsedLen) {
299  ArrayCopyConstruct(newArray + index + count, newUsedLen - index - count, mpArray + index, mUsedLen - index);
300  }
301 
302  // Destroy the old array
305 
306  mpArray = newArray;
307  mUsedLen = newUsedLen;
308  mReservedLen = newUsedLen;
309  }
310  else {
311  if(index < mUsedLen) {
312  // Shift elements that get moved beyond the current limit of the array
314 
315  // Shift elements that stay inside the current limits of the array
316  if((index + count) < mUsedLen) {
317  ArrayCopyOverlap(mpArray + index + count, mReservedLen - index - count, mpArray + index, mUsedLen - index - count);
318  }
319 
320  // Copy new elements that get inserted within the current size of the array
321  if(lastInsertIndex < mUsedLen) {
322  ArrayCopy(mpArray + index, mReservedLen - index, values, count);
323  }
324  else {
325  ArrayCopy(mpArray + index, mReservedLen - index, values, mUsedLen - index);
326  }
327  }
328 
329  // Copy new elements that get inserted beyond the current size of the array
330  if(lastInsertIndex >= mUsedLen) {
331  size_t numElementsInserted = (mUsedLen - index);
332  DbgAssert(numElementsInserted < count);
333  ArrayCopyConstruct(mpArray + mUsedLen, mReservedLen - mUsedLen, values + numElementsInserted, count - numElementsInserted);
334  }
335 
336  mUsedLen += count;
337  }
338  }
339 
340  return *this;
341 }
static void ArrayCopyOverlap(T *pCopy, size_t nMaxCount, const T *pSource, size_t nCount)
Copies an array of elements when the target and destination memory buffers may overlap.
Definition: Array.inline.h:85

◆ removeAt()

Array< T > & removeAt ( size_t  index)

Removes a single element from the array.

Parameters
[in]index- The index of the element to be removed. This index must be valid (within bounds).
Returns
A reference to 'this'.
347 {
348  DbgAssert(isValidIndex(index));
349 
350  if(index < mUsedLen) {
351  // Shift array elements to the left if needed.
352  //
353  if (index < mUsedLen - 1) {
354  for(size_t i = index; i < mUsedLen - 1; ++i) {
355  mpArray[i] = mpArray[i+1];
356  }
357  }
358 
359  // Destroy the last element of the array
360  ArrayDestruct(mpArray + mUsedLen - 1, 1);
361 
362  mUsedLen--;
363  }
364 
365  return *this;
366 }

◆ remove()

bool remove ( const T &  value,
size_t  start = 0 
)

Searches for a value in the array and, if it is found, removes it from the array.

Parameters
[in]value- The value to search for.
[in]start- The index at which to start searching. Preceding elements are not searched.
Returns
true if a value was found & removed; false otherwise.
Remarks
If multiple copies of the same value are stored in the array, only the first instance will be removed.
559 {
560  const size_t i = this->findFrom(value, start);
561  if (i == -1)
562  return false;
563  this->removeAt(i);
564  return true;
565 }
size_t findFrom(const T &value, size_t start) const
Searches for a value in the array, starting at a given index.
Definition: Array.imp.h:418
Array< T > & removeAt(size_t index)
Removes a single element from the array.
Definition: Array.imp.h:346

◆ removeFirst()

Array< T > & removeFirst
inline

Removes the first element of the array.

Returns
A reference to 'this'.
Remarks
Must not be called on an empty array.
324 {
325  DbgAssert(!isEmpty());
326  return removeAt(0);
327 }

◆ removeLast()

Array< T > & removeLast
inline

Removes the last element of the array.

Returns
A reference to 'this'.
Remarks
Must not be called on an empty array.
330 {
331  DbgAssert(!isEmpty());
332  return removeAt(mUsedLen - 1);
333 }

◆ removeAll()

Array< T > & removeAll
inline

Removes all the elements from the array.

Returns
A reference to 'this'.
336 {
337  if(mUsedLen > 0) {
339  mUsedLen = 0;
340  }
341  return *this;
342 }

◆ removeSubArray()

Array< T > & removeSubArray ( size_t  startIndex,
size_t  endIndex 
)

Removes a subset of the array.

Parameters
[in]startIndex- The index of the first element to be removed.
[in]endIndex- The index of the last element to be removed.
Returns
A reference to 'this'.
Remarks
  • Both the start and end indices must be within bounds.
  • The end index must be greater or equal to the start index.
372 {
373  DbgAssert(isValidIndex(startIndex));
374  DbgAssert(startIndex <= endIndex);
375 
376  if(startIndex < mUsedLen) {
377 
378  if(endIndex >= mUsedLen) {
379  endIndex = mUsedLen - 1;
380  }
381 
382  size_t numToRemove = endIndex - startIndex + 1;
383 
384  // Shift all elements that reside on the right of the sub-array to be removed
385  for(size_t i = endIndex + 1; i < mUsedLen; ++i) {
386  mpArray[i - numToRemove] = mpArray[i];
387  }
388 
389  // Truncate the array
390  ArrayDestruct(mpArray + mUsedLen - numToRemove, numToRemove);
391 
392  mUsedLen -= numToRemove;
393  }
394 
395  return *this;
396 }

◆ contains()

bool contains ( const T &  value,
size_t  start = 0 
) const
inline

Determines if a value is stored in the array.

Parameters
[in]value- The value for which to search for.
[in]start- The index at which to start searching. Preceding elements are not searched.
Returns
true if the value was found in the array; false otherwise.
155 {
156  return this->findFrom(value, start) != -1;
157 }

◆ find() [1/2]

bool find ( const T &  value,
size_t foundAt,
size_t  start = 0 
) const

Searches for a value in the array.

Parameters
[in]value- The value to search for.
[out]foundAt- The index at which the value was found. Indeterminate if the value was not found.
[in]start- The index at which to start searching. Preceding elements are not searched.
Returns
true if the value was found in the array; false otherwise.
405 {
406  const size_t nFoundAt = this->findFrom(value, start);
407  if (nFoundAt == -1)
408  return false;
409  index = nFoundAt;
410  return true;
411 }

◆ find() [2/2]

size_t find ( const T &  value) const

Searches for a value in the array.

Parameters
[in]value- The value to search for.
Returns
The index at which the value was found, or -1 if the value was not found. (Since this returns an unsigned value, -1 is converted to the the largest positive value).
414 {
415  return this->findFrom(value, 0); // search from the beginning
416 }

◆ findFrom()

size_t findFrom ( const T &  value,
size_t  start 
) const

Searches for a value in the array, starting at a given index.

Parameters
[in]value- The value to search for.
[in]start- The index at which to start searching.
Returns
The index at which the value was found, or -1 if the value was not found. (Since this returns an unsigned value, -1 is converted to the the largest positive value).
419 {
420  for (size_t i = start; i < this->mUsedLen; i++) {
421  if (mpArray[i] == value)
422  return i;
423  }
424  return (size_t)-1;
425 }

◆ length()

size_t length
inline

Returns the number of used elements (as opposed to simply allocated/reserved) in the array.

160 {
161  return mUsedLen;
162 }

◆ isEmpty()

bool isEmpty
inline

Returns true if the number of used elements in the array is 0; returns false otherwise.

165 {
166  return mUsedLen == 0;
167 }

◆ lengthUsed()

size_t lengthUsed
inline

Returns the number of elements used (as opposed to simply allocated/reserved) in the array.

170 {
171  return mUsedLen;
172 }

◆ setLengthUsed()

Array< T > & setLengthUsed ( size_t  length,
const T &  defaultVal = T() 
)

Sets the number of elements used (as opposed to simply allocated/reserved) in the array.

Parameters
[in]length- The new "used length" of the array.
[in]defaultVal- The default value for new elements, used only if the length of the array is increased.
Returns
A reference to 'this'.
435 {
436  DbgAssert(n >= 0);
437  if (n > mReservedLen) {
438  // We over-allocate some extra slack
439  setLengthReserved(__max(n + mGrowLen, n + n / 2));
440  }
441 
442  if(n > mUsedLen) {
443  // Initialize the new elements
444  ArrayConstruct(mpArray + mUsedLen, n - mUsedLen, defaultVal);
445  }
446  else {
447  // Destroy the elements to be removed
448  ArrayDestruct(mpArray + n, mUsedLen - n);
449  }
450 
451  mUsedLen = n;
452  return *this;
453 }

◆ lengthReserved()

size_t lengthReserved
inline

Returns the number of elements allocated/reserved (as opposed to actually used) in the array.

175 {
176  return mReservedLen;
177 }

◆ setLengthReserved()

Array< T > & setLengthReserved ( size_t  length)

Sets the number of elements allocated/reserved (as opposed to actually used) in the array.

Parameters
[in]length- The new "reserved length" of the array.
Returns
A reference to 'this'.
462 {
463  DbgAssert(n >= 0);
464 
465  if(n != mReservedLen) {
466 
467  if(n == 0) {
468  if(mReservedLen > 0) {
471  mpArray = NULL;
472  mUsedLen = 0;
473  mReservedLen = 0;
474  }
475  }
476  else if(mReservedLen == 0) {
477  mpArray = ArrayAllocate(n);
478  if(mpArray == NULL) {
479  // Failure to allocate memory; can't increase the reserved length.
481  return *this;
482  }
483  mReservedLen = n;
484  }
485  else {
486  T* oldArray = mpArray;
487  size_t oldUsedLen = mUsedLen;
488 
489  // Allocate the new array
490  mpArray = ArrayAllocate(n);
491  if(mpArray == NULL) {
492  // Failure to allocate memory; can't change the reserved length.
494  mpArray = oldArray;
495  return *this;
496  }
497 
498  // Copy the old array to the new one.
499  if(n < mUsedLen) {
500  // The old members don't all fit in the new array
501  ArrayCopyConstruct(mpArray, n, oldArray, n);
502  mUsedLen = n;
503  }
504  else {
505  ArrayCopyConstruct(mpArray, n, oldArray, mUsedLen);
506  }
507  mReservedLen = n;
508 
509  // Destroy the old array
510  ArrayDestruct(oldArray, oldUsedLen);
511  ArrayDeAllocate(oldArray);
512  }
513  }
514 
515  return *this;
516 }

◆ reserve()

void reserve ( size_t  capacity)

Alias for setLengthReserved.

Sets the number of elements allocated/reserved (as opposed to actually used) in the array. Named to be similar to the STL containers.

Parameters
[in]capacity- The new "reserved length" or possible capacity of the array.
Returns
void
519 {
520  setLengthReserved(capacity);
521 }

◆ growLength()

size_t growLength
inline

Returns the growth length of the array.

For more information on the growth length, see setGrowLength().

180 {
181  return mGrowLen;
182 }

◆ setGrowLength()

Array< T > & setGrowLength ( size_t  glen)
inline

Sets the growth length of the array.

The growth length is the minimum number elements by which the reserved space is grown whenever the array runs out of reserved space.

345 {
346  DbgAssert(glen > 0);
347  if(glen > 0) {
348  mGrowLen = glen;
349  }
350  else {
351  DbgAssert(false);
352  // Growth length needs to be at least 1.
353  mGrowLen = 1;
354  }
355  return *this;
356 }

◆ reverse()

Array< T > & reverse

Reverses the sequence of elements in the array.

Reverses the sequence of elements in the array such that the last element becomes the first.

Returns
A reference to 'this'.
528 {
529  size_t halfUsedLen = mUsedLen/2;
530  for (size_t i = 0; i < halfUsedLen; i++) {
531  T tmp = mpArray[i];
532  mpArray[i] = mpArray[mUsedLen - 1 - i];
533  mpArray[mUsedLen - 1 - i] = tmp;
534  }
535  return *this;
536 }

◆ swap()

Array< T > & swap ( size_t  i1,
size_t  i2 
)

Swaps two elements in this array.

Parameters
[in]i1- The index of the first element to swap. This index must be within bounds.
[in]i2- The index of the second element to swap. This index must be within bounds.
541 {
542  DbgAssert(isValidIndex(i1));
543  DbgAssert(isValidIndex(i2));
544 
545  if (i1 == i2) return *this;
546 
547  T tmp = mpArray[i1];
548  mpArray[i1] = mpArray[i2];
549  mpArray[i2] = tmp;
550  return *this;
551 }

◆ sort()

void sort ( CompareFnc  cmp)

Sorts the elements of the array using a custom comparison function.

The sort if performed with the QuickSort algorithm.

Parameters
[in]cmp- The comparison function used to order the elements.
See also
CompareFnc
570 {
571  if (mUsedLen > 1)
572  {
573  // Use the standard C function if the type is trivial
574  // (meaning that memcpy() is safe)
575  if (std::is_trivial<T>::value)
576  {
577  qsort(mpArray, mUsedLen, sizeof(T), cmp);
578  }
579  else
580  {
581  quickSortRecursive(mpArray, 0, mUsedLen - 1, cmp);
582  }
583  }
584 }
static void quickSortRecursive(T *data, size_t first, size_t last, CompareFnc cmp)
Recursive QuickSort function used to sort the elements of the array.
Definition: Array.imp.h:619

◆ asArrayPtr() [1/2]

const T * asArrayPtr
inline

Returns the array storage as a C-style array pointer.

Remarks
Any modification to the contents of the array, through this pointer, may be dangerous.
185 {
186  return mpArray;
187 }

◆ asArrayPtr() [2/2]

T * asArrayPtr
inline

Accesses the first element in the array.

Returns
A reference to the first element of the array.
Remarks
It is invalid to call this on an empty array.
190 {
191  return mpArray;
192 }

◆ isValidIndex()

bool isValidIndex ( size_t  i) const
inline

Returns whether the given array index is valid for this array.

Returns
true if the given index is within the bounds of this array; false otherwise.
195 {
196  // We should prohibit index's that are the maximum size_t value
197  return (i != (size_t)-1) && i < mUsedLen;
198 }

◆ quickSortPartition()

size_t quickSortPartition ( T *  data,
size_t  first,
size_t  last,
CompareFnc  cmp 
)
staticprotected

The partition portion of the QuickSort algorithm.

588 {
589  const T& pivot = data[last]; // use the last item as the pivot
590  size_t left = first; // sort from the first item
591  size_t right = last - 1; // sort to the item excluding the pivot
592 
593  do {
594  while ((left < last) && (cmp(&(data[left]), &pivot) <= 0))
595  {
596  ++left;
597  }
598  while ((right > first) && (cmp(&(data[right]), &pivot) >= 0))
599  {
600  --right;
601  }
602  if (left < right) {
603  T swapValue = data[left];
604  data[left] = data[right];
605  data[right] = swapValue;
606  }
607  } while (left < right);
608 
609  if (cmp(&data[left], &pivot) > 0)
610  {
611  T swapValue = data[left];
612  data[left] = data[last];
613  data[last] = swapValue;
614  }
615 
616  return left;
617 }
T & first()
Accesses the first element in the array.
Definition: Array.inline.h:251
T & last()
Accesses the last element in the array.
Definition: Array.inline.h:282

◆ quickSortRecursive()

void quickSortRecursive ( T *  data,
size_t  first,
size_t  last,
CompareFnc  cmp 
)
staticprotected

Recursive QuickSort function used to sort the elements of the array.

620 {
621  if (first < last)
622  {
623  size_t pivot_position = quickSortPartition(data, first, last, cmp);
624 
625  // Protect against overflow. Normally the "if (first < last)" test would
626  // guard against this, but size_t is unsigned, meaning "right - 1" can result
627  // in a test of -1 > 0 when right is 0, which is an invalid unsigned inequality.
628  if (pivot_position > 0)
629  {
630  quickSortRecursive(data, first, pivot_position - 1, cmp);
631  }
632  quickSortRecursive(data, pivot_position + 1, last, cmp);
633  }
634 }
static size_t quickSortPartition(T *data, size_t first, size_t last, CompareFnc cmp)
The partition portion of the QuickSort algorithm.
Definition: Array.imp.h:587

◆ handleOutOfMemory()

void handleOutOfMemory
inlinestaticprotected

Utility function, called when the array fails to allocate memory.

359  {
360 
361  DbgAssert(false);
363 }
UtilExport void UtilOutOfMemoryException()

◆ ArrayAllocate()

T * ArrayAllocate ( size_t  len)
inlinestaticprotected

Allocates an array of elements without constructing them.

22 {
23  DbgAssert(len < 0x40000000); // 1G sanity check
24  T* p = (T*) UtilAllocateMemory(len * sizeof(T));
25  return p;
26 }
UtilExport void * UtilAllocateMemory(size_t)

◆ ArrayConstruct()

void ArrayConstruct ( T *  arrayBegin,
size_t  len,
const T &  defaultVal 
)
inlinestaticprotected

Constructs an array of elements.

35 {
36  for(size_t i = 0; i < len; ++i)
37  {
38  new(&(arrayBegin[i])) T(defaultVal);
39  }
40 }

◆ ArrayDeAllocate()

void ArrayDeAllocate ( T *  arrayBegin)
inlinestaticprotected

De-allocates an array of elements without destructing them.

44 {
45  UtilDeallocateMemory(arrayBegin);
46 }
UtilExport void UtilDeallocateMemory(void *)

◆ ArrayDestruct()

void ArrayDestruct ( T *  arrayBegin,
size_t  len 
)
inlinestaticprotected

Destructs an array of elements.

51 {
52  if (!std::is_trivially_destructible<T>::value)
53  {
54  for (size_t i = 0; i < len; ++i)
55  {
56  arrayBegin[i].~T();
57  }
58  }
59 }

◆ ArrayCopy()

void ArrayCopy ( T *  pCopy,
size_t  nMaxCount,
const T *  pSource,
size_t  nCount 
)
staticprotected

Copies an array of elements to an already-constructed buffer.

Will use the copy operator if needed.

63 {
64  // Auto-detect whether it's safe to use memcpy() or whether we need
65  // to call the copy operator. We're counting on the fact that this condition,
66  // being resolvable at compile-time, will be removed by the optimizer.
67  if (std::is_copy_assignable<T>::value)
68  {
69  // Type has an assignment operator; use it.
70  for (size_t i = 0; i < nCount; ++i)
71  {
72  pCopy[i] = (pSource[i]);
73  }
74  }
75  else
76  {
77  // Type does not have an assignment operator; use memcpy() as it's usually faster.
78  if (nCount > 0)
79  {
80  memcpy_s(pCopy, nMaxCount * sizeof(T), pSource, nCount * sizeof(T));
81  }
82  }
83 }

◆ ArrayCopyOverlap()

void ArrayCopyOverlap ( T *  pCopy,
size_t  nMaxCount,
const T *  pSource,
size_t  nCount 
)
staticprotected

Copies an array of elements when the target and destination memory buffers may overlap.

86 {
87  // Auto-detect whether it's safe to use memcpy() or whether we need
88  // to call the copy operator. We're counting on the fact that this condition,
89  // being resolvable at compile-time, will be removed by the optimizer.
90  if (std::is_copy_assignable<T>::value)
91  {
92  // Type has an assignment operator; use it.
93  if (pCopy == pSource)
94  {
95  // nothing to do here, bail early
96  return;
97  }
98 
99  if (pCopy < pSource)
100  {
101  // forward iteration
102  for (size_t i = 0; i < nCount; i++)
103  {
104  pCopy[i] = pSource[i];
105  }
106  }
107  else
108  {
109  // backward iteration
110  for (size_t i = nCount - 1; i != (size_t)-1; --i)
111  {
112  pCopy[i] = pSource[i];
113  }
114  }
115  }
116  else
117  {
118  // Type does not have an assignment operator; use memmove() as it's usually faster.
119  if (nCount > 0)
120  {
121  memmove_s(pCopy, nMaxCount * sizeof(T), pSource, nCount * sizeof(T));
122  }
123  }
124 }
MAXMEM_EXTERN_C UtilExport size_t(__cdecl *MAX_msize)(void *memblock)

◆ ArrayCopyConstruct()

void ArrayCopyConstruct ( T *  pCopy,
size_t  nMaxCount,
const T *  pSource,
size_t  nCount 
)
staticprotected

Copies and array of elements to a non-constructed.

Will use the copy constructor if needed.

129 {
130  // Auto-detect whether it's safe to use memcpy() or whether we need
131  // to call the copy operator. We're counting on the fact that this condition,
132  // being resolvable at compile-time, will be removed by the optimizer.
133  if (std::is_copy_constructible<T>::value)
134  {
135  // Type has an assignment operator; use it.
136  for (size_t i = 0; i < nCount; ++i)
137  {
138  new(&(pCopy[i])) T(pSource[i]); // using placement new.
139  }
140  }
141  else
142  {
143  // Type does not have an assignment operator; use memcpy() as it's usually faster.
144  if (nCount > 0)
145  {
146  memcpy_s(pCopy, nMaxCount * sizeof(T), pSource, nCount * sizeof(T));
147  }
148  }
149 }

Member Data Documentation

◆ mpArray

T* mpArray
protected

Pointer to the storage buffer.

◆ mReservedLen

size_t mReservedLen
protected

The reserved length (in number of elements, not bytes).

◆ mUsedLen

size_t mUsedLen
protected

The used length (in number of elements, not bytes).

◆ mGrowLen

size_t mGrowLen
protected

The growth length. See setGrowLength().