Embedded Template Library  1.0
deque.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_DEQUE_INCLUDED
32 #define ETL_DEQUE_INCLUDED
33 
34 #include <stddef.h>
35 #include <stdint.h>
36 
37 #include "platform.h"
38 #include "algorithm.h"
39 #include "iterator.h"
40 #include "utility.h"
41 #include "container.h"
42 #include "memory.h"
43 #include "exception.h"
44 #include "error_handler.h"
45 #include "debug_count.h"
46 #include "algorithm.h"
47 #include "type_traits.h"
48 #include "iterator.h"
49 #include "placement_new.h"
50 
51 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
52  #include <initializer_list>
53 #endif
54 
55 #include "private/minmax_push.h"
56 
57 #undef ETL_FILE
58 #define ETL_FILE "1"
59 
60 //*****************************************************************************
64 //*****************************************************************************
65 
66 namespace etl
67 {
68  //***************************************************************************
71  //***************************************************************************
73  {
74  public:
75 
76  deque_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
77  : exception(reason_, file_name_, line_number_)
78  {
79  }
80  };
81 
82  //***************************************************************************
85  //***************************************************************************
87  {
88  public:
89 
90  deque_full(string_type file_name_, numeric_type line_number_)
91  : etl::deque_exception(ETL_ERROR_TEXT("deque:full", ETL_FILE"A"), file_name_, line_number_)
92  {
93  }
94  };
95 
96  //***************************************************************************
99  //***************************************************************************
101  {
102  public:
103 
104  deque_empty(string_type file_name_, numeric_type line_number_)
105  : etl::deque_exception(ETL_ERROR_TEXT("deque:empty", ETL_FILE"B"), file_name_, line_number_)
106  {
107  }
108  };
109 
110  //***************************************************************************
113  //***************************************************************************
115  {
116  public:
117 
118  deque_out_of_bounds(string_type file_name_, numeric_type line_number_)
119  : etl::deque_exception(ETL_ERROR_TEXT("deque:bounds", ETL_FILE"C"), file_name_, line_number_)
120  {
121  }
122  };
123 
124  //***************************************************************************
127  //***************************************************************************
129  {
130  public:
131 
132  deque_incompatible_type(string_type file_name_, numeric_type line_number_)
133  : deque_exception(ETL_ERROR_TEXT("deque:type", ETL_FILE"D"), file_name_, line_number_)
134  {
135  }
136  };
137 
138  //***************************************************************************
141  //***************************************************************************
143  {
144  public:
145 
146  typedef size_t size_type;
147 
148  //*************************************************************************
151  //*************************************************************************
152  size_type size() const
153  {
154  return current_size;
155  }
156 
157  //*************************************************************************
160  //*************************************************************************
161  bool empty() const
162  {
163  return (current_size == 0);
164  }
165 
166  //*************************************************************************
169  //*************************************************************************
170  bool full() const
171  {
172  return current_size == CAPACITY;
173  }
174 
175  //*************************************************************************
178  //*************************************************************************
179  size_type max_size() const
180  {
181  return CAPACITY;
182  }
183 
184  //*************************************************************************
187  //*************************************************************************
188  size_type capacity() const
189  {
190  return CAPACITY;
191  }
192 
193  //*************************************************************************
196  //*************************************************************************
197  size_t available() const
198  {
199  return max_size() - size();
200  }
201 
202  protected:
203 
204  //*************************************************************************
206  //*************************************************************************
207  deque_base(size_t max_size_, size_t buffer_size_)
208  : current_size(0),
209  CAPACITY(max_size_),
210  BUFFER_SIZE(buffer_size_)
211  {
212  }
213 
214  //*************************************************************************
216  //*************************************************************************
218  {
219  }
220 
221  size_type current_size;
222  const size_type CAPACITY;
223  const size_type BUFFER_SIZE;
224  ETL_DECLARE_DEBUG_COUNT
225  };
226 
227  //***************************************************************************
231  //***************************************************************************
232  template <typename T>
233  class ideque : public etl::deque_base
234  {
235  public:
236 
237  typedef T value_type;
238  typedef size_t size_type;
239  typedef T& reference;
240  typedef const T& const_reference;
241 #if ETL_CPP11_SUPPORTED
242  typedef T&& rvalue_reference;
243 #endif
244  typedef T* pointer;
245  typedef const T* const_pointer;
246  typedef typename etl::iterator_traits<pointer>::difference_type difference_type;
247 
248  protected:
249 
250  //*************************************************************************
252  //*************************************************************************
253  template <typename TIterator>
254  struct is_iterator : public etl::integral_constant<bool, !etl::is_integral<TIterator>::value && !etl::is_floating_point<TIterator>::value>
255  {
256  };
257 
258  public:
259 
260  //*************************************************************************
262  //*************************************************************************
263  struct iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, T>
264  {
265  friend class ideque;
266  friend struct const_iterator;
267 
268  //***************************************************
269  iterator()
270  : index(0)
271  , p_deque(0)
272  , p_buffer(0)
273  {
274  }
275 
276  //***************************************************
277  iterator(const iterator& other)
278  : index(other.index),
279  p_deque(other.p_deque),
280  p_buffer(other.p_buffer)
281  {
282  }
283 
284  //***************************************************
285  iterator& operator =(const iterator& other)
286  {
287  index = other.index;
288  p_deque = other.p_deque;
289  p_buffer = other.p_buffer;
290 
291  return *this;
292  }
293 
294  //***************************************************
295  iterator& operator ++()
296  {
297  index = (static_cast<size_t>(index) == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1;
298 
299  return *this;
300  }
301 
302  //***************************************************
303  iterator operator ++(int)
304  {
305  iterator previous(*this);
306  index = (static_cast<size_t>(index) == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1;
307 
308  return previous;
309  }
310 
311  //***************************************************
312  iterator& operator +=(difference_type offset)
313  {
314  if (offset > 0)
315  {
316  index += offset;
317  index = (static_cast<size_t>(index) > p_deque->BUFFER_SIZE - 1) ? index - p_deque->BUFFER_SIZE : index;
318  }
319  else if (offset < 0)
320  {
321  operator -= (-offset);
322  }
323 
324  return *this;
325  }
326 
327  //***************************************************
328  iterator& operator -=(difference_type offset)
329  {
330  if (offset > 0)
331  {
332  index -= offset;
333  index = (index < 0) ? index + p_deque->BUFFER_SIZE : index;
334  }
335  else if (offset < 0)
336  {
337  operator += (-offset);
338  }
339 
340  return *this;
341  }
342 
343  //***************************************************
344  iterator& operator --()
345  {
346  index = (index == 0) ? p_deque->BUFFER_SIZE - 1 : index - 1;
347 
348  return *this;
349  }
350 
351  //***************************************************
352  iterator operator --(int)
353  {
354  iterator previous(*this);
355  index = (index == 0) ? p_deque->BUFFER_SIZE - 1 : index - 1;
356 
357  return previous;
358  }
359 
360  //***************************************************
361  reference operator *()
362  {
363  return p_buffer[index];
364  }
365 
366  //***************************************************
367  const_reference operator *() const
368  {
369  return p_buffer[index];
370  }
371 
372  //***************************************************
373  pointer operator ->()
374  {
375  return &p_buffer[index];
376  }
377 
378  //***************************************************
379  const_pointer operator ->() const
380  {
381  return &p_buffer[index];
382  }
383 
384  //***************************************************
385  friend iterator operator +(const iterator& lhs, difference_type offset)
386  {
387  iterator result(lhs);
388  result += offset;
389  return result;
390  }
391 
392  //***************************************************
393  friend iterator operator -(const iterator& lhs, difference_type offset)
394  {
395  iterator result(lhs);
396  result -= offset;
397  return result;
398  }
399 
400  //***************************************************
401  friend bool operator == (const iterator& lhs, const iterator& rhs)
402  {
403  return lhs.index == rhs.index;
404  }
405 
406  //***************************************************
407  friend bool operator != (const iterator& lhs, const iterator& rhs)
408  {
409  return !(lhs == rhs);
410  }
411 
412  //***************************************************
413  friend bool operator < (const iterator& lhs, const iterator& rhs)
414  {
415  const difference_type lhs_index = lhs.get_index();
416  const difference_type rhs_index = rhs.get_index();
417  const difference_type reference_index = lhs.container().begin().get_index();
418  const size_t buffer_size = lhs.container().max_size() + 1;
419 
420  const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
421  const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
422 
423  return lhs_distance < rhs_distance;
424  }
425 
426  //***************************************************
427  friend bool operator <= (const iterator& lhs, const iterator& rhs)
428  {
429  return !(lhs > rhs);
430  }
431 
432  //***************************************************
433  friend bool operator > (const iterator& lhs, const iterator& rhs)
434  {
435  return (rhs < lhs);
436  }
437 
438  //***************************************************
439  friend bool operator >= (const iterator& lhs, const iterator& rhs)
440  {
441  return !(lhs < rhs);
442  }
443 
444  //***************************************************
445  difference_type get_index() const
446  {
447  return index;
448  }
449 
450  //***************************************************
451  ideque& container() const
452  {
453  return *p_deque;
454  }
455 
456  //***************************************************
457  pointer get_buffer() const
458  {
459  return p_buffer;
460  }
461 
462  //***************************************************
463  void swap(iterator& other)
464  {
465  using ETL_OR_STD::swap; // Allow ADL
466 
467  swap(index, other.index);
468  }
469 
470  private:
471 
472  //***************************************************
473  difference_type distance(difference_type firstIndex, difference_type index_) const
474  {
475  if (index_ < firstIndex)
476  {
477  return p_deque->BUFFER_SIZE + index_ - firstIndex;
478  }
479  else
480  {
481  return index_ - firstIndex;
482  }
483  }
484 
485  //***************************************************
486  iterator(difference_type index_, ideque& the_deque, pointer p_buffer_)
487  : index(index_)
488  , p_deque(&the_deque)
489  , p_buffer(p_buffer_)
490  {
491  }
492 
493  difference_type index;
494  ideque* p_deque;
495  pointer p_buffer;
496  };
497 
498  //*************************************************************************
500  //*************************************************************************
501  struct const_iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, const T>
502  {
503  friend class ideque;
504 
505  //***************************************************
507  : index(0)
508  , p_deque(0)
509  , p_buffer(0)
510  {
511  }
512 
513  //***************************************************
514  const_iterator(const const_iterator& other)
515  : index(other.index)
516  , p_deque(other.p_deque)
517  , p_buffer(other.p_buffer)
518  {
519  }
520 
521  //***************************************************
522  const_iterator(const typename ideque::iterator& other)
523  : index(other.index)
524  , p_deque(other.p_deque)
525  , p_buffer(other.p_buffer)
526  {
527  }
528 
529  //***************************************************
530  const_iterator& operator =(const const_iterator& other)
531  {
532  index = other.index;
533  p_deque = other.p_deque;
534  p_buffer = other.p_buffer;
535 
536  return *this;
537  }
538 
539  const_iterator& operator =(const typename ideque::iterator& other)
540  {
541  index = other.index;
542  p_deque = other.p_deque;
543  p_buffer = other.p_buffer;
544 
545  return *this;
546  }
547 
548  //***************************************************
549  const_iterator& operator ++()
550  {
551  index = (static_cast<size_t>(index) == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1;
552 
553  return *this;
554  }
555 
556  //***************************************************
557  const_iterator operator ++(int)
558  {
559  const_iterator previous(*this);
560  index = (static_cast<size_t>(index) == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1;
561 
562  return previous;
563  }
564 
565  //***************************************************
566  const_iterator& operator +=(difference_type offset)
567  {
568  if (offset > 0)
569  {
570  index += offset;
571  index = (static_cast<size_t>(index) > p_deque->BUFFER_SIZE - 1) ? index - p_deque->BUFFER_SIZE : index;
572  }
573  else if (offset < 0)
574  {
575  operator -= (-offset);
576  }
577 
578  return *this;
579  }
580 
581  //***************************************************
582  const_iterator& operator -=(difference_type offset)
583  {
584  if (offset > 0)
585  {
586  index -= offset;
587  index = (index < 0) ? static_cast<size_t>(index) + p_deque->BUFFER_SIZE : index;
588  }
589  else if (offset < 0)
590  {
591  operator += (-offset);
592  }
593 
594  return *this;
595  }
596 
597  //***************************************************
598  const_iterator& operator --()
599  {
600  index = (index == 0) ? p_deque->BUFFER_SIZE - 1 : index - 1;
601 
602  return *this;
603  }
604 
605  //***************************************************
606  const_iterator operator --(int)
607  {
608  const_iterator previous(*this);
609  index = (index == 0) ? p_deque->BUFFER_SIZE - 1 : index - 1;
610 
611  return previous;
612  }
613 
614  //***************************************************
615  const_reference operator *() const
616  {
617  return p_buffer[index];
618  }
619 
620  //***************************************************
621  const_pointer operator ->() const
622  {
623  return &p_buffer[index];
624  }
625 
626 
627 
628  //***************************************************
629  friend const_iterator operator +(const const_iterator& lhs, difference_type offset)
630  {
631  const_iterator result(lhs);
632  result += offset;
633  return result;
634  }
635 
636  //***************************************************
637  friend const_iterator operator -(const const_iterator& lhs, difference_type offset)
638  {
639  const_iterator result(lhs);
640  result -= offset;
641  return result;
642  }
643 
644  //***************************************************
645  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
646  {
647  return lhs.index == rhs.index;
648  }
649 
650  //***************************************************
651  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
652  {
653  return !(lhs == rhs);
654  }
655 
656  //***************************************************
657  friend bool operator < (const const_iterator& lhs, const const_iterator& rhs)
658  {
659  const difference_type lhs_index = lhs.get_index();
660  const difference_type rhs_index = rhs.get_index();
661  const difference_type reference_index = lhs.container().begin().get_index();
662  const size_t buffer_size = lhs.container().max_size() + 1;
663 
664  const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
665  const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
666 
667  return lhs_distance < rhs_distance;
668  }
669 
670  //***************************************************
671  friend bool operator <= (const const_iterator& lhs, const const_iterator& rhs)
672  {
673  return !(lhs > rhs);
674  }
675 
676  //***************************************************
677  friend bool operator > (const const_iterator& lhs, const const_iterator& rhs)
678  {
679  return (rhs < lhs);
680  }
681 
682  //***************************************************
683  friend bool operator >= (const const_iterator& lhs, const const_iterator& rhs)
684  {
685  return !(lhs < rhs);
686  }
687 
688  //***************************************************
689  difference_type get_index() const
690  {
691  return index;
692  }
693 
694  //***************************************************
695  ideque& container() const
696  {
697  return *p_deque;
698  }
699 
700  //***************************************************
701  pointer get_buffer() const
702  {
703  return p_buffer;
704  }
705 
706  //***************************************************
707  void swap(const_iterator& other)
708  {
709  ETL_OR_STD::swap(index, other.index);
710  }
711 
712  private:
713 
714  //***************************************************
715  difference_type distance(difference_type firstIndex, difference_type index_) const
716  {
717  if (index_ < firstIndex)
718  {
719  return p_deque->BUFFER_SIZE + index_ - firstIndex;
720  }
721  else
722  {
723  return index_ - firstIndex;
724  }
725  }
726 
727  //***************************************************
728  const_iterator(difference_type index_, ideque& the_deque, pointer p_buffer_)
729  : index(index_)
730  , p_deque(&the_deque)
731  , p_buffer(p_buffer_)
732  {
733  }
734 
735  difference_type index;
736  ideque* p_deque;
737  pointer p_buffer;
738  };
739 
740  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
741  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
742 
743  //*************************************************************************
745  //*************************************************************************
746  template<typename TIterator>
748  assign(TIterator range_begin, TIterator range_end)
749  {
750  initialise();
751 
752  while (range_begin != range_end)
753  {
754  push_back(*range_begin++);
755  }
756  }
757 
758  //*************************************************************************
763  //*************************************************************************
764  void assign(size_type n, const value_type& value)
765  {
766  ETL_ASSERT(n <= CAPACITY, ETL_ERROR(deque_full));
767 
768  initialise();
769 
770  while (n > 0)
771  {
772  create_element_back(value);
773  --n;
774  }
775  }
776 
777  //*************************************************************************
781  //*************************************************************************
782  reference at(size_t index)
783  {
784  ETL_ASSERT(index < current_size, ETL_ERROR(deque_out_of_bounds));
785 
786  iterator result(_begin);
787  result += index;
788 
789  return *result;
790  }
791 
792  //*************************************************************************
796  //*************************************************************************
797  const_reference at(size_t index) const
798  {
799  ETL_ASSERT(index < current_size, ETL_ERROR(deque_out_of_bounds));
800 
801  iterator result(_begin);
802  result += index;
803 
804  return *result;
805  }
806 
807  //*************************************************************************
810  //*************************************************************************
811  reference operator [](size_t index)
812  {
813  iterator result(_begin);
814  result += index;
815 
816  return *result;
817  }
818 
819  //*************************************************************************
822  //*************************************************************************
823  const_reference operator [](size_t index) const
824  {
825  iterator result(_begin);
826  result += index;
827 
828  return *result;
829  }
830 
831  //*************************************************************************
834  //*************************************************************************
835  reference front()
836  {
837  return *_begin;
838  }
839 
840  //*************************************************************************
843  //*************************************************************************
844  const_reference front() const
845  {
846  return *_begin;
847  }
848 
849  //*************************************************************************
852  //*************************************************************************
853  reference back()
854  {
855  return *(_end - 1);
856  }
857 
858  //*************************************************************************
861  //*************************************************************************
862  const_reference back() const
863  {
864  return *(_end - 1);
865  }
866 
867  //*************************************************************************
869  //*************************************************************************
871  {
872  return _begin;
873  }
874 
875  //*************************************************************************
877  //*************************************************************************
879  {
880  return _begin;
881  }
882 
883  //*************************************************************************
885  //*************************************************************************
887  {
888  return _begin;
889  }
890 
891  //*************************************************************************
893  //*************************************************************************
895  {
896  return iterator(_end);
897  }
898 
899  //*************************************************************************
901  //*************************************************************************
903  {
904  return iterator(_end);
905  }
906 
907  //*************************************************************************
909  //*************************************************************************
911  {
912  return const_iterator(_end);
913  }
914 
915  //*************************************************************************
917  //*************************************************************************
918  reverse_iterator rbegin()
919  {
920  return reverse_iterator(end());
921  }
922 
923  //*************************************************************************
925  //*************************************************************************
926  const_reverse_iterator rbegin() const
927  {
928  return const_reverse_iterator(end());
929  }
930 
931  //*************************************************************************
933  //*************************************************************************
934  const_reverse_iterator crbegin() const
935  {
936  return const_reverse_iterator(cend());
937  }
938 
939  //*************************************************************************
941  //*************************************************************************
942  reverse_iterator rend()
943  {
944  return reverse_iterator(begin());
945  }
946 
947  //*************************************************************************
949  //*************************************************************************
950  const_reverse_iterator rend() const
951  {
952  return const_reverse_iterator(begin());
953  }
954 
955  //*************************************************************************
957  //*************************************************************************
958  const_reverse_iterator crend() const
959  {
960  return const_reverse_iterator(cbegin());
961  }
962 
963  //*************************************************************************
965  //*************************************************************************
966  void clear()
967  {
968  initialise();
969  }
970 
971  //*************************************************************************
976  //*************************************************************************
977  iterator insert(const_iterator insert_position, const value_type& value)
978  {
979  iterator position(insert_position.index, *this, p_buffer);
980 
981  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
982 
983  if (insert_position == begin())
984  {
985  create_element_front(value);
986  position = _begin;
987  }
988  else if (insert_position == end())
989  {
990  create_element_back(value);
991  position = _end - 1;
992  }
993  else
994  {
995  // Are we closer to the front?
996  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
997  {
998  // Construct the _begin.
999  create_element_front(*_begin);
1000 
1001  // Move the values.
1002  etl::move(_begin + 1, position, _begin);
1003 
1004  // Write the new value.
1005  *--position = value;
1006  }
1007  else
1008  {
1009  // Construct the _end.
1010  create_element_back(*(_end - 1));
1011 
1012  // Move the values.
1013  etl::move_backward(position, _end - 2, _end - 1);
1014 
1015  // Write the new value.
1016  *position = value;
1017  }
1018  }
1019 
1020  return position;
1021  }
1022 
1023 #if ETL_CPP11_SUPPORTED
1024  //*************************************************************************
1029  //*************************************************************************
1030  iterator insert(const_iterator insert_position, value_type&& value)
1031  {
1032  iterator position(insert_position.index, *this, p_buffer);
1033 
1034  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1035 
1036  if (insert_position == begin())
1037  {
1038  create_element_front(etl::move(value));
1039  position = _begin;
1040  }
1041  else if (insert_position == end())
1042  {
1043  create_element_back(etl::move(value));
1044  position = _end - 1;
1045  }
1046  else
1047  {
1048  // Are we closer to the front?
1049  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1050  {
1051  // Construct the _begin.
1052  create_element_front(etl::move(*_begin));
1053 
1054  // Move the values.
1055  etl::move(_begin + 1, position, _begin);
1056 
1057  // Write the new value.
1058  *--position = etl::move(value);
1059  }
1060  else
1061  {
1062  // Construct the _end.
1063  create_element_back(etl::move(*(_end - 1)));
1064 
1065  // Move the values.
1066  etl::move_backward(position, _end - 2, _end - 1);
1067 
1068  // Write the new value.
1069  *position = etl::move(value);
1070  }
1071  }
1072 
1073  return position;
1074  }
1075 #endif
1076 
1077  //*************************************************************************
1081  //*************************************************************************
1082 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
1083  template <typename ... Args>
1084  iterator emplace(const_iterator insert_position, Args && ... args)
1085  {
1086  iterator position(insert_position.index, *this, p_buffer);
1087 
1088  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1089 
1090  void* p;
1091 
1092  if (insert_position == begin())
1093  {
1094  --_begin;
1095  p = etl::addressof(*_begin);
1096  ++current_size;
1097  ETL_INCREMENT_DEBUG_COUNT
1098  position = _begin;
1099  }
1100  else if (insert_position == end())
1101  {
1102  p = etl::addressof(*_end);
1103  ++_end;
1104  ++current_size;
1105  ETL_INCREMENT_DEBUG_COUNT
1106  position = _end - 1;
1107  }
1108  else
1109  {
1110  // Are we closer to the front?
1111  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1112  {
1113  // Construct the _begin.
1114  create_element_front(*_begin);
1115 
1116  // Move the values.
1117  etl::move(_begin + 1, position, _begin);
1118 
1119  // Write the new value.
1120  --position;
1121  (*position).~T();
1122  p = etl::addressof(*position);
1123  }
1124  else
1125  {
1126  // Construct the _end.
1127  create_element_back(*(_end - 1));
1128 
1129  // Move the values.
1130  etl::move_backward(position, _end - 2, _end - 1);
1131 
1132  // Write the new value.
1133  (*position).~T();
1134  p = etl::addressof(*position);
1135  }
1136  }
1137 
1138  ::new (p) T(etl::forward<Args>(args)...);
1139 
1140  return position;
1141  }
1142 
1143 #else
1144 
1145  //*************************************************************************
1149  //*************************************************************************
1150  template <typename T1>
1151  iterator emplace(const_iterator insert_position, const T1& value1)
1152  {
1153  iterator position(insert_position.index, *this, p_buffer);
1154 
1155  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1156 
1157  void* p;
1158 
1159  if (insert_position == begin())
1160  {
1161  --_begin;
1162  p = etl::addressof(*_begin);
1163  ++current_size;
1164  ETL_INCREMENT_DEBUG_COUNT
1165  position = _begin;
1166  }
1167  else if (insert_position == end())
1168  {
1169  p = etl::addressof(*_end);
1170  ++_end;
1171  ++current_size;
1172  ETL_INCREMENT_DEBUG_COUNT
1173  position = _end - 1;
1174  }
1175  else
1176  {
1177  // Are we closer to the front?
1178  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1179  {
1180  // Construct the _begin.
1181  create_element_front(*_begin);
1182 
1183  // Move the values.
1184  etl::move(_begin + 1, position, _begin);
1185 
1186  // Write the new value.
1187  --position;
1188  (*position).~T();
1189  p = etl::addressof(*position);
1190  }
1191  else
1192  {
1193  // Construct the _end.
1194  create_element_back(*(_end - 1));
1195 
1196  // Move the values.
1197  etl::move_backward(position, _end - 2, _end - 1);
1198 
1199  // Write the new value.
1200  (*position).~T();
1201  p = etl::addressof(*position);
1202  }
1203  }
1204 
1205  ::new (p) T(value1);
1206 
1207  return position;
1208  }
1209 
1210  //*************************************************************************
1214  //*************************************************************************
1215  template <typename T1, typename T2>
1216  iterator emplace(const_iterator insert_position, const T1& value1, const T2& value2)
1217  {
1218  iterator position(insert_position.index, *this, p_buffer);
1219 
1220  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1221 
1222  void* p;
1223 
1224  if (insert_position == begin())
1225  {
1226  --_begin;
1227  p = etl::addressof(*_begin);
1228  ++current_size;
1229  ETL_INCREMENT_DEBUG_COUNT
1230  position = _begin;
1231  }
1232  else if (insert_position == end())
1233  {
1234  p = etl::addressof(*_end);
1235  ++_end;
1236  ++current_size;
1237  ETL_INCREMENT_DEBUG_COUNT
1238  position = _end - 1;
1239  }
1240  else
1241  {
1242  // Are we closer to the front?
1243  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1244  {
1245  // Construct the _begin.
1246  create_element_front(*_begin);
1247 
1248  // Move the values.
1249  etl::move(_begin + 1, position, _begin);
1250 
1251  // Write the new value.
1252  --position;
1253  (*position).~T();
1254  p = etl::addressof(*position);
1255  }
1256  else
1257  {
1258  // Construct the _end.
1259  create_element_back(*(_end - 1));
1260 
1261  // Move the values.
1262  etl::move_backward(position, _end - 2, _end - 1);
1263 
1264  // Write the new value.
1265  (*position).~T();
1266  p = etl::addressof(*position);
1267  }
1268  }
1269 
1270  ::new (p) T(value1, value2);
1271 
1272  return position;
1273  }
1274 
1275  //*************************************************************************
1279  //*************************************************************************
1280  template <typename T1, typename T2, typename T3>
1281  iterator emplace(const_iterator insert_position, const T1& value1, const T2& value2, const T3& value3)
1282  {
1283  iterator position(insert_position.index, *this, p_buffer);
1284 
1285  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1286 
1287  void* p;
1288 
1289  if (insert_position == begin())
1290  {
1291  --_begin;
1292  p = etl::addressof(*_begin);
1293  ++current_size;
1294  ETL_INCREMENT_DEBUG_COUNT
1295  position = _begin;
1296  }
1297  else if (insert_position == end())
1298  {
1299  p = etl::addressof(*_end);
1300  ++_end;
1301  ++current_size;
1302  ETL_INCREMENT_DEBUG_COUNT
1303  position = _end - 1;
1304  }
1305  else
1306  {
1307  // Are we closer to the front?
1308  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1309  {
1310  // Construct the _begin.
1311  create_element_front(*_begin);
1312 
1313  // Move the values.
1314  etl::move(_begin + 1, position, _begin);
1315 
1316  // Write the new value.
1317  --position;
1318  (*position).~T();
1319  p = etl::addressof(*position);
1320  }
1321  else
1322  {
1323  // Construct the _end.
1324  create_element_back(*(_end - 1));
1325 
1326  // Move the values.
1327  etl::move_backward(position, _end - 2, _end - 1);
1328 
1329  // Write the new value.
1330  (*position).~T();
1331  p = etl::addressof(*position);
1332  }
1333  }
1334 
1335  ::new (p) T(value1, value2, value3);
1336 
1337  return position;
1338  }
1339 
1340  //*************************************************************************
1344  //*************************************************************************
1345  template <typename T1, typename T2, typename T3, typename T4>
1346  iterator emplace(const_iterator insert_position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1347  {
1348  iterator position(insert_position.index, *this, p_buffer);
1349 
1350  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1351 
1352  void* p;
1353 
1354  if (insert_position == begin())
1355  {
1356  --_begin;
1357  p = etl::addressof(*_begin);
1358  ++current_size;
1359  ETL_INCREMENT_DEBUG_COUNT
1360  position = _begin;
1361  }
1362  else if (insert_position == end())
1363  {
1364  p = etl::addressof(*_end);
1365  ++_end;
1366  ++current_size;
1367  ETL_INCREMENT_DEBUG_COUNT
1368  position = _end - 1;
1369  }
1370  else
1371  {
1372  // Are we closer to the front?
1373  if (etl::distance(_begin, position) < etl::distance(position, _end - 1))
1374  {
1375  // Construct the _begin.
1376  create_element_front(*_begin);
1377 
1378  // Move the values.
1379  etl::move(_begin + 1, position, _begin);
1380 
1381  // Write the new value.
1382  --position;
1383  (*position).~T();
1384  p = etl::addressof(*position);
1385  }
1386  else
1387  {
1388  // Construct the _end.
1389  create_element_back(*(_end - 1));
1390 
1391  // Move the values.
1392  etl::move_backward(position, _end - 2, _end - 1);
1393 
1394  // Write the new value.
1395  (*position).~T();
1396  p = etl::addressof(*position);
1397  }
1398  }
1399 
1400  ::new (p) T(value1, value2, value3, value4);
1401 
1402  return position;
1403  }
1404 #endif
1405 
1406  //*************************************************************************
1412  //*************************************************************************
1413  iterator insert(const_iterator insert_position, size_type n, const value_type& value)
1414  {
1415  iterator position;
1416 
1417  ETL_ASSERT((current_size + n) <= CAPACITY, ETL_ERROR(deque_full));
1418 
1419  if (insert_position == begin())
1420  {
1421  for (size_t i = 0; i < n; ++i)
1422  {
1423  create_element_front(value);
1424  }
1425 
1426  position = _begin;
1427  }
1428  else if (insert_position == end())
1429  {
1430  for (size_t i = 0; i < n; ++i)
1431  {
1432  create_element_back(value);
1433  }
1434 
1435  position = _end - n;
1436  }
1437  else
1438  {
1439  // Non-const insert iterator.
1440  position = iterator(insert_position.index, *this, p_buffer);
1441 
1442  // Are we closer to the front?
1443  if (distance(_begin, insert_position) <= difference_type(current_size / 2))
1444  {
1445  size_t n_insert = n;
1446  size_t n_move = etl::distance(begin(), position);
1447  size_t n_create_copy = etl::min(n_insert, n_move);
1448  size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0;
1449  size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0;
1450  size_t n_copy_old = n_move - n_create_copy;
1451 
1452  // Remember the original start.
1453  iterator from = _begin + n_create_copy - 1;
1454  iterator to;
1455 
1456  // Create new.
1457  for (size_t i = 0; i < n_create_new; ++i)
1458  {
1459  create_element_front(value);
1460  }
1461 
1462  // Create copy.
1463  for (size_t i = 0; i < n_create_copy; ++i)
1464  {
1465  create_element_front(*from--);
1466  }
1467 
1468  // Move old.
1469  from = position - n_copy_old;
1470  to = _begin + n_create_copy;
1471  etl::move(from, from + n_copy_old, to);
1472 
1473  // Copy new.
1474  to = position - n_create_copy;
1475  etl::fill_n(to, n_copy_new, value);
1476 
1477  position = _begin + n_move;
1478  }
1479  else
1480  {
1481  size_t n_insert = n;
1482  size_t n_move = etl::distance(position, end());
1483  size_t n_create_copy = etl::min(n_insert, n_move);
1484  size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0;
1485  size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0;
1486  size_t n_copy_old = n_move - n_create_copy;
1487 
1488  // Create new.
1489  for (size_t i = 0; i < n_create_new; ++i)
1490  {
1491  create_element_back(value);
1492  }
1493 
1494  // Create copy.
1495  const_iterator from = position + n_copy_old;
1496 
1497  for (size_t i = 0; i < n_create_copy; ++i)
1498  {
1499  create_element_back(*from++);
1500  }
1501 
1502  // Move old.
1503  etl::move_backward(position, position + n_copy_old, position + n_insert + n_copy_old);
1504 
1505  // Copy new.
1506  etl::fill_n(position, n_copy_new, value);
1507  }
1508  }
1509 
1510  return position;
1511  }
1512 
1513  //*************************************************************************
1519  //*************************************************************************
1520  template<typename TIterator>
1522  insert(const_iterator insert_position, TIterator range_begin, TIterator range_end)
1523  {
1524  iterator position;
1525 
1526  difference_type n = etl::distance(range_begin, range_end);
1527 
1528  ETL_ASSERT((current_size + n) <= CAPACITY, ETL_ERROR(deque_full));
1529 
1530  if (insert_position == begin())
1531  {
1532  create_element_front(n, range_begin);
1533 
1534  position = _begin;
1535  }
1536  else if (insert_position == end())
1537  {
1538  for (difference_type i = 0; i < n; ++i)
1539  {
1540  create_element_back(*range_begin++);
1541  }
1542 
1543  position = _end - n;
1544  }
1545  else
1546  {
1547  // Non-const insert iterator.
1548  position = iterator(insert_position.index, *this, p_buffer);
1549 
1550  // Are we closer to the front?
1551  if (distance(_begin, insert_position) < difference_type(current_size / 2))
1552  {
1553  size_t n_insert = n;
1554  size_t n_move = etl::distance(begin(), position);
1555  size_t n_create_copy = etl::min(n_insert, n_move);
1556  size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0;
1557  size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0;
1558  size_t n_copy_old = n_move - n_create_copy;
1559 
1560  // Remember the original start.
1561  iterator from;
1562  iterator to;
1563 
1564  // Create new.
1565  create_element_front(n_create_new, range_begin);
1566 
1567  // Create copy.
1568  create_element_front(n_create_copy, _begin + n_create_new);
1569 
1570  // Move old.
1571  from = position - n_copy_old;
1572  to = _begin + n_create_copy;
1573  etl::move(from, from + n_copy_old, to);
1574 
1575  // Copy new.
1576  to = position - n_create_copy;
1577  range_begin += n_create_new;
1578  etl::copy(range_begin, range_begin + n_copy_new, to);
1579 
1580  position = _begin + n_move;
1581  }
1582  else
1583  {
1584  size_t n_insert = n;
1585  size_t n_move = etl::distance(position, end());
1586  size_t n_create_copy = etl::min(n_insert, n_move);
1587  size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0;
1588  size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0;
1589  size_t n_copy_old = n_move - n_create_copy;
1590 
1591  // Create new.
1592  TIterator item = range_begin + (n - n_create_new);
1593  for (size_t i = 0; i < n_create_new; ++i)
1594  {
1595  create_element_back(*item++);
1596  }
1597 
1598  // Create copy.
1599  const_iterator from = position + n_copy_old;
1600 
1601  for (size_t i = 0; i < n_create_copy; ++i)
1602  {
1603  create_element_back(*from++);
1604  }
1605 
1606  // Move old.
1607  etl::move_backward(position, position + n_copy_old, position + n_insert + n_copy_old);
1608 
1609  // Copy new.
1610  item = range_begin;
1611  etl::copy(item, item + n_copy_new, position);
1612  }
1613  }
1614 
1615  return position;
1616  }
1617 
1618  //*************************************************************************
1622  //*************************************************************************
1624  {
1625  iterator position(erase_position.index, *this, p_buffer);
1626 
1627  ETL_ASSERT(distance(position) <= difference_type(current_size), ETL_ERROR(deque_out_of_bounds));
1628 
1629  if (position == _begin)
1630  {
1631  destroy_element_front();
1632  position = begin();
1633  }
1634  else if (position == _end - 1)
1635  {
1636  destroy_element_back();
1637  position = end();
1638  }
1639  else
1640  {
1641  // Are we closer to the front?
1642  if (distance(_begin, position) < difference_type(current_size / 2))
1643  {
1644  etl::move_backward(_begin, position, position + 1);
1645  destroy_element_front();
1646  ++position;
1647  }
1648  else
1649  {
1650  etl::move(position + 1, _end, position);
1651  destroy_element_back();
1652  }
1653  }
1654 
1655  return position;
1656  }
1657 
1658  //*************************************************************************
1663  //*************************************************************************
1665  {
1666  iterator position(range_begin.index, *this, p_buffer);
1667 
1668  ETL_ASSERT((distance(range_begin) <= difference_type(current_size)) && (distance(range_end) <= difference_type(current_size)), ETL_ERROR(deque_out_of_bounds));
1669 
1670  // How many to erase?
1671  size_t length = etl::distance(range_begin, range_end);
1672 
1673  // At the beginning?
1674  if (position == _begin)
1675  {
1676  for (size_t i = 0; i < length; ++i)
1677  {
1678  destroy_element_front();
1679  }
1680 
1681  position = begin();
1682  }
1683  // At the end?
1684  else if (position == _end - length)
1685  {
1686  for (size_t i = 0; i < length; ++i)
1687  {
1688  destroy_element_back();
1689  }
1690 
1691  position = end();
1692  }
1693  else
1694  {
1695  // Copy the smallest number of items.
1696  // Are we closer to the front?
1697  if (distance(_begin, position) < difference_type(current_size / 2))
1698  {
1699  // Move the items.
1700  etl::move_backward(_begin, position, position + length);
1701 
1702  for (size_t i = 0; i < length; ++i)
1703  {
1704  destroy_element_front();
1705  }
1706 
1707  position += length;
1708  }
1709  else
1710  // Must be closer to the back.
1711  {
1712  // Move the items.
1713  etl::move(position + length, _end, position);
1714 
1715  for (size_t i = 0; i < length; ++i)
1716  {
1717  destroy_element_back();
1718  }
1719  }
1720  }
1721 
1722  return position;
1723  }
1724 
1725  //*************************************************************************
1729  //*************************************************************************
1730  void push_back(const_reference item)
1731  {
1732 #if defined(ETL_CHECK_PUSH_POP)
1733  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1734 #endif
1735  create_element_back(item);
1736  }
1737 
1738 #if ETL_CPP11_SUPPORTED
1739  //*************************************************************************
1743  //*************************************************************************
1744  void push_back(rvalue_reference item)
1745  {
1746 #if defined(ETL_CHECK_PUSH_POP)
1747  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1748 #endif
1749  create_element_back(etl::move(item));
1750  }
1751 #endif
1752 
1753 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
1754  //*************************************************************************
1757  //*************************************************************************
1758  template <typename ... Args>
1759  void emplace_back(Args && ... args)
1760  {
1761 #if defined(ETL_CHECK_PUSH_POP)
1762  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1763 #endif
1764 
1765  ::new (&(*_end)) T(etl::forward<Args>(args)...);
1766  ++_end;
1767  ++current_size;
1768  ETL_INCREMENT_DEBUG_COUNT
1769  }
1770 
1771 #else
1772 
1773  //*************************************************************************
1776  //*************************************************************************
1777  template <typename T1>
1778  void emplace_back(const T1& value1)
1779  {
1780 #if defined(ETL_CHECK_PUSH_POP)
1781  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1782 #endif
1783 
1784  ::new (&(*_end)) T(value1);
1785  ++_end;
1786  ++current_size;
1787  ETL_INCREMENT_DEBUG_COUNT
1788  }
1789 
1790  //*************************************************************************
1793  //*************************************************************************
1794  template <typename T1, typename T2>
1795  void emplace_back(const T1& value1, const T2& value2)
1796  {
1797 #if defined(ETL_CHECK_PUSH_POP)
1798  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1799 #endif
1800 
1801  ::new (&(*_end)) T(value1, value2);
1802  ++_end;
1803  ++current_size;
1804  ETL_INCREMENT_DEBUG_COUNT
1805  }
1806 
1807  //*************************************************************************
1810  //*************************************************************************
1811  template <typename T1, typename T2, typename T3>
1812  void emplace_back(const T1& value1, const T2& value2, const T3& value3)
1813  {
1814 #if defined(ETL_CHECK_PUSH_POP)
1815  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1816 #endif
1817 
1818  ::new (&(*_end)) T(value1, value2, value3);
1819  ++_end;
1820  ++current_size;
1821  ETL_INCREMENT_DEBUG_COUNT
1822  }
1823 
1824  //*************************************************************************
1827  //*************************************************************************
1828  template <typename T1, typename T2, typename T3, typename T4>
1829  void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1830  {
1831 #if defined(ETL_CHECK_PUSH_POP)
1832  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1833 #endif
1834 
1835  ::new (&(*_end)) T(value1, value2, value3, value4);
1836  ++_end;
1837  ++current_size;
1838  ETL_INCREMENT_DEBUG_COUNT
1839  }
1840 #endif
1841 
1842  //*************************************************************************
1844  //*************************************************************************
1845  void pop_back()
1846  {
1847 #if defined(ETL_CHECK_PUSH_POP)
1848  ETL_ASSERT(!empty(), ETL_ERROR(deque_empty));
1849 #endif
1850  destroy_element_back();
1851  }
1852 
1853  //*************************************************************************
1857  //*************************************************************************
1858  void push_front(const_reference item)
1859  {
1860 #if defined(ETL_CHECK_PUSH_POP)
1861  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1862 #endif
1863  create_element_front(item);
1864  }
1865 
1866 #if ETL_CPP11_SUPPORTED
1867  //*************************************************************************
1871  //*************************************************************************
1872  void push_front(rvalue_reference item)
1873  {
1874 #if defined(ETL_CHECK_PUSH_POP)
1875  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1876 #endif
1877  create_element_front(etl::move(item));
1878  }
1879 #endif
1880 
1881 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
1882  //*************************************************************************
1885  //*************************************************************************
1886  template <typename ... Args>
1887  void emplace_front(Args && ... args)
1888  {
1889 #if defined(ETL_CHECK_PUSH_POP)
1890  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1891 #endif
1892 
1893  --_begin;
1894  ::new (&(*_begin)) T(etl::forward<Args>(args)...);
1895  ++current_size;
1896  ETL_INCREMENT_DEBUG_COUNT
1897  }
1898 
1899 #else
1900 
1901  //*************************************************************************
1904  //*************************************************************************
1905  template <typename T1>
1906  void emplace_front(const T1& value1)
1907  {
1908 #if defined(ETL_CHECK_PUSH_POP)
1909  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1910 #endif
1911 
1912  --_begin;
1913  ::new (&(*_begin)) T(value1);
1914  ++current_size;
1915  ETL_INCREMENT_DEBUG_COUNT
1916  }
1917 
1918  //*************************************************************************
1921  //*************************************************************************
1922  template <typename T1, typename T2>
1923  void emplace_front(const T1& value1, const T2& value2)
1924  {
1925 #if defined(ETL_CHECK_PUSH_POP)
1926  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1927 #endif
1928 
1929  --_begin;
1930  ::new (&(*_begin)) T(value1, value2);
1931  ++current_size;
1932  ETL_INCREMENT_DEBUG_COUNT
1933  }
1934 
1935  //*************************************************************************
1938  //*************************************************************************
1939  template <typename T1, typename T2, typename T3>
1940  void emplace_front(const T1& value1, const T2& value2, const T3& value3)
1941  {
1942 #if defined(ETL_CHECK_PUSH_POP)
1943  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1944 #endif
1945 
1946  --_begin;
1947  ::new (&(*_begin)) T(value1, value2, value3);
1948  ++current_size;
1949  ETL_INCREMENT_DEBUG_COUNT
1950  }
1951 
1952  //*************************************************************************
1955  //*************************************************************************
1956  template <typename T1, typename T2, typename T3, typename T4>
1957  void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1958  {
1959 #if defined(ETL_CHECK_PUSH_POP)
1960  ETL_ASSERT(!full(), ETL_ERROR(deque_full));
1961 #endif
1962 
1963  --_begin;
1964  ::new (&(*_begin)) T(value1, value2, value3, value4);
1965  ++current_size;
1966  ETL_INCREMENT_DEBUG_COUNT
1967  }
1968 #endif
1969 
1970  //*************************************************************************
1972  //*************************************************************************
1973  void pop_front()
1974  {
1975 #if defined(ETL_CHECK_PUSH_POP)
1976  ETL_ASSERT(!empty(), ETL_ERROR(deque_empty));
1977 #endif
1978  destroy_element_front();
1979  }
1980 
1981  //*************************************************************************
1986  //*************************************************************************
1987  void resize(size_t new_size, const value_type& value = value_type())
1988  {
1989  ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(deque_out_of_bounds));
1990 
1991  // Make it smaller?
1992  if (new_size < current_size)
1993  {
1994  while (current_size > new_size)
1995  {
1996  destroy_element_back();
1997  }
1998  }
1999  // Make it larger?
2000  else if (new_size > current_size)
2001  {
2002  size_t count = new_size - current_size;
2003 
2004  for (size_t i = 0; i < count; ++i)
2005  {
2006  create_element_back(value);
2007  }
2008  }
2009  }
2010 
2011  //*************************************************************************
2013  //*************************************************************************
2014  friend difference_type operator -(const iterator& lhs, const iterator& rhs)
2015  {
2016  return distance(rhs, lhs);
2017  }
2018 
2019  //*************************************************************************
2021  //*************************************************************************
2022  friend difference_type operator -(const const_iterator& lhs, const const_iterator& rhs)
2023  {
2024  return distance(rhs, lhs);
2025  }
2026 
2027  //*************************************************************************
2029  //*************************************************************************
2030  friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs)
2031  {
2032  return distance(lhs.base(), rhs.base());
2033  }
2034 
2035  //*************************************************************************
2037  //*************************************************************************
2038  friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs)
2039  {
2040  return distance(lhs.base(), rhs.base());
2041  }
2042 
2043  //*************************************************************************
2045  //*************************************************************************
2046  ideque& operator =(const ideque& rhs)
2047  {
2048  if (&rhs != this)
2049  {
2050  assign(rhs.begin(), rhs.end());
2051  }
2052 
2053  return *this;
2054  }
2055 
2056 #if ETL_CPP11_SUPPORTED
2057  //*************************************************************************
2059  //*************************************************************************
2060  ideque& operator =(ideque&& rhs)
2061  {
2062  if (&rhs != this)
2063  {
2064  clear();
2065  iterator itr = rhs.begin();
2066  while (itr != rhs.end())
2067  {
2068  push_back(etl::move(*itr));
2069  ++itr;
2070  }
2071 
2072  rhs.initialise();
2073  }
2074 
2075  return *this;
2076  }
2077 #endif
2078 
2079 #ifdef ETL_IDEQUE_REPAIR_ENABLE
2080  //*************************************************************************
2082  //*************************************************************************
2083  virtual void repair() = 0;
2084 #endif
2085 
2086  protected:
2087 
2088  //*************************************************************************
2090  //*************************************************************************
2091  ideque(pointer p_buffer_, size_t max_size_, size_t buffer_size_)
2092  : deque_base(max_size_, buffer_size_),
2093  p_buffer(p_buffer_)
2094  {
2095  }
2096 
2097  //*********************************************************************
2099  //*********************************************************************
2100  void initialise()
2101  {
2102  if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
2103  {
2104  current_size = 0;
2105  ETL_RESET_DEBUG_COUNT
2106  }
2107  else
2108  {
2109  while (current_size > 0)
2110  {
2111  destroy_element_back();
2112  }
2113  }
2114 
2115  _begin = iterator(0, *this, p_buffer);
2116  _end = iterator(0, *this, p_buffer);
2117  }
2118 
2119  //*************************************************************************
2121  //*************************************************************************
2122  void repair_buffer(pointer p_buffer_)
2123  {
2124  p_buffer = p_buffer_;
2125 
2126  _begin = iterator(_begin.index, *this, p_buffer);
2127  _end = iterator(_end.index, *this, p_buffer);
2128  }
2129 
2130  iterator _begin;
2132  pointer p_buffer;
2133 
2134  private:
2135 
2136  //*********************************************************************
2138  //*********************************************************************
2139  void create_element_front()
2140  {
2141  --_begin;
2142  ::new (&(*_begin)) T();
2143  ++current_size;
2144  ETL_INCREMENT_DEBUG_COUNT
2145  }
2146 
2147  //*********************************************************************
2149  //*********************************************************************
2150  template <typename TIterator>
2151  void create_element_front(size_t n, TIterator from)
2152  {
2153  if (n == 0)
2154  {
2155  return;
2156  }
2157 
2158  _begin -= n;
2159 
2160  iterator item = _begin;
2161 
2162  do
2163  {
2164  ::new (&(*item++)) T(*from);
2165  ++from;
2166  ++current_size;
2167  ETL_INCREMENT_DEBUG_COUNT
2168  } while (--n != 0);
2169  }
2170 
2171  //*********************************************************************
2173  //*********************************************************************
2174  void create_element_back()
2175  {
2176  ::new (&(*_end)) T();
2177  ++_end;
2178  ++current_size;
2179  ETL_INCREMENT_DEBUG_COUNT
2180  }
2181 
2182  //*********************************************************************
2184  //*********************************************************************
2185  void create_element_front(const_reference value)
2186  {
2187  --_begin;
2188  ::new (&(*_begin)) T(value);
2189  ++current_size;
2190  ETL_INCREMENT_DEBUG_COUNT
2191  }
2192 
2193  //*********************************************************************
2195  //*********************************************************************
2196  void create_element_back(const_reference value)
2197  {
2198  ::new (&(*_end)) T(value);
2199  ++_end;
2200  ++current_size;
2201  ETL_INCREMENT_DEBUG_COUNT
2202  }
2203 
2204 #if ETL_CPP11_SUPPORTED
2205  //*********************************************************************
2207  //*********************************************************************
2208  void create_element_front(rvalue_reference value)
2209  {
2210  --_begin;
2211  ::new (&(*_begin)) T(etl::move(value));
2212  ++current_size;
2213  ETL_INCREMENT_DEBUG_COUNT
2214  }
2215 
2216  //*********************************************************************
2218  //*********************************************************************
2219  void create_element_back(rvalue_reference value)
2220  {
2221  ::new (&(*_end)) T(etl::move(value));
2222  ++_end;
2223  ++current_size;
2224  ETL_INCREMENT_DEBUG_COUNT
2225  }
2226 #endif
2227 
2228  //*********************************************************************
2230  //*********************************************************************
2231  void destroy_element_front()
2232  {
2233  (*_begin).~T();
2234  --current_size;
2235  ETL_DECREMENT_DEBUG_COUNT
2236  ++_begin;
2237  }
2238 
2239  //*********************************************************************
2241  //*********************************************************************
2242  void destroy_element_back()
2243  {
2244  --_end;
2245  (*_end).~T();
2246  --current_size;
2247  ETL_DECREMENT_DEBUG_COUNT
2248  }
2249 
2250  //*************************************************************************
2252  //*************************************************************************
2253  template <typename TIterator1, typename TIterator2>
2254  static difference_type distance(const TIterator1& range_begin, const TIterator2& range_end)
2255  {
2256  difference_type distance1 = distance(range_begin);
2257  difference_type distance2 = distance(range_end);
2258 
2259  return distance2 - distance1;
2260  }
2261 
2262  //*************************************************************************
2264  //*************************************************************************
2265  template <typename TIterator>
2266  static difference_type distance(const TIterator& other)
2267  {
2268  const difference_type index = other.get_index();
2269  const difference_type reference_index = other.container()._begin.index;
2270  const size_t buffer_size = other.container().BUFFER_SIZE;
2271 
2272  if (index < reference_index)
2273  {
2274  return buffer_size + index - reference_index;
2275  }
2276  else
2277  {
2278  return index - reference_index;
2279  }
2280  }
2281 
2282  // Disable copy construction.
2283  ideque(const ideque&);
2284 
2285  //*************************************************************************
2287  //*************************************************************************
2288 #if defined(ETL_POLYMORPHIC_DEQUE) || defined(ETL_POLYMORPHIC_CONTAINERS)
2289  public:
2290  virtual ~ideque()
2291  {
2292  }
2293 #else
2294  protected:
2296  {
2297  }
2298 #endif
2299  };
2300 
2301  //***************************************************************************
2307  //***************************************************************************
2308  template <typename T, const size_t MAX_SIZE_>
2309  class deque : public etl::ideque<T>
2310  {
2311  public:
2312 
2313  static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
2314 
2315  private:
2316 
2317  static ETL_CONSTANT size_t BUFFER_SIZE = MAX_SIZE + 1;
2318 
2319  public:
2320 
2321  typedef T value_type;
2322  typedef T* pointer;
2323  typedef const T* const_pointer;
2324  typedef T& reference;
2325  typedef const T& const_reference;
2326  typedef size_t size_type;
2327  typedef typename etl::iterator_traits<pointer>::difference_type difference_type;
2328 
2329  //*************************************************************************
2331  //*************************************************************************
2333  : etl::ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2334  {
2335  this->initialise();
2336  }
2337 
2338  //*************************************************************************
2340  //*************************************************************************
2342  {
2343  this->initialise();
2344  }
2345 
2346  //*************************************************************************
2348  //*************************************************************************
2349  deque(const deque& other)
2350  : etl::ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2351  {
2352  if (this != &other)
2353  {
2354  this->assign(other.begin(), other.end());
2355  }
2356  }
2357 
2358 #if ETL_CPP11_SUPPORTED
2359  //*************************************************************************
2361  //*************************************************************************
2362  deque(deque&& other)
2363  : etl::ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2364  {
2365  if (this != &other)
2366  {
2367  this->initialise();
2368 
2369  typename etl::ideque<T>::iterator itr = other.begin();
2370  while (itr != other.end())
2371  {
2372  this->push_back(etl::move(*itr));
2373  ++itr;
2374  }
2375  }
2376  }
2377 #endif
2378 
2379  //*************************************************************************
2381  //*************************************************************************
2382  template <typename TIterator>
2383  deque(TIterator begin_, TIterator end_)
2384  : etl::ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2385  {
2386  this->assign(begin_, end_);
2387  }
2388 
2389  //*************************************************************************
2391  //*************************************************************************
2392  explicit deque(size_t n, const_reference value = value_type())
2393  : etl::ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2394  {
2395  this->assign(n, value);
2396  }
2397 
2398 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
2399  //*************************************************************************
2401  //*************************************************************************
2402  deque(std::initializer_list<T> init)
2403  : ideque<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, BUFFER_SIZE)
2404  {
2405  this->assign(init.begin(), init.end());
2406  }
2407 #endif
2408 
2409  //*************************************************************************
2411  //*************************************************************************
2412  deque& operator =(const deque& rhs)
2413  {
2414  if (&rhs != this)
2415  {
2416  this->assign(rhs.begin(), rhs.end());
2417  }
2418 
2419  return *this;
2420  }
2421 
2422 #if ETL_CPP11_SUPPORTED
2423  //*************************************************************************
2425  //*************************************************************************
2426  deque& operator =(deque&& rhs)
2427  {
2428  if (&rhs != this)
2429  {
2430  this->clear();
2431  typename etl::ideque<T>::iterator itr = rhs.begin();
2432  while (itr != rhs.end())
2433  {
2434  this->push_back(etl::move(*itr));
2435  ++itr;
2436  }
2437  }
2438 
2439  return *this;
2440  }
2441 #endif
2442 
2443  //*************************************************************************
2445  //*************************************************************************
2446  void repair()
2447 #ifdef ETL_ISTRING_REPAIR_ENABLE
2448  ETL_OVERRIDE
2449 #endif
2450  {
2451 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2453 #endif
2454 
2455  etl::ideque<T>::repair_buffer(reinterpret_cast<T*>(buffer.raw));
2456  }
2457 
2458  private:
2459 
2462  };
2463 
2464  //*************************************************************************
2466  //*************************************************************************
2467 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
2468  template <typename T, typename... Ts>
2469  deque(T, Ts...)
2470  ->deque<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
2471 #endif
2472 
2473  //***************************************************************************
2479  //***************************************************************************
2480  template <typename T>
2481  bool operator ==(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2482  {
2483  return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
2484  }
2485 
2486  //***************************************************************************
2492  //***************************************************************************
2493  template <typename T>
2494  bool operator !=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2495  {
2496  return !(lhs == rhs);
2497  }
2498 
2499  //***************************************************************************
2505  //***************************************************************************
2506  template <typename T>
2507  bool operator <(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2508  {
2509  return etl::lexicographical_compare(lhs.begin(),
2510  lhs.end(),
2511  rhs.begin(),
2512  rhs.end());
2513  }
2514 
2515  //***************************************************************************
2521  //***************************************************************************
2522  template <typename T>
2523  bool operator <=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2524  {
2525  return !(lhs > rhs);
2526  }
2527 
2528  //***************************************************************************
2534  //***************************************************************************
2535  template <typename T>
2536  bool operator >(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2537  {
2538  return (rhs < lhs);
2539  }
2540 
2541  //***************************************************************************
2547  //***************************************************************************
2548  template <typename T>
2549  bool operator >=(const etl::ideque<T>& lhs, const etl::ideque<T>& rhs)
2550  {
2551  return !(lhs < rhs);
2552  }
2553 }
2554 
2555 #undef ETL_FILE
2556 
2557 #include "private/minmax_pop.h"
2558 
2559 #endif
deque(TIterator begin_, TIterator end_)
Assigns data to the deque.
Definition: deque.h:2383
void emplace_front(const T1 &value1)
Definition: deque.h:1906
const_reverse_iterator crbegin() const
Gets a const reverse iterator to the end of the deque.
Definition: deque.h:934
void clear()
Clears the deque.
Definition: deque.h:966
iterator erase(const_iterator erase_position)
Definition: deque.h:1623
const size_type CAPACITY
The maximum number of elements in the deque.
Definition: deque.h:222
ideque & operator=(const ideque &rhs)
Assignment operator.
Definition: deque.h:2046
etl::enable_if< is_iterator< TIterator >::value, void >::type assign(TIterator range_begin, TIterator range_end)
Assigns a range to the deque.
Definition: deque.h:748
void pop_back()
Removes the oldest item from the deque.
Definition: deque.h:1845
const size_type BUFFER_SIZE
The number of elements in the buffer.
Definition: deque.h:223
const_reverse_iterator rbegin() const
Gets a const reverse iterator to the end of the deque.
Definition: deque.h:926
void resize(size_t new_size, const value_type &value=value_type())
Definition: deque.h:1987
iterator emplace(const_iterator insert_position, const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition: deque.h:1346
iterator begin()
Gets an iterator to the beginning of the deque.
Definition: deque.h:870
reference front()
Definition: deque.h:835
reference at(size_t index)
Definition: deque.h:782
pointer p_buffer
Iterator to the _end item in the deque.
Definition: deque.h:2132
friend difference_type operator-(const iterator &lhs, const iterator &rhs)
Definition: deque.h:2014
void initialise()
Initialise the deque.
Definition: deque.h:2100
reference operator[](size_t index)
Definition: deque.h:811
~deque_base()
Destructor.
Definition: deque.h:217
iterator _end
Iterator to the _begin item in the deque.
Definition: deque.h:2131
size_type size() const
Definition: deque.h:152
const_reference at(size_t index) const
Definition: deque.h:797
const_reverse_iterator crend() const
Gets a const reverse iterator to the beginning of the deque.
Definition: deque.h:958
void emplace_back(const T1 &value1, const T2 &value2, const T3 &value3)
Definition: deque.h:1812
iterator end()
Gets an iterator to the end of the deque.
Definition: deque.h:894
const_iterator end() const
Gets a const iterator to the end of the deque.
Definition: deque.h:902
void push_front(const_reference item)
Definition: deque.h:1858
size_type max_size() const
Definition: deque.h:179
~ideque()
Destructor.
Definition: deque.h:2295
iterator erase(const_iterator range_begin, const_iterator range_end)
Definition: deque.h:1664
iterator emplace(const_iterator insert_position, const T1 &value1)
Definition: deque.h:1151
deque(const deque &other)
Copy constructor.
Definition: deque.h:2349
iterator emplace(const_iterator insert_position, const T1 &value1, const T2 &value2)
Definition: deque.h:1216
iterator insert(const_iterator insert_position, size_type n, const value_type &value)
Definition: deque.h:1413
void emplace_front(const T1 &value1, const T2 &value2)
Definition: deque.h:1923
bool full() const
Definition: deque.h:170
size_type capacity() const
Definition: deque.h:188
void emplace_front(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition: deque.h:1957
const_reference back() const
Definition: deque.h:862
bool empty() const
Definition: deque.h:161
void repair()
Fix the internal pointers after a low level memory copy.
Definition: deque.h:2446
const_reverse_iterator rend() const
Gets a const reverse iterator to the beginning of the deque.
Definition: deque.h:950
const_iterator cend() const
Gets a const iterator to the end of the deque.
Definition: deque.h:910
void emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Definition: deque.h:1940
deque_base(size_t max_size_, size_t buffer_size_)
Constructor.
Definition: deque.h:207
enable_if< is_iterator< TIterator >::value, iterator >::type insert(const_iterator insert_position, TIterator range_begin, TIterator range_end)
Definition: deque.h:1522
void assign(size_type n, const value_type &value)
Definition: deque.h:764
void emplace_back(const T1 &value1)
Definition: deque.h:1778
deque()
Default constructor.
Definition: deque.h:2332
reference back()
Definition: deque.h:853
iterator emplace(const_iterator insert_position, const T1 &value1, const T2 &value2, const T3 &value3)
Definition: deque.h:1281
reverse_iterator rbegin()
Gets a reverse iterator to the end of the deque.
Definition: deque.h:918
void pop_front()
Removes the oldest item from the deque.
Definition: deque.h:1973
void emplace_back(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition: deque.h:1829
void push_back(const_reference item)
Definition: deque.h:1730
const_iterator cbegin() const
Gets a const iterator to the beginning of the deque.
Definition: deque.h:886
~deque()
Destructor.
Definition: deque.h:2341
reverse_iterator rend()
Gets a reverse iterator to the beginning of the deque.
Definition: deque.h:942
const_reference front() const
Definition: deque.h:844
deque(size_t n, const_reference value=value_type())
Assigns data to the deque.
Definition: deque.h:2392
size_t available() const
Definition: deque.h:197
const_iterator begin() const
Gets a const iterator to the beginning of the deque.
Definition: deque.h:878
iterator insert(const_iterator insert_position, const value_type &value)
Definition: deque.h:977
void repair_buffer(pointer p_buffer_)
Fix the internal pointers after a low level memory copy.
Definition: deque.h:2122
size_type current_size
The current number of elements in the deque.
Definition: deque.h:221
void emplace_back(const T1 &value1, const T2 &value2)
Definition: deque.h:1795
ideque(pointer p_buffer_, size_t max_size_, size_t buffer_size_)
Constructor.
Definition: deque.h:2091
Definition: deque.h:2310
Definition: deque.h:143
Definition: deque.h:101
Definition: deque.h:73
Definition: deque.h:87
Definition: deque.h:115
Definition: deque.h:234
bool operator>=(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: deque.h:2549
bool operator==(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Template deduction guides.
Definition: deque.h:2481
bool operator<(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: deque.h:2507
bool operator<=(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: deque.h:2523
bool operator>(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: deque.h:2536
bool operator!=(const etl::ideque< T > &lhs, const etl::ideque< T > &rhs)
Definition: deque.h:2494
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
T * addressof(T &t)
Definition: memory.h:61
enable_if
Definition: type_traits_generator.h:1228
integral_constant
Definition: type_traits_generator.h:800
is_trivially_copyable
Definition: type_traits_generator.h:1191
is_trivially_destructible
Definition: type_traits_generator.h:1171
Definition: deque.h:129
Definition: absolute.h:37
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
etl::fixed_iterator< TIterator > & operator-(etl::fixed_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type)
Definition: fixed_iterator.h:193
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:570
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
etl::fixed_iterator< TIterator > & operator+(etl::fixed_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type)
Definition: fixed_iterator.h:183
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:606
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:621
Const Iterator.
Definition: deque.h:502
Test for an iterator.
Definition: deque.h:255
Iterator.
Definition: deque.h:264
iterator
Definition: iterator.h:422