Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cArray.h
Go to the documentation of this file.
1 //
5 //
6 
7 #ifndef _INC_cArray_H
8 #define _INC_cArray_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "cHeap.h"
14 #include "cObject.h"
15 #include "cValT.h"
16 #ifdef _MFC_VER
17 #include <afxtempl.h> // CArray
18 #else
19 #include <new> // STL overload the new operator to allow call of constructor directly.
20 #endif
21 
22 namespace Gray
23 {
24  // similar to BOOST_FOREACH()
25 #define GRAY_FOREACH( _ITYPE, i, a ) for ( ITERATE_t index_##i=0, _foreach_int=true; index_##i < a.GetSize(); index_##i++, _foreach_int=true ) \
26  for ( _ITYPE i=a[index_##i]; _foreach_int; _foreach_int=false )
27 
28 #ifndef _MFC_VER
29 
30  template <class TYPE>
31  void __cdecl ConstructElements(TYPE* pElements, ITERATE_t nCount)
32  {
36 
37  if (nCount <= 0)
38  return;
39 
40 #ifdef _DEBUG
41  ASSERT(cMem::IsValid(pElements, nCount * sizeof(TYPE), true));
42  // for debug. first do bit-wise init (or zero) initialization
43  cValArray::FillSize<BYTE>(pElements, nCount * sizeof(TYPE), cHeap::FILL_Alloc);
44 #endif
45 
46  for (; (nCount--) != 0; pElements++)
47  {
48  ::new((void*)pElements) TYPE;
49  }
50  }
51 
52  template <class TYPE>
53  void __cdecl DestructElements(TYPE* pElements, ITERATE_t nCount)
54  {
56  if (nCount <= 0)
57  return;
58 
59 #ifdef _DEBUG
60  ASSERT(cMem::IsValid(pElements, nCount * sizeof(TYPE), true));
61  const ITERATE_t nCountPrev = nCount; // just for debug
62  UNREFERENCED_PARAMETER(nCountPrev);
63 #endif
64 
65  for (; (nCount--) != 0; pElements++)
66  {
67  (pElements)->~TYPE();
68  }
69  }
70 
71  template <class TYPE>
72  void __cdecl CopyElements(TYPE* pDest, const TYPE* pSrc, ITERATE_t nCount)
73  {
75  if (nCount <= 0)
76  return;
77 
78  ASSERT(cMem::IsValid(pDest, nCount * sizeof(TYPE), true));
79  ASSERT(cMem::IsValid(pSrc, nCount * sizeof(TYPE), false));
80 
81  while ((nCount--) != 0)
82  {
83  *pDest++ = *pSrc++;
84  }
85  }
86 
87  // Override implementation of templates
88  template <>
89  inline void __cdecl CopyElements<BYTE>(BYTE* pDest, const BYTE* pSrc, ITERATE_t nCount)
90  {
92  cMem::Copy(pDest, pSrc, nCount);
93  }
94 
96 
97  template <class TYPE, class ARG_TYPE = const TYPE& >
98  class CArray : public CObject
99  {
104 
106 
107  protected:
110 
111  protected:
112  bool IsValidIndex(ITERATE_t i) const noexcept
113  {
114  return IS_INDEX_GOOD(i, this->m_nSize);
115  }
116 
117  public:
118  CArray() noexcept
119  : m_pData(nullptr)
120  , m_nSize(0)
121  {
122  }
123  CArray(THIS_t&& ref) noexcept
124  {
126  m_pData = ref.m_pData; ref.m_pData = nullptr;
127  m_nSize = ref.m_nSize; ref.m_nSize = 0;
128  }
129  virtual ~CArray()
130  {
131  RemoveAll();
132  }
133 
134  bool IsValidMallocSize() const noexcept;
135 
136  // Attributes
137  inline ITERATE_t GetSize() const noexcept
138  {
139  return m_nSize;
140  }
141  inline ITERATE_t GetUpperBound() const noexcept
142  {
143  return m_nSize - 1;
144  }
145  bool IsEmpty() const noexcept
146  {
147  return this->m_nSize <= 0;
148  }
149  void SetSize(ITERATE_t nNewSize);
150  ITERATE_t GetMallocSize() const noexcept
151  {
154  return (ITERATE_t)(cHeap::GetSize(m_pData) / sizeof(TYPE));
155  }
156 
157  // Operations
159  void RemoveAll();
160 
161  // Accessing elements
162  const TYPE& GetAt(ITERATE_t nIndex) const
163  {
164  ASSERT(IsValidIndex(nIndex));
165  return m_pData[nIndex];
166  }
168  {
169  ASSERT(IsValidIndex(nIndex));
170  return m_pData[nIndex];
171  }
172 
173  void SetAt(ITERATE_t nIndex, ARG_TYPE newElement) // throw
174  {
176  ASSERT(IsValidIndex(nIndex));
177  m_pData[nIndex] = newElement; // may call a copy constructor.
178  }
179 
180  // Direct Access to the element data (may return nullptr)
181  inline const TYPE* GetData() const
182  {
183  return m_pData;
184  }
185  inline TYPE* GetData()
186  {
187  return m_pData;
188  }
189  void SetDataArrayPtr(TYPE* pData, ITERATE_t nSize)
190  {
192  ASSERT(!cMem::IsCorrupt(pData, nSize));
193  m_pData = pData;
194  m_nSize = nSize;
195  }
196 
197  // Potentially growing the array
198  void SetAtGrow(ITERATE_t nIndex, ARG_TYPE newElement);
199  ITERATE_t Add(ARG_TYPE newElement)
200  {
202  const ITERATE_t nIndex = m_nSize;
203  SetAtGrow(nIndex, newElement);
204  return nIndex;
205  }
206 
207  void Copy(const CArray& src);
208 
209  // overloaded operator helpers
210  inline TYPE& operator[](ITERATE_t nIndex)
211  {
212  return ElementAt(nIndex);
213  }
214  inline const TYPE& operator[](ITERATE_t nIndex) const
215  {
216  return GetAt(nIndex);
217  }
218 
219  // Operations that move elements around
220  void InsertAt(ITERATE_t nIndex, ARG_TYPE newElement);
221  void RemoveAt(ITERATE_t nIndex);
222  void RemoveAt(ITERATE_t nIndex, ITERATE_t iQty);
223 
224  void MoveElement(ITERATE_t iFrom, ITERATE_t iTo); // throw
225  };
226 
227  //************************************************************************
228 
229  template <class TYPE, class ARG_TYPE>
231  {
234 #ifdef _DEBUG
235  // AssertSize();
236 #endif
237  const ITERATE_t iSize = m_nSize;
238  m_nSize = 0;
239  if (m_pData != nullptr)
240  {
241  DestructElements<TYPE>(m_pData, iSize);
242  cHeap::FreePtr((void*)(m_pData)); // const_cast
243  m_pData = nullptr;
244  }
245  }
246 
247  template <class TYPE, class ARG_TYPE>
249  {
251  ASSERT_VALID(this);
252  ASSERT(nNewSize >= 0);
253  if (nNewSize <= 0)
254  {
255  // shrink to nothing but keep any allocated memory.
256  goto do_try_resize;
257  }
258  else if (m_pData == nullptr)
259  {
260  // create one with exact size
261  m_pData = (TYPE*)cHeap::AllocPtr(nNewSize * sizeof(TYPE));
262  ASSERT(m_pData != nullptr);
263  ConstructElements<TYPE>(m_pData, nNewSize);
264  }
265  else if (nNewSize <= GetMallocSize())
266  {
267  // it fits. don't shrink the allocated array. we may expand again some day.
268  do_try_resize:
269  if (nNewSize > m_nSize)
270  {
271  // initialize the new elements
272  ConstructElements<TYPE>(&m_pData[m_nSize], nNewSize - m_nSize);
273  }
274  else if (m_nSize > nNewSize)
275  {
276  // destroy the old elements
277  DestructElements<TYPE>(&m_pData[nNewSize], m_nSize - nNewSize);
278  }
279  }
280  else
281  {
282  // otherwise, grow array
283  // MFC will heuristically determine growth when nGrowBy == 0 (this avoids heap fragmentation in many situations)
284 #if 1
285  m_pData = (TYPE*)cHeap::ReAllocPtr(m_pData, (nNewSize + (nNewSize / 16)) * sizeof(TYPE));
286 #else
287  m_pData = (TYPE*)cHeap::ReAllocPtr(m_pData, nNewSize * sizeof(TYPE));
288 #endif
289  ASSERT_N(m_pData != nullptr);
290 
291  // construct remaining elements
292  ASSERT(nNewSize > m_nSize);
293  ConstructElements<TYPE>(&m_pData[m_nSize], nNewSize - m_nSize);
294  }
295  m_nSize = nNewSize;
296  }
297 
298  template <class TYPE, class ARG_TYPE>
300  {
301  ASSERT_VALID(this);
302  ASSERT(this != &src); // ASSUME Not copy to self.
303  SetSize(src.m_nSize);
304  CopyElements<TYPE>(m_pData, src.m_pData, src.m_nSize);
305  }
306 
307  template <class TYPE, class ARG_TYPE>
308  void CArray<TYPE, ARG_TYPE>::SetAtGrow(ITERATE_t nIndex, ARG_TYPE newElement)
309  {
310  ASSERT_VALID(this);
311  ASSERT(nIndex >= 0);
312  if (nIndex < m_nSize)
313  {
314  m_pData[nIndex] = newElement;
315  return;
316  }
317 
318  SetSize(nIndex + 1);
319  ASSERT_N(m_pData != nullptr);
320  m_pData[nIndex] = newElement;
321  }
322 
323  template <class TYPE, class ARG_TYPE>
325  {
329  BYTE bTmp[sizeof(TYPE)];
330  ASSERT(IsValidIndex(iFrom));
331  cMem::Copy(bTmp, &m_pData[iFrom], sizeof(TYPE));
332  // shift old data to fill gap
333  ASSERT(IsValidIndex(iTo));
334  cMem::CopyOverlap(&m_pData[iTo + 1], &m_pData[iTo],
335  (iFrom - iTo) * sizeof(TYPE));
336  // re-init slots we copied from
337  cMem::Copy(&m_pData[iTo], bTmp, sizeof(TYPE));
338  }
339 
340  template <class TYPE, class ARG_TYPE>
341  void CArray<TYPE, ARG_TYPE>::InsertAt(ITERATE_t nIndex, ARG_TYPE newElement)
342  {
344  ASSERT_VALID(this);
345  ASSERT(nIndex >= 0); // will expand to meet need
346 
347  if (nIndex >= m_nSize)
348  {
349  // adding after the end of the array
350  SetSize(nIndex + 1); // grow so nIndex is valid
351  }
352  else
353  {
354  // inserting in the middle of the array
355  ITERATE_t nOldSize = m_nSize;
356  SetSize(m_nSize + 1); // grow it to new size
357  // destroy initial data before copying over it (inefficient i know but is very convenient)
358  MoveElement(nOldSize, nIndex);
359  }
360 
361  // insert new value in the gap
362  ASSERT(nIndex + 1 <= m_nSize);
363  m_pData[nIndex] = newElement; // ASSUME copy constructor will be called!
364  }
365 
366  template <class TYPE, class ARG_TYPE>
368  {
369  // NOTE: Any destructor effecting the array will be reentrant ?!
370  ASSERT_VALID(this);
371  if (nIndex < 0)
372  return;
373  ITERATE_t nMoveCount = m_nSize - (nIndex + 1);
374  if (nMoveCount < 0)
375  return;
376  DestructElements<TYPE>(&m_pData[nIndex], 1);
377  m_nSize--;
378  if (nMoveCount > 0) // not last.
379  {
380  cMem::CopyOverlap(&m_pData[nIndex], &m_pData[nIndex + 1], nMoveCount * sizeof(TYPE));
381  }
382  }
383 
384  template <class TYPE, class ARG_TYPE>
386  {
387  // NOTE: Any destructor effecting the array will be reentrant ?!
388  ASSERT_VALID(this);
389  if (iQty <= 0 || nIndex < 0)
390  return;
391  ITERATE_t nMoveCount = m_nSize - (nIndex + iQty);
392  if (nMoveCount < 0) // iQty beyond the end!
393  {
394  ASSERT(nMoveCount >= 0);
395  nMoveCount = 0; // Last element.
396  iQty = m_nSize - nIndex;
397  }
398  if (iQty >= m_nSize)
399  {
400  // ASSERT(nIndex == 0); // assumed.
401  RemoveAll();
402  return;
403  }
404  // just remove a range
405  DestructElements<TYPE>(&m_pData[nIndex], iQty);
406  if (nMoveCount > 0) // not last.
407  {
408  cMem::CopyOverlap(&m_pData[nIndex], &m_pData[nIndex + iQty], nMoveCount * sizeof(TYPE));
409  }
410  m_nSize -= iQty;
411  }
412 
413  template <class TYPE, class ARG_TYPE>
415  {
416  // Make sure the alloc is actually bigger than the declared size.
417  if (m_pData == nullptr)
418  {
419  if (m_nSize != 0)
420  return false;
421  }
422  else
423  {
424  // ASSERT(m_nSize>0);
425  if (m_nSize > GetMallocSize()) // NOTE: GetMallocSize will check m_pData
426  return false;
427  }
428  return true;
429  }
430 
431 #endif // _MFC_VER
432 
433  //*************************************************
434 
435  template <class TYPE, class ARG_TYPE = const TYPE&>
436  class cArrayTyped : public CArray < TYPE, ARG_TYPE >
437  {
441  public:
444 
445  typedef ITERATE_t iterator; // like STL
446  typedef ITERATE_t const_iterator; // like STL
447 
448  typedef TYPE ELEM_t;
449  typedef ARG_TYPE REF_t;
450 
451  protected:
452  virtual COMPARE_t CompareData(REF_t Data1, REF_t Data2) const noexcept
453  {
457  // return cValT::Compare(Data1,Data2);
458  return cMem::Compare(&Data1, &Data2, sizeof(Data1)); // should we use use cValT::Compare()??
459  }
460 
462  void QSort(ITERATE_t iLeft, ITERATE_t iRight);
463 
464  public:
465  cArrayTyped() noexcept
466  {
467  }
468  cArrayTyped(const THIS_t& rArray)
469  {
471  this->SetSize(rArray.GetSize());
472  CopyElements(this->GetData(), rArray.GetData(), this->GetSize());
473  }
474  explicit cArrayTyped(ITERATE_t iSize)
475  {
476  this->SetSize(iSize);
477  }
478  virtual ~cArrayTyped()
479  {
480  }
481 
482  bool isValidCheck() const noexcept
483  {
484  if (!COBJECT_IsValidCheck())
485  return false;
486  // ASSERT( ISTYPE_OF(CArray<TYPE, ARG_TYPE>,this));
487 #ifndef _MFC_VER
488  if (!this->IsValidMallocSize())
489  return false;
490 #endif
491  return true;
492  }
493 
494  // New
495  bool IsValidIndex(ITERATE_t i) const noexcept
496  {
497  return IS_INDEX_GOOD(i, this->m_nSize);
498  }
500  {
502  if (i < 0)
503  i = 0;
504  if (i >= this->m_nSize)
505  return(this->m_nSize - 1);
506  return i;
507  }
508  size_t GetHeapStats(OUT ITERATE_t& iAllocCount) const noexcept
509  {
511  if (this->m_pData == nullptr)
512  return 0;
513  iAllocCount++; // just the alloc for the array
514  return cHeap::GetSize(this->m_pData);
515  }
516 
517  void AssertValidIndex(ITERATE_t nIndex) const
518  {
519  ASSERT_THROW(IsValidIndex(nIndex));
520  }
521  const TYPE& GetAtSecure(ITERATE_t nIndex) const // throw
522  {
524  AssertValidIndex(nIndex);
525  return this->m_pData[nIndex];
526  }
527  TYPE& ElementAtSecure(ITERATE_t nIndex) // throw
528  {
530  AssertValidIndex(nIndex);
531  return this->m_pData[nIndex];
532  }
533 
534  REF_t ConstElementAt(ITERATE_t nIndex) const // throw
535  {
536  // Same as GetAt ?
537  AssertValidIndex(nIndex);
538  return this->m_pData[nIndex];
539  }
540  inline TYPE& operator[](ITERATE_t nIndex) // throw
541  {
542  return this->ElementAt(nIndex);
543  }
544  inline const TYPE& operator[](ITERATE_t nIndex) const // throw
545  {
546  // Const array should return const values.
547  AssertValidIndex(nIndex);
548  return this->m_pData[nIndex];
549  }
550 
551  TYPE& Head() // throw
552  {
553  return this->ElementAt(0);
554  }
556  {
557  return this->ElementAt(this->GetSize() - 1);
558  }
560  {
561  return this->ElementAt(0);
562  }
564  {
565  return this->ElementAt(this->GetSize() - 1);
566  }
567  REF_t ConstHead() const
568  {
569  return ConstElementAt(0);
570  }
571  REF_t ConstTail() const
572  {
573  return ConstElementAt(this->GetSize() - 1);
574  }
575 
576  REF_t GetAtTail()
577  {
578  return this->GetAt(this->GetSize() - 1);
579  }
580 
581  void UnLinkIndex(ITERATE_t nIndex)
582  {
585  ASSERT(IsValidIndex(nIndex));
586  cMem::CopyOverlap(&(this->m_pData[nIndex]), &(this->m_pData[nIndex + 1]), ((this->m_nSize - nIndex) - 1) * sizeof(TYPE));
587  this->m_nSize--;
588  if (this->m_nSize == 0)
589  this->RemoveAll();
590  }
592  {
594  if (i == j)
595  return;
596  cMem::Swap((BYTE*)&this->ElementAt(i), (BYTE*)&(this->ElementAt(j)), sizeof(TYPE));
597  }
599  {
601  if (this == &aValues)
602  return;
603  this->RemoveAll(); // destruct any previous data.
604  this->SetSize(aValues.GetSize());
605  CopyElements(this->GetData(), aValues.GetData(), this->GetSize());
606  }
607 
609  {
610  SetCopy(aValues);
611  return *this;
612  }
613 
614  ITERATE_t FindIFor(ARG_TYPE arg) const
615  {
618  for (ITERATE_t nIndex = 0; nIndex < this->GetSize(); nIndex++)
619  {
620  if (this->m_pData[nIndex] == arg)
621  return nIndex;
622  }
623  return k_ITERATE_BAD;
624  }
625  bool HasArg(ARG_TYPE arg) const
626  {
628  return FindIFor(arg) >= 0;
629  }
630 
631  void RemoveLast()
632  {
633  this->RemoveAt((this->GetSize()) - 1);
634  }
635  ELEM_t PopHead()
636  {
637  ASSERT(this->GetSize() > 0);
638  ELEM_t tmp = this->GetAt(0); // copy it.
639  this->RemoveAt(0);
640  return tmp;
641  }
643  {
644  ASSERT(this->GetSize() > 0);
645  ITERATE_t i = (this->GetSize()) - 1;
646  ELEM_t tmp = this->GetAt(i); // copy it.
647  this->RemoveAt(i);
648  return tmp;
649  }
650  bool RemoveArg(ARG_TYPE arg)
651  {
653  ITERATE_t nIndex = FindIFor(arg);
654  if (nIndex < 0)
655  return false;
656  this->RemoveAt(nIndex);
657  return true;
658  }
659  void UnLinkArg(ARG_TYPE arg)
660  {
661  ITERATE_t nIndex = FindIFor(arg);
662  if (nIndex < 0)
663  return;
664  UnLinkIndex(nIndex);
665  }
666  ITERATE_t AddTail(ARG_TYPE newElement) // a "Push"
667  {
668  // add to tail. alias
669  return this->Add(newElement);
670  }
671  ITERATE_t PushTail(ARG_TYPE newElement)
672  {
673  // add to tail. alias
674  return this->Add(newElement);
675  }
676  void AddHead(ARG_TYPE newElement)
677  {
678  // NOT a normal stack or queue. Adds are usually to the tail.
679  this->InsertAt(0, newElement);
680  }
681 
683  {
684  return this->m_pData;
685  }
686 
687  void AddArray(const SUPER_t& src)
688  {
691  ASSERT_VALID(this);
692  ASSERT(this != &src); // cannot append to itself
693  ITERATE_t nOldSize = this->GetSize();
694  ITERATE_t nSrcSize = src.GetSize();
695  if (nSrcSize > 0)
696  {
697  this->SetSize(nOldSize + nSrcSize);
698  CopyElements<TYPE>(this->GetData() + nOldSize, src.GetData(), nSrcSize);
699  }
700  }
701 
702  bool IsEqualArray(const SUPER_t& aValues) const
703  {
707  if (this == &aValues)
708  return true;
709  if (this->GetSize() != aValues.GetSize())
710  return false;
711  for (ITERATE_t i = 0; i < this->GetSize(); i++)
712  {
713  if (!(this->GetAt(i) == aValues.GetAt(i))) // Assume everything supports the == operator.
714  return false;
715  }
716  return true; // looks the same to me.
717  }
718 
719  bool isArraySorted() const;
720  bool isArraySortedND() const; // no dupes
721 
722  void QSort()
723  {
724  ITERATE_t iSize = this->GetSize() - 1;
725  if (iSize <= 0)
726  return;
727  QSort(0, iSize);
728  }
729  };
730 
731  template<class TYPE, class ARG_TYPE>
733  {
735  ITERATE_t iQty = this->GetSize() - 1;
736  for (ITERATE_t i = 0; i < iQty; i++)
737  {
738  REF_t a = this->ConstElementAt(i);
739  REF_t b = this->ConstElementAt(i + 1);
740  if (CompareData(a, b) > 0)
741  {
742  return false;
743  }
744  }
745  return true;
746  }
747 
748  template<class TYPE, class ARG_TYPE>
750  {
752  ITERATE_t iQty = this->GetSize() - 1;
753  for (ITERATE_t i = 0; i < iQty; i++)
754  {
755  const TYPE& a = this->ConstElementAt(i);
756  const TYPE& b = this->ConstElementAt(i + 1);
757  if (CompareData(a, b) >= 0)
758  {
759  return false;
760  }
761  }
762  return true;
763  }
764 
765  template<class TYPE, class ARG_TYPE>
767  {
768  ASSERT(iLeft < iRight);
769  for (;;)
770  {
771  // Do right side.
772  while (iLeft < iRight && CompareData(this->ElementAt(iLeft), this->ElementAt(iRight)) <= COMPARE_Equal) // skip stuff already in order.
773  iRight--;
774  if (iLeft >= iRight)
775  break;
776  this->Swap(iRight, iLeft);
777 
778  // Do left side.
779  while (iLeft < iRight && CompareData(this->ElementAt(iLeft), this->ElementAt(iRight)) <= COMPARE_Equal)
780  iLeft++;
781  if (iLeft >= iRight)
782  break;
783  this->Swap(iLeft, iRight);
784  }
785  return iLeft; // Next mid point.
786  }
787 
788  template<class TYPE, class ARG_TYPE>
790  {
793  ITERATE_t iMid = QSortPartition(iLeft, iRight);
794  if (iLeft < iMid - 1)
795  QSort(iLeft, iMid - 1);
796  if (iMid + 1 < iRight)
797  QSort(iMid + 1, iRight);
798  }
799 
800  //*************************************************
801 
802  template <class TYPE, class TYPE_ARG = TYPE*>
803  class cArrayFacade : public cArrayTyped < TYPE, TYPE_ARG >
804  {
808 
809  public:
812 
813  typedef typename SUPER_t::ELEM_t ELEM_t; // GCC needs this silliness.
814  typedef typename SUPER_t::REF_t REF_t; //
815 
816  public:
817  virtual ~cArrayFacade()
818  {
820  this->RemoveAll();
821  }
822 
823  virtual COMPARE_t CompareData(REF_t pData1, REF_t pData2) const noexcept override
824  {
826  // return cValT::Compare(Data1,Data2);
827  return cMem::Compare(pData1, pData2, sizeof(*pData2));
828  }
829 
830  REF_t GetAt(ITERATE_t index) const // Override
831  {
833  }
835  {
838  {
839  return nullptr;
840  }
842  }
843 
845  {
846  if (!SUPER_t::GetSize())
847  {
848  return nullptr;
849  }
850  return SUPER_t::PopHead();
851  }
853  {
854  if (!SUPER_t::GetSize())
855  {
856  return nullptr;
857  }
858  return SUPER_t::PopTail();
859  }
860  };
861 
862  template <class TYPE>
863  class cArrayPtr : public cArrayFacade < TYPE*, TYPE* >
864  {
868 
869  public:
871  typedef typename SUPER_t::REF_t REF_t; // How to refer to this? value or ref or pointer?
872  typedef typename SUPER_t::ELEM_t ELEM_t; // How to refer to this? value or ref or pointer?
873 
874  public:
876  {
878  REF_t pObj = this->GetAt(i);
879  this->RemoveAt(i);
880  delete pObj;
881  }
882  void DeleteAll()
883  {
886 
887  ITERATE_t iSize = this->GetSize();
888  if (iSize <= 0)
889  return;
890  {
891  // save original list, call DisposeThis on everything from original list
892  SUPER_t orig;
893  orig.SetCopy(*this);
894 
895  ASSERT(orig.GetSize() == iSize);
896  for (ITERATE_t i = iSize - 1; i >= 0; i--) // reverse order they got added?
897  {
898  REF_t pObj = orig.GetAt(i);
899  if (pObj != nullptr)
900  {
901  delete pObj;
902  }
903  }
904  }
906  }
907  };
908 
909  //*************************************************
910  // cArrayVal
911 
912  template<class TYPE>
913  class cArrayVal : public cArrayTyped < TYPE, TYPE >
914  {
918  public:
920  {
921  }
922  explicit cArrayVal(ITERATE_t iSize) : cArrayTyped<TYPE, TYPE>(iSize)
923  {
924  }
925  };
926 
927  //*************************************************
928  // cArrayStruct
929 
930  template<class TYPE>
931  class cArrayStruct : public cArrayTyped < TYPE, const TYPE& >
932  {
937  public:
938  cArrayStruct() noexcept
939  {
940  }
941  explicit cArrayStruct(ITERATE_t iSize) : cArrayTyped<TYPE, const TYPE&>(iSize)
942  {
943  }
944  };
945 }
946 #endif // _INC_cArray_H
#define IS_INDEX_GOOD(i, q)
cast the (likely) int to unsigned to check for negatives.
Definition: Index.h:35
#define TYPE
Definition: StrT.cpp:38
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define ASSERT_N(exp)
Definition: cDebugAssert.h:70
#define ASSERT_THROW(exp)
Definition: cDebugAssert.h:68
#define COBJECT_IsValidCheck()
Definition: cObject.h:64
#define ASSERT_VALID(p)
Definition: cObject.h:61
Definition: cArray.h:99
void RemoveAll()
Clean up.
Definition: cArray.h:230
CArray(THIS_t &&ref) noexcept
Definition: cArray.h:123
ITERATE_t m_nSize
Number of elements (upperBound - 1)
Definition: cArray.h:109
void SetAtGrow(ITERATE_t nIndex, ARG_TYPE newElement)
Definition: cArray.h:308
bool IsEmpty() const noexcept
Definition: cArray.h:145
const TYPE & GetAt(ITERATE_t nIndex) const
Definition: cArray.h:162
void SetAt(ITERATE_t nIndex, ARG_TYPE newElement)
Definition: cArray.h:173
virtual ~CArray()
Definition: cArray.h:129
TYPE & ElementAt(ITERATE_t nIndex)
Definition: cArray.h:167
ITERATE_t GetMallocSize() const noexcept
Definition: cArray.h:150
void SetDataArrayPtr(TYPE *pData, ITERATE_t nSize)
Definition: cArray.h:189
ITERATE_t GetUpperBound() const noexcept
Definition: cArray.h:141
TYPE * GetData()
Definition: cArray.h:185
void InsertAt(ITERATE_t nIndex, ARG_TYPE newElement)
Definition: cArray.h:341
TYPE & operator[](ITERATE_t nIndex)
Definition: cArray.h:210
bool IsValidMallocSize() const noexcept
Definition: cArray.h:414
bool IsValidIndex(ITERATE_t i) const noexcept
Definition: cArray.h:112
void MoveElement(ITERATE_t iFrom, ITERATE_t iTo)
Definition: cArray.h:324
ITERATE_t Add(ARG_TYPE newElement)
Definition: cArray.h:199
TYPE * m_pData
the actual array of data
Definition: cArray.h:108
ITERATE_t GetSize() const noexcept
Definition: cArray.h:137
void RemoveAt(ITERATE_t nIndex)
Definition: cArray.h:367
const TYPE & operator[](ITERATE_t nIndex) const
Definition: cArray.h:214
void Copy(const CArray &src)
Definition: cArray.h:299
void RemoveAt(ITERATE_t nIndex, ITERATE_t iQty)
Definition: cArray.h:385
const TYPE * GetData() const
Definition: cArray.h:181
void SetSize(ITERATE_t nNewSize)
Definition: cArray.h:248
CArray() noexcept
Definition: cArray.h:118
Definition: cObject.h:67
Definition: cArray.h:804
TYPE PopHead()
Definition: cArray.h:844
virtual COMPARE_t CompareData(REF_t pData1, REF_t pData2) const noexcept override
Definition: cArray.h:823
REF_t GetAtCheck(ITERATE_t index) const
Definition: cArray.h:834
cArrayTyped< TYPE, TYPE_ARG > SUPER_t
Definition: cArray.h:810
SUPER_t::ELEM_t ELEM_t
Definition: cArray.h:813
REF_t GetAt(ITERATE_t index) const
Definition: cArray.h:830
virtual ~cArrayFacade()
Definition: cArray.h:817
SUPER_t::REF_t REF_t
Definition: cArray.h:814
cArrayFacade< TYPE, TYPE_ARG > THIS_t
Definition: cArray.h:811
TYPE PopTail()
Definition: cArray.h:852
Definition: cArray.h:864
void DeleteAt(ITERATE_t i)
Definition: cArray.h:875
SUPER_t::REF_t REF_t
Definition: cArray.h:871
cArrayFacade< TYPE *, TYPE * > SUPER_t
Definition: cArray.h:870
void DeleteAll()
Definition: cArray.h:882
SUPER_t::ELEM_t ELEM_t
Definition: cArray.h:872
Definition: cArray.h:932
cArrayStruct() noexcept
Definition: cArray.h:938
cArrayStruct(ITERATE_t iSize)
Definition: cArray.h:941
Definition: cArray.h:437
void RemoveLast()
Definition: cArray.h:631
virtual COMPARE_t CompareData(REF_t Data1, REF_t Data2) const noexcept
Definition: cArray.h:452
REF_t ConstElementAt(ITERATE_t nIndex) const
Definition: cArray.h:534
TYPE & operator[](ITERATE_t nIndex)
Definition: cArray.h:540
void QSort()
Definition: cArray.h:722
REF_t ConstHead() const
Definition: cArray.h:567
size_t GetHeapStats(OUT ITERATE_t &iAllocCount) const noexcept
Definition: cArray.h:508
bool isArraySortedND() const
Definition: cArray.h:749
const TYPE & operator[](ITERATE_t nIndex) const
Definition: cArray.h:544
ITERATE_t PushTail(ARG_TYPE newElement)
Definition: cArray.h:671
void UnLinkArg(ARG_TYPE arg)
Definition: cArray.h:659
void AddArray(const SUPER_t &src)
Definition: cArray.h:687
const cArrayTyped< TYPE, ARG_TYPE > & operator=(const cArrayTyped< TYPE, ARG_TYPE > &aValues)
Definition: cArray.h:608
void AddHead(ARG_TYPE newElement)
Definition: cArray.h:676
TYPE & Head()
Definition: cArray.h:551
cArrayTyped(const THIS_t &rArray)
Definition: cArray.h:468
void SetCopy(const cArrayTyped< TYPE, ARG_TYPE > &aValues)
Definition: cArray.h:598
REF_t GetAtTail()
Definition: cArray.h:576
ITERATE_t ClampValidIndex(ITERATE_t i) const noexcept
Definition: cArray.h:499
TYPE & ElementAtHead()
Definition: cArray.h:559
void AssertValidIndex(ITERATE_t nIndex) const
Definition: cArray.h:517
cArrayTyped< TYPE, ARG_TYPE > THIS_t
Definition: cArray.h:443
REF_t ConstTail() const
Definition: cArray.h:571
bool HasArg(ARG_TYPE arg) const
Definition: cArray.h:625
bool IsValidIndex(ITERATE_t i) const noexcept
Definition: cArray.h:495
ARG_TYPE REF_t
How to refer to this? value or ref or pointer?
Definition: cArray.h:449
bool RemoveArg(ARG_TYPE arg)
Definition: cArray.h:650
TYPE & ElementAtSecure(ITERATE_t nIndex)
Definition: cArray.h:527
cArrayTyped() noexcept
Definition: cArray.h:465
TYPE & Tail()
Definition: cArray.h:555
TYPE & ElementAtTail()
Definition: cArray.h:563
bool isValidCheck() const noexcept
< memory allocation and structure definitions are valid.
Definition: cArray.h:482
virtual ~cArrayTyped()
Definition: cArray.h:478
ITERATE_t QSortPartition(ITERATE_t iLeft, ITERATE_t iRight)
Definition: cArray.h:766
bool IsEqualArray(const SUPER_t &aValues) const
Definition: cArray.h:702
ITERATE_t iterator
Definition: cArray.h:445
ITERATE_t AddTail(ARG_TYPE newElement)
Definition: cArray.h:666
ITERATE_t FindIFor(ARG_TYPE arg) const
Definition: cArray.h:614
ELEM_t PopTail()
Definition: cArray.h:642
cArrayTyped(ITERATE_t iSize)
Definition: cArray.h:474
void UnLinkIndex(ITERATE_t nIndex)
Definition: cArray.h:581
TYPE * get_DataWork() const
Definition: cArray.h:682
CArray< TYPE, ARG_TYPE > SUPER_t
Definition: cArray.h:442
const TYPE & GetAtSecure(ITERATE_t nIndex) const
Definition: cArray.h:521
bool isArraySorted() const
Definition: cArray.h:732
void QSort(ITERATE_t iLeft, ITERATE_t iRight)
Definition: cArray.h:789
ITERATE_t const_iterator
Definition: cArray.h:446
void Swap(ITERATE_t i, ITERATE_t j)
Definition: cArray.h:591
TYPE ELEM_t
What type is stored.
Definition: cArray.h:448
ELEM_t PopHead()
Definition: cArray.h:635
Definition: cArray.h:914
cArrayVal()
Definition: cArray.h:919
cArrayVal(ITERATE_t iSize)
Definition: cArray.h:922
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
void __cdecl CopyElements(TYPE *pDest, const TYPE *pSrc, ITERATE_t nCount)
Definition: cArray.h:72
void __cdecl DestructElements(TYPE *pElements, ITERATE_t nCount)
Definition: cArray.h:53
void __cdecl ConstructElements(TYPE *pElements, ITERATE_t nCount)
Definition: cArray.h:31
void __cdecl CopyElements< BYTE >(BYTE *pDest, const BYTE *pSrc, ITERATE_t nCount)
Definition: cArray.h:89
int ITERATE_t
like size_t but signed
Definition: Index.h:28
const ITERATE_t k_ITERATE_BAD
Definition: Index.h:30
@ COMPARE_Equal
VARCMP_EQ.
Definition: cValT.h:23
uint16 index
Definition: sample3.cpp:29
Definition: cDebugAssert.h:29
static void *__stdcall ReAllocPtr(void *pData, size_t nSize)
Definition: cHeap.cpp:158
static void *__stdcall AllocPtr(size_t nSize)
Definition: cHeap.cpp:125
static void __stdcall FreePtr(void *pData)
Definition: cHeap.cpp:103
static size_t __stdcall GetSize(const void *pData) noexcept
Definition: cHeap.cpp:226
@ FILL_Alloc
filled to indicate malloc() memory in debug mode.
Definition: cHeap.h:33
static void Copy(void *pDst, const void *pSrc, size_t nSizeBlock) noexcept
Definition: cMem.h:132
static bool __stdcall IsValid(const void *pData, size_t nSize=1, bool bWriteAccess=false) noexcept
Definition: cMem.cpp:33
static bool IsCorrupt(const void *pData, size_t nSize=1, bool bWriteAccess=false) noexcept
Definition: cMem.h:57
static void CopyOverlap(void *pDst, const void *pSrc, size_t nSizeBlock) noexcept
Definition: cMem.h:139
static COMPARE_t Compare(const void *p1, const void *p2, size_t nSizeBlock) noexcept
Definition: cMem.h:78
static void Swap(void *pvMem1, void *pvMem2, size_t nBlockSize) noexcept
Definition: cMem.h:213