3DCoat Core API
The 3DCoat API documentation.
Loading...
Searching...
No Matches
cList.h
1#pragma once
2
3//--------------------------------------------------------------------------------------------------------------|
4// Speed comparison between "cList<>::Ctor / cList<>" (sec) |
5//--------------------------------------------------------------------------------------------------------------|
6// "100" times allocate "500000" elements and free them |
7// | cStr | int | float | cVec3 |
8// Debug 32 | 11.76 / 2.06 (x 5.7) | 0.18 / 0.18 (x 1.0) | 0.18 / 0.18 (x 1.0) | 2.44 / 0.70 (x 3.5) |
9// Release 32 | 2.06 / 0.01 (x 298.3) | 0.00 / 0.00 (x 1.1) | 0.00 / 0.00 (x 1.0) | 0.00 / 0.00 (x 1.0) |
10// Debug 64 | 5.59 / 2.57 (x 2.2) | 0.19 / 0.19 (x 1.0) | 0.19 / 0.19 (x 1.0) | 0.94 / 0.69 (x 1.4) |
11// Release 64 | 2.62 / 0.01 (x 311.0) | 0.00 / 0.00 (x 1.1) | 0.00 / 0.00 (x 1.0) | 0.00 / 0.00 (x 1.0) |
12//--------------------------------------------------------------------------------------------------------------|
13// "500000" times allocate "100" elements and free them |
14// | cStr | int | float | cVec3 |
15// Debug 32 | 19.64 / 6.93 (x 2.8) | 1.70 / 1.12 (x 1.5) | 1.70 / 1.09 (x 1.6) | 4.98 / 2.10 (x 2.4) |
16// Release 32 | 3.41 / 2.10 (x 1.6) | 1.13 / 0.74 (x 1.5) | 1.84 / 1.45 (x 1.3) | 3.36 / 2.93 (x 1.1) |
17// Debug 64 | 7.58 / 3.23 (x 2.3) | 2.23 / 1.70 (x 1.3) | 2.37 / 1.74 (x 1.4) | 5.11 / 4.23 (x 1.2) |
18// Release 64 | 5.07 / 4.18 (x 1.2) | 0.86 / 0.59 (x 1.5) | 0.86 / 0.59 (x 1.5) | 3.60 / 3.33 (x 1.1) |
19//--------------------------------------------------------------------------------------------------------------|
20
21//*****************************************************************************
22// cList_DefCompare
23//*****************************************************************************
24template<class TYPE>
25inline int cList_DefCompare(const TYPE *l, const TYPE *r) {
26 if(*l > *r) {
27 return 1;
28 } else if(*l < *r) {
29 return -1;
30 } else {
31 return 0;
32 }
33}
34
35//*****************************************************************************
36// cList_DefEquals
37//*****************************************************************************
38template<class TYPE>
39inline bool cList_DefEquals(const TYPE *l, const TYPE *r) {
40 return *l == *r;
41}
42
43// @todo fine Rewrite by explicit specialization on the VS2013.
44inline bool cList_DefEqualsFloat(const float *l, const float *r) {
45 return cMath::Equals( *l, *r );
46}
47
48// cList_Debug
49struct APICALL cList_Debug {
50 static int ContainersCount;
51 static int CtorContainersCount;
52};
53
54//*****************************************************************************
55// cList_Container
56//*****************************************************************************
57template<class TYPE>
58class cList_Container { // most common container
59public:
60 int Count, Capacity;
61 TYPE List[1024];
62 static cList_Container * New(const int Capacity) {
63 //cList_Debug::ContainersCount++;
64 const size_t ST = sizeof(TYPE); // TYPE == std::function: macOS 48, Windows 64, Linux 32
65 const size_t Size = 8 + Capacity * ST; // 8 bytes for fields "Count" and "Capacity"
66 byte *Ptr = new byte[Size]; // Aligned by: macOS 16, Windows 16, Linux 16
67 cList_Container *C = (cList_Container *)Ptr; // This conversion applies alignment.
68 const bool Triv = std::is_trivially_default_constructible<TYPE>();
69 if (!Triv){
70 for (int i = 0; i < Capacity; i++) {
71 // Note that "std::alignment_of<std::function<void()>>::value" is macOS 16, Windows 8, Linux 8.
72 // When "TYPE == std::function" under macOS the gap between "Capacity" and element "List[0]" is 8 bytes.
73 // That is why we should not use a byte pointer (or we should respect the gap) to call the default constructors here.
74 new (&C->List[i])TYPE();
75 }
76 }
77 return C;
78 }
79 static void Free(cList_Container *Ptr) {
80 //cList_Debug::ContainersCount--;
81 delete[] ((byte *)Ptr);
82 }
83 void Copy(cList_Container* to, int Count) const {
84 if (std::is_trivially_copy_constructible<TYPE>()){
85 memcpy(((byte*)to) + 8, List, Count*sizeof(TYPE));
86 }
87 else{
88 for (int i = 0; i < Count; i++){
89 to->List[i] = List[i];
90 }
91 }
92 }
93 void DestroyElements(){
94 if (std::is_compound<TYPE>()){
95 for (int i = 0; i < Capacity; i++){
96 List[i].~TYPE();
97 }
98 }
99 }
100}; // cList_Container
101
102//*****************************************************************************
103// cList_TrivialContainer
104//*****************************************************************************
105template<class TYPE>
106class cList_TrivialContainer { // Doesn't call constructors/destructors in the lists like "cList<cStr>"
107public:
108 int Count, Capacity;
109 TYPE List[1024];
110 static cList_TrivialContainer * New(const int Capacity) {
111 //cList_Debug::ContainersCount++;
112 size_t Size = 8 + Capacity * sizeof(TYPE);
113 byte *Ptr = new byte[Size];
114 return (cList_TrivialContainer *)Ptr;
115 }
116 static void Free(cList_TrivialContainer *Ptr) {
117 //cList_Debug::ContainersCount--;
118 delete[]((byte *)Ptr);
119 }
120 void Copy(cList_TrivialContainer* to, int Count) const {
121 memcpy(((byte*)to) + 8, List, Count*sizeof(TYPE));
122 }
123 void DestroyElements(){
124 }
125}; // cList_Container
126
132template <class TYPE, class CONTAINER = cList_Container<TYPE> >
133class cList {
134public:
135 // you can use it for agile grab the types in the code
136 // # By analogy with the STL-containers.
137 typedef TYPE value_type;
138 typedef CONTAINER container_type;
139
140 typedef cList<TYPE, cList_Container<TYPE> > Ctor; // C++ doesn't support template typedefs. Use for type "cList<cStr>::Ctor".
141
142 typedef int Compare(const TYPE *, const TYPE *);
143
144 struct CompareFunctor {
145 virtual ~CompareFunctor() {}
146 virtual bool operator()( const TYPE& a, const TYPE& b ) const = 0;
147 };
148
149 typedef bool Equals(const TYPE *, const TYPE *);
150
151 typedef TYPE* iterator;
152 iterator begin() {
153 return m_Container ? m_Container->List : nullptr;
154 }
155 iterator end() {
156 return m_Container ? m_Container->List + m_Container->Count : nullptr;
157 }
158
159 iterator begin() const {
160 return m_Container ? m_Container->List : nullptr;
161 }
162 iterator end() const {
163 return m_Container ? m_Container->List + m_Container->Count : nullptr;
164 }
165 //-------------------------------------------------------------------------
166 // .ctor
167 //-------------------------------------------------------------------------
168 cList();
169 cList(const cList<TYPE, CONTAINER> &Src);
170 cList(const TYPE *Src, const int Count); // cList<int> U(I, 100);
171 explicit cList(const int Count); // cList<int> T(20);
172 cList(const int Count, const TYPE &Fill); // cList<int> Z(20, 0);
173
174 // .dtor
175 ~cList();
176
177 size_t Size() const; // Total size of used for elements memory (bytes)
178 size_t SizeCapacity() const; // Total size of allocated memory (bytes)
179
180 // Assignment operators
181 void Copy(const cList<TYPE, CONTAINER> &Src);
182 void Copy(const TYPE *Src, const int Count);
183 // @copy DynArray::MoveArrayTo()
184 void Move( cList<TYPE, CONTAINER>& Dest );
185 // @copy DynArray::Move()
186 bool Move( int from, int to );
187 // @copy DynArray::CopyTo()
188 void CopyTo(cList<TYPE, CONTAINER>& Dest);
189 void Set(cList<TYPE, CONTAINER> *Src);
190 void operator = (const cList<TYPE, CONTAINER> &Src);
191 void Swap(cList<TYPE, CONTAINER> *With);
192 template <class Reader>
193 void FromBS(Reader& BS, int count);
194 template <class Writer>
195 void ToBS(Writer& BS);
196
197 // Access operators
198 const TYPE & operator [] (const int Index) const;
199 TYPE & operator [] (const int Index);
200 const TYPE & GetAt(const int Index) const;
201 TYPE & GetAt(const int Index);
202 const TYPE & GetFirst() const;
203 TYPE & GetFirst();
204 const TYPE & GetLast() const;
205 TYPE & GetLast();
206 void SetAt(const int Index, const TYPE &Value);
207 const TYPE * ToPtr() const; // Returns a const pointer to the list
208 TYPE * ToPtr(); // Returns a mutable pointer to the list
209 void GetRange(const int Index, const int Count, cList<TYPE, CONTAINER> *To) const;
211 TYPE uGet(const int Index, const TYPE& defvalue);
213 void uSet(const int Index, const TYPE& value, const TYPE& defvalue);
214
215 // @copy DynArray::operator+( int )
216 // @todo Remove it?
217 TYPE* operator + ( int Index ) {
218 cAssert( Index >= 0 && Index < Count() && !IsEmpty() );
219 return m_Container->List + Index;
220 }
221
222 void Free(); // Removes all items from the list and frees all the space
223 void FreeUnused(); // Resizes the list to exactly the number of elements it contains
224 void FreeContents(); // Calls the destructor of all elements in the list
225
226 // Fast version of Resize().
227 // @copy "SetCapacityMod" == DynArray::CleanupAllocation()
228 // @see pool.cpp
229 template< int mod = 8 >
230 void SetCapacityMod();
231
232 int Count() const; // Gets the number of elements actually contained in the "cList"
233
234 // @todo fine Remove after change DynArray<> to cList<>.
235 int GetAmount() const { return Count(); }
236
237 void SetCount(const int Count); // Sets the number of elements actually contained in the "cList"
238 // Sets the number of elements actually contained in the "cList" and
239 // initializes every element with specified value "Fill"
240 void SetCount(int Count, const TYPE &Value);
241
242 // Gets or sets the number of elements that the "cList" can contain
243 int Capacity() const;
244 void SetCapacity(const int Capacity);
245
246 bool IsEmpty() const;
247 void Clear();
248 void Fill(const TYPE &Value);
249
250 // Adds "Count" elements to the end of the list. Returns the index of the last added element.
251 int Add(const TYPE &Value, const int Count = 1);
252
253 // @todo fine Copied from class DynArray<>. Remove or rename it.
254 void AddValues( const TYPE* Values, int N ) {
255 AddRange( Values, N );
256 }
257
258 template <class array>
259 void AddRange(const array &Src); // Adds the elements of another "cList" object to the end of current
260 void AddRange(const TYPE *Src, const int Count); // Adds "Count" elements of another list to the end of current
261
262 // Inserts element to the list at the specified position with specified number of times
263 void Insert(const int Index, const TYPE &Value, const int Count = 1);
264
265 // Inserts the elements of another "cList" object into current at the specified position
266 void InsertRange(const int Index, const cList<TYPE, CONTAINER> &Src);
267
268 // Insert the elements of another list of specified length at the specified position
269 void InsertRange(const int Index, const TYPE *Src, const int Count);
270
271 TYPE& ExpandTo( int Index, const TYPE& );
272
273 // @copy DynArray::Putp()
274 // @return true when inserted.
275 bool InsertFirstOrRemove( const TYPE& );
276
277 // Removes the first occurence of a specific object from the "cList" object.
278 // Returns "true" if value was found; otherwise, false.
279 bool Remove(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals);
280
281 // cList<int> L;
282 // ...
283 // while(L.Remove(10, ZeroResidue)) {
284 // }
285
286 // Removes a range of elements from the "cList" object with
287 // specified number of elements to remove
288 void RemoveAt(const int Index, const int Count = 1);
289
290 void RemoveLast();
291
292 // Searches for the specified object and returns the zero - based index of the first occurrence
293 // within the entire "cList" object using the specified equals function
294 int IndexOf(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;
295
296 // cList<cStr> L;
297 // ...
298 // int i = L.IndexOf("Tilda", cStr::EqualsNoCase);
299
300 // Using the specified equals function searches for the specified object and returns the zero - based
301 // index of the first occurrence within the range of elements in the "cList" object that
302 // extends from the specified index to the last element
303 int IndexOf(const TYPE &Value, const int StartIndex, Equals *E = (Equals *)&cList_DefEquals) const;
304
305 // Searches for the specified "Value" and returns the zero - based index of the first occurrence
306 // within the range of elements in the "cList" object that starts at the specified index and
307 // contains the specified number of elements
308 int IndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E = (Equals *)&cList_DefEquals) const;
309
310 // Searches for the specified "Value" and returns the zero - based index of the last occurrence
311 // within the entire "cList" object
312 int LastIndexOf(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;
313
314 // Searches for the specified "Value" and returns the zero - based index of the last occurrence
315 // within the range of elements in the "cList" object that extends from the first element
316 // to the specified index
317 int LastIndexOf(const TYPE &Value, const int StartIndex, Equals *E = (Equals *)&cList_DefEquals) const;
318
319 // Searches for the specified "Value" and returns the zero - based index of the last occurrence
320 // within the range of elements in the "cList" object the contains the specified number of elements
321 // and ends at the specified index
322 int LastIndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E = (Equals *)&cList_DefEquals) const;
323
324 // Searches the entire sorted "cList" object for an element using the specified compare function and returns
325 // the zero - based index, if "Value" is found; otherwise, -1
326 int BinarySearch(const TYPE &Value, Compare *C = (Compare *)&cList_DefCompare) const;
327
328 // cList<cStr> L;
329 // ...
330 // int i = L.BinarySearch("Over", cStr::CompareNoCase);
331
332 // Searches the range of elements in the sorted "cList" object for an element using the specified
333 // compare function and returns the zero - based index, if "Value" is found; otherwise, -1
334 int BinarySearch(const int Index, const int Count, const TYPE &Value, Compare *C = (Compare *)&cList_DefCompare) const;
335
336 // Determines whether an element is in the "cList" object using the specified equals function
337 bool Contains(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;
338
339 // @todo fine Copied from class DynArray<>. Change to cList::Contains().
340 int find( const TYPE& Value ) const {
341 for ( int i = 0; i < Count(); i++ ) {
342 if ( !memcmp( &Value, &m_Container->List[ i ], sizeof( TYPE ) ) ) {
343 return i;
344 }
345 }
346 return -1;
347 }
348
349 // @todo fine Copied from the class DynArray<>. Remove or rename it.
350 TYPE pop_front() {
351 const TYPE e = GetFirst();
352 RemoveAt( 0, 1 );
353 return e;
354 }
355
356 // @todo fine Copied from the class DynArray<>. Remove or rename it.
357 TYPE pop_back() {
358 const TYPE e = GetLast();
359 RemoveLast();
360 return e;
361 }
362
363 // Determines using "IndexOf" function whether an element is in the "cList" object, and only if
364 // it is not in the list, adds it. Returns the index of founded or added element.
365 int AddUnique(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals);
366
367 // @return true when added
368 bool AddOnce( const TYPE&, Equals *E = ( Equals * )&cList_DefEquals );
369
370 // cList<cStr> L;
371 // ...
372 // bool s = L.Contains("Over", cStr::EqualsNoCase);
373
374 void Reverse(); // Reverses the order of the elements in the entire "cList" object
375 void Reverse(const int Index, const int Count); // Reverses the order of the elements in the specified range
376
377 // Sorts the elements in the entire "cList" object using the specified compare function
378 void Sort(Compare *C = (Compare *)&cList_DefCompare);
379 void Sort(const CompareFunctor&);
380
381 // Sorts the elements in a range of elements in "cList" object using the specified compare function
382 void Sort(const int Index, const int Count, Compare *C = (Compare *)&cList_DefCompare);
383 void Sort(int Index, int Count, const CompareFunctor& );
384 void EnsureCapacity(int size);
385
386 void operator += (const TYPE &);
387 void operator -= (const TYPE &);
388 void operator *= (const TYPE &);
389 void operator /= (const TYPE &);
390
391 bool operator == (const cList<TYPE, CONTAINER> &) const;
392 bool operator != (const cList<TYPE, CONTAINER> &) const;
393
394 // cList<cVec3> L;
395 // ...
396 // L += cVec3(10, 20, 0);
397 // L *= cVec3(20.0f);
398 //
399
400
402
404 bool some(::std::function<bool(const TYPE&)>) const;
405 bool some(::std::function<bool(TYPE&)>);
406
408 bool every(::std::function<bool(const TYPE&)>) const;
409 bool every(::std::function<bool(TYPE&)>);
410
412 int find(::std::function<bool(const TYPE&)>) const;
413 int find(::std::function<bool(TYPE&)>);
414
416 void forEach(::std::function<void(const TYPE&)>) const;
417 void forEach(::std::function<void(TYPE&)>);
418
420 void filter(cList<TYPE, CONTAINER>& result, ::std::function<bool(const TYPE&)>) const;
421 void filter(cList<TYPE, CONTAINER>& result, ::std::function<bool(TYPE&)>);
422
424 template<class RES>
425 void reduce(RES& res, ::std::function<void(RES&, const TYPE&)> fn) const;
426 template<class RES>
427 void reduce(RES& res, ::std::function<void(RES&, TYPE&)> fn);
428
429
430
431protected:
432 friend class cXml;
433 void Null();
434 CONTAINER *m_Container;
435
436 CONTAINER * EnsureCapacity(const int Capacity, const bool SkipDelete);
437 CONTAINER * Resize(const int Capacity, const bool SkipDelete);
438};
439
440//the difference from cList is that destuctors are not called during deallocation of the list
441//this array is most efficient of all in terms of memory consumption and speed of allocation
442template <class TYPE>
443class cArray : public cList<TYPE, cList_TrivialContainer<TYPE> >{
444
445};
446
447// cList<TYPE, CONTAINER>::Null
448template<class TYPE, class CONTAINER>
449inline void cList<TYPE, CONTAINER>::Null() {
450 m_Container = nullptr;
451}
452
453
454// cList<TYPE, CONTAINER>.ctor : ()
455template<class TYPE, class CONTAINER>
457 Null();
458}
459
460// cList<TYPE, CONTAINER>.ctor : (const cList<TYPE, CONTAINER> &)
461template<class TYPE, class CONTAINER>
463 Null();
464 Copy(Src);
465}
466
467// cList<TYPE, CONTAINER>.ctor : (const TYPE *, const int)
468template<class TYPE, class CONTAINER>
469inline cList<TYPE, CONTAINER>::cList(const TYPE *Src, const int Count) {
470 Null();
471 Copy(Src, Count);
472}
473
474// cList<TYPE, CONTAINER>.ctor : (const int)
475template<class TYPE, class CONTAINER>
476inline cList<TYPE, CONTAINER>::cList(const int Count) {
477 Null();
478 SetCount(Count);
479}
480
481// cList<TYPE, CONTAINER>.ctor : (const int, const TYPE &)
482template<class TYPE, class CONTAINER>
483inline cList<TYPE, CONTAINER>::cList(const int Count, const TYPE &Fill) {
484 Null();
485 SetCount(Count, Fill);
486}
487
488// cList<TYPE, CONTAINER>.dtor
489template<class TYPE, class CONTAINER>
491 Free();
492}
493
494// cList<TYPE, CONTAINER>::Size
495template<class TYPE, class CONTAINER>
496inline size_t cList<TYPE, CONTAINER>::Size() const {
497 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
498 return CurCount * sizeof(TYPE);
499}
500
501// cList<TYPE, CONTAINER>::SizeCapacity
502template<class TYPE, class CONTAINER>
503inline size_t cList<TYPE, CONTAINER>::SizeCapacity() const {
504 int CurCapacity = (nullptr == m_Container) ? 0 : m_Container->Capacity;
505 return CurCapacity * sizeof(TYPE);
506}
507
508// cList<TYPE, CONTAINER>::Copy : (const cList<TYPE, CONTAINER> &)
509template<class TYPE, class CONTAINER>
511 int i;
512 int SrcCount = (nullptr == Src.m_Container) ? 0 : Src.m_Container->Count;
513 EnsureCapacity(SrcCount, false);
514 if(m_Container != nullptr) {
515 m_Container->Count = SrcCount;
516 for(i = 0; i < m_Container->Count; i++) {
517 m_Container->List[i] = Src.m_Container->List[i];
518 }
519 }
520}
521
522// cList<TYPE, CONTAINER>::Copy : (const TYPE *, const int)
523template<class TYPE, class CONTAINER>
524inline void cList<TYPE, CONTAINER>::Copy(const TYPE *Src, const int Count) {
525 int i;
526
527 CONTAINER *OldContainer = EnsureCapacity(Count, true);
528 if(m_Container != nullptr) {
529 m_Container->Count = Count;
530 for(i = 0; i < m_Container->Count; i++) {
531 m_Container->List[i] = Src[i];
532 }
533 }
534 if(OldContainer != nullptr) {
535 if (!std::is_trivially_copy_constructible<TYPE>()){
536 OldContainer->DestroyElements();
537 }
538 CONTAINER::Free(OldContainer);
539 }
540}
541
542// cList<TYPE, CONTAINER>::Move : (cList<TYPE, CONTAINER> &)
543template<class TYPE, class CONTAINER>
545 Dest.Clear();
546 Dest.m_Container = m_Container;
547 m_Container = nullptr;
548}
549
550// cList<TYPE, CONTAINER>::Move : (int, int)
551template<class TYPE, class CONTAINER>
552inline bool cList<TYPE, CONTAINER>::Move( int from, int to ){
553 const int n = Count();
554 if ( from >= n ) from = n - 1; else if ( from < 0 ) from = 0;
555 if ( to >= n ) to = n - 1; else if ( to < 0 ) to = 0;
556 if ( from == to ) return false;
557 const TYPE t = m_Container->List[ from ];
558 if ( from < to ) {
559 memcpy(
560 m_Container->List + from,
561 m_Container->List + from + 1,
562 (to - from) * sizeof( TYPE ) );
563 } else {
564 memmove(
565 m_Container->List + to + 1,
566 m_Container->List + to,
567 (from - to) * sizeof( TYPE ) );
568 }
569 m_Container->List[ to ] = t;
570 return true;
571}
572
573template <class TYPE, class CONTAINER>
575 Dest = *this;
576}
577
578// cList<TYPE, CONTAINER>::Set : (cList<TYPE, CONTAINER> *)
579template<class TYPE, class CONTAINER>
581 cAssert((nullptr == m_Container) || (m_Container != Src->m_Container));
582 Free();
583
584 m_Container = Src->m_Container;
585 Src->m_Container = nullptr;
586}
587
588// cList<TYPE, CONTAINER>::operator =
589template<class TYPE, class CONTAINER>
591 Copy(Src);
592}
593
594// cList<TYPE, CONTAINER>::Swap : (cList<TYPE, CONTAINER> *)
595template<class TYPE, class CONTAINER>
597 cMath::Swap(m_Container, With->m_Container);
598}
599
600template <class TYPE, class CONTAINER>
601template <class Reader>
602void cList<TYPE, CONTAINER>::FromBS(Reader& BS, int count) {
603 Clear();
604 SetCount(count);
605 if(Count()){
606 BS.Read(ToPtr(), Count() * sizeof(TYPE));
607 }
608}
609
610template <class TYPE, class CONTAINER>
611template <class Writer>
612void cList<TYPE, CONTAINER>::ToBS(Writer& BS) {
613 BS.Write(ToPtr(), Count() * sizeof(TYPE));
614}
615
616// cList<TYPE, CONTAINER>::operator [] const
617template<class TYPE, class CONTAINER>
618inline const TYPE & cList<TYPE, CONTAINER>::operator [] (const int Index) const {
619 cAssert(Index >= 0);
620 cAssert(m_Container != nullptr);
621 cAssert(Index < m_Container->Count);
622 return m_Container->List[Index];
623}
624
625// cList<TYPE, CONTAINER>::operator []
626template<class TYPE, class CONTAINER>
627inline TYPE & cList<TYPE, CONTAINER>::operator [] (const int Index) {
628 cAssert(Index >= 0);
629 cAssert(m_Container != nullptr);
630 cAssert(Index < m_Container->Count);
631 return m_Container->List[Index];
632}
633
634// cList<TYPE, CONTAINER>::GetAt const
635template<class TYPE, class CONTAINER>
636inline const TYPE & cList<TYPE, CONTAINER>::GetAt(const int Index) const {
637 cAssert(Index >= 0);
638 cAssert(m_Container != nullptr);
639 cAssert(Index < m_Container->Count);
640 return m_Container->List[Index];
641}
642
643// cList<TYPE, CONTAINER>::GetAt
644template<class TYPE, class CONTAINER>
645inline TYPE & cList<TYPE, CONTAINER>::GetAt(const int Index) {
646 cAssert(Index >= 0);
647 cAssert(m_Container != nullptr);
648 cAssert(Index < m_Container->Count);
649 return m_Container->List[Index];
650}
651
652// cList<TYPE, CONTAINER>::GetFirst const
653template<class TYPE, class CONTAINER>
654inline const TYPE & cList<TYPE, CONTAINER>::GetFirst() const {
655 cAssert(m_Container != nullptr);
656 cAssert(m_Container->Count >= 1);
657 return m_Container->List[0];
658}
659
660// cList<TYPE, CONTAINER>::GetFirst
661template<class TYPE, class CONTAINER>
662inline TYPE & cList<TYPE, CONTAINER>::GetFirst() {
663 cAssert(m_Container != nullptr);
664 cAssert(m_Container->Count >= 1);
665 return m_Container->List[0];
666}
667
668// cList<TYPE, CONTAINER>::GetLast const
669template<class TYPE, class CONTAINER>
670inline const TYPE & cList<TYPE, CONTAINER>::GetLast() const {
671 cAssert(m_Container != nullptr);
672 cAssert(m_Container->Count >= 1);
673 return m_Container->List[m_Container->Count - 1];
674}
675
676// cList<TYPE, CONTAINER>::GetLast
677template<class TYPE, class CONTAINER>
678inline TYPE & cList<TYPE, CONTAINER>::GetLast() {
679 cAssert(m_Container != nullptr);
680 cAssert(m_Container->Count >= 1);
681 return m_Container->List[m_Container->Count - 1];
682}
683
684// cList<TYPE, CONTAINER>::SetAt
685template<class TYPE, class CONTAINER>
686inline void cList<TYPE, CONTAINER>::SetAt(const int Index, const TYPE &Value) {
687 cAssert(Index >= 0);
688 cAssert(m_Container != nullptr);
689 cAssert(Index < m_Container->Count);
690 m_Container->List[Index] = Value;
691}
692
693// cList<TYPE, CONTAINER>::ToPtr() const
694template<class TYPE, class CONTAINER>
695inline const TYPE * cList<TYPE, CONTAINER>::ToPtr() const {
696 return (nullptr == m_Container) ? nullptr : m_Container->List;
697}
698
699// cList<TYPE, CONTAINER>::ToPtr
700template<class TYPE, class CONTAINER>
701inline TYPE * cList<TYPE, CONTAINER>::ToPtr() {
702 return (nullptr == m_Container) ? nullptr : m_Container->List;
703}
704
705//------------------------------------------------------------------------------------------
706// cList<TYPE, CONTAINER>::GetRange
707//------------------------------------------------------------------------------------------
708template<class TYPE, class CONTAINER>
709inline void cList<TYPE, CONTAINER>::GetRange(const int Index, const int Count, cList<TYPE, CONTAINER> *To) const {
710 cAssert(Index >= 0);
711 cAssert(Count >= 0);
712 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
713 cAssert(Index + Count <= CurCount);
714
715 int i;
716
717 To->Clear();
718
719 for(i = Index; i < Index + Count; i++) {
720 To->Add(m_Container->List[i]);
721 }
722} // cList<TYPE, CONTAINER>::GetRange
723
724// cList<TYPE, CONTAINER>::Free
725template<class TYPE, class CONTAINER>
726inline void cList<TYPE, CONTAINER>::Free() {
727 if(m_Container != nullptr) {
728 m_Container->DestroyElements();
729 CONTAINER::Free(m_Container);
730 m_Container = nullptr;
731 }
732}
733
734template<class TYPE, class CONTAINER>
735TYPE cList<TYPE, CONTAINER>::uGet(const int Index, const TYPE& defvalue){
736 if (Index >= 0 && Index < Count())return (*this)[Index];
737 return defvalue;
738}
739
740template<class TYPE, class CONTAINER>
741void cList<TYPE, CONTAINER>::uSet(const int Index, const TYPE& value, const TYPE& defvalue){
742 if (Index >= 0){
743 int n = Count();
744 if (Index >= n)Add(defvalue, Index - n + 1);
745 (*this)[Index] = value;
746 }
747}
748
749// cList<TYPE, CONTAINER>::FreeContents
750template<class TYPE, class CONTAINER>
752 if(m_Container != nullptr) {
753 int i;
754 for(i = 0; i < m_Container->Count; i++) {
755 delete m_Container->List[i];
756 m_Container->List[i] = nullptr;
757 }
758 }
759}
760
761// cList<TYPE, CONTAINER>::FreeUnused
762template<class TYPE, class CONTAINER>
764 if(m_Container != nullptr) {
765 Resize(m_Container->Count, false);
766 }
767}
768
769// cList<TYPE, CONTAINER>::Clear
770template<class TYPE, class CONTAINER>
771inline void cList<TYPE, CONTAINER>::Clear() {
772 if(m_Container != nullptr) {
773 m_Container->Count = 0;
774 }
775}
776
777// cList<TYPE, CONTAINER>::SetCapacityMod
778template<class TYPE, class CONTAINER>
779template< int mod >
781 static_assert( mod % 8 == 0,
782 "`mod` must be an integral of multiple of 8" );
783 const int ncap = Count() * mod / 8;
784 SetCapacity( ncap );
785}
786
787// cList<TYPE, CONTAINER>::Count
788template<class TYPE, class CONTAINER>
789inline int cList<TYPE, CONTAINER>::Count() const {
790 return (nullptr == m_Container) ? 0 : m_Container->Count;
791}
792
793// cList<TYPE, CONTAINER>::IsEmpty
794template<class TYPE, class CONTAINER>
795inline bool cList<TYPE, CONTAINER>::IsEmpty() const {
796 return (nullptr == m_Container) || (m_Container->Count < 1);
797}
798
799// cList<TYPE, CONTAINER>::Capacity
800template<class TYPE, class CONTAINER>
801inline int cList<TYPE, CONTAINER>::Capacity() const {
802 return (nullptr == m_Container) ? 0 : m_Container->Capacity;
803}
804
805// cList<TYPE, CONTAINER>::SetCapacity
806template<class TYPE, class CONTAINER>
807inline void cList<TYPE, CONTAINER>::SetCapacity(const int Capacity) {
808 Resize(Capacity, false);
809}
810
811//-----------------------------------------------------------------------------
812// cList<TYPE, CONTAINER>::Add
813//-----------------------------------------------------------------------------
814template<class TYPE, class CONTAINER>
815inline int cList<TYPE, CONTAINER>::Add(const TYPE &Value, const int Count) {
816 cAssert(Count >= 0);
817 int i;
818 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
819 CONTAINER *OldContainer = EnsureCapacity(CurCount + Count, true);
820 for(i = 0; i < Count; i++) {
821 m_Container->List[m_Container->Count] = Value;
822 m_Container->Count++;
823 }
824 if(OldContainer != nullptr) {
825 if (!std::is_trivially_copy_constructible<TYPE>()){
826 OldContainer->DestroyElements();
827 }
828 CONTAINER::Free(OldContainer);
829 }
830 return ((nullptr == m_Container) ? 0 : m_Container->Count) - 1;
831} // cList<TYPE, CONTAINER>::Add
832
833template <class TYPE, class CONTAINER>
834template <class array>
835void cList<TYPE, CONTAINER>::AddRange(const array& Src) {
836 int i;
837 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
838 int SrcCount = Src.Count();
839 EnsureCapacity(CurCount + SrcCount, false);
840 for (i = 0; i < SrcCount; i++) {
841 m_Container->List[m_Container->Count] = Src[i];
842 m_Container->Count++;
843 }
844}
845
846//-----------------------------------------------------------------------------
847// cList<TYPE, CONTAINER>::AddRange : (const TYPE *, const int)
848//-----------------------------------------------------------------------------
849template<class TYPE, class CONTAINER>
850inline void cList<TYPE, CONTAINER>::AddRange(const TYPE *Src, const int Count) {
851 cAssert(Count >= 0);
852 int i;
853 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
854 CONTAINER *OldContainer = EnsureCapacity(CurCount + Count, true);
855 for(i = 0; i < Count; i++) {
856 m_Container->List[m_Container->Count] = Src[i];
857 m_Container->Count++;
858 }
859 if(OldContainer != nullptr) {
860 if (!std::is_trivially_copy_constructible<TYPE>()){
861 OldContainer->DestroyElements();
862 }
863 CONTAINER::Free(OldContainer);
864 }
865} // cList<TYPE, CONTAINER>::AddRange
866
867//-------------------------------------------------------------------------------------------------------------
868// cList<TYPE, CONTAINER>::IndexOf
869//-------------------------------------------------------------------------------------------------------------
870template<class TYPE, class CONTAINER>
871inline int cList<TYPE, CONTAINER>::IndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E) const {
872 cAssert(StartIndex >= 0);
873 cAssert(Count >= 0);
874 cAssert(StartIndex + Count <= ((nullptr == m_Container) ? 0 : m_Container->Count));
875
876 int i;
877
878 for(i = StartIndex; i < StartIndex + Count; i++) {
879 if(E(&m_Container->List[i], &Value)) {
880 return i;
881 }
882 }
883
884 return -1;
885}
886
887template<class TYPE, class CONTAINER>
888inline int cList<TYPE, CONTAINER>::IndexOf(const TYPE &Value, const int StartIndex, Equals *E) const {
889 return IndexOf(Value, StartIndex, Count() - StartIndex, E);
890}
891
892template<class TYPE, class CONTAINER>
893inline int cList<TYPE, CONTAINER>::IndexOf(const TYPE &Value, Equals *E) const {
894 return IndexOf(Value, 0, Count(), E);
895}
896// cList<TYPE, CONTAINER>::IndexOf
897
898//--------------------------------------------------------------------------------------------------------------
899// cList<TYPE, CONTAINER>::LastIndexOf
900//--------------------------------------------------------------------------------------------------------------
901template<class TYPE, class CONTAINER>
902inline int cList<TYPE, CONTAINER>::LastIndexOf(const TYPE &Value, Equals *E) const {
903 return LastIndexOf(Value, Count() - 1, Count(), E);
904}
905
906template<class TYPE, class CONTAINER>
907inline int cList<TYPE, CONTAINER>::LastIndexOf(const TYPE &Value, const int StartIndex, Equals *E) const {
908 return LastIndexOf(Value, StartIndex, StartIndex + 1, E);
909}
910
911template<class TYPE, class CONTAINER>
912inline int cList<TYPE, CONTAINER>::LastIndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E) const {
913 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
914 if(0 == CurCount) {
915 cAssert(StartIndex >= -1);
916 cAssert(StartIndex <= 0);
917 cAssert(Count >= 0);
918 return -1;
919 }
920
921 cAssert(StartIndex >= 0);
922 cAssert(StartIndex < CurCount);
923 cAssert(Count >= 0);
924 cAssert(Count <= StartIndex + 1);
925
926 int i, i0;
927
928 i0 = StartIndex - Count + 1;
929 for(i = StartIndex; i >= i0; i--) {
930 if(E(&m_Container->List[i], &Value)) {
931 return i;
932 }
933 }
934
935 return -1;
936} // cList<TYPE, CONTAINER>::LastIndexOf
937
938//------------------------------------------------------------------------------------------------------------
939// cList<TYPE, CONTAINER>::BinarySearch
940//------------------------------------------------------------------------------------------------------------
941template<class TYPE, class CONTAINER>
942inline int cList<TYPE, CONTAINER>::BinarySearch(const int Index, const int Count, const TYPE &Value, Compare *C) const {
943 cAssert(Index >= 0);
944 cAssert(Count >= 0);
945 cAssert(Index + Count <= ((nullptr == m_Container) ? 0 : m_Container->Count));
946
947 int l, r, m;
948
949 if(Count > 0) {
950 l = 0;
951 r = Index + Count - 1;
952 while(l < r) {
953 m = (l + r) / 2;
954 if(C(&Value, &GetAt(m)) <= 0) {
955 r = m;
956 } else {
957 l = m + 1;
958 }
959 }
960 if(C(&Value, &GetAt(l)) == 0) {
961 return l;
962 }
963 }
964
965 return -1;
966}
967
968template<class TYPE, class CONTAINER>
969inline int cList<TYPE, CONTAINER>::BinarySearch(const TYPE &Value, Compare *C) const {
970 return BinarySearch(0, Count(), Value, C);
971}
972// cList<TYPE, CONTAINER>::BinarySearch
973
974// cList<TYPE, CONTAINER>::Contains
975template<class TYPE, class CONTAINER>
976inline bool cList<TYPE, CONTAINER>::Contains(const TYPE &Value, Equals *E) const {
977 int i;
978 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
979 for(i = 0; i < CurCount; i++) {
980 if(E(&m_Container->List[i], &Value)) {
981 return true;
982 }
983 }
984 return false;
985}
986
987// cList<TYPE, CONTAINER>::AddUnique
988template<class TYPE, class CONTAINER>
989inline int cList<TYPE, CONTAINER>::AddUnique(const TYPE &Value, Equals *E) {
990 int i = IndexOf(Value, E);
991 if(-1 == i) {
992 i = Add(Value);
993 }
994 return i;
995}
996
997// cList<TYPE, CONTAINER>::AddOnce
998template<class TYPE, class CONTAINER>
999inline bool cList<TYPE, CONTAINER>::AddOnce( const TYPE& Value, Equals* E ){
1000 const int i = IndexOf( Value, E );
1001 if ( i == -1 ) {
1002 Add( Value );
1003 return true;
1004 }
1005 return false;
1006}
1007
1008//-----------------------------------------------------------------------------
1009// cList<TYPE, CONTAINER>::RemoveAt
1010//-----------------------------------------------------------------------------
1011template<class TYPE, class CONTAINER>
1012inline void cList<TYPE, CONTAINER>::RemoveAt(const int Index, const int Count) {
1013 cAssert(Index >= 0);
1014 cAssert(Count >= 0);
1015 cAssert(Index + Count <= ((nullptr == m_Container) ? 0 : m_Container->Count));
1016 int i;
1017 if(m_Container != nullptr) {
1018 int lcount = Count;
1019 if (Index + lcount > m_Container->Count){
1020 lcount = m_Container->Count - Index;
1021 }
1022 m_Container->Count -= lcount;
1023 for(i = Index; i < m_Container->Count; i++) {
1024 m_Container->List[i] = m_Container->List[i + lcount];
1025 }
1026 }
1027} // cList<TYPE, CONTAINER>::RemoveAt
1028
1029// cList<TYPE, CONTAINER>::RemoveLast
1030template<class TYPE, class CONTAINER>
1032 cAssert(m_Container != nullptr);
1033 cAssert(m_Container->Count >= 1);
1034 m_Container->Count--;
1035}
1036
1037//-----------------------------------------------------------------------------
1038// cList<TYPE, CONTAINER>::Remove
1039//-----------------------------------------------------------------------------
1040template<class TYPE, class CONTAINER>
1041inline bool cList<TYPE, CONTAINER>::Remove(const TYPE &Value, Equals *E) {
1042 int Index = IndexOf(Value, E);
1043 if(Index >= 0) {
1044 RemoveAt(Index);
1045 return true;
1046 }
1047 return false;
1048} // cList<TYPE, CONTAINER>::Remove
1049
1050//-----------------------------------------------------------------------------------
1051// cList<TYPE, CONTAINER>::Insert
1052//-----------------------------------------------------------------------------------
1053template<class TYPE, class CONTAINER>
1054inline void cList<TYPE, CONTAINER>::Insert(const int Index, const TYPE &Value, const int Count) {
1055 cAssert(Index >= 0);
1056 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1057 cAssert(Index <= CurCount);
1058 cAssert(Count >= 0);
1059
1060 int i;
1061
1062 CONTAINER *OldContainer = EnsureCapacity(CurCount + Count, true);
1063 for(i = CurCount - 1 + Count; i >= Index + Count; i--) {
1064 m_Container->List[i] = m_Container->List[i - Count];
1065 }
1066 if(m_Container != nullptr) {
1067 m_Container->Count += Count;
1068 cAssert(Index + Count <= m_Container->Count);
1069 }
1070 for(i = 0; i < Count; i++) {
1071 m_Container->List[Index + i] = Value;
1072 }
1073 if(OldContainer != nullptr) {
1074 if (!std::is_trivially_copy_constructible<TYPE>()){
1075 OldContainer->DestroyElements();
1076 }
1077 CONTAINER::Free(OldContainer);
1078 }
1079} // cList<TYPE, CONTAINER>::Insert
1080
1081//---------------------------------------------------------------------------------------
1082// cList<TYPE, CONTAINER>::InsertRange : void (const int, const cList<TYPE, CONTAINER> &)
1083//---------------------------------------------------------------------------------------
1084template<class TYPE, class CONTAINER>
1085inline void cList<TYPE, CONTAINER>::InsertRange(const int Index, const cList<TYPE, CONTAINER> &Src) {
1086 cAssert(Index >= 0);
1087 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1088 cAssert(Index <= CurCount);
1089 int SrcCount = (nullptr == Src.m_Container) ? 0 : Src.m_Container->Count;
1090
1091 int i;
1092
1093 EnsureCapacity(CurCount + SrcCount, false);
1094 for(i = CurCount - 1 + SrcCount; i >= Index + SrcCount; i--) {
1095 m_Container->List[i] = m_Container->List[i - SrcCount];
1096 }
1097 if(m_Container != nullptr) {
1098 m_Container->Count += SrcCount;
1099 cAssert(Index + SrcCount <= m_Container->Count);
1100 }
1101 for(i = 0; i < SrcCount; i++) {
1102 m_Container->List[Index + i] = Src.m_Container->List[i];
1103 }
1104} // cList<TYPE, CONTAINER>::InsertRange
1105
1106//--------------------------------------------------------------------------------
1107// cList<TYPE, CONTAINER>::InsertRange : void (const int, const TYPE *, const int)
1108//--------------------------------------------------------------------------------
1109template<class TYPE, class CONTAINER>
1110inline void cList<TYPE, CONTAINER>::InsertRange(const int Index, const TYPE *Src, const int Count) {
1111 cAssert(Index >= 0);
1112 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1113 cAssert(Index <= CurCount);
1114 cAssert(Count >= 0);
1115
1116 int i;
1117
1118 CONTAINER *OldContainer = EnsureCapacity(CurCount + Count, true);
1119 for(i = CurCount - 1 + Count; i >= Index + Count; i--) {
1120 m_Container->List[i] = m_Container->List[i - Count];
1121 }
1122 if(m_Container != nullptr) {
1123 m_Container->Count += Count;
1124 cAssert(Index + Count <= m_Container->Count);
1125 }
1126 for(i = 0; i < Count; i++) {
1127 m_Container->List[Index + i] = Src[i];
1128 }
1129 if(OldContainer != nullptr) {
1130 if (!std::is_trivially_copy_constructible<TYPE>()){
1131 OldContainer->DestroyElements();
1132 }
1133 CONTAINER::Free(OldContainer);
1134 }
1135} // cList<TYPE, CONTAINER>::InsertRange
1136
1137
1138//--------------------------------------------------------------------------------
1139// cList<TYPE, CONTAINER>::ExpandTo
1140//--------------------------------------------------------------------------------
1141template<class TYPE, class CONTAINER>
1142inline TYPE& cList<TYPE, CONTAINER>::ExpandTo( int Index, const TYPE& Value ) {
1143 if ( Index >= Count() ) {
1144 Add( Value, Index - Count() + 1 );
1145 }
1146 return (*this)[ Index ];
1147}
1148
1149//-----------------------------------------------------------------------------
1150// cList<TYPE, CONTAINER>::Putp
1151//-----------------------------------------------------------------------------
1152template<class TYPE, class CONTAINER>
1153inline bool cList<TYPE, CONTAINER>::InsertFirstOrRemove( const TYPE& Value ) {
1154 const int i = find( Value );
1155 (i == -1) ? Insert( 0, Value ) : RemoveAt( i, 1 );
1156 return (i == -1);
1157}
1158
1159//-----------------------------------------------------------------------------
1160// cList<TYPE, CONTAINER>::Reverse
1161//-----------------------------------------------------------------------------
1162template<class TYPE, class CONTAINER>
1163inline void cList<TYPE, CONTAINER>::Reverse(const int Index, const int Count) {
1164 cAssert(Index >= 0);
1165 cAssert(Count >= 0);
1166 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1167 cAssert(Index + Count <= CurCount);
1168
1169 int i, h;
1170
1171 if(Count > 1) {
1172 h = Count / 2;
1173 for(i = 0; i < h; i++) {
1174 cMath::Swap(m_Container->List[Index + i], m_Container->List[Index + Count - 1 - i]);
1175 }
1176 }
1177}
1178
1179template<class TYPE, class CONTAINER>
1180inline void cList<TYPE, CONTAINER>::Reverse() {
1181 if(m_Container != nullptr) {
1182 Reverse(0, m_Container->Count);
1183 }
1184}
1185// cList<TYPE, CONTAINER>::Reverse
1186
1187//-----------------------------------------------------------------------------
1188// cList<TYPE, CONTAINER>::Resize
1189//-----------------------------------------------------------------------------
1190template<class TYPE, class CONTAINER>
1191inline CONTAINER * cList<TYPE, CONTAINER>::Resize(const int Capacity, const bool SkipDelete) {
1192 cAssert(Capacity >= 0);
1193
1194 if(Capacity <= 0) {
1195 Free();
1196 return nullptr;
1197 }
1198
1199 int OldCapacity = (nullptr == m_Container) ? 0 : m_Container->Capacity;
1200 if(Capacity == OldCapacity) {
1201 return nullptr;
1202 }
1203
1204 CONTAINER *OldContainer = m_Container;
1205 m_Container = CONTAINER::New(Capacity);
1206 m_Container->Count = (nullptr == OldContainer) ? 0 : OldContainer->Count;
1207 m_Container->Capacity = Capacity;
1208
1209 if(Capacity < m_Container->Count) {
1210 m_Container->Count = Capacity;
1211 }
1212
1213 if(OldContainer != nullptr) {
1214 OldContainer->Copy(m_Container, m_Container->Count);
1215 if(SkipDelete) {
1216 return OldContainer;
1217 } else {
1218 if (!std::is_trivially_copy_constructible<TYPE>()){
1219 OldContainer->DestroyElements();
1220 }
1221 CONTAINER::Free(OldContainer);
1222 }
1223 }
1224 return nullptr;
1225} // cList<TYPE, CONTAINER>::Resize
1226
1227//------------------------------------------------------------------------------------
1228// cList<TYPE, CONTAINER>::EnsureCapacity
1229//------------------------------------------------------------------------------------
1230template<class TYPE, class CONTAINER>
1231inline CONTAINER * cList<TYPE, CONTAINER>::EnsureCapacity(const int Capacity, const bool SkipDelete) {
1232 int OldCapacity = (nullptr == m_Container) ? 0 : m_Container->Capacity;
1233 if(Capacity > OldCapacity) {
1234 int S = Capacity + OldCapacity / 2;
1235 if (S < 8)S = 8;
1236 return Resize(S, SkipDelete);
1237 }
1238 return nullptr;
1239} // cList<TYPE, CONTAINER>::EnsureCapacity
1240
1241template<class TYPE, class CONTAINER>
1242inline void cList<TYPE, CONTAINER>::EnsureCapacity(int size){
1243 EnsureCapacity(size, false);
1244
1245}
1246// cList<TYPE, CONTAINER>::SetCount : void (const int)
1247template<class TYPE, class CONTAINER>
1248inline void cList<TYPE, CONTAINER>::SetCount(const int Count) {
1249 cAssert(Count >= 0);
1250 EnsureCapacity(Count, false);
1251 if(m_Container != nullptr) {
1252 m_Container->Count = Count;
1253 }
1254}
1255
1256// cList<TYPE, CONTAINER>::Fill
1257template<class TYPE, class CONTAINER>
1258inline void cList<TYPE, CONTAINER>::Fill(const TYPE &Value) {
1259 int i;
1260 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1261 for(i = 0; i < CurCount; i++) {
1262 m_Container->List[i] = Value;
1263 }
1264}
1265
1266// cList<TYPE, CONTAINER>::SetCount : void (const int, const TYPE &)
1267template<class TYPE, class CONTAINER>
1268inline void cList<TYPE, CONTAINER>::SetCount(const int _Count, const TYPE &Value) {
1269 int n0 = Count();
1270 SetCount(_Count);
1271 for (int i = n0; i < _Count; i++)SetAt(i, Value);
1272}
1273
1274//-----------------------------------------------------------------------------
1275// cList<TYPE, CONTAINER>::Sort : (..., Compare *)
1276//-----------------------------------------------------------------------------
1277template<class TYPE, class CONTAINER>
1278inline void cList<TYPE, CONTAINER>::Sort(const int Index, const int Count, Compare *C) {
1279 cAssert(Index >= 0);
1280 cAssert(Count >= 0);
1281 cAssert(Index + Count <= ((nullptr == m_Container) ? 0 : m_Container->Count));
1282
1283 int i = 0, j = 0, M = 0;
1284 bool f = false;
1285 TYPE K;
1286
1287 M = Count / 2;
1288 while(M >= 1) {
1289 for(i = M; i < Count; i++) {
1290 K = GetAt(i + Index);
1291 j = i - M;
1292 f = false;
1293 while(j >= 0 && !f) {
1294 if(C(&K, &GetAt(j + Index)) < 0) {
1295 SetAt(j + M + Index, GetAt(j + Index));
1296 j -= M;
1297 } else {
1298 f = true;
1299 }
1300 }
1301 SetAt(j + M + Index, K);
1302 }
1303 M /= 2;
1304 }
1305} // cList<TYPE, CONTAINER>::Sort : (..., Compare *)
1306
1307//-----------------------------------------------------------------------------
1308// cList<TYPE, CONTAINER>::Sort : (..., const CompareFunctor &)
1309//-----------------------------------------------------------------------------
1310template<class TYPE, class CONTAINER>
1311inline void cList<TYPE, CONTAINER>::Sort(const int Index, const int Count, const CompareFunctor &C) {
1312 cAssert(Index >= 0);
1313 cAssert(Count >= 0);
1314 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1315 cAssert(Index + Count <= CurCount);
1316
1317 int i = 0, j = 0, M = 0;
1318 bool f = false;
1319 TYPE K;
1320
1321 M = Count / 2;
1322 while(M >= 1) {
1323 for(i = M; i < Count; i++) {
1324 K = GetAt(i + Index);
1325 j = i - M;
1326 f = false;
1327 while(j >= 0 && !f) {
1328 if(C(K, GetAt(j + Index))) {
1329 f = true;
1330 } else {
1331 SetAt(j + M + Index, GetAt(j + Index));
1332 j -= M;
1333 }
1334 }
1335 SetAt(j + M + Index, K);
1336 }
1337 M /= 2;
1338 }
1339} // cList<TYPE, CONTAINER>::Sort : (..., const CompareFunctor &)
1340
1341// cList<TYPE, CONTAINER>::Sort
1342template<class TYPE, class CONTAINER>
1343void cList<TYPE, CONTAINER>::Sort(Compare *C) {
1344 Sort(0, Count(), C);
1345}
1346// cList<TYPE, CONTAINER>::Sort
1347template<class TYPE, class CONTAINER>
1348void cList<TYPE, CONTAINER>::Sort(const CompareFunctor &C) {
1349 Sort(0, Count(), C);
1350}
1351
1352// cList<TYPE, CONTAINER>::operator +=
1353template<class TYPE, class CONTAINER>
1354inline void cList<TYPE, CONTAINER>::operator += (const TYPE &u) {
1355 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1356 for(int i = 0; i < CurCount; i++) {
1357 m_Container->List[i] += u;
1358 }
1359}
1360
1361// cList<TYPE, CONTAINER>::operator -=
1362template<class TYPE, class CONTAINER>
1363inline void cList<TYPE, CONTAINER>::operator -= (const TYPE &u) {
1364 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1365 for(int i = 0; i < CurCount; i++) {
1366 m_Container->List[i] -= u;
1367 }
1368}
1369
1370// cList<TYPE, CONTAINER>::operator *=
1371template<class TYPE, class CONTAINER>
1372inline void cList<TYPE, CONTAINER>::operator *= (const TYPE &u) {
1373 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1374 for(int i = 0; i < CurCount; i++) {
1375 m_Container->List[i] *= u;
1376 }
1377}
1378
1379// cList<TYPE, CONTAINER>::operator /=
1380template<class TYPE, class CONTAINER>
1381inline void cList<TYPE, CONTAINER>::operator /= (const TYPE &u) {
1382 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1383 for(int i = 0; i < CurCount; i++) {
1384 m_Container->List[i] /= u;
1385 }
1386}
1387
1388// cList<TYPE, CONTAINER>::operator ==
1389template<class TYPE, class CONTAINER>
1390inline bool cList<TYPE, CONTAINER>::operator == (const cList<TYPE, CONTAINER> &Other) const {
1391 int CurCount = (nullptr == m_Container) ? 0 : m_Container->Count;
1392 int OtherCount = (nullptr == Other.m_Container) ? 0 : Other.m_Container->Count;
1393 if(CurCount != OtherCount) {
1394 return false;
1395 }
1396 for(int i = 0; i < CurCount; i++) {
1397 if(m_Container->List[i] != Other.m_Container->List[i]) {
1398 return false;
1399 }
1400 }
1401 return true;
1402}
1403
1404// cList<TYPE, CONTAINER>::operator !=
1405template<class TYPE, class CONTAINER>
1406inline bool cList<TYPE, CONTAINER>::operator != (const cList<TYPE, CONTAINER> &Other) const {
1407 return !(*this == Other);
1408}
1409
1410template<class TYPE, class CONTAINER>
1411::std::ostream & operator << (::std::ostream &out, const cList<TYPE, CONTAINER> &l) {
1412 for(int i = 0; i < l.Count(); ++i) {
1413 const bool needSeparator = ((i + 1) != l.Count());
1414 out << l[i] << (needSeparator ? " " : "");
1415 }
1416 return out;
1417}
1418
1419template<class TYPE, class CONTAINER>
1420inline bool cList<TYPE, CONTAINER>::some(::std::function<bool(const TYPE&)> fn) const {
1421 for (int i = 0; i < Count(); i++) if (fn((*this)[i])) return true;
1422 return false;
1423}
1424
1425template<class TYPE, class CONTAINER>
1426inline bool cList<TYPE, CONTAINER>::some(::std::function<bool(TYPE&)> fn) {
1427 for (int i = 0; i < Count(); i++) if (fn((*this)[i])) return true;
1428 return false;
1429}
1430
1431template<class TYPE, class CONTAINER>
1432inline int cList<TYPE, CONTAINER>::find(::std::function<bool(const TYPE&)> fn) const {
1433 for (int i = 0; i < Count(); i++) if (fn((*this)[i])) return i;
1434 return -1;
1435}
1436
1437template<class TYPE, class CONTAINER>
1438inline int cList<TYPE, CONTAINER>::find(::std::function<bool(TYPE&)> fn) {
1439 for (int i = 0; i < Count(); i++) if (fn((*this)[i])) return i;
1440 return -1;
1441}
1442
1443template<class TYPE, class CONTAINER>
1444inline bool cList<TYPE, CONTAINER>::every(::std::function<bool(const TYPE&)> fn) const {
1445 for (int i = 0; i < Count(); i++) if (!fn((*this)[i])) return false;
1446 return true;
1447}
1448
1449template<class TYPE, class CONTAINER>
1450inline void cList<TYPE, CONTAINER>::forEach(::std::function<void(TYPE&)> fn) {
1451 for (int i = 0; i < Count(); i++) fn((*this)[i]);
1452}
1453
1454template<class TYPE, class CONTAINER>
1455inline void cList<TYPE, CONTAINER>::forEach(::std::function<void(const TYPE&)> fn) const {
1456 for (int i = 0; i < Count(); i++) fn((*this)[i]);
1457}
1458
1459template<class TYPE, class CONTAINER>
1460inline void cList<TYPE, CONTAINER>::filter(cList<TYPE, CONTAINER>& result, ::std::function<bool(const TYPE&)> fn) const {
1461 result.Clear();
1462 for (int i = 0; i < Count(); i++) if (fn((*this)[i])) result.Add((*this)[i]);
1463}
1464
1465template<class TYPE, class CONTAINER>
1466template<class RES>
1467inline void cList<TYPE, CONTAINER>::reduce(RES& res, ::std::function<void(RES&, const TYPE&)> fn) const {
1468 for (int i = 0; i < Count(); i++) fn(res, (*this)[i]);
1469}
1470
1471template<class TYPE, class CONTAINER>
1472template<class RES>
1473inline void cList<TYPE, CONTAINER>::reduce(RES& res, ::std::function<void(RES&, TYPE&)> fn) {
1474 for (int i = 0; i < Count(); i++) fn(res, (*this)[i]);
1475}
The array template, refer it as coat::list <...> if you are using the Core API.
Definition cList.h:133
void filter(cList< TYPE, CONTAINER > &result, ::std::function< bool(const TYPE &)>) const
filter returns new array with elements that passed the check
Definition cList.h:1460
void reduce(RES &res, ::std::function< void(RES &, const TYPE &)> fn) const
reduce - sort of summ of all elements
Definition cList.h:1467
void forEach(::std::function< void(const TYPE &)>) const
execute callback for each element
Definition cList.h:1455
TYPE uGet(const int Index, const TYPE &defvalue)
Unlimited get - get value at index Index, if beyoud range - return defvalue.
Definition cList.h:735
bool every(::std::function< bool(const TYPE &)>) const
every returns true if all callbacks returned true
Definition cList.h:1444
int find(::std::function< bool(const TYPE &)>) const
find returns index of the element if some of callbacks returns true or returns -1
Definition cList.h:1432
bool some(::std::function< bool(const TYPE &)>) const
js - like functions
Definition cList.h:1420
void uSet(const int Index, const TYPE &value, const TYPE &defvalue)
Unlimited set - set value at index Index, if beyoud range - add correcsponding count of defvalue-s.
Definition cList.h:741