-
Notifications
You must be signed in to change notification settings - Fork 112
/
TELinkedList.hpp
1183 lines (1019 loc) · 40.8 KB
/
TELinkedList.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef AREG_BASE_TELINKEDLIST_HPP
#define AREG_BASE_TELINKEDLIST_HPP
/************************************************************************
* This file is part of the AREG SDK core engine.
* AREG SDK is dual-licensed under Free open source (Apache version 2.0
* License) and Commercial (with various pricing models) licenses, depending
* on the nature of the project (commercial, research, academic or free).
* You should have received a copy of the AREG SDK license description in LICENSE.txt.
* If not, please contact to info[at]aregtech.com
*
* \copyright (c) 2017-2023 Aregtech UG. All rights reserved.
* \file areg/base/TELinkedList.hpp
* \ingroup AREG SDK, Automated Real-time Event Grid Software Development Kit
* \author Artak Avetyan
* \brief AREG Platform, Linked List class template.
* The linked list contains list of values that can be
* accessed either by Position or by valid index.
* The size of Linked List is dynamic, Elements contain
* information of previous and next Block.
* Accessing element, insert and remove by Position
* operations are proceed fast. Accessing by index
* is slower.
*
************************************************************************/
/************************************************************************
* Include files.
************************************************************************/
#include "areg/base/GEGlobal.h"
#include "areg/base/TETemplateBase.hpp"
#include "areg/base/IEIOStream.hpp"
#include <algorithm>
#include <list>
//////////////////////////////////////////////////////////////////////////
// TELinkedList<VALUE> class template declaration
//////////////////////////////////////////////////////////////////////////
/**
* \brief Bi-directional Linked List class template to access, insert and
* remove entries by position, where is next and previous entry
* at the given position is accessed fast.
*
* The type VALUE should have at least default constructor, applicable
* comparing and assigning operators. The TELinkedList object is not
* thread safe and data access should be synchronized manually.
*
* \tparam VALUE The type of stored elements should be either primitive or have
* default constructor, applicable comparing and assigning operators.
**/
template <typename VALUE>
class TELinkedList : private Constless<std::list<VALUE>>
{
//////////////////////////////////////////////////////////////////////////
// Internal objects and types declaration
//////////////////////////////////////////////////////////////////////////
public:
using LISTPOS = typename std::list<VALUE>::iterator;
//////////////////////////////////////////////////////////////////////////
// Constructor / Destructor
//////////////////////////////////////////////////////////////////////////
public:
/**
* \brief Constructs en empty linked list object.
**/
TELinkedList( void ) = default;
/**
* \brief Copies entries from given source.
* \param src The source to copy data.
**/
TELinkedList( const TELinkedList<VALUE> & src ) = default;
/**
* \brief Moves entries from given source.
* \param src The source to move data.
**/
TELinkedList( TELinkedList<VALUE> && src ) noexcept = default;
/**
* \brief Destructor.
**/
~TELinkedList( void ) = default;
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
public:
/************************************************************************/
// Basic operators
/************************************************************************/
/**
* \brief Subscript operator. Returns reference to value of element by given valid zero-based index.
* May be used on either the right (r-value) or the left (l-value) of an assignment statement.
**/
inline VALUE& operator [] (uint32_t atIndex);
/**
* \brief Subscript operator. Returns reference to value of element by given valid zero-based index.
* The index should be valid number between 0 and (mSize -1).
* May be used on the right (r-value).
**/
inline const VALUE& operator [] (uint32_t atIndex) const;
/**
* \brief Subscript operator. Returns reference to value of element by given valid position value.
* May be used on either the right (r-value) or the left (l-value) of an assignment statement.
**/
inline VALUE& operator [] (LISTPOS atPosition);
/**
* \brief Subscript operator. Returns reference to value of element by given valid position value.
* May be used on the right (r-value).
**/
inline const VALUE& operator [] (const LISTPOS atPosition) const;
/**
* \brief Assigning operator. Copies all values from given source.
* If linked list previously had values, they will be removed and new values
* from source linked list will be set in the same sequence as they are
* present in the source.
* \param src The source of linked list values.
**/
inline TELinkedList<VALUE> & operator = ( const TELinkedList<VALUE> & src );
/**
* \brief Move operator. Moves all values from given source.
* If Array previously had values, they will be removed and new values
* from source Array will be set in the same sequence as they are
* present in the source.
* \param src The source of linked list values.
**/
inline TELinkedList<VALUE> & operator = ( TELinkedList<VALUE> && src ) noexcept;
/**
* \brief Checks equality of 2 linked list objects, and returns true if they are equal.
* There should be possible to compare VALUE type entries in the linked list.
* \param other The linked list object to compare.
**/
inline bool operator == ( const TELinkedList<VALUE> & other ) const;
/**
* \brief Checks inequality of 2 linked list objects, and returns true if they are not equal.
* There should be possible to compare VALUE type entries in the linked list.
* \param other The linked list object to compare.
**/
inline bool operator != ( const TELinkedList<VALUE> & other ) const;
/************************************************************************/
// Friend global operators to make Linked List streamable
/************************************************************************/
/**
* \brief Reads out from the stream linked list values.
* If linked list previously had values, they will be removed and new values
* from the stream will be set in the same sequence as they are present
* in the stream. There should be possibility to initialize values from
* streaming object and if VALUE is not a primitive, but an object, it
* should have implemented streaming operator.
* \param stream The streaming object to read values.
* \param input The linked list object to save initialized values.
**/
template<typename V>
friend inline const IEInStream & operator >> ( const IEInStream & stream, TELinkedList<V> & input );
/**
* \brief Writes to the stream the values of linked list.
* The values will be written to the stream starting from firs entry.
* There should be possibility to stream values and if VALUE is not a
* primitive, but an object, it should have implemented streaming operator.
* \param stream The stream to write values.
* \param input The linked list object containing value to stream.
**/
template<typename V>
friend inline IEOutStream & operator << ( IEOutStream & stream, const TELinkedList<V> & output );
//////////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////////
public:
/************************************************************************/
// Attributes
/************************************************************************/
/**
* \brief Returns true if the linked list is empty and has no elements.
**/
inline bool isEmpty( void ) const;
/**
* \brief Returns the current size of the linked list.
**/
inline uint32_t getSize( void ) const;
/**
* \brief Returns the position of the first value entry in the linked list, which is
* not invalid if the linked list is not empty. Otherwise, returns invalid position.
**/
inline LISTPOS firstPosition(void) const;
/**
* \brief Returns the position of the last value entry in the linked list, which is
* not invalid if the linked list is not empty. Otherwise, returns invalid position.
**/
inline LISTPOS lastPosition(void) const;
/**
* \brief Returns true if specified position points the first entry in the linked list.
* \param pos The position to check.
**/
inline bool isStartPosition(const LISTPOS pos) const;
/**
* \brief Returns true if specified position points the last entry in the linked list.
* \param pos The position to check.
**/
inline bool isLastPosition(const LISTPOS pos) const;
/**
* \brief Returns the invalid position of the linked list.
**/
inline LISTPOS invalidPosition(void) const;
/**
* \brief Returns true if specified position is invalid, i.e. points the end of the linked list.
**/
inline bool isInvalidPosition(const LISTPOS pos) const;
/**
* \brief Returns true if the given position is not pointing the end of the linked list.
* Note, it does not check whether there is a such position existing in the linked list.
*/
inline bool isValidPosition(const LISTPOS pos) const;
/**
* \brief Checks and ensures that specified position is pointing the valid entry in the linked list.
* The duration of checkup depends on the location of the position in the linked list.
* \param pos The position to check.
**/
inline bool checkPosition(const LISTPOS pos) const;
/**
* \brief Checks whether given element exist in the linked list or not. The elements of type
* VALUE should have comparing operators.
* \param elemSearch The element to search.
* \param startAt The position to start searching.
* \return Returns true if could find element starting at given position.
**/
inline bool contains(const VALUE& elemSearch) const;
inline bool contains( const VALUE & elemSearch, LISTPOS startAt) const;
/**
* \brief Returns the vector object where the data are stored.
**/
inline const std::list<VALUE>& getData(void) const;
//////////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////////
/**
* \brief Remove all entries of the linked list.
**/
inline void clear(void);
/**
* \brief Delete extra entries in the linked list.
**/
inline void freeExtra(void);
/**
* \brief Sets the size of the linked list to zero and deletes all capacity space.
*/
inline void release(void);
/**
* \brief Returns value of head element in Linked List container.
* On call the Linked List should not be empty, otherwise assertion is raised.
**/
inline const VALUE & firstEntry( void ) const;
inline VALUE & firstEntry(void);
/**
* \brief Returns value of tail element in Linked List container.
* On call the Linked List should not be empty, otherwise assertion is raised.
**/
inline const VALUE & lastEntry( void ) const;
inline VALUE & lastEntry(void);
/**
* \brief Returns the value at the given position of the linked list and on output the value
* of in_out_NextPosition points the next entry in the linked list or points to the
* invalid position if no more elements exist.
* \param in_out_NextPosition On input, this should be valid position of the element in the Linked List.
* On output, this contains position of the next entry in the Linked List
* or invalid position if reached end of the linked list.
**/
inline const VALUE & getNext( LISTPOS & IN OUT in_out_NextPosition ) const;
inline VALUE& getNext(LISTPOS& IN OUT in_out_NextPosition);
/**
* \brief Returns either valid position of the next entry in the Linked List or invalid position if
* reached end of the linked list.
* \param atPosition Actual position to get the next position. Should be valid position.
**/
inline LISTPOS nextPosition( LISTPOS atPosition ) const;
/**
* \brief Returns the value at the given position of the linked list and on output the value
* of in_out_PrevPosition points the previous entry in the linked list or points to the
* invalid position if it was the fist entry in the linked list.
* \param in_out_PrevPosition On input, this should be valid position of the element in the Linked List.
* On output, this contains position of the previous entry in the Linked List
* or invalid position if there is no more previous position in the linked list.
**/
inline const VALUE & getPrev( LISTPOS & IN OUT in_out_PrevPosition ) const;
inline VALUE& getPrev(LISTPOS& IN OUT in_out_PrevPosition);
/**
* \brief Returns either valid position of the previous entry in the Linked List or invalid position if
* indicates the first entry (no previous entry) of the linked list.
* \param atPosition Actual position to get the previous position. Should be valid position.
**/
inline LISTPOS prevPosition( LISTPOS atPosition ) const;
/**
* \brief Returns the value of entry at the given valid position.
* \param atPosition The valid position in Linked List
**/
inline VALUE& valueAtPosition(LISTPOS atPosition);
inline const VALUE & valueAtPosition( const LISTPOS atPosition ) const;
/**
* \brief Returns element value by valid zero-based index, which can be used by left (l-value) and
* right operation (r-value). The index should be valid.
**/
inline VALUE & getAt( uint32_t index );
/**
* \brief Returns element value by valid zero-based index, which can be used by right operation (r-value).
* The index should be valid.
**/
inline const VALUE & getAt(uint32_t index ) const;
/**
* \brief Extracts next position and value of the element in the linked list followed position.
*
* \param in_out_NextPosition On input this indicates the valid position of the entry in the linked list.
* On output, this parameter points either next valid entry in the linked list
* or invalid entry if no more entry is following.
* \param out_NextValue On output, this contain value of the next entry in the linked list.
* \return Returns true, if there is a next element and the output value is valid.
**/
inline bool nextEntry( LISTPOS & IN OUT in_out_NextPosition, VALUE & OUT out_NextValue ) const;
/**
* \brief Extracts previous position and value of the element in the linked list prior position.
*
* \param in_out_PrevPosition On input this indicates the valid position of the entry in the linked list.
* On output, this parameter points either previous valid entry in the linked list
* or invalid entry if has no previous entry, i.e. indicates first entry.
* \param out_PrevValue On output, this contain value of the previous entry in the linked list.
* \return Returns true, if there is a previous element and the output value is valid.
**/
inline bool prevEntry( LISTPOS & IN OUT in_out_PrevPosition, VALUE & OUT out_PrevValue ) const;
/**
* \brief Removes head element from Linked List.
**/
inline void removeFirst( void );
/**
* \brief Removes the head element from the linked list. On output, the 'value' contains
* data of removed element. Function returns true if linked list was not empty
* and the 'value' contains the data of removed element.
**/
inline bool removeFirst( VALUE & OUT value );
/**
* \brief Removes tail element from Linked List.
**/
inline void removeLast( void );
/**
* \brief Removes the tails element from the linked list. On output, the 'value' contains
* data of removed element. Function returns true if linked list was not empty
* and the 'value' contains the data of removed element.
**/
inline bool removeLast(VALUE& value);
/**
* \brief Add element to head of Linked List.
* \param newElement New head element to add in Linked List
**/
inline void pushFirst( const VALUE & newElement );
inline void pushFirst( VALUE && newElement );
/**
* \brief Adds new entry at the head of linked list if it is not existing.
* If parameter 'updateExisting' is true, it updates the existing entry.
* The method returns true if new element is added.
* \param newElement The element to add at the head of linked list.
* \param updateExisting If true, updates the existing element.
* If, for example, 2 objects are compared by the name and not by
* absolute values, setting this parameter true updates the existing entry.
* \return Returns true if inserted new entry at the head of the linked list. Otherwise, returns false.
**/
inline bool pushFirstIfUnique(const VALUE& newElement, bool updateExisting = false );
inline bool pushFirstIfUnique(VALUE&& newElement, bool updateExisting = false );
/**
* \brief Add element to tail of Linked List.
* \param newElement New tail element to add in Linked List
**/
inline void pushLast( const VALUE & newElement );
inline void pushLast( VALUE && newElement );
/**
* \brief Adds new entry at the tail of linked list if it is not existing.
* If parameter 'updateExisting' is true, it updates the existing entry.
* The method returns true if new element is added.
* \param newElement The element to add at the tail of linked list.
* \param updateExisting If true, updates the existing element.
* If, for example, 2 objects are compared by the name and not by
* absolute values, by setting this parameter true, you can replace
* the existing object.
* \return Returns true if inserted new entry at the tail of the linked list. Otherwise, returns false.
**/
inline bool pushLastIfUnique(const VALUE& newElement, bool updateExisting = false );
inline bool pushLastIfUnique(VALUE&& newElement, bool updateExisting = false );
/**
* \brief Pops the element at the head of linked list and returns the stored value.
* The linked list must not be empty.
**/
inline VALUE popFirst(void);
/**
* \brief Pops the element at the tails of linked list and returns the stored value.
* The linked list must not be empty.
**/
inline VALUE popLast(void);
/**
* \brief Inserts new element before given position. If given position is head element,
* it adds new head element.
* \param beforePosition The Linked List element valid position before new element should be inserted.
* \param newElement Value of new element to insert
* \return Returns position of new inserted element.
**/
inline LISTPOS insertBefore( LISTPOS beforePosition, const VALUE & newElement );
inline LISTPOS insertBefore(LISTPOS beforePosition, VALUE && newElement);
/**
* \brief Inserts new element after given position. If given position is tail element,
* it adds new tail element.
* \param afterPosition The Linked List element position after new element should be inserted
* \param newElement Value of new element to insert
* \return Returns position of new inserted element.
**/
inline LISTPOS insertAfter(LISTPOS afterPosition, const VALUE & newElement);
inline LISTPOS insertAfter(LISTPOS afterPosition, VALUE && newElement);
/**
* \brief Sets new value at give position.
* \param atPosition The Linked List element valid position to change value.
* \param newValue The Value to update.
**/
inline void setAt( LISTPOS atPosition, const VALUE & newValue );
/**
* \brief Removes element at given position and returns position of the next entry in the linked list.
* Returns invalid position if tail entry is removed.
* \param atPosition Position of the element to remove from Linked List.
* \param out_Value On output, it contains value of removed element
**/
inline LISTPOS removeAt( LISTPOS atPosition );
inline LISTPOS removeAt( LISTPOS atPosition, VALUE & OUT out_Value );
/**
* \brief Searches and removes first match of entry, which value is equal to the given element.
* Returns true if found and removed entry with success.
* \param removeElement Element to search and remove from Linked List
* \param searchAfter The valid position in the linked list to start searching.
**/
inline bool removeEntry( const VALUE & removeElement );
inline bool removeEntry(const VALUE& removeElement, LISTPOS searchAfter);
/**
* \brief Searches position of the entry by given value and returns valid position if found an entry.
* Otherwise, it returns invalid position.
* \param searchValue Value of element to search.
* \param searchAfter The valid position in the linked list to start searching.
**/
inline LISTPOS find(const VALUE& searchValue) const;
inline LISTPOS find( const VALUE & searchValue, LISTPOS searchAfter ) const;
/**
* \brief Returns valid position of the element by given zero-based index.
* Returns invalid position if the index is invalid.
* \param index The index of element in Linked List to get position.
**/
inline LISTPOS findIndex( uint32_t index ) const;
/**
* \brief Returns valid zero-based index of the element by given valid position.
* Returns invalid index (0xFFFFFFFF) if the position is invalid.
* \param atPosition The valid position in the linked list to return index.
**/
inline uint32_t makeIndex( LISTPOS atPosition ) const;
/**
* \brief Extracts elements from the given source and inserts into the linked list.
* No elements are copied. The container other becomes empty after the operation.
* \param source The source of linked list to merge.
*/
inline void merge(const TELinkedList<VALUE> & source);
inline void merge(TELinkedList<VALUE> && source);
protected:
/**
* \brief Returns the position of the element at the given zero-based index.
* \param index The index of the element to return position.
**/
inline LISTPOS getPosition( uint32_t index ) const;
inline LISTPOS getPosition(uint32_t index);
//////////////////////////////////////////////////////////////////////////
// Member Variables
//////////////////////////////////////////////////////////////////////////
protected:
/**
* \brief The linked list object
**/
std::list<VALUE> mValueList;
};
//////////////////////////////////////////////////////////////////////////
// TELinkedList<VALUE> class template implementation
//////////////////////////////////////////////////////////////////////////
template <typename VALUE >
inline TELinkedList<VALUE>& TELinkedList<VALUE>::operator = (const TELinkedList<VALUE>& src)
{
mValueList = src.mValueList;
return (*this);
}
template <typename VALUE >
inline TELinkedList<VALUE>& TELinkedList<VALUE>::operator = (TELinkedList<VALUE>&& src) noexcept
{
mValueList = std::move(src.mValueList);
return (*this);
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::operator == (const TELinkedList<VALUE>& other) const
{
return (mValueList == other.mValueList);
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::operator != (const TELinkedList<VALUE>& other) const
{
return (mValueList != other.mValueList);
}
template <typename VALUE >
inline VALUE & TELinkedList<VALUE>::operator [](uint32_t atIndex )
{
return getAt(atIndex);
}
template <typename VALUE >
inline VALUE & TELinkedList<VALUE>::operator []( LISTPOS atPosition )
{
return valueAtPosition(atPosition);
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::operator [](uint32_t atIndex ) const
{
return getAt(atIndex);
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::operator [] ( const LISTPOS atPosition ) const
{
return valueAtPosition(atPosition);
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::isEmpty( void ) const
{
return mValueList.empty();
}
template <typename VALUE >
inline uint32_t TELinkedList<VALUE>::getSize( void ) const
{
return static_cast<uint32_t>(mValueList.size());
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::firstPosition( void ) const
{
auto cit = mValueList.begin();
return Constless<std::list<VALUE>>::iter(mValueList, cit);
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::lastPosition( void ) const
{
auto cit = mValueList.empty() == false ? --mValueList.end() : mValueList.end();
return Constless<std::list<VALUE>>::iter(mValueList, cit);
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::isStartPosition(const LISTPOS pos) const
{
return (pos == mValueList.begin());
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::isLastPosition(const LISTPOS pos) const
{
return ((mValueList.empty() == false) && (pos == --mValueList.end()));
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::invalidPosition(void) const
{
auto end = mValueList.end();
return Constless<std::list<VALUE>>::iter(mValueList, end);
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::isInvalidPosition(const LISTPOS pos) const
{
return (pos == mValueList.end());
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::isValidPosition(const LISTPOS pos) const
{
return (pos != mValueList.end());
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::checkPosition(const LISTPOS pos) const
{
auto it = mValueList.begin();
while ((it != mValueList.end()) && (it != pos))
++it;
return (it != mValueList.end());
}
template <typename VALUE >
inline void TELinkedList<VALUE>::clear(void)
{
mValueList.clear();
}
template <typename VALUE >
inline void TELinkedList<VALUE>::freeExtra(void)
{
mValueList.clear();
}
template <typename VALUE >
inline void TELinkedList<VALUE>::release(void)
{
mValueList.clear();
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::firstEntry( void ) const
{
ASSERT(mValueList.empty() == false);
return mValueList.front();
}
template <typename VALUE >
inline VALUE& TELinkedList<VALUE>::firstEntry(void)
{
ASSERT(mValueList.empty() == false);
return mValueList.front();
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::lastEntry( void ) const
{
ASSERT(mValueList.empty() == false);
return mValueList.back();
}
template <typename VALUE >
inline VALUE& TELinkedList<VALUE>::lastEntry(void)
{
ASSERT(mValueList.empty() == false);
return mValueList.back();
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::getNext(LISTPOS& IN OUT in_out_NextPosition) const
{
return *in_out_NextPosition++;
}
template <typename VALUE >
inline VALUE& TELinkedList<VALUE>::getNext(LISTPOS& IN OUT in_out_NextPosition)
{
LISTPOS pos = in_out_NextPosition++;
return *pos;
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::nextPosition(LISTPOS atPosition) const
{
ASSERT(atPosition != mValueList.end());
return ++atPosition;
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::getPrev(LISTPOS& IN OUT in_out_PrevPosition) const
{
ASSERT(in_out_PrevPosition != mValueList.end());
LISTPOS pos = in_out_PrevPosition;
in_out_PrevPosition = in_out_PrevPosition == mValueList.begin() ? mValueList.end() : --in_out_PrevPosition;
return *pos;
}
template <typename VALUE >
inline VALUE & TELinkedList<VALUE>::getPrev(LISTPOS& IN OUT in_out_PrevPosition)
{
ASSERT(in_out_PrevPosition != mValueList.end());
LISTPOS pos = in_out_PrevPosition;
in_out_PrevPosition = in_out_PrevPosition == mValueList.begin() ? mValueList.end() : --in_out_PrevPosition;
return *pos;
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::prevPosition(LISTPOS atPosition) const
{
ASSERT(atPosition != mValueList.end());
return (atPosition == mValueList.begin() ? invalidPosition() : --atPosition);
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::valueAtPosition( const LISTPOS atPosition ) const
{
ASSERT(atPosition != mValueList.end());
return *atPosition;
}
template <typename VALUE >
inline VALUE & TELinkedList<VALUE>::valueAtPosition(LISTPOS atPosition)
{
ASSERT(atPosition != mValueList.end());
return *atPosition;
}
template <typename VALUE >
inline const VALUE & TELinkedList<VALUE>::getAt(uint32_t index) const
{
LISTPOS pos = getPosition(index);
ASSERT(isValidPosition(pos));
return *pos;
}
template <typename VALUE >
inline VALUE & TELinkedList<VALUE>::getAt(uint32_t index)
{
LISTPOS pos = getPosition(index);
ASSERT(isValidPosition(pos));
return *pos;
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::nextEntry(LISTPOS & IN OUT in_out_NextPosition, VALUE & OUT out_NextValue) const
{
bool result = false;
ASSERT(in_out_NextPosition != mValueList.end());
in_out_NextPosition = nextPosition(in_out_NextPosition);
if (in_out_NextPosition != mValueList.end())
{
out_NextValue = *in_out_NextPosition;
result = true;
}
return result;
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::prevEntry(LISTPOS& IN OUT in_out_PrevPosition, VALUE & OUT out_PrevValue) const
{
bool result = false;
ASSERT(in_out_PrevPosition != mValueList.end());
in_out_PrevPosition = prevPosition(in_out_PrevPosition);
if (in_out_PrevPosition != mValueList.end())
{
out_PrevValue = *in_out_PrevPosition;
result = true;
}
return result;
}
template <typename VALUE >
inline void TELinkedList<VALUE>::removeFirst( void )
{
ASSERT(mValueList.empty() == false);
mValueList.pop_front();
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::removeFirst(VALUE & OUT value)
{
bool result = false;
if (mValueList.empty() == false)
{
value = mValueList.front();
mValueList.pop_front();
result = true;
}
return result;
}
template <typename VALUE >
inline void TELinkedList<VALUE>::removeLast( void )
{
ASSERT(mValueList.empty() == false);
mValueList.pop_back();
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::removeLast(VALUE & value)
{
bool result = false;
if (mValueList.empty() == false)
{
value = mValueList.back();
mValueList.pop_back();
result = true;
}
return result;
}
template <typename VALUE >
inline void TELinkedList<VALUE>::pushFirst(const VALUE & newElement)
{
mValueList.push_front(newElement);
}
template <typename VALUE >
inline void TELinkedList<VALUE>::pushFirst( VALUE && newElement )
{
mValueList.push_front(std::move(newElement));
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::pushFirstIfUnique(const VALUE& newElement, bool updateExisting /*= false*/ )
{
bool result{ false };
auto pos = std::find( mValueList.begin( ), mValueList.end( ), newElement );
if ( pos == mValueList.end())
{
result = true;
mValueList.push_front(newElement);
}
else if (updateExisting )
{
*pos = newElement;
}
return result;
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::pushFirstIfUnique(VALUE&& newElement, bool updateExisting /*= false*/ )
{
bool result{ false };
auto pos = std::find( mValueList.begin( ), mValueList.end( ), newElement );
if ( pos == mValueList.end())
{
result = true;
mValueList.push_front(std::move(newElement));
}
else if ( updateExisting )
{
*pos = newElement;
}
return result;
}
template <typename VALUE >
inline void TELinkedList<VALUE>::pushLast(const VALUE & newElement)
{
mValueList.push_back(newElement);
}
template <typename VALUE >
inline void TELinkedList<VALUE>::pushLast(VALUE && newElement)
{
mValueList.push_back(std::move(newElement));
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::pushLastIfUnique(const VALUE& newElement, bool updateExisting /*= false*/ )
{
bool result{ false };
auto pos = std::find( mValueList.rbegin( ), mValueList.rend( ), newElement );
if (pos == mValueList.rend())
{
result = true;
mValueList.push_back(newElement);
}
else if ( updateExisting )
{
*pos = newElement;
}
return result;
}
template <typename VALUE >
inline bool TELinkedList<VALUE>::pushLastIfUnique(VALUE&& newElement, bool updateExisting /*= false*/ )
{
bool result{ false };
auto pos = std::find( mValueList.rbegin( ), mValueList.rend( ), newElement );
if (pos == mValueList.rend())
{
result = true;
mValueList.push_back(std::move(newElement));
}
else if ( updateExisting )
{
*pos = newElement;
}
return result;
}
template <typename VALUE >
inline VALUE TELinkedList<VALUE>::popFirst(void)
{
ASSERT(mValueList.empty() == false);
VALUE result = mValueList.front();
mValueList.pop_front();
return result;
}
template <typename VALUE >
inline VALUE TELinkedList<VALUE>::popLast(void)
{
ASSERT(mValueList.empty() == false);
VALUE result = mValueList.back();
mValueList.pop_back();
return result;
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::insertBefore(LISTPOS beforePosition, const VALUE & newElement)
{
return mValueList.insert(beforePosition, std::move(newElement));
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::insertBefore(LISTPOS beforePosition, VALUE && newElement)
{
return mValueList.insert(beforePosition, std::move(newElement));
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::insertAfter(LISTPOS afterPosition, const VALUE & newElement)
{
if (afterPosition == mValueList.end())
{
mValueList.push_back(newElement);
return lastPosition();
}
else
{
return mValueList.insert(++afterPosition, newElement);
}
}
template <typename VALUE >
inline typename TELinkedList<VALUE>::LISTPOS TELinkedList<VALUE>::insertAfter(LISTPOS afterPosition, VALUE && newElement)
{
if (afterPosition == mValueList.end())
{
mValueList.push_back(newElement);