Embedded Template Library  1.0
 All Classes Files Functions Variables Typedefs Friends Modules Pages
ilist.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 
8 Copyright(c) 2014 jwellbelove
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files(the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions :
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 ******************************************************************************/
28 
29 #ifndef __ETL_ILIST__
30 #define __ETL_ILIST__
31 #define __ETL_IN_ILIST_H__
32 
33 #if WIN32
34 #undef min
35 #endif
36 
37 #include <iterator>
38 #include <algorithm>
39 #include <functional>
40 #include <stddef.h>
41 
42 #include "nullptr.h"
43 #include "list_base.h"
44 #include "type_traits.h"
45 #include "parameter_type.h"
46 
47 namespace etl
48 {
49  //***************************************************************************
52  //***************************************************************************
53  template <typename T>
54  class ilist : public list_base
55  {
56  public:
57 
58  typedef T value_type;
59  typedef T* pointer;
60  typedef const T* const_pointer;
61  typedef T& reference;
62  typedef const T& const_reference;
63  typedef size_t size_type;
64 
65  protected:
66 
67  typedef typename parameter_type<T, is_fundamental<T>::value || is_pointer<T>::value>::type parameter_t;
68 
69 
70  //*************************************************************************
72  //*************************************************************************
73  struct Node
74  {
75  //***********************************************************************
77  //***********************************************************************
78  Node()
79  : previous(nullptr),
80  next(nullptr)
81  {
82  }
83 
84  //***********************************************************************
86  //***********************************************************************
87  void mark_as_free()
88  {
89  previous = nullptr;
90  next = nullptr;
91  }
92 
93  //***********************************************************************
95  //***********************************************************************
96  bool is_free() const
97  {
98  return next == nullptr;
99  }
100 
101  //***********************************************************************
103  //***********************************************************************
104  void reverse()
105  {
106  std::swap(previous, next);
107  }
108 
109  Node* previous;
110  Node* next;
111  };
112 
113  //*************************************************************************
115  //*************************************************************************
116  struct Data_Node : public Node
117  {
118  T value;
119  };
120 
123 
124  private:
125 
127  Data_Node* node_pool;
128 
129  //*************************************************************************
131  //*************************************************************************
132  static Data_Node* data_cast(Node* p_node)
133  {
134  return static_cast<Data_Node*>(p_node);
135  }
136 
137  //*************************************************************************
139  //*************************************************************************
140  static Data_Node& data_cast(Node& node)
141  {
142  return static_cast<Data_Node&>(node);
143  }
144 
145  //*************************************************************************
147  //*************************************************************************
148  static const Data_Node* data_cast(const Node* p_node)
149  {
150  return static_cast<const Data_Node*>(p_node);
151  }
152 
153  //*************************************************************************
155  //*************************************************************************
156  static const Data_Node& data_cast(const Node& node)
157  {
158  return static_cast<const Data_Node&>(node);
159  }
160 
161  public:
162 
163  //*************************************************************************
165  //*************************************************************************
166  class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
167  {
168  public:
169 
170  friend class ilist;
171 
172  iterator()
173  : p_node(nullptr)
174  {
175  }
176 
177  iterator(Node& node)
178  : p_node(&node)
179  {
180  }
181 
182  iterator(const iterator& other)
183  : p_node(other.p_node)
184  {
185  }
186 
187  iterator& operator ++()
188  {
189  p_node = p_node->next;
190  return *this;
191  }
192 
193  iterator operator ++(int)
194  {
195  iterator temp(*this);
196  p_node = p_node->next;
197  return temp;
198  }
199 
200  iterator& operator --()
201  {
202  p_node = p_node->previous;
203  return *this;
204  }
205 
206  iterator operator --(int)
207  {
208  iterator temp(*this);
209  p_node = p_node->previous;
210  return temp;
211  }
212 
213  iterator operator =(const iterator& other)
214  {
215  p_node = other.p_node;
216  return *this;
217  }
218 
219  reference operator *()
220  {
221  return ilist::data_cast(p_node)->value;
222  }
223 
224  const_reference operator *() const
225  {
226  return p_node->value;
227  }
228 
229  pointer operator &()
230  {
231  return &(ilist::data_cast(p_node)->value);
232  }
233 
234  const_pointer operator &() const
235  {
236  return &(ilist::data_cast(p_node)->value);
237  }
238 
239  pointer operator ->()
240  {
241  return &(ilist::data_cast(p_node)->value);
242  }
243 
244  const_pointer operator ->() const
245  {
246  return &(ilist::data_cast(p_node)->value);
247  }
248 
249  friend bool operator == (const iterator& lhs, const iterator& rhs)
250  {
251  return lhs.p_node == rhs.p_node;
252  }
253 
254  friend bool operator != (const iterator& lhs, const iterator& rhs)
255  {
256  return !(lhs == rhs);
257  }
258 
259  private:
260 
261  Node* p_node;
262  };
263 
264  //*************************************************************************
266  //*************************************************************************
267  class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const T>
268  {
269  public:
270 
271  friend class ilist;
272 
274  : p_node(nullptr)
275  {
276  }
277 
278  const_iterator(Node& node)
279  : p_node(&node)
280  {
281  }
282 
283  const_iterator(const Node& node)
284  : p_node(&node)
285  {
286  }
287 
288  const_iterator(const typename ilist::iterator& other)
289  : p_node(other.p_node)
290  {
291  }
292 
293  const_iterator(const const_iterator& other)
294  : p_node(other.p_node)
295  {
296  }
297 
298  const_iterator& operator ++()
299  {
300  p_node = p_node->next;
301  return *this;
302  }
303 
304  const_iterator operator ++(int)
305  {
306  const_iterator temp(*this);
307  p_node = p_node->next;
308  return temp;
309  }
310 
311  const_iterator& operator --()
312  {
313  p_node = p_node->previous;
314  return *this;
315  }
316 
317  const_iterator operator --(int)
318  {
319  const_iterator temp(*this);
320  p_node = p_node->previous;
321  return temp;
322  }
323 
324  const_iterator operator =(const const_iterator& other)
325  {
326  p_node = other.p_node;
327  return *this;
328  }
329 
330  const_reference operator *() const
331  {
332  return ilist::data_cast(p_node)->value;
333  }
334 
335  const_pointer operator &() const
336  {
337  return ilist::data_cast(p_node)->value;
338  }
339 
340  const Data_Node* operator ->() const
341  {
342  return p_node;
343  }
344 
345  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
346  {
347  return lhs.p_node == rhs.p_node;
348  }
349 
350  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
351  {
352  return !(lhs == rhs);
353  }
354 
355  private:
356 
357  const Node* p_node;
358  };
359 
360  typedef typename std::iterator_traits<iterator>::difference_type difference_type;
361 
362  typedef std::reverse_iterator<iterator> reverse_iterator;
363  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
364 
365  //*************************************************************************
367  //*************************************************************************
368  ilist& operator = (const ilist& rhs)
369  {
370  assign(rhs.cbegin(), rhs.cend());
371 
372  return *this;
373  }
374 
375  //*************************************************************************
377  //*************************************************************************
379  {
380  return iterator(get_head());
381  }
382 
383  //*************************************************************************
385  //*************************************************************************
387  {
388  return const_iterator(get_head());
389  }
390 
391  //*************************************************************************
393  //*************************************************************************
395  {
396  return iterator(terminal_node);
397  }
398 
399  //*************************************************************************
401  //*************************************************************************
403  {
404  return const_iterator(static_cast<const Data_Node&>(terminal_node));
405  }
406 
407  //*************************************************************************
409  //*************************************************************************
411  {
412  return const_iterator(get_head());
413  }
414 
415  //*************************************************************************
417  //*************************************************************************
419  {
420  return const_iterator(static_cast<const Data_Node&>(terminal_node));
421  }
422 
423  //*************************************************************************
425  //*************************************************************************
426  reverse_iterator rbegin()
427  {
428  return reverse_iterator(terminal_node);
429  }
430 
431  //*************************************************************************
433  //*************************************************************************
434  const_reverse_iterator rbegin() const
435  {
436  return const_reverse_iterator(static_cast<const Data_Node&>(terminal_node));
437  }
438 
439  //*************************************************************************
441  //*************************************************************************
442  reverse_iterator rend()
443  {
444  return reverse_iterator(get_head());
445  }
446 
447  //*************************************************************************
449  //*************************************************************************
450  const_reverse_iterator crbegin() const
451  {
452  return const_reverse_iterator(static_cast<const Data_Node&>(terminal_node));
453  }
454 
455  //*************************************************************************
457  //*************************************************************************
458  const_reverse_iterator crend() const
459  {
460  return const_reverse_iterator(get_head());
461  }
462 
463  //*************************************************************************
465  //*************************************************************************
466  reference front()
467  {
468  return data_cast(get_head()).value;
469  }
470 
471  //*************************************************************************
473  //*************************************************************************
474  const_reference front() const
475  {
476  return data_cast(get_head()).value;
477  }
478 
479  //*************************************************************************
481  //*************************************************************************
482  reference back()
483  {
484  return data_cast(get_tail()).value;
485  }
486 
487  //*************************************************************************
489  //*************************************************************************
490  const_reference back() const
491  {
492  return data_cast(get_tail()).value;
493  }
494 
495  //*************************************************************************
499  //*************************************************************************
500  template <typename TIterator>
501  void assign(TIterator first, TIterator last)
502  {
503  // Reset the links.
504  join(terminal_node, terminal_node);
505  current_size = 0;
506 
507  // Add all of the elements.
508  while (first != last)
509  {
510  if (!full())
511  {
512  Data_Node& data_node = node_pool[current_size];
513  data_node.value = *first;
514  join(get_tail(), data_node);
515  join(data_node, terminal_node);
516  }
517  else
518  {
519 #ifdef ETL_THROW_EXCEPTIONS
520  throw list_full();
521 #else
523 #endif
524  }
525 
526  ++first;
527  ++current_size;
528  }
529 
531 
532  // Clear the remaining elements in the node pool.
533  for (size_t i = current_size; i < MAX_SIZE; ++i)
534  {
535  node_pool[i].mark_as_free();
536  }
537  }
538 
539  //*************************************************************************
541  //*************************************************************************
542  void assign(size_t n, parameter_t value)
543  {
544  // Reset the links.
545  join(terminal_node, terminal_node);
546  current_size = 0;
547 
548  // Add all of the elements.
549  while (current_size < n)
550  {
551  if (!full())
552  {
553  Data_Node& data_node = node_pool[current_size];
554  data_node.value = value;
555  join(*terminal_node.previous, data_node);
556  join(data_node, terminal_node);
557  }
558  else
559  {
560 #ifdef ETL_THROW_EXCEPTIONS
561  throw list_full();
562 #else
564 #endif
565  }
566 
567  ++current_size;
568  }
569 
571 
572  // Clear the remaining elements in the node pool.
573  for (size_t i = current_size; i < MAX_SIZE; ++i)
574  {
575  node_pool[i].mark_as_free();
576  }
577  }
578 
579  //*************************************************************************
581  //*************************************************************************
582  void push_front()
583  {
584  if (!full())
585  {
586  Data_Node& data_node = node_pool[next_free];
587  insert_node(get_head(), data_node);
588  }
589  else
590  {
591 #ifdef ETL_THROW_EXCEPTIONS
592  throw list_full();
593 #else
595 #endif
596  }
597  }
598 
599  //*************************************************************************
601  //*************************************************************************
602  void push_front(parameter_t value)
603  {
604  if (!full())
605  {
606  Data_Node& data_node = node_pool[next_free];
607  data_node.value = value;
608  insert_node(get_head(), data_node);
609  }
610  else
611  {
612 #ifdef ETL_THROW_EXCEPTIONS
613  throw list_full();
614 #else
616 #endif
617  }
618  }
619 
620  //*************************************************************************
622  //*************************************************************************
623  void pop_front()
624  {
625  if (!empty())
626  {
627  remove_node(get_head());
628  }
629  }
630 
631  //*************************************************************************
633  //*************************************************************************
634  void push_back()
635  {
636  if (!full())
637  {
638  Data_Node& data_node = node_pool[next_free];
639  insert_node(terminal_node, data_node);
640  }
641  else
642  {
643 #ifdef ETL_THROW_EXCEPTIONS
644  throw list_full();
645 #else
647 #endif
648  }
649  }
650 
651  //*************************************************************************
653  //*************************************************************************
654  void push_back(parameter_t value)
655  {
656  if (!full())
657  {
658  Data_Node& data_node = node_pool[next_free];
659  data_node.value = value;
660  insert_node(terminal_node, data_node);
661  }
662  else
663  {
664 #ifdef ETL_THROW_EXCEPTIONS
665  throw list_full();
666 #else
668 #endif
669  }
670  }
671 
672  //*************************************************************************
674  //*************************************************************************
675  void pop_back()
676  {
677  if (!empty())
678  {
679  remove_node(get_tail());
680  }
681  }
682 
683  //*************************************************************************
685  //*************************************************************************
686  iterator insert(iterator position, const value_type& value)
687  {
688  if (!full())
689  {
690  Data_Node& data_node = node_pool[next_free];
691  data_node.value = value;
692 
693  insert_node(*position.p_node, data_node);
694 
695  return iterator(data_node);
696  }
697  else
698  {
699 #ifdef ETL_THROW_EXCEPTIONS
700  throw list_full();
701 #else
703  return end();
704 #endif
705  }
706  }
707 
708  //*************************************************************************
710  //*************************************************************************
711  void insert(iterator position, size_t n, const value_type& value)
712  {
713  for (size_t i = 0; i < n; ++i)
714  {
715  if (!full())
716  {
717  // Set up the next free node and insert.
718  Data_Node& data_node = node_pool[next_free];
719  data_node.value = value;
720  insert_node(*position.p_node, data_node);
721  }
722  else
723  {
724 #ifdef ETL_THROW_EXCEPTIONS
725  throw list_full();
726 #else
728 #endif
729  }
730  }
731  }
732 
733  //*************************************************************************
735  //*************************************************************************
736  template <typename TIterator>
737  void insert(iterator position, TIterator first, TIterator last)
738  {
739  while (first != last)
740  {
741  if (!full())
742  {
743  // Set up the next free node and insert.
744  Data_Node& data_node = node_pool[next_free];
745  data_node.value = *first++;
746  insert_node(*position.p_node, data_node);
747  }
748  else
749  {
750 #ifdef ETL_THROW_EXCEPTIONS
751  throw list_full();
752 #else
754 #endif
755  }
756  }
757  }
758 
759  //*************************************************************************
761  //*************************************************************************
763  {
764  iterator next(position);
765  ++next;
766 
767  remove_node(*position.p_node);
768 
769  return next;
770  }
771 
772  //*************************************************************************
774  //*************************************************************************
776  {
777  Node* p_first = first.p_node;
778  Node* p_last = last.p_node;
779  Node* p_next;
780 
781  // Join the ends.
782  join(*(p_first->previous), *p_last);
783 
784  // Erase the ones in between.
785  while (p_first != p_last)
786  {
787  // Update the position of the earliest free node in the pool.
788  size_t new_free = std::distance(&node_pool[0], data_cast(p_first));
789  next_free = std::min(next_free, new_free);
790 
791  // One less.
792  --current_size;
793 
794  p_next = p_first->next; // Remember the next node.
795  p_first->mark_as_free(); // Free the current node.
796  p_first = p_next; // Move to the next node.
797  }
798 
799  return last;
800  }
801 
802  //*************************************************************************
804  //*************************************************************************
805  void resize(size_t n)
806  {
807  resize(n, T());
808  }
809 
810  //*************************************************************************
812  //*************************************************************************
813  void resize(size_t n, parameter_t value)
814  {
815  if (n > MAX_SIZE)
816  {
817 #ifdef ETL_THROW_EXCEPTIONS
818  throw list_full();
819 #else
821  n = MAX_SIZE;
822 #endif
823  }
824 
825  // Smaller?
826  if (n < size())
827  {
828  iterator i_start = end();
829  std::advance(i_start, -difference_type(size() - n));
830  erase(i_start, end());
831  }
832  // Larger?
833  else if (n > size())
834  {
835  insert(end(), n - size(), value);
836  }
837  }
838 
839  //*************************************************************************
841  //*************************************************************************
842  void clear()
843  {
844  initialise();
845  }
846 
847  //*************************************************************************
848  // Removes the values specified.
849  //*************************************************************************
850  void remove(const value_type& value)
851  {
852  iterator iValue = begin();
853 
854  while (iValue != end())
855  {
856  if (value == *iValue)
857  {
858  iValue = erase(iValue);
859  }
860  else
861  {
862  ++iValue;
863  }
864  }
865  }
866 
867  //*************************************************************************
869  //*************************************************************************
870  template <typename TPredicate>
871  void remove_if(TPredicate predicate)
872  {
873  iterator iValue = begin();
874 
875  while (iValue != end())
876  {
877  if (predicate(*iValue))
878  {
879  iValue = erase(iValue);
880  }
881  else
882  {
883  ++iValue;
884  }
885  }
886  }
887 
888  //*************************************************************************
891  //*************************************************************************
892  void unique()
893  {
894  unique(std::equal_to<T>());
895  }
896 
897  //*************************************************************************
900  //*************************************************************************
901  template <typename TIsEqual>
902  void unique(TIsEqual isEqual)
903  {
904  if (empty())
905  {
906  return;
907  }
908 
909  iterator i_item = begin();
910  ++i_item;
911  iterator i_previous = begin();
912 
913  while (i_item != end())
914  {
915  if (isEqual(*i_previous, *i_item))
916  {
917  i_item = erase(i_item);
918  }
919  else
920  {
921  i_previous = i_item;
922  ++i_item;
923  }
924  }
925  }
926 
927  //*************************************************************************
930  //*************************************************************************
931  void sort()
932  {
933  sort(std::less<T>());
934  }
935 
936  //*************************************************************************
940  //*************************************************************************
941  template <typename TCompare>
942  void sort(TCompare compare)
943  {
944  iterator i_left;
945  iterator i_right;
946  iterator i_node;
947  iterator i_head;
948  iterator i_tail;
949  int list_size = 1;
950  int number_of_merges;
951  int left_size;
952  int right_size;
953 
954  if (is_trivial_list())
955  {
956  return;
957  }
958 
959  while (true)
960  {
961  i_left = begin();
962  i_head = end();
963  i_tail = end();
964 
965  number_of_merges = 0; // Count the number of merges we do in this pass.
966 
967  while (i_left != end())
968  {
969  ++number_of_merges; // There exists a merge to be done.
970  i_right = i_left;
971  left_size = 0;
972 
973  // Step 'list_size' places along from left
974  for (int i = 0; i < list_size; ++i)
975  {
976  ++left_size;
977  ++i_right;
978 
979  if (i_right == end())
980  {
981  break;
982  }
983  }
984 
985  // If right hasn't fallen off end, we have two lists to merge.
986  right_size = list_size;
987 
988  // Now we have two lists. Merge them.
989  while (left_size > 0 || (right_size > 0 && i_right != end()))
990  {
991  // Decide whether the next node of merge comes from left or right.
992  if (left_size == 0)
993  {
994  // Left is empty. The node must come from right.
995  i_node = i_right++;
996  --right_size;
997  }
998  else if (right_size == 0 || i_right == end())
999  {
1000  // Right is empty. The node must come from left.
1001  i_node = i_left++;
1002  --left_size;
1003  }
1004  else if (compare(*i_left, *i_right))
1005  {
1006  // First node of left is lower or same. The node must come from left.
1007  i_node = i_left++;
1008  --left_size;
1009  }
1010  else
1011  {
1012  // First node of right is lower. The node must come from right.
1013  i_node = i_right;
1014  ++i_right;
1015  --right_size;
1016  }
1017 
1018  // Add the next node to the merged head.
1019  if (i_head == end())
1020  {
1021  join(*i_head.p_node, *i_node.p_node);
1022  i_head = i_node;
1023  i_tail = i_node;
1024  }
1025  else
1026  {
1027  join(*i_tail.p_node, *i_node.p_node);
1028  i_tail = i_node;
1029  }
1030 
1031  join(*i_tail.p_node, terminal_node);
1032  }
1033 
1034  // Now left has stepped `list_size' places along, and right has too.
1035  i_left = i_right;
1036  }
1037 
1038  // If we have done only one merge, we're finished.
1039  if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
1040  {
1041  return;
1042  }
1043 
1044  // Otherwise repeat, merging lists twice the size
1045  list_size *= 2;
1046  }
1047  }
1048 
1049  //*************************************************************************
1051  //*************************************************************************
1052  void reverse()
1053  {
1054  if (is_trivial_list())
1055  {
1056  return;
1057  }
1058 
1059  iterator i_item = begin();
1060 
1061  while (i_item != end())
1062  {
1063  i_item.p_node->reverse();
1064  --i_item; // Now we've reversed it, we must decrement it.
1065  }
1066 
1067  // Terminal node.
1068  i_item.p_node->reverse();
1069  }
1070 
1071  protected:
1072 
1073  //*************************************************************************
1075  //*************************************************************************
1076  ilist(Data_Node* node_pool, size_t max_size_)
1077  : list_base(max_size_),
1078  node_pool(node_pool)
1079  {
1080  initialise();
1081  }
1082 
1083  private:
1084 
1085  //*************************************************************************
1087  //*************************************************************************
1088  void join(Node& left, Node& right)
1089  {
1090  left.next = &right;
1091  right.previous = &left;
1092  }
1093 
1094  //*************************************************************************
1096  //*************************************************************************
1097  void join(Data_Node& left, Data_Node& right)
1098  {
1099  left.next = &right;
1100  right.previous = &left;
1101  }
1102 
1103  //*************************************************************************
1105  //*************************************************************************
1106  bool is_trivial_list() const
1107  {
1108  return (size() < 2);
1109  }
1110 
1111  //*************************************************************************
1113  //*************************************************************************
1114  void find_next_free()
1115  {
1116  while (next_free != MAX_SIZE)
1117  {
1118  if (node_pool[next_free].is_free())
1119  {
1120  return;
1121  }
1122  else
1123  {
1124  ++next_free;
1125  }
1126  }
1127  }
1128 
1129  //*************************************************************************
1131  //*************************************************************************
1132  void insert_node(Node& position, Node& node)
1133  {
1134  // Connect to the list.
1135  join(*position.previous, node);
1136  join(node, position);
1137 
1138  // One more.
1139  ++current_size;
1140 
1141  // Update the position of the next free node in the pool.
1142  find_next_free();
1143  }
1144 
1145  //*************************************************************************
1147  //*************************************************************************
1148  void remove_node(Node& node)
1149  {
1150  // Update the position of the next free node in the pool.
1151  size_t new_free = std::distance(&node_pool[0], data_cast(&node));
1152  next_free = std::min(next_free, new_free);
1153 
1154  // One less.
1155  --current_size;
1156 
1157  // Disconnect the node from the list.
1158  join(*node.previous, *node.next);
1159  node.mark_as_free();
1160  }
1161 
1162  //*************************************************************************
1164  //*************************************************************************
1165  Node& get_head()
1166  {
1167  return *terminal_node.next;
1168  }
1169 
1170  //*************************************************************************
1172  //*************************************************************************
1173  const Node& get_head() const
1174  {
1175  return *terminal_node.next;
1176  }
1177 
1178  //*************************************************************************
1180  //*************************************************************************
1181  Node& get_tail()
1182  {
1183  return *terminal_node.previous;
1184  }
1185 
1186  //*************************************************************************
1188  //*************************************************************************
1189  const Node& get_tail() const
1190  {
1191  return *terminal_node.previous;
1192  }
1193 
1194  //*************************************************************************
1196  //*************************************************************************
1197  void initialise()
1198  {
1199  // Reset the node pool.
1200  for (size_t i = 0; i < max_size(); ++i)
1201  {
1202  node_pool[i].mark_as_free();
1203  }
1204 
1205  next_free = 0;
1206  current_size = 0;
1207  join(terminal_node, terminal_node);
1208  }
1209  };
1210 }
1211 
1212 //*************************************************************************
1217 //*************************************************************************
1218 template <typename T>
1219 bool operator ==(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1220 {
1221  return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
1222 }
1223 
1224 //*************************************************************************
1229 //*************************************************************************
1230 template <typename T>
1231 bool operator !=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1232 {
1233  return !(lhs == rhs);
1234 }
1235 
1236 //*************************************************************************
1242 //*************************************************************************
1243 template <typename T>
1244 bool operator <(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1245 {
1246  return std::lexicographical_compare(lhs.begin(),
1247  lhs.end(),
1248  rhs.begin(),
1249  rhs.end());
1250 }
1251 
1252 //*************************************************************************
1258 //*************************************************************************
1259 template <typename T>
1260 bool operator >(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1261 {
1262  return std::lexicographical_compare(lhs.begin(),
1263  lhs.end(),
1264  rhs.begin(),
1265  rhs.end(),
1266  std::greater<T>());
1267 }
1268 
1269 //*************************************************************************
1275 //*************************************************************************
1276 template <typename T>
1277 bool operator <=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1278 {
1279  return !operator >(lhs, rhs);
1280 }
1281 
1282 //*************************************************************************
1288 //*************************************************************************
1289 template <typename T>
1290 bool operator >=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
1291 {
1292  return !operator <(lhs, rhs);
1293 }
1294 
1295 #if WIN32
1296 #define min(a,b) (((a) < (b)) ? (a) : (b))
1297 #endif
1298 
1299 #endif
bool operator!=(const etl::ilist< T > &lhs, const etl::ilist< T > &rhs)
Definition: ilist.h:1231
const size_type MAX_SIZE
The maximum size of the list.
Definition: list_base.h:149
reference front()
Gets a reference to the first element.
Definition: ilist.h:466
void assign(size_t n, parameter_t value)
Assigns 'n' copies of a value to the list.
Definition: ilist.h:542
bitset< N > operator&(const bitset< N > &lhs, const bitset< N > &rhs)
Definition: bitset.h:1154
const_iterator
Definition: ilist.h:267
void assign(TIterator first, TIterator last)
If ETL_THROW_EXCEPTIONS & _DEBUG are defined throws list_iterator if the iterators are reversed...
Definition: ilist.h:501
const_reference front() const
Gets a const reference to the first element.
Definition: ilist.h:474
void clear()
Clears the list.
Definition: ilist.h:842
reference back()
Gets a reference to the last element.
Definition: ilist.h:482
void pop_back()
Removes a value from the back of the list.
Definition: ilist.h:675
iterator.
Definition: ilist.h:166
void swap(etl::bitset< N > &lhs, etl::bitset< N > &rhs)
swap
Definition: bitset.h:1200
void pop_front()
Removes a value from the front of the list.
Definition: ilist.h:623
Determine how to pass parameters.
Definition: parameter_type.h:40
void sort()
Definition: ilist.h:931
Node()
Constructor.
Definition: ilist.h:78
bool full() const
Checks to see if the list is full.
Definition: list_base.h:120
void push_back()
Adds a node to the back of the list so a new value can be assigned to back().
Definition: ilist.h:634
void unique()
Definition: ilist.h:892
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition: ilist.h:871
iterator end()
Gets the end of the list.
Definition: ilist.h:394
void push_front(parameter_t value)
Pushes a value to the front of the list.
Definition: ilist.h:602
Definition: list_base.h:59
size_type current_size
The number of the used nodes.
Definition: list_base.h:148
void reverse()
Reverses the previous & next pointers.
Definition: ilist.h:104
iterator erase(iterator position)
Erases the value at the specified position.
Definition: ilist.h:762
const_iterator end() const
Gets the end of the list.
Definition: ilist.h:402
void push_back(parameter_t value)
Pushes a value to the back of the list..
Definition: ilist.h:654
bool empty() const
Checks to see if the list is empty.
Definition: list_base.h:112
void reverse()
Reverses the list.
Definition: ilist.h:1052
The node element in the list.
Definition: ilist.h:73
const_reverse_iterator rbegin() const
Gets the reverse beginning of the list.
Definition: ilist.h:434
void unique(TIsEqual isEqual)
Definition: ilist.h:902
Definition: algorithm.h:43
bool operator>=(const etl::ilist< T > &lhs, const etl::ilist< T > &rhs)
Definition: ilist.h:1290
ilist(Data_Node *node_pool, size_t max_size_)
Constructor.
Definition: ilist.h:1076
void push_front()
Adds a node to the front of the list so a new value can be assigned to front().
Definition: ilist.h:582
const_reverse_iterator crbegin() const
Gets the reverse beginning of the list.
Definition: ilist.h:450
bool operator<(const etl::ilist< T > &lhs, const etl::ilist< T > &rhs)
Definition: ilist.h:1244
const_reverse_iterator crend() const
Gets the reverse end of the list.
Definition: ilist.h:458
const_iterator begin() const
Gets the beginning of the list.
Definition: ilist.h:386
ilist & operator=(const ilist &rhs)
Assignment operator.
Definition: ilist.h:368
TIterator next(TIterator iterator, ptrdiff_t n=1)
Definition: container.h:245
size_type max_size() const
Gets the maximum possible size of the list.
Definition: list_base.h:104
const_iterator cend() const
Gets the end of the list.
Definition: ilist.h:418
const_reference back() const
Gets a reference to the last element.
Definition: ilist.h:490
bool operator>(const etl::ilist< T > &lhs, const etl::ilist< T > &rhs)
Definition: ilist.h:1260
Definition: type_traits.h:226
size_type next_free
The index of the next free node.
Definition: list_base.h:147
void resize(size_t n)
Resizes the list.
Definition: ilist.h:805
Definition: list_base.h:87
void resize(size_t n, parameter_t value)
Resizes the list.
Definition: ilist.h:813
reverse_iterator rend()
Gets the reverse end of the list.
Definition: ilist.h:442
static void error(const exception &e)
Definition: error_handler.cpp:50
size_type size() const
Gets the size of the list.
Definition: list_base.h:96
Node terminal_node
The node that acts as the list start and end.
Definition: ilist.h:122
void sort(TCompare compare)
Definition: ilist.h:942
void mark_as_free()
Marks the node as free.
Definition: ilist.h:87
bool operator==(const etl::ilist< T > &lhs, const etl::ilist< T > &rhs)
Definition: ilist.h:1219
void insert(iterator position, TIterator first, TIterator last)
Inserts a range of values to the list at the specified position.
Definition: ilist.h:737
bool is_free() const
Checks if the node is free.
Definition: ilist.h:96
void insert(iterator position, size_t n, const value_type &value)
Inserts 'n' copies of a value to the list at the specified position.
Definition: ilist.h:711
iterator begin()
Gets the beginning of the list.
Definition: ilist.h:378
iterator insert(iterator position, const value_type &value)
Inserts a value to the list at the specified position.
Definition: ilist.h:686
reverse_iterator rbegin()
Gets the reverse beginning of the list.
Definition: ilist.h:426
Definition: ilist.h:54
const_iterator cbegin() const
Gets the beginning of the list.
Definition: ilist.h:410
iterator erase(iterator first, iterator last)
Erases a range of elements.
Definition: ilist.h:775
The data node element in the list.
Definition: ilist.h:116