21 template <
class DataType>
25 friend class VectorDequeTest;
28 template <
class VectorDequeType,
class MemberType,
bool IS_REVERSE>
30 typedef IteratorBase<VectorDeque, DataType, IS_REVERSE>
Iterator;
31 typedef IteratorBase<const VectorDeque, const DataType, IS_REVERSE>
ConstIterator;
39 VectorDequeType*
const _vectorDequePtr;
41 static MemberType& dereferenceAt(VectorDequeType*
const vectorDequePtr,
const ptrdiff_t position)
throw() {
43 return (*vectorDequePtr)[vectorDequePtr->size() - position - 1];
45 return (*vectorDequePtr)[position];
50 IteratorBase(VectorDequeType*
const vectorDequePtr,
const size_t position)
throw():
51 _vectorDequePtr(vectorDequePtr), _position(position) {}
54 IteratorBase(VectorDequeType*
const vectorDequePtr)
throw(): _vectorDequePtr(vectorDequePtr), _position(0) {}
60 IteratorBase()
throw(): _position(0), _vectorDequePtr(NULL) {}
67 IteratorBase(
const Iterator& that)
throw(): _position(that._position),
68 _vectorDequePtr(that._vectorDequePtr) {}
75 IteratorBase(
const ConstIterator& that)
throw(): _position(that._position),
76 _vectorDequePtr(that._vectorDequePtr) {}
85 _position = that._position;
86 _vectorDequePtr = that._vectorDequePointer;
97 _position = that._position;
98 _vectorDequePtr = that._vectorDequePointer;
120 return _position == that._position && _vectorDequePtr == that._vectorDequePtr;
131 return !(*
this == that);
142 return _position < that._position;
153 return _position > that._position;
165 return *
this == that || *
this < that;
177 return *
this == that || *
this > that;
185 IteratorBase& operator ++()
throw() {
195 IteratorBase operator ++(
int)
throw() {
196 const IteratorBase copy(*
this);
206 IteratorBase& operator --()
throw() {
216 IteratorBase operator --(
int)
throw() {
217 const IteratorBase copy(*
this);
228 IteratorBase& operator +=(
const ptrdiff_t amount)
throw() {
239 IteratorBase& operator -=(
const ptrdiff_t amount)
throw() {
251 IteratorBase operator +(
const ptrdiff_t amount)
const throw() {
252 return IteratorBase(*
this) += amount;
262 friend IteratorBase operator +(
const ptrdiff_t amount,
const IteratorBase& it)
throw() {
273 IteratorBase operator -(
const ptrdiff_t amount)
const throw() {
274 return IteratorBase(*
this) -= amount;
286 ptrdiff_t operator -(
const ConstIterator& that)
const throw() {
287 return static_cast<ptrdiff_t
>(_position) - that._position;
297 MemberType& operator *()
const {
298 return dereferenceAt(_vectorDequePtr, static_cast<ptrdiff_t>(_position));
307 MemberType* operator ->()
const throw() {
318 MemberType&
operator [](
const ptrdiff_t offset)
const {
319 return dereferenceAt(_vectorDequePtr, static_cast<ptrdiff_t>(_position) + offset);
337 void _addAll(
const DataType*
const elements,
const size_t start,
const size_t length)
throw() {
339 const size_t numBeforeWrap = std::min(_capacity - start, length);
340 const size_t numAfterWrap = length - numBeforeWrap;
341 std::memcpy(_data + start, elements,
sizeof(DataType) * numBeforeWrap);
342 std::memcpy(_data, elements + numBeforeWrap,
sizeof(DataType) * numAfterWrap);
347 void _checkIndex(
const size_t index)
const {
348 if (index >= _size) {
349 throw std::length_error(std::to_string(index));
355 template <
class IteratorType>
356 void _checkIterator(
const IteratorType& it)
const {
357 if (
this != it._vectorDequePtr) {
358 throw std::invalid_argument(
"Iterator is not iterating over this VectorDeque");
364 void _checkRange(
const size_t from,
const size_t until)
const {
367 throw std::invalid_argument(
"Bad range: start = " + std::to_string(from) +
", end = " +
368 std::to_string(until));
374 void _checkSize(
const size_t required = 1)
const {
376 _checkIndex(required - 1);
382 void _ensureCapacity(
const size_t required)
throw() {
383 if (_capacity < required) {
384 const size_t newCapacity = required * 2 + 1;
385 DataType*
const newData =
new DataType[newCapacity];
390 _capacity = newCapacity;
396 void _ensureCanFit(
const size_t amount = 1)
throw() {
397 _ensureCapacity(_size + amount);
401 void _init(
const size_t capacity)
throw() {
402 _capacity = capacity;
403 _data =
new DataType[capacity];
409 void _insertAndResize(
const DataType& element,
const size_t before) {
410 const size_t newCapacity = 2 * _capacity + 1;
411 DataType*
const newData =
new DataType[newCapacity];
413 newData[before] = element;
414 if (before < _size) {
420 _capacity = newCapacity;
426 size_t _internalIndex(
const size_t offset)
const throw() {
427 if (_position + offset < _capacity) {
428 return _position + offset;
432 return _position + offset - _capacity;
436 size_t _internalNegativeIndexFrom(
const size_t from,
const size_t offset)
const throw() {
437 const size_t internal = _internalIndex(from);
438 if (
internal >= offset) {
439 return internal - offset;
443 return _capacity - (offset -
internal);
448 size_t _numBeforeWrap(
const size_t start,
const size_t length)
const throw() {
449 return std::min(_capacity - start, length);
453 void _shiftDown(
const size_t from,
const size_t until)
throw() {
455 const size_t length = until - from;
457 const size_t start = _internalNegativeIndexFrom(from, 1);
458 const size_t numBeforeWrap = _numBeforeWrap(start, length);
459 const size_t numAfterWrap = length - numBeforeWrap;
460 std::memcpy(_data + start, _data + start + 1,
sizeof(DataType) * numBeforeWrap);
461 if (numAfterWrap != 0) {
463 _data[_capacity - 1] = _data[0];
465 std::memcpy(_data, _data + 1,
sizeof(DataType) * (numAfterWrap - 1));
469 if (_position == 0) {
470 _position = _capacity - 1;
478 void _shiftUp(
const size_t from,
const size_t until) {
481 for (
size_t i = 0; i < until - from; ++i) {
482 _data[_internalNegativeIndexFrom(until, i)] = _data[_internalNegativeIndexFrom(until, i + 1)];
486 if (_position == _capacity - 1) {
495 size_t _writePosition()
const throw() {
497 return _internalIndex(_size);
504 typedef IteratorBase<VectorDeque, DataType, false>
Iterator;
509 typedef IteratorBase<const VectorDeque, const DataType, false>
ConstIterator;
552 that.copyToArray(_data);
581 if (_capacity < that._size) {
583 _data =
new DataType[that._size];
584 _capacity = that._size;
586 that.copyToArray(_data);
617 if (_size != that.size()) {
620 for (
size_t i = 0; i < _size; ++i) {
621 if ((*
this)[i] != that[i]) {
635 return !(*
this == that);
648 return _data[_internalIndex(index)];
656 operator std::string()
const throw() {
660 std::stringstream stream;
662 stream << (*this)[0];
663 for (
size_t i = 1; i < _size; ++i) {
664 stream <<
", " << (*this)[i];
675 void add(
const DataType& element)
throw() {
677 _data[_writePosition()] = element;
687 void addAll(
const DataType*
const elements,
const size_t length)
throw() {
688 _ensureCanFit(length);
689 _addAll(elements, _writePosition(), length);
700 template <
class IteratorType>
702 for (IteratorType it =
begin; it !=
end; ++it) {
715 void addAllFirst(
const DataType*
const elements,
const size_t length)
throw() {
729 template <
class IteratorType>
731 for (IteratorType it =
begin; it !=
end; ++it) {
743 if (_position == 0) {
744 _position = _capacity - 1;
749 _data[_position] = element;
794 bool contains(
const DataType& element)
const throw() {
795 return find(element) != -1;
840 ssize_t
find(
const DataType& element)
const throw() {
841 for (
size_t i = 0; i < _size; ++i) {
842 if (element == (*
this)[i]) {
858 return (*
this)[_size - index - 1];
869 void insert(
const DataType& element,
const size_t before) {
875 if (before != _size) {
882 if (_size == _capacity) {
884 _insertAndResize(element, before);
888 if (before <= _size / 2) {
890 _shiftDown(0, before);
894 _shiftUp(before, _size);
897 const size_t insertionIndex = _internalIndex(before);
898 _data[insertionIndex] = element;
912 insert(element, it._position);
926 insert(element, _size - it._position);
959 return (*
this)[_size - 1];
971 const DataType popped =
peek();
981 void popAll(DataType*
const target)
throw() {
1005 const DataType popped =
peekLast();
1017 void popSome(DataType*
const target,
const size_t amount) {
1055 const DataType result = (*this)[index];
1056 if (index == _size - 1) {
1059 else if (index / 2 <= _size) {
1066 _shiftDown(index + 1, _size);
1129 _checkRange(from, until);
1130 const size_t length = until - from;
1131 for (
size_t i = 0; i < length; ++i) {
1152 void skip(
const size_t amount = 1) {
1154 _position = _internalIndex(amount);
1180 void sliceToArray(DataType*
const target,
const size_t from,
const size_t until)
const {
1181 _checkRange(from, until);
1182 const size_t length = until - from;
1183 const size_t start = _internalIndex(from);
1184 const size_t numBeforeWrap = _numBeforeWrap(start, length);
1185 const size_t numAfterWrap = length - numBeforeWrap;
1186 memcpy(target, _data + start,
sizeof(DataType) * numBeforeWrap);
1187 memcpy(target + numBeforeWrap, _data,
sizeof(DataType) * numAfterWrap);
1191 template <
class DataType>
1196 template <
class DataType,
class VectorDequeType,
class MemberType,
bool IS_REVERSE>
1199 IteratorBase<VectorDequeType, MemberType, IS_REVERSE>& it)
throw();
ssize_t find(const DataType &element) const
Check to see where element is located in *this.
Definition: VectorDeque.hpp:840
DataType pop()
Remove and return the first element.
Definition: VectorDeque.hpp:969
DataType removeAt(const ConstReverseIterator &it)
Remove the element pointed to by it.
Definition: VectorDeque.hpp:1095
ReverseIterator rbegin()
Get a reverse iterator pointing to the last element of *this.
Definition: VectorDeque.hpp:1041
bool operator==(const VectorDeque &that) const
Checks to see if *this is equal to another VectorDeque.
Definition: VectorDeque.hpp:613
void reverseCopyToArray(DataType *const target) const
Copy the contents of *this to the given array in reverse order.
Definition: VectorDeque.hpp:1114
DataType & operator[](const size_t index) const
Access the element at index.
Definition: VectorDeque.hpp:646
void insert(const DataType &element, const ConstReverseIterator &it)
Insert element after (with respect to *this) the element pointed to by the reverse iterator it...
Definition: VectorDeque.hpp:924
Iterator end()
Get an iterator past the last element of *this.
Definition: VectorDeque.hpp:830
size_t size() const
Returns the number of elements in *this.
Definition: VectorDeque.hpp:1141
void insert(const DataType &element, const size_t before)
Insert element before before.
Definition: VectorDeque.hpp:869
Iterator rend()
Get an iterator past the last element of *this.
Definition: VectorDeque.hpp:1105
bool operator!=(const VectorDeque &that) const
Checks to see if *this is not equal to another VectorDeque.
Definition: VectorDeque.hpp:634
VectorDeque satisfies the resource constraints typically expected of both Vectors and Deques...
Definition: VectorDeque.hpp:22
DataType popLast()
Remove and return the last element.
Definition: VectorDeque.hpp:1003
IteratorBase< VectorDeque, DataType, true > ReverseIterator
Mutable reverse iterator for VectorDeques.
Definition: VectorDeque.hpp:514
VectorDeque(VectorDeque &&that)
Temporary copy constructor.
Definition: VectorDeque.hpp:563
ConstIterator cend() const
Get an iterator past the last element of *this.
Definition: VectorDeque.hpp:776
void popAllLast(DataType *const target)
Put every element into target from the back and then remove them from *this.
Definition: VectorDeque.hpp:991
VectorDeque(const VectorDeque &that)
Non-temporary copy constructor.
Definition: VectorDeque.hpp:549
DataType peekLast() const
Get the last element of *this.
Definition: VectorDeque.hpp:957
IteratorBase< const VectorDeque, const DataType, true > ConstReverseIterator
Immutable reverse iterator for VectorDeques.
Definition: VectorDeque.hpp:519
void addFirst(const DataType &element)
Add element to the front of *this.
Definition: VectorDeque.hpp:741
DataType peek() const
Get the first element of *this.
Definition: VectorDeque.hpp:945
DataType & fromBack(const size_t index) const
Access the element at index starting from the last element.
Definition: VectorDeque.hpp:857
void popSomeLast(DataType *const target, const size_t amount)
Remove amount elements from the back and put them into target.
Definition: VectorDeque.hpp:1031
IteratorBase< const VectorDeque, const DataType, false > ConstIterator
Immutable iterator for VectorDeques.
Definition: VectorDeque.hpp:509
void addAllFirst(IteratorType begin, IteratorType end)
Add a collection of elements to the front of *this.
Definition: VectorDeque.hpp:730
VectorDeque & operator=(const VectorDeque &that)
Non-temporary assignment.
Definition: VectorDeque.hpp:577
VectorDeque()
Constructs a VectorDeque with a default initial capacity.
Definition: VectorDeque.hpp:530
void sliceToArray(DataType *const target, const size_t from, const size_t until) const
Copy a slice of elements of *this to target.
Definition: VectorDeque.hpp:1180
void addAll(IteratorType begin, IteratorType end)
Add a collection of elements to the back of *this.
Definition: VectorDeque.hpp:701
void popSome(DataType *const target, const size_t amount)
Remove amount elements and put them into target.
Definition: VectorDeque.hpp:1017
DataType removeAt(const size_t index)
Remove the element at index.
Definition: VectorDeque.hpp:1053
ConstIterator cbegin() const
Get a constant iterator pointing to the first element of *this.
Definition: VectorDeque.hpp:767
DataType removeAt(const ConstIterator &it)
Remove the element pointed to by it.
Definition: VectorDeque.hpp:1081
Iterator begin()
Get an iterator pointing to the first element of *this.
Definition: VectorDeque.hpp:758
ConstReverseIterator crend() const
Get an iterator past the last element of *this.
Definition: VectorDeque.hpp:821
IteratorBase< VectorDeque, DataType, false > Iterator
Mutable iterator for VectorDeques.
Definition: VectorDeque.hpp:504
void popAll(DataType *const target)
Put every element into target and then remove them from *this.
Definition: VectorDeque.hpp:981
void add(const DataType &element)
Add element to the back of *this.
Definition: VectorDeque.hpp:675
bool isEmpty() const
Checks whether *this is empty.
Definition: VectorDeque.hpp:934
bool contains(const DataType &element) const
Check to see if element is contained in *this.
Definition: VectorDeque.hpp:794
ConstReverseIterator crbegin() const
Get a constant reverse iterator pointing to the last element of *this.
Definition: VectorDeque.hpp:812
void skip(const size_t amount=1)
Removes amount elements from the front of *this.
Definition: VectorDeque.hpp:1152
void reverseSliceToArray(DataType *const target, const size_t from, const size_t until) const
Copy a slice of contents of *this to target in reverse order.
Definition: VectorDeque.hpp:1128
void copyToArray(DataType *const target) const
Copy the contents of *this to target.
Definition: VectorDeque.hpp:803
static const size_t DEFAULT_INITIAL_CAPACITY
The capacity to initialize a VectorDeque to by default.
Definition: VectorDeque.hpp:524
void clear()
Remove all elements from *this.
Definition: VectorDeque.hpp:784
void addAll(const DataType *const elements, const size_t length)
Add an array of elements to the back of *this.
Definition: VectorDeque.hpp:687
void insert(const DataType &element, const ConstIterator &it)
Insert element before the element pointed to by it.
Definition: VectorDeque.hpp:910
void addAllFirst(const DataType *const elements, const size_t length)
Add an array of elements to the front of *this.
Definition: VectorDeque.hpp:715
void skipLast(const size_t amount=1)
Removes amount elements from the back of *this.
Definition: VectorDeque.hpp:1165
VectorDeque(const size_t capacity)
Constructs a VectorDeque with the given initial capacity.
Definition: VectorDeque.hpp:539