Embedded Template Library  1.0
 All Classes Files Functions Variables Typedefs Friends Modules Pages
ideque.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_IDEQUE__
30 #define __ETL_IDEQUE__
31 #define __ETL_IN_IDEQUE_H__
32 
33 #include <stddef.h>
34 #include <iterator>
35 
36 #include "type_traits.h"
37 #include "deque_base.h"
38 #include "parameter_type.h"
39 
40 #ifndef ETL_THROW_EXCEPTIONS
41 #include "error_handler.h"
42 #endif
43 
44 namespace etl
45 {
46  //***************************************************************************
50  //***************************************************************************
51  template <typename T>
52  class ideque : public deque_base
53  {
54  public:
55 
56  typedef T value_type;
57  typedef size_t size_type;
58  typedef T& reference;
59  typedef const T& const_reference;
60  typedef T* pointer;
61  typedef const T* const_pointer;
62  typedef typename std::iterator_traits<pointer>::difference_type difference_type;
63 
64  protected:
65 
66  typedef typename parameter_type<T>::type parameter_t;
67 
68  //*************************************************************************
70  //*************************************************************************
71  template <typename TIterator>
72  struct is_iterator : public etl::integral_constant<bool, !etl::is_integral<TIterator>::value && !etl::is_floating_point<TIterator>::value>
73  {
74  };
75 
76  public:
77 
78  //*************************************************************************
80  //*************************************************************************
81  struct iterator : public std::iterator<std::random_access_iterator_tag, T>
82  {
83  friend class ideque;
84 
85  //***************************************************
86  iterator()
87  : index(0),
88  p_deque(0),
89  p_buffer(0)
90  {
91  }
92 
93  //***************************************************
94  iterator(const iterator& other)
95  : index(other.index),
96  p_deque(other.p_deque),
97  p_buffer(other.p_buffer)
98  {
99  }
100 
101  //***************************************************
102  iterator& operator ++()
103  {
104  index = (index == p_deque->MAX_SIZE) ? 0 : index + 1;
105 
106  return *this;
107  }
108 
109  //***************************************************
110  iterator operator ++(int)
111  {
112  iterator previous(*this);
113  index = (index == p_deque->MAX_SIZE) ? 0 : index + 1;
114 
115  return previous;
116  }
117 
118  //***************************************************
119  iterator operator +=(difference_type offset)
120  {
121  if (offset > 0)
122  {
123  index += offset;
124  index = (static_cast<size_t>(index) > p_deque->MAX_SIZE) ? index - p_deque->BUFFER_SIZE : index;
125  }
126  else if (offset < 0)
127  {
128  operator -= (-offset);
129  }
130 
131  return *this;
132  }
133 
134  //***************************************************
135  iterator operator -=(difference_type offset)
136  {
137  if (offset > 0)
138  {
139  index -= offset;
140  index = (index < 0) ? index + p_deque->BUFFER_SIZE : index;
141  }
142  else if (offset < 0)
143  {
144  operator += (-offset);
145  }
146 
147  return *this;
148  }
149 
150  //***************************************************
151  iterator& operator --()
152  {
153  index = (index == 0) ? p_deque->MAX_SIZE : index - 1;
154 
155  return *this;
156  }
157 
158  //***************************************************
159  iterator operator --(int)
160  {
161  iterator previous(*this);
162  index = (index == 0) ? p_deque->MAX_SIZE : index - 1;
163 
164  return previous;
165  }
166 
167  //***************************************************
168  reference operator *()
169  {
170  return p_buffer[index];
171  }
172 
173  //***************************************************
174  const_reference operator *() const
175  {
176  return p_buffer[index];
177  }
178 
179  //***************************************************
180  pointer operator ->()
181  {
182  return &p_buffer[index];
183  }
184 
185  //***************************************************
186  const_pointer operator ->() const
187  {
188  return &p_buffer[index];
189  }
190 
191  //***************************************************
192  bool operator <(const iterator& other) const
193  {
194  return ideque::distance(*this, other) > 0;
195  }
196 
197  //***************************************************
198  friend iterator operator +(const iterator& lhs, difference_type offset)
199  {
200  iterator result(lhs);
201  result += offset;
202  return result;
203  }
204 
205  //***************************************************
206  friend iterator operator -(const iterator& lhs, difference_type offset)
207  {
208  iterator result(lhs);
209  result -= offset;
210  return result;
211  }
212 
213  //***************************************************
214  friend bool operator == (const iterator& lhs, const iterator& rhs)
215  {
216  return lhs.index == rhs.index;
217  }
218 
219  //***************************************************
220  friend bool operator != (const iterator& lhs, const iterator& rhs)
221  {
222  return !(lhs == rhs);
223  }
224 
225  //***************************************************
226  difference_type get_index() const
227  {
228  return index;
229  }
230 
231  //***************************************************
232  ideque& get_deque() const
233  {
234  return *p_deque;
235  }
236 
237  //***************************************************
238  pointer get_buffer() const
239  {
240  return p_buffer;
241  }
242 
243  //***************************************************
244  void swap(iterator& other)
245  {
246  std::swap(index, other.index);
247  }
248 
249  private:
250 
251  //***************************************************
252  iterator(difference_type index, ideque& the_deque, pointer p_buffer)
253  : index(index),
254  p_deque(&the_deque),
255  p_buffer(p_buffer)
256  {
257  }
258 
259  difference_type index;
260  ideque* p_deque;
261  pointer p_buffer;
262  };
263 
264  //*************************************************************************
266  //*************************************************************************
267  struct const_iterator : public std::iterator<std::random_access_iterator_tag, const T>
268  {
269  friend class ideque;
270 
271  //***************************************************
273  : index(0),
274  p_deque(0),
275  p_buffer(0)
276  {
277  }
278 
279  //***************************************************
280  const_iterator(const const_iterator& other)
281  : index(other.index),
282  p_deque(other.p_deque),
283  p_buffer(other.p_buffer)
284  {
285  }
286 
287  //***************************************************
288  const_iterator(const typename ideque::iterator& other)
289  : index(other.index),
290  p_deque(other.p_deque),
291  p_buffer(other.p_buffer)
292  {
293  }
294 
295  //***************************************************
296  const_iterator& operator ++()
297  {
298  index = (index == p_deque->MAX_SIZE) ? 0 : index + 1;
299 
300  return *this;
301  }
302 
303  //***************************************************
304  const_iterator operator ++(int)
305  {
306  const_iterator previous(*this);
307  index = (index == p_deque->MAX_SIZE) ? 0 : index + 1;
308 
309  return previous;
310  }
311 
312  //***************************************************
313  const_iterator operator +=(difference_type offset)
314  {
315  if (offset > 0)
316  {
317  index += offset;
318  index = (static_cast<size_t>(index) > p_deque->MAX_SIZE) ? index - p_deque->BUFFER_SIZE : index;
319  }
320  else if (offset < 0)
321  {
322  operator -= (-offset);
323  }
324 
325  return *this;
326  }
327 
328  //***************************************************
329  const_iterator operator -=(difference_type offset)
330  {
331  if (offset > 0)
332  {
333  index -= offset;
334  index = (index < 0) ? index + p_deque->BUFFER_SIZE : index;
335  }
336  else if (offset < 0)
337  {
338  operator += (-offset);
339  }
340 
341  return *this;
342  }
343 
344  //***************************************************
345  const_iterator& operator --()
346  {
347  index = (index == 0) ? p_deque->MAX_SIZE : index - 1;
348 
349  return *this;
350  }
351 
352  //***************************************************
353  const_iterator operator --(int)
354  {
355  iterator previous(*this);
356  index = (index == 0) ? p_deque->MAX_SIZE : index - 1;
357 
358  return previous;
359  }
360 
361  //***************************************************
362  const_reference operator *() const
363  {
364  return p_buffer[index];
365  }
366 
367  //***************************************************
368  const_pointer operator ->() const
369  {
370  return &p_buffer[index];
371  }
372 
373  //***************************************************
374  bool operator <(const const_iterator& other) const
375  {
376  return ideque::distance(*this, other) > 0;
377  }
378 
379  //***************************************************
380  friend const_iterator operator +(const const_iterator& lhs, difference_type offset)
381  {
382  const_iterator result(lhs);
383  result += offset;
384  return result;
385  }
386 
387  //***************************************************
388  friend const_iterator operator -(const const_iterator& lhs, difference_type offset)
389  {
390  const_iterator result(lhs);
391  result -= offset;
392  return result;
393  }
394 
395  //***************************************************
396  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
397  {
398  return lhs.index == rhs.index;
399  }
400 
401  //***************************************************
402  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
403  {
404  return !(lhs == rhs);
405  }
406 
407  //***************************************************
408  difference_type get_index() const
409  {
410  return index;
411  }
412 
413  //***************************************************
414  ideque& get_deque() const
415  {
416  return *p_deque;
417  }
418 
419  //***************************************************
420  pointer get_buffer() const
421  {
422  return p_buffer;
423  }
424 
425  //***************************************************
426  void swap(const_iterator& other)
427  {
428  std::swap(index, other.index);
429  }
430 
431  private:
432 
433  //***************************************************
434  difference_type distance(difference_type firstIndex, difference_type index)
435  {
436  if (index < firstIndex)
437  {
438  return p_deque->BUFFER_SIZE + index - firstIndex;
439  }
440  else
441  {
442  return index - firstIndex;
443  }
444  }
445 
446  //***************************************************
447  const_iterator(difference_type index, ideque& the_deque, pointer p_buffer)
448  : index(index),
449  p_deque(&the_deque),
450  p_buffer(p_buffer)
451  {
452  }
453 
454  difference_type index;
455  ideque* p_deque;
456  pointer p_buffer;
457  };
458 
459  typedef std::reverse_iterator<iterator> reverse_iterator;
460  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
461 
462  //*************************************************************************
464  //*************************************************************************
465  ideque& operator =(const ideque& other)
466  {
467  assign(other.begin(), other.end());
468 
469  return *this;
470  }
471 
472  //*************************************************************************
474  //*************************************************************************
475  template<typename TIterator>
477  assign(TIterator range_begin, TIterator range_end)
478  {
479  clear();
480 
481  while (range_begin != range_end)
482  {
483  push_back(*range_begin++);
484  }
485  }
486 
487  //*************************************************************************
492  //*************************************************************************
493  void assign(size_type n, const value_type& value)
494  {
495 
496  if (n > MAX_SIZE)
497  {
498 #ifdef ETL_THROW_EXCEPTIONS
499  throw deque_full();
500 #else
502 #endif
503  }
504 
505 
506  clear();
507 
508  std::fill_n(p_buffer, n, value);
509 
510  first.index = 0;
511  last.index = n - 1;
512  current_size = n;
513  }
514 
515  //*************************************************************************
519  //*************************************************************************
520  reference at(size_t index)
521  {
522  if (index >= current_size)
523  {
524 #ifdef ETL_THROW_EXCEPTIONS
525  throw deque_out_of_bounds();
526 #else
528 #endif
529  }
530 
531  iterator result(first);
532  result += index;
533 
534  return *result;
535  }
536 
537  //*************************************************************************
541  //*************************************************************************
542  const_reference at(size_t index) const
543  {
544  if (index >= current_size)
545  {
546 #ifdef ETL_THROW_EXCEPTIONS
547  throw deque_out_of_bounds();
548 #else
550 #endif
551  }
552 
553  iterator result(first);
554  result += index;
555 
556  return *result;
557  }
558 
559  //*************************************************************************
562  //*************************************************************************
563  reference operator [](size_t index)
564  {
565  iterator result(first);
566  result += index;
567 
568  return *result;
569  }
570 
571  //*************************************************************************
574  //*************************************************************************
575  const_reference operator [](size_t index) const
576  {
577  iterator result(first);
578  result += index;
579 
580  return *result;
581  }
582 
583  //*************************************************************************
586  //*************************************************************************
587  reference front()
588  {
589  return *first;
590  }
591 
592  //*************************************************************************
595  //*************************************************************************
596  const_reference front() const
597  {
598  return *first;
599  }
600 
601  //*************************************************************************
604  //*************************************************************************
605  reference back()
606  {
607  return *last;
608  }
609 
610  //*************************************************************************
613  //*************************************************************************
614  const_reference back() const
615  {
616  return *last;
617  }
618 
619  //*************************************************************************
621  //*************************************************************************
623  {
624  return first;
625  }
626 
627  //*************************************************************************
629  //*************************************************************************
631  {
632  return first;
633  }
634 
635  //*************************************************************************
637  //*************************************************************************
639  {
640  return first;
641  }
642 
643  //*************************************************************************
645  //*************************************************************************
647  {
648  return ++iterator(last);
649  }
650 
651  //*************************************************************************
653  //*************************************************************************
655  {
656  return ++iterator(last);
657  }
658 
659  //*************************************************************************
661  //*************************************************************************
663  {
664  return ++const_iterator(last);
665  }
666 
667  //*************************************************************************
669  //*************************************************************************
670  reverse_iterator rbegin()
671  {
672  return reverse_iterator(end());
673  }
674 
675  //*************************************************************************
677  //*************************************************************************
678  const_reverse_iterator rbegin() const
679  {
680  return const_reverse_iterator(end());
681  }
682 
683  //*************************************************************************
685  //*************************************************************************
686  const_reverse_iterator crbegin() const
687  {
688  return const_reverse_iterator(cend());
689  }
690 
691  //*************************************************************************
693  //*************************************************************************
694  reverse_iterator rend()
695  {
696  return reverse_iterator(begin());
697  }
698 
699  //*************************************************************************
701  //*************************************************************************
702  const_reverse_iterator rend() const
703  {
704  return const_reverse_iterator(begin());
705  }
706 
707  //*************************************************************************
709  //*************************************************************************
710  const_reverse_iterator crend() const
711  {
712  return const_reverse_iterator(cbegin());
713  }
714 
715  //*************************************************************************
717  //*************************************************************************
718  void clear()
719  {
720  first = iterator(0, *this, p_buffer);
721  last = iterator(0, *this, p_buffer);
722  current_size = 0;
723  }
724 
725  //*************************************************************************
730  //*************************************************************************
731  iterator insert(const_iterator insert_position, const value_type& value)
732  {
733  iterator position(insert_position.index, *this, p_buffer);
734 
735  if (!full())
736  {
737  if (insert_position == begin())
738  {
739  push_front(value);
740  position = first;
741  }
742  else if (insert_position == end())
743  {
744  push_back(value);
745  position = last;
746  }
747  else
748  {
749  // Are we closer to the front?
750  if (std::distance(first, position) < std::distance(position, last))
751  {
752  // Move the values.
753  std::copy(first, position, first - 1);
754 
755  // Write the new value.
756  *(--position) = value;
757 
758  // Adjust the iterator
759  --first;
760  }
761  else
762  {
763  // Adjust the iterator
764  ++last;
765 
766  // Move the values.
767  std::copy_backward(position, last, last + 1);
768 
769  // Write the new value.
770  *position = value;
771  }
772 
773  ++current_size;
774  }
775  }
776  else
777  {
778 #ifdef ETL_THROW_EXCEPTIONS
779  throw deque_full();
780 #else
782 #endif
783  }
784 
785  return position;
786  }
787 
788  //*************************************************************************
794  //*************************************************************************
795  iterator insert(const_iterator insert_position, size_type n, const value_type& value)
796  {
797  iterator position;
798 
799  if ((current_size + n) <= MAX_SIZE)
800  {
801  if (insert_position == begin())
802  {
803  first -= n;
804  std::fill_n(first, n, value);
805  position = first;
806  }
807  else if (insert_position == end())
808  {
809  position = last + 1;
810  std::fill_n(position, n, value);
811  last += n;
812  }
813  else
814  {
815  // Non-const insert iterator.
816  position = iterator(insert_position.index, *this, p_buffer);
817 
818  // Are we closer to the front?
819  if (distance(first, insert_position) < difference_type(current_size / 2))
820  {
821  iterator new_first = first - n;
822  iterator new_position = position - n;
823 
824  // Move the values.
825  std::copy(first, position, new_first);
826 
827  // Write the new value.
828  std::fill_n(new_position, n, value);
829 
830  // Adjust the iterators
831  first = new_first;
832  position = new_position;
833  }
834  else
835  {
836  iterator new_last = last + n;
837 
838  // Move the values.
839  std::copy_backward(position, last + 1, new_last + 1);
840 
841  // Write the new value.
842  std::fill_n(position, n, value);
843 
844  // Adjust the iterator
845  last = new_last;
846  }
847  }
848 
849  current_size += n;
850  }
851  else
852  {
853 #ifdef ETL_THROW_EXCEPTIONS
854  throw deque_full();
855 #else
857 #endif
858  }
859 
860  return position;
861  }
862 
863  //*************************************************************************
869  //*************************************************************************
870  template<typename TIterator>
871  typename enable_if<is_iterator<TIterator>::value, iterator>::type
872  insert(const_iterator insert_position, TIterator range_begin, TIterator range_end)
873  {
874  iterator position;
875 
876  // Find out how much room we need.
877  size_t n = std::distance(range_begin, range_end);
878 
879  if ((current_size + n) <= MAX_SIZE)
880  {
881  if (insert_position == begin())
882  {
883  // Adjust the iterator.
884  first -= n;
885  iterator destination(first);
886 
887  // Copy them over.
888  while (range_begin != range_end)
889  {
890  *destination++ = *range_begin++;
891  }
892 
893  position = first;
894  }
895  else if (insert_position == end())
896  {
897  position = last + 1;
898 
899  while (range_begin != range_end)
900  {
901  *(++last) = *range_begin++;
902  }
903  }
904  else
905  {
906  // Non-const insert iterator.
907  position = iterator(insert_position.index, *this, p_buffer);
908 
909  // Are we closer to the front?
910  if (distance(first, insert_position) < difference_type(current_size / 2))
911  {
912  iterator new_first = first - n;
913  iterator new_position = position - n;
914 
915  // Move the values.
916  std::copy(first, position, new_first);
917 
918  // Write the new values.
919  std::copy(range_begin, range_end, new_position);
920 
921  // Adjust the iterators
922  first = new_first;
923  position = new_position;
924  }
925  else
926  {
927  iterator new_last = last + n;
928 
929  // Move the values.
930  std::copy_backward(position, last + 1, new_last + 1);
931 
932  // Write the new values.
933  std::copy(range_begin, range_end, position);
934 
935  // Adjust the iterator.
936  last = new_last;
937  }
938  }
939 
940  current_size += n;
941  }
942  else
943  {
944 #ifdef ETL_THROW_EXCEPTIONS
945  throw deque_full();
946 #else
948 #endif
949  }
950 
951  return position;
952  }
953 
954  //*************************************************************************
958  //*************************************************************************
959  iterator erase(const_iterator erase_position)
960  {
961  iterator position(erase_position.index, *this, p_buffer);
962 
963  if (distance(position) <= difference_type(current_size))
964  {
965  if (position == first)
966  {
967  ++first;
968  position = first;
969  }
970  else if (position == last)
971  {
972  --last;
973  }
974  else
975  {
976  // Are we closer to the front?
977  if (distance(first, position) < difference_type(current_size / 2))
978  {
979  std::copy_backward(first, position, position + 1);
980  ++first;
981  ++position;
982  }
983  else
984  {
985  std::copy(position + 1, last + 1, position);
986  --last;
987  }
988  }
989 
990  --current_size;
991  }
992  else
993  {
994 #ifdef ETL_THROW_EXCEPTIONS
995  throw deque_out_of_bounds();
996 #else
998 #endif
999  }
1000 
1001  return position;
1002  }
1003 
1004  //*************************************************************************
1009  //*************************************************************************
1011  {
1012  iterator position(range_begin.index, *this, p_buffer);
1013 
1014  if ((distance(range_begin) <= difference_type(current_size)) &&
1015  (distance(range_end) <= difference_type(current_size)))
1016  {
1017  // How many to erase?
1018  difference_type length = std::distance(range_begin, range_end);
1019 
1020  // At the beginning?
1021  if (position == first)
1022  {
1023  first += length;
1024  position = first;
1025  }
1026  // At the end?
1027  else if (position == last - length + 1)
1028  {
1029  last -= length;
1030  }
1031  else
1032  {
1033  // Copy the smallest number of items.
1034  // Are we closer to the front?
1035  if (distance(first, position) < difference_type(current_size / 2))
1036  {
1037  // Move the items.
1038  std::copy_backward(first, position, position + length);
1039  first += length;
1040  position += length;
1041  }
1042  else
1043  // Must be closer to the back.
1044  {
1045  // Move the items.
1046  std::copy(position + length, last + 1, position);
1047  last -= length;
1048  }
1049  }
1050 
1051  current_size -= length;
1052  }
1053  else
1054  {
1055 #ifdef ETL_THROW_EXCEPTIONS
1056  throw deque_out_of_bounds();
1057 #else
1059 #endif
1060  }
1061 
1062  return position;
1063  }
1064 
1065  //*************************************************************************
1069  //*************************************************************************
1070  void push_back(parameter_t item)
1071  {
1072  if (!full())
1073  {
1074  if (!empty())
1075  {
1076  ++last;
1077  }
1078 
1079  *last = item;
1080  ++current_size;
1081  }
1082  else
1083  {
1084 #ifdef ETL_THROW_EXCEPTIONS
1085  throw deque_full();
1086 #else
1088 #endif
1089  }
1090  }
1091 
1092  //*************************************************************************
1096  //*************************************************************************
1097  reference push_back()
1098  {
1099  if (!full())
1100  {
1101  if (!empty())
1102  {
1103  ++last;
1104  }
1105 
1106  ++current_size;
1107  }
1108  else
1109  {
1110 #ifdef ETL_THROW_EXCEPTIONS
1111  throw deque_full();
1112 #else
1114 #endif
1115  }
1116 
1117  return *last;
1118  }
1119 
1120  //*************************************************************************
1122  //*************************************************************************
1123  void pop_back()
1124  {
1125  if (!empty())
1126  {
1127  --current_size;
1128 
1129  if (!empty())
1130  {
1131  --last;
1132  }
1133  }
1134  }
1135 
1136  //*************************************************************************
1140  //*************************************************************************
1141  void push_front(parameter_t item)
1142  {
1143  if (!full())
1144  {
1145  if (!empty())
1146  {
1147  --first;
1148  }
1149 
1150  *first = item;
1151  ++current_size;
1152  }
1153  else
1154  {
1155 #ifdef ETL_THROW_EXCEPTIONS
1156  throw deque_full();
1157 #else
1159 #endif
1160  }
1161  }
1162 
1163  //*************************************************************************
1167  //*************************************************************************
1168  reference push_front()
1169  {
1170  if (!full())
1171  {
1172  if (!empty())
1173  {
1174  --first;
1175  }
1176 
1177  ++current_size;
1178  }
1179  else
1180  {
1181 #ifdef ETL_THROW_EXCEPTIONS
1182  throw deque_full();
1183 #else
1185 #endif
1186  }
1187 
1188  return *first;
1189  }
1190 
1191  //*************************************************************************
1193  //*************************************************************************
1194  void pop_front()
1195  {
1196  if (!empty())
1197  {
1198  --current_size;
1199 
1200  if (!empty())
1201  {
1202  ++first;
1203  }
1204  }
1205  }
1206 
1207  //*************************************************************************
1212  //*************************************************************************
1213  void resize(size_t new_size, const value_type& value = value_type())
1214  {
1215  if (new_size <= MAX_SIZE)
1216  {
1217  // Make it smaller?
1218  if (new_size < current_size)
1219  {
1220  last -= (current_size - new_size);
1221  }
1222  // Make it larger?
1223  else if (new_size > current_size)
1224  {
1225  size_t count = new_size - current_size;
1226 
1227  for (size_t i = 0; i < count; ++i)
1228  {
1229  *(++last) = value;
1230  }
1231  }
1232 
1233  current_size = new_size;
1234  }
1235 
1236  else
1237  {
1238 #ifdef ETL_THROW_EXCEPTIONS
1239  throw deque_out_of_bounds();
1240 #else
1242 #endif
1243  }
1244  }
1245 
1246  //*************************************************************************
1248  //*************************************************************************
1249  friend difference_type operator -(const iterator& lhs, const iterator& rhs)
1250  {
1251  return distance(rhs, lhs);
1252  }
1253 
1254  //*************************************************************************
1256  //*************************************************************************
1257  friend difference_type operator -(const const_iterator& lhs, const const_iterator& rhs)
1258  {
1259  return distance(rhs, lhs);
1260  }
1261 
1262  //*************************************************************************
1264  //*************************************************************************
1265  friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs)
1266  {
1267  return distance(lhs.base(), rhs.base());
1268  }
1269 
1270  //*************************************************************************
1272  //*************************************************************************
1273  friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs)
1274  {
1275  return distance(lhs.base(), rhs.base());
1276  }
1277 
1278  protected:
1279 
1280  //*************************************************************************
1282  //*************************************************************************
1283  ideque(pointer p_buffer, size_t max_size, size_t buffer_size)
1284  : deque_base(max_size, buffer_size),
1285  p_buffer(p_buffer)
1286  {
1287  clear();
1288  }
1289 
1290  iterator first;
1292  pointer p_buffer;
1293 
1294  private:
1295 
1296  //*************************************************************************
1298  //*************************************************************************
1299  template <typename TIterator1, typename TIterator2>
1300  static difference_type distance(const TIterator1& range_begin, const TIterator2& range_end)
1301  {
1302  difference_type distance1 = distance(range_begin);
1303  difference_type distance2 = distance(range_end);
1304 
1305  return distance2 - distance1;
1306  }
1307 
1308  //*************************************************************************
1310  //*************************************************************************
1311  template <typename TIterator>
1312  static difference_type distance(const TIterator& other)
1313  {
1314  const difference_type index = other.get_index();
1315  const difference_type reference_index = other.get_deque().first.index;
1316  const size_t buffer_size = other.get_deque().BUFFER_SIZE;
1317 
1318  if (index < reference_index)
1319  {
1320  return buffer_size + index - reference_index;
1321  }
1322  else
1323  {
1324  return index - reference_index;
1325  }
1326  }
1327  };
1328 }
1329 
1330 //***************************************************************************
1336 //***************************************************************************
1337 template <typename T>
1338 bool operator ==(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1339 {
1340  return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
1341 }
1342 
1343 //***************************************************************************
1349 //***************************************************************************
1350 template <typename T>
1351 bool operator !=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1352 {
1353  return !(lhs == rhs);
1354 }
1355 
1356 //***************************************************************************
1362 //***************************************************************************
1363 template <typename T>
1364 bool operator <(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1365 {
1366  return std::lexicographical_compare(lhs.begin(),
1367  lhs.end(),
1368  rhs.begin(),
1369  rhs.end());
1370 }
1371 
1372 //***************************************************************************
1378 //***************************************************************************
1379 template <typename T>
1380 bool operator <=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1381 {
1382  return !operator >(lhs, rhs);
1383 }
1384 
1385 //***************************************************************************
1391 //***************************************************************************
1392 template <typename T>
1393 bool operator >(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1394 {
1395  return std::lexicographical_compare(lhs.begin(),
1396  lhs.end(),
1397  rhs.begin(),
1398  rhs.end(),
1399  std::greater<T>());
1400 }
1401 
1402 //***************************************************************************
1408 //***************************************************************************
1409 template <typename T>
1410 bool operator >=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
1411 {
1412  return !operator <(lhs, rhs);
1413 }
1414 
1415 #endif
size_type size() const
Definition: deque_base.h:112
const_reverse_iterator crend() const
Gets a const reverse iterator to the beginning of the deque.
Definition: ideque.h:710
void push_back(parameter_t item)
Definition: ideque.h:1070
Const Iterator.
Definition: ideque.h:267
iterator last
Iterator to the first item in the deque.
Definition: ideque.h:1291
Definition: ideque.h:52
void pop_back()
Removes the oldest item from the deque.
Definition: ideque.h:1123
bool operator>(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: ideque.h:1393
bool operator<(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: ideque.h:1364
const_reverse_iterator rend() const
Gets a const reverse iterator to the beginning of the deque.
Definition: ideque.h:702
iterator insert(const_iterator insert_position, const value_type &value)
Definition: ideque.h:731
const_iterator begin() const
Gets a const iterator to the beginning of the deque.
Definition: ideque.h:630
reference at(size_t index)
Definition: ideque.h:520
void swap(etl::bitset< N > &lhs, etl::bitset< N > &rhs)
swap
Definition: bitset.h:1200
const_iterator cend() const
Gets a const iterator to the end of the deque.
Definition: ideque.h:662
Definition: deque_base.h:102
Determine how to pass parameters.
Definition: parameter_type.h:40
ideque & operator=(const ideque &other)
Assignment operator.
Definition: ideque.h:465
const_reference front() const
Definition: ideque.h:596
const size_type MAX_SIZE
The maximum number of elements in the deque.
Definition: deque_base.h:183
void pop_front()
Removes the oldest item from the deque.
Definition: ideque.h:1194
Definition: type_traits.h:268
enable_if< is_iterator< TIterator >::value, iterator >::type insert(const_iterator insert_position, TIterator range_begin, TIterator range_end)
Definition: ideque.h:872
iterator insert(const_iterator insert_position, size_type n, const value_type &value)
Definition: ideque.h:795
const_reverse_iterator crbegin() const
Gets a const reverse iterator to the end of the deque.
Definition: ideque.h:686
const_iterator end() const
Gets a const iterator to the end of the deque.
Definition: ideque.h:654
iterator erase(const_iterator erase_position)
Definition: ideque.h:959
reference push_back()
Definition: ideque.h:1097
reference operator[](size_t index)
Definition: ideque.h:563
bool operator!=(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: ideque.h:1351
const_reverse_iterator rbegin() const
Gets a const reverse iterator to the end of the deque.
Definition: ideque.h:678
void clear()
Clears the deque.
Definition: ideque.h:718
const_iterator cbegin() const
Gets a const iterator to the beginning of the deque.
Definition: ideque.h:638
Definition: algorithm.h:43
pointer p_buffer
Iterator to the last item in the deque.
Definition: ideque.h:1292
bool full() const
Definition: deque_base.h:130
size_type max_size() const
Definition: deque_base.h:148
reference back()
Definition: ideque.h:605
iterator end()
Gets an iterator to the end of the deque.
Definition: ideque.h:646
Iterator.
Definition: ideque.h:81
const size_type BUFFER_SIZE
The of elements in the buffer.
Definition: deque_base.h:184
const_reference back() const
Definition: ideque.h:614
bool operator>=(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: ideque.h:1410
void push_front(parameter_t item)
Definition: ideque.h:1141
iterator erase(const_iterator range_begin, const_iterator range_end)
Definition: ideque.h:1010
Test for an iterator.
Definition: ideque.h:72
iterator begin()
Gets an iterator to the beginning of the deque.
Definition: ideque.h:622
reference front()
Definition: ideque.h:587
bool operator==(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: ideque.h:1338
size_type current_size
The current number of elements in the deque.
Definition: deque_base.h:182
static void error(const exception &e)
Definition: error_handler.cpp:50
Definition: type_traits.h:45
void assign(size_type n, const value_type &value)
Definition: ideque.h:493
etl::enable_if< is_iterator< TIterator >::value, void >::type assign(TIterator range_begin, TIterator range_end)
Assigns a range to the deque.
Definition: ideque.h:477
reverse_iterator rbegin()
Gets a reverse iterator to the end of the deque.
Definition: ideque.h:670
bool empty() const
Definition: deque_base.h:121
Definition: deque_base.h:88
const_reference at(size_t index) const
Definition: ideque.h:542
Definition: deque_base.h:60
reference push_front()
Definition: ideque.h:1168
reverse_iterator rend()
Gets a reverse iterator to the beginning of the deque.
Definition: ideque.h:694
void resize(size_t new_size, const value_type &value=value_type())
Definition: ideque.h:1213
ideque(pointer p_buffer, size_t max_size, size_t buffer_size)
Constructor.
Definition: ideque.h:1283
friend difference_type operator-(const iterator &lhs, const iterator &rhs)
Definition: ideque.h:1249