diff --git a/include/etl/circular_buffer.h b/include/etl/circular_buffer.h index b8ea0a64..5e2f2962 100644 --- a/include/etl/circular_buffer.h +++ b/include/etl/circular_buffer.h @@ -144,15 +144,285 @@ namespace etl typedef T* pointer; typedef const T* const_pointer; + typedef typename etl::iterator_traits::difference_type difference_type; + //************************************************************************* /// Iterator iterating through the circular buffer. //************************************************************************* - class const_iterator : public etl::iterator + class iterator : public etl::iterator + { + public: + + friend class icircular_buffer; + + //************************************************************************* + /// Constructor + //************************************************************************* + iterator() + : picb(ETL_NULLPTR) + , current(0U) + { + } + + //************************************************************************* + /// Copy Constructor + //************************************************************************* + iterator(const iterator& other) + : picb(other.picb) + , current(other.current) + { + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + iterator& operator =(const iterator& other) + { + picb = other.picb; + current = other.current; + + return *this; + } + + //************************************************************************* + /// * operator + //************************************************************************* + T& operator *() + { + return picb->pbuffer[current]; + } + + //************************************************************************* + /// * operator + //************************************************************************* + const T& operator *() const + { + return picb->pbuffer[current]; + } + + //************************************************************************* + /// -> operator + //************************************************************************* + T* operator ->() + { + return picb->pbuffer[current]; + } + + //************************************************************************* + /// -> operator + //************************************************************************* + const T* operator ->() const + { + return picb->pbuffer[current]; + } + + //************************************************************************* + /// Pre-increment. + //************************************************************************* + iterator& operator ++() + { + ++current; + + // Did we reach the end of the buffer? + if (current == picb->BUFFER_SIZE) + { + current = 0U; + } + + return (*this); + } + + //************************************************************************* + /// Post increment. + //************************************************************************* + iterator operator ++(int) + { + iterator original(*this); + + ++(*this); + + return (original); + } + + //************************************************************************* + /// Pre-decrement. + //************************************************************************* + iterator& operator --() + { + // Are we at the end of the buffer? + if (current == 0U) + { + current = picb->BUFFER_SIZE - 1; + } + else + { + --current; + } + + return (*this); + } + + //************************************************************************* + /// Post increment. + //************************************************************************* + iterator operator --(int) + { + iterator original(*this); + + --(*this); + + return (original); + } + + //************************************************************************* + /// Add offset. + //************************************************************************* + iterator& operator +=(int n) + { + n = picb->BUFFER_SIZE + n; + + current += n; + current %= picb->BUFFER_SIZE; + + return (*this); + } + + //************************************************************************* + /// Subtract offset. + //************************************************************************* + iterator& operator -=(int n) + { + return (this->operator+=(-n)); + } + + //************************************************************************* + /// Add offset. + //************************************************************************* + friend iterator operator +(const iterator& lhs, int n) + { + iterator temp = lhs; + + temp += n; + + return temp; + } + + //************************************************************************* + /// Subtract offset. + //************************************************************************* + friend iterator operator -(const iterator& lhs, int n) + { + iterator temp = lhs; + + temp -= n; + + return temp; + } + + //************************************************************************* + /// Equality operator + //************************************************************************* + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return (lhs.current == rhs.current); + } + + //************************************************************************* + /// Inequality operator + //************************************************************************* + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + //*************************************************** + friend bool operator < (const iterator& lhs, const iterator& rhs) + { + const difference_type lhs_index = lhs.get_index(); + const difference_type rhs_index = rhs.get_index(); + const difference_type reference_index = lhs.container().begin().get_index(); + const size_t buffer_size = lhs.container().max_size() + 1; + + const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index; + const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index; + + return lhs_distance < rhs_distance; + } + + //*************************************************** + friend bool operator <= (const iterator& lhs, const iterator& rhs) + { + return !(lhs > rhs); + } + + //*************************************************** + friend bool operator > (const iterator& lhs, const iterator& rhs) + { + return (rhs < lhs); + } + + //*************************************************** + friend bool operator >= (const iterator& lhs, const iterator& rhs) + { + return !(lhs < rhs); + } + + //*************************************************** + difference_type get_index() const + { + return current; + } + + //*************************************************** + const icircular_buffer& container() const + { + return *picb; + } + + //*************************************************** + pointer get_buffer() const + { + return pbuffer; + } + + protected: + + //*************************************************** + difference_type distance(difference_type firstIndex, difference_type index) const + { + if (index < firstIndex) + { + return picb->BUFFER_SIZE + current - firstIndex; + } + else + { + return index - firstIndex; + } + } + + //************************************************************************* + /// Protected constructor. Only icircular_buffer can create one. + //************************************************************************* + iterator(const icircular_buffer* picb_, size_type current_) + : picb(picb_) + , current(current_) + { + } + + private: + + const icircular_buffer* picb; + size_type current; + }; + + //************************************************************************* + /// Iterator iterating through the circular buffer. + //************************************************************************* + class const_iterator : public etl::iterator { public: friend class icircular_buffer; - friend class const_cyclic_iterator; //************************************************************************* /// Constructor @@ -163,6 +433,46 @@ namespace etl { } + //************************************************************************* + /// Copy Constructor from iterator + //************************************************************************* + const_iterator(const typename icircular_buffer::iterator& other) + : picb(other.picb) + , current(other.current) + { + } + + //************************************************************************* + /// Copy Constructor from const iterator + //************************************************************************* + const_iterator(const const_iterator& other) + : picb(other.picb) + , current(other.current) + { + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + const_iterator& operator =(const typename icircular_buffer::iterator& other) + { + picb = other.picb; + current = other.current; + + return *this; + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + const_iterator& operator =(const const_iterator& other) + { + picb = other.picb; + current = other.current; + + return *this; + } + //************************************************************************* /// * operator //************************************************************************* @@ -298,6 +608,56 @@ namespace etl return !(lhs == rhs); } + //*************************************************** + friend bool operator < (const const_iterator& lhs, const const_iterator& rhs) + { + const difference_type lhs_index = lhs.get_index(); + const difference_type rhs_index = rhs.get_index(); + const difference_type reference_index = lhs.container().begin().get_index(); + const size_t buffer_size = lhs.container().max_size() + 1; + + const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index; + const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index; + + return lhs_distance < rhs_distance; + } + + //*************************************************** + friend bool operator <= (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs > rhs); + } + + //*************************************************** + friend bool operator > (const const_iterator& lhs, const const_iterator& rhs) + { + return (rhs < lhs); + } + + //*************************************************** + friend bool operator >= (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs < rhs); + } + + //*************************************************** + difference_type get_index() const + { + return current; + } + + //*************************************************** + const icircular_buffer& container() const + { + return *picb; + } + + //*************************************************** + pointer get_buffer() const + { + return pbuffer; + } + protected: //************************************************************************* @@ -315,10 +675,20 @@ namespace etl size_type current; }; + friend class iterator; friend class const_iterator; + typedef etl::reverse_iterator reverse_iterator; typedef etl::reverse_iterator const_reverse_iterator; + //************************************************************************* + /// Gets an iterator to the start of the buffer. + //************************************************************************* + iterator begin() + { + return iterator(this, out); + } + //************************************************************************* /// Gets a const iterator to the start of the buffer. //************************************************************************* @@ -335,6 +705,14 @@ namespace etl return const_iterator(this, out); } + //************************************************************************* + /// Gets an iterator to the end of the buffer. + //************************************************************************* + iterator end() + { + return iterator(this, in); + } + //************************************************************************* /// Gets a const iterator to the end of the buffer. //************************************************************************* @@ -351,6 +729,14 @@ namespace etl return const_iterator(this, in); } + //************************************************************************* + /// Gets a reverse iterator to the start of the buffer. + //************************************************************************* + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + //************************************************************************* /// Gets a const reverse iterator to the start of the buffer. //************************************************************************* @@ -367,6 +753,14 @@ namespace etl return const_reverse_iterator(end()); } + //************************************************************************* + /// Gets a reverse iterator to the end of the buffer. + //************************************************************************* + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + //************************************************************************* /// Gets a const reverse iterator to the end of the buffer. //************************************************************************* @@ -383,6 +777,17 @@ namespace etl return const_reverse_iterator(begin()); } + //************************************************************************* + /// Get a const reference to the item at the front of the buffer. + /// Asserts an error if the buffer is empty. + //************************************************************************* + reference front() + { + ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty)); + + return pbuffer[out]; + } + //************************************************************************* /// Get a const reference to the item at the front of the buffer. /// Asserts an error if the buffer is empty. @@ -394,6 +799,17 @@ namespace etl return pbuffer[out]; } + //************************************************************************* + /// Get a reference to the item at the back of the buffer. + /// Asserts an error if the buffer is empty. + //************************************************************************* + reference back() + { + ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty)); + + return pbuffer[in == 0U ? BUFFER_SIZE - 1 : in - 1U]; + } + //************************************************************************* /// Get a const reference to the item at the back of the buffer. /// Asserts an error if the buffer is empty. @@ -507,6 +923,38 @@ namespace etl } } + //************************************************************************* + /// - operator for iterator + //************************************************************************* + friend difference_type operator -(const iterator& lhs, const iterator& rhs) + { + return distance(rhs, lhs); + } + + //************************************************************************* + /// - operator for const_iterator + //************************************************************************* + friend difference_type operator -(const const_iterator& lhs, const const_iterator& rhs) + { + return distance(rhs, lhs); + } + + //************************************************************************* + /// - operator for reverse_iterator + //************************************************************************* + friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs) + { + return distance(lhs.base(), rhs.base()); + } + + //************************************************************************* + /// - operator for const_reverse_iterator + //************************************************************************* + friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs) + { + return distance(lhs.base(), rhs.base()); + } + protected: //************************************************************************* @@ -518,6 +966,38 @@ namespace etl { } + //************************************************************************* + /// Measures the distance between two iterators. + //************************************************************************* + template + static difference_type distance(const TIterator1& range_begin, const TIterator2& range_end) + { + difference_type distance1 = distance(range_begin); + difference_type distance2 = distance(range_end); + + return distance2 - distance1; + } + + //************************************************************************* + /// Measures the distance from the _begin iterator to the specified iterator. + //************************************************************************* + template + static difference_type distance(const TIterator& other) + { + const difference_type index = other.get_index(); + const difference_type reference_index = other.container().out; + const size_t buffer_size = other.container().BUFFER_SIZE; + + if (index < reference_index) + { + return buffer_size + index - reference_index; + } + else + { + return index - reference_index; + } + } + pointer pbuffer; private: @@ -540,8 +1020,9 @@ namespace etl //*************************************************************************** /// A fixed capacity circular buffer. + /// Internal buffer. //*************************************************************************** - template + template class circular_buffer : public icircular_buffer { public: @@ -579,6 +1060,67 @@ namespace etl { this->push(init.begin(), init.end()); } +#endif + + //************************************************************************* + /// Copy Constructor. + //************************************************************************* + circular_buffer(const circular_buffer& other) + : icircular_buffer(reinterpret_cast(buffer.raw), MAX_SIZE) + { + if (this != &other) + { + this->push(other.begin(), other.end()); + } + } + + //************************************************************************* + /// Assignment operator + //************************************************************************* + circular_buffer& operator =(const circular_buffer& other) + { + if (this != &other) + { + this->push(other.begin(), other.end()); + } + + return *this; + } + +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move Constructor. + //************************************************************************* + circular_buffer(circular_buffer&& other) + : icircular_buffer(reinterpret_cast(buffer.raw), MAX_SIZE) + { + if (this != &other) + { + typename etl::icircular_buffer::iterator itr = other.begin(); + while (itr != other.end()) + { + this->push(etl::move(*itr)); + ++itr; + } + } + } + + //************************************************************************* + /// Move Assignment operator + //************************************************************************* + circular_buffer& operator =(circular_buffer&& other) + { + if (this != &other) + { + for (const_iterator itr = other.begin(); itr != other.end(); ++itr) + { + this->push(etl::move(*itr)); + } + } + + return *this; + } + #endif //************************************************************************* @@ -591,15 +1133,133 @@ namespace etl private: - circular_buffer(const circular_buffer&) ETL_DELETE; - circular_buffer(circular_buffer&&) ETL_DELETE; - - circular_buffer& operator =(const circular_buffer&) ETL_DELETE; - circular_buffer& operator =(circular_buffer&&) ETL_DELETE; - + /// The uninitialised storage. etl::uninitialized_buffer_of buffer; }; + //*************************************************************************** + /// A fixed capacity circular buffer. + /// External buffer. + //*************************************************************************** + template + class circular_buffer : public icircular_buffer + { + public: + + //************************************************************************* + /// Constructor. + //************************************************************************* + circular_buffer(void* buffer, size_t max_size) + : icircular_buffer(reinterpret_cast(buffer), max_size) + { + } + + //************************************************************************* + /// Constructor. + /// Constructs a buffer from an iterator range. + //************************************************************************* + template + circular_buffer(TIterator first, const TIterator& last, void* buffer, size_t max_size) + : icircular_buffer(reinterpret_cast(buffer), max_size) + { + while (first != last) + { + this->push(*first++); + } + } + +#if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL + //************************************************************************* + /// Construct from initializer_list. + //************************************************************************* + circular_buffer(std::initializer_list init, void* buffer, size_t max_size) + : icircular_buffer(reinterpret_cast(buffer), max_size) + { + this->push(init.begin(), init.end()); + } +#endif + + //************************************************************************* + /// Copy Constructor. + //************************************************************************* + circular_buffer(const circular_buffer& other, void* buffer, size_t max_size) + : icircular_buffer(reinterpret_cast(buffer), max_size) + { + if (this != &other) + { + this->push(other.begin(), other.end()); + } + } + + //************************************************************************* + /// Assignment operator + //************************************************************************* + circular_buffer& operator =(const circular_buffer& other) + { + if (this != &other) + { + this->push(other.begin(), other.end()); + } + + return *this; + } + +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move Constructor. + //************************************************************************* + circular_buffer(circular_buffer&& other, void* buffer, size_t max_size) + : icircular_buffer(reinterpret_cast(buffer), max_size) + { + if (this != &other) + { + typename etl::icircular_buffer::iterator itr = other.begin(); + while (itr != other.end()) + { + this->push(etl::move(*itr)); + ++itr; + } + } + } + + //************************************************************************* + /// Move Assignment operator + //************************************************************************* + circular_buffer& operator =(circular_buffer&& other) + { + if (this != &other) + { + for (const_iterator itr = other.begin(); itr != other.end(); ++itr) + { + this->push(etl::move(*itr)); + } + } + + return *this; + } +#endif + + //************************************************************************* + /// Swap with another circular buffer + //************************************************************************* + void swap(circular_buffer& other) + { + using ETL_OR_STD::swap; // Allow ADL + + swap(in, other.in); + swap(out, other.out); + swap(pbuffer, other.pbuffer); + } + + //************************************************************************* + /// Destructor. + //************************************************************************* + ~circular_buffer() + { + this->clear(); + } + }; + //************************************************************************* /// Template deduction guides. //************************************************************************* @@ -608,6 +1268,33 @@ namespace etl circular_buffer(T, Ts...) ->circular_buffer && ...), T>, 1U + sizeof...(Ts)>; #endif + + //************************************************************************* + /// Overloaded swap for etl::circular_buffer + //************************************************************************* + template + void swap(etl::circular_buffer& lhs, etl::circular_buffer& rhs) + { + lhs.swap(rhs); + } + + //************************************************************************* + /// Equality operator + //************************************************************************* + template + bool operator ==(const icircular_buffer& lhs, const icircular_buffer& rhs) + { + return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + //************************************************************************* + /// Inequality operator + //************************************************************************* + template + bool operator !=(const icircular_buffer& lhs, const icircular_buffer& rhs) + { + return !(lhs == rhs); + } } #undef ETL_FILE diff --git a/include/etl/deque.h b/include/etl/deque.h index d8d2caba..75f8d4af 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -417,8 +417,8 @@ namespace etl { const difference_type lhs_index = lhs.get_index(); const difference_type rhs_index = rhs.get_index(); - const difference_type reference_index = lhs.get_deque().begin().get_index(); - const size_t buffer_size = lhs.get_deque().max_size() + 1; + const difference_type reference_index = lhs.container().begin().get_index(); + const size_t buffer_size = lhs.container().max_size() + 1; const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index; const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index; @@ -451,7 +451,7 @@ namespace etl } //*************************************************** - ideque& get_deque() const + ideque& container() const { return *p_deque; } @@ -661,8 +661,8 @@ namespace etl { const difference_type lhs_index = lhs.get_index(); const difference_type rhs_index = rhs.get_index(); - const difference_type reference_index = lhs.get_deque().begin().get_index(); - const size_t buffer_size = lhs.get_deque().max_size() + 1; + const difference_type reference_index = lhs.container().begin().get_index(); + const size_t buffer_size = lhs.container().max_size() + 1; const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index; const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index; @@ -695,7 +695,7 @@ namespace etl } //*************************************************** - ideque& get_deque() const + ideque& container() const { return *p_deque; } @@ -2269,8 +2269,8 @@ namespace etl static difference_type distance(const TIterator& other) { const difference_type index = other.get_index(); - const difference_type reference_index = other.get_deque()._begin.index; - const size_t buffer_size = other.get_deque().BUFFER_SIZE; + const difference_type reference_index = other.container()._begin.index; + const size_t buffer_size = other.container().BUFFER_SIZE; if (index < reference_index) { diff --git a/test/test_circular_buffer.cpp b/test/test_circular_buffer.cpp index 4b4054cf..c33fdc7c 100644 --- a/test/test_circular_buffer.cpp +++ b/test/test_circular_buffer.cpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace { @@ -43,13 +44,14 @@ namespace { static const size_t SIZE = 10; - using Data = etl::circular_buffer; - using Compare = std::vector; - - using ItemM = TestDataM; + using ItemM = TestDataM; using DataM = etl::circular_buffer; using CompareM = std::vector; + using Ndc = TestDataNDC; + using Data = etl::circular_buffer; + using Compare = std::vector; + //************************************************************************* TEST(test_default_constructor) { @@ -68,8 +70,8 @@ namespace //************************************************************************* TEST(test_constructor_from_literal) { - Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Data data = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; CHECK(data.begin() != data.end()); @@ -83,8 +85,8 @@ namespace //************************************************************************* TEST(test_constructor_from_literal_excess) { - Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; - Compare compare = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Data data = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -99,8 +101,8 @@ namespace //************************************************************************* TEST(test_cpp17_deduced_constructor) { - Data data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - Data compare{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Data data{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -113,8 +115,8 @@ namespace //************************************************************************* TEST(test_cpp17_deduced_constructor_excess) { - Data data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; - Data compare{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Data data{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -128,14 +130,14 @@ namespace //************************************************************************* TEST(test_push) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; for (auto v : test) { data.push(v); } - Compare compare{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -153,8 +155,8 @@ namespace for (uint32_t i = 0; i < SIZE; ++i) { - data.push(ItemM(i)); - compare.push_back(ItemM(i)); + data.push(ItemM(std::to_string(i))); + compare.push_back(ItemM(std::to_string(i))); } CHECK(data.begin() != data.end()); @@ -168,11 +170,11 @@ namespace //************************************************************************* TEST(test_push_full_range) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -185,11 +187,11 @@ namespace //************************************************************************* TEST(test_push_full_range_reverse_iterator) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -202,11 +204,11 @@ namespace //************************************************************************* TEST(test_push_excess_range) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -219,11 +221,11 @@ namespace //************************************************************************* TEST(test_push_excess_range_reverse_iterator) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -236,11 +238,11 @@ namespace //************************************************************************* TEST(test_push_short_range_at_start_of_buffer) { - Compare test{ 0, 1, 2, 3, 4 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 0, 1, 2, 3, 4 }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -253,11 +255,11 @@ namespace //************************************************************************* TEST(test_push_short_range_at_start_of_buffer_reverse_iterator) { - Compare test{ 0, 1, 2, 3, 4 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; Data data; data.push(test.begin(), test.end()); - Compare compare{ 0, 1, 2, 3, 4 }; + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -270,12 +272,12 @@ namespace //************************************************************************* TEST(test_push_short_range_at_end_of_buffer) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; Data data; data.push(test.begin(), test.end()); data.pop(5); - Compare compare{ 6, 7, 8, 9, 10 }; + Compare compare{ Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -288,12 +290,12 @@ namespace //************************************************************************* TEST(test_push_short_range_at_end_of_buffer_reverse_iterator) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; Data data; data.push(test.begin(), test.end()); data.pop(5); - Compare compare{ 6, 7, 8, 9, 10 }; + Compare compare{ Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -306,14 +308,14 @@ namespace //************************************************************************* TEST(test_push_short_range_middle_of_buffer) { - Compare test1{ 0, 1, 2, 3, 4 }; - Compare test2{ 5, 6, 7 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("5"), Ndc("6"), Ndc("7") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); data.pop(3); - data.push(test2.begin(), test2.end()); + data.push(input2.begin(), input2.end()); - Compare compare{ 3, 4, 5, 6, 7 }; + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -326,14 +328,14 @@ namespace //************************************************************************* TEST(test_push_short_range_middle_of_buffer_reverse_iterator) { - Compare test1{ 0, 1, 2, 3, 4 }; - Compare test2{ 5, 6, 7 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("5"), Ndc("6"), Ndc("7") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); data.pop(3); - data.push(test2.begin(), test2.end()); + data.push(input2.begin(), input2.end()); - Compare compare{ 3, 4, 5, 6, 7 }; + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -346,14 +348,14 @@ namespace //************************************************************************* TEST(test_push_short_range_overlap_start_and_end_of_buffer) { - Compare test1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - Compare test2{ 10, 11, 12 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("10"), Ndc("11"), Ndc("12") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); data.pop(7); - data.push(test2.begin(), test2.end()); + data.push(input2.begin(), input2.end()); - Compare compare{ 7, 8, 9, 10, 11, 12 }; + Compare compare{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); @@ -366,14 +368,14 @@ namespace //************************************************************************* TEST(test_push_short_range_overlap_start_and_end_of_buffer_reverse_iterator) { - Compare test1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - Compare test2{ 10, 11, 12 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("10"), Ndc("11"), Ndc("12") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); data.pop(7); - data.push(test2.begin(), test2.end()); + data.push(input2.begin(), input2.end()); - Compare compare{ 7, 8, 9, 10, 11, 12 }; + Compare compare{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; CHECK(data.rbegin() != data.rend()); CHECK(data.crbegin() != data.crend()); @@ -386,37 +388,37 @@ namespace //************************************************************************* TEST(test_front_const) { - Compare test1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; - const int& ref = data.front(); + const Ndc& ref = data.front(); CHECK(ref == compare.front()); } //************************************************************************* TEST(test_back_const) { - Compare test1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; - data.push(test1.begin(), test1.end()); + data.push(input1.begin(), input1.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; - const int& ref = data.back(); + const Ndc& ref = data.back(); CHECK(ref == compare.back()); } //************************************************************************* TEST(test_random_iterator_plus) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; for (int step = 1; step < int(data.size()); ++step) { @@ -435,11 +437,11 @@ namespace //************************************************************************* TEST(test_random_iterator_plus_rollover) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; for (int step = 1; step < int(data.size()); ++step) { @@ -458,11 +460,11 @@ namespace //************************************************************************* TEST(test_random_iterator_plus_equals) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; for (int step = 1; step < int(data.size()); ++step) { @@ -481,11 +483,11 @@ namespace //************************************************************************* TEST(test_random_iterator_plus_equals_rollover) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; for (int step = 1; step < int(data.size()); ++step) { @@ -504,11 +506,11 @@ namespace //************************************************************************* TEST(test_random_iterator_minus) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; for (int step = 1; step < int(data.size()); ++step) { @@ -527,11 +529,11 @@ namespace //************************************************************************* TEST(test_random_iterator_minus_rollover) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; for (int step = 1; step < int(data.size()); ++step) { @@ -550,11 +552,11 @@ namespace //************************************************************************* TEST(test_random_iterator_minus_equals) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Data data; data.push(test.begin(), test.end()); - Compare compare = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; for (int step = 1; step < int(data.size()); ++step) { @@ -573,11 +575,11 @@ namespace //************************************************************************* TEST(test_random_iterator_minus_equals_rollover) { - Compare test{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data; - data.push(test.begin(), test.end()); + data.push(input.begin(), input.end()); - Compare compare = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; for (int step = 1; step < int(data.size()); ++step) { @@ -593,84 +595,228 @@ namespace } } -// ////************************************************************************* -// //TEST(test_swap) -// //{ -// // Data data1 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; -// // Data data2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// -// // swap(data1, data2); -// -// // CHECK(std::equal(compare_data.begin(), compare_data.end(), data1.begin())); -// // CHECK(std::equal(swap_data.begin(), swap_data.end(), data2.begin())); -// //} + //************************************************************************* + TEST(test_copy_constructor) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("9"), Ndc("8"), Ndc("7"), Ndc("6"), Ndc("5"), Ndc("4"), Ndc("3"), Ndc("2"), Ndc("1"), Ndc("0") }; + Data data1; + data1.push(input1.begin(), input1.end()); + // Copy construct from data1 + Data data2(data1); + // Now change data1 + data1.clear(); + data1.push(input2.begin(), input2.end()); -// ////************************************************************************* -// //TEST(test_equal) -// //{ -// // Data data1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data data2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// -// // CHECK(data1 == data2); -// //} -// -// ////************************************************************************* -// //TEST(test_not_equal) -// //{ -// // Data data1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data data2 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; -// -// // CHECK(data1 != data2); -// //} -// -// ////************************************************************************* -// //TEST(test_less_than) -// //{ -// // Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data greater = { 0, 1, 2, 3, 5, 5, 6, 7, 8, 9 }; -// // Data lesser = { 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; -// -// // CHECK(lesser < data); -// // CHECK(!(data < data)); -// // CHECK(!(greater < data)); -// //} -// -// ////************************************************************************* -// //TEST(test_less_than_equal) -// //{ -// // Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data greater = { 0, 1, 2, 3, 5, 5, 6, 7, 8, 9 }; -// // Data lesser = { 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; -// -// // CHECK(lesser <= data); -// // CHECK(data <= data); -// // CHECK(!(greater <= data)); -// //} -// -// ////************************************************************************* -// //TEST(test_greater_than) -// //{ -// // Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data greater = { 0, 1, 2, 3, 5, 5, 6, 7, 8, 9 }; -// // Data lesser = { 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; -// -// // CHECK(greater > data); -// // CHECK(!(data > data)); -// // CHECK(!(lesser > data)); -// //} -// -// ////************************************************************************* -// //TEST(test_greater_than_equal) -// //{ -// // Data data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// // Data greater = { 0, 1, 2, 3, 5, 5, 6, 7, 8, 9 }; -// // Data lesser = { 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; -// -// // CHECK(greater >= data); -// // CHECK(data >= data); -// // CHECK(!(lesser >= data)); -// //} + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(input1.begin(), input1.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_move_constructor) + { + CompareM input1; + CompareM input2; + CompareM compare; + + for (uint32_t i = 0; i < SIZE; ++i) + { + input1.push_back(ItemM(std::to_string(i))); + input2.push_back(ItemM(std::to_string(SIZE - i))); + compare.push_back(ItemM(std::to_string(i))); + } + + DataM data1; + for (auto&& v : input1) + { + data1.push(std::move(v)); + } + + // Move construct from data1 + DataM data2(std::move(data1)); + + // Now change data1 + data1.clear(); + for (auto&& v : input2) + { + data1.push(std::move(v)); + } + + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_assignment) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("9"), Ndc("8"), Ndc("7"), Ndc("6"), Ndc("5"), Ndc("4"), Ndc("3"), Ndc("2"), Ndc("1"), Ndc("0") }; + Data data1; + data1.push(input1.begin(), input1.end()); + + // Copy construct from data1 + Data data2; + + data2 = data1; + + // Now change data1 + data1.clear(); + data1.push(input2.begin(), input2.end()); + + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(input1.begin(), input1.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_swap_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + data.push(test.begin(), test.end()); + + Data::iterator itr1 = data.begin() + 2; + Data::iterator itr2 = data.begin() + 3; + + const Ndc& original1 = *itr1; + const Ndc& original2 = *itr2; + + std::swap(itr1, itr2); + + const Ndc& swapped1 = *itr1; + const Ndc& swapped2 = *itr2; + + CHECK(swapped1 == original2); + CHECK(swapped2 == original1); + } + + //************************************************************************* + TEST(test_swap_const_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + data.push(test.begin(), test.end()); + + Data::const_iterator itr1 = data.begin() + 2; + Data::const_iterator itr2 = data.begin() + 3; + + const Ndc& original1 = *itr1; + const Ndc& original2 = *itr2; + + std::swap(itr1, itr2); + + const Ndc& swapped1 = *itr1; + const Ndc& swapped2 = *itr2; + + CHECK(swapped1 == original2); + CHECK(swapped2 == original1); + } + + //************************************************************************* + TEST(test_iterator_difference) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + data.push(test.begin(), test.end()); + + Data::iterator begin = data.begin(); + Data::iterator end = data.begin(); + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(i, end - begin); + CHECK_EQUAL(i, -(begin - end)); + ++end; + } + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.size() - i, end - begin); + CHECK_EQUAL(data.size() - i, -(begin - end)); + ++begin; + } + } + + //************************************************************************* + TEST(test_const_iterator_difference) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data; + data.push(test.begin(), test.end()); + + Data::const_iterator begin = data.begin(); + Data::const_iterator end = data.begin(); + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(i, end - begin); + CHECK_EQUAL(i, -(begin - end)); + ++end; + } + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.size() - i, end - begin); + CHECK_EQUAL(data.size() - i, -(begin - end)); + ++begin; + } + } + + //************************************************************************* + TEST(test_swap) + { + // Over-write by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare output{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1; + Data data2; + data1.push(input.begin(), input.end()); + data2.push(input.rbegin(), input.rend()); + + swap(data1, data2); + + CHECK(std::equal(output.rbegin() + 3, output.rend(), data1.begin())); + CHECK(std::equal(output.begin() + 3, output.end(), data2.begin())); + } + + //************************************************************************* + TEST(test_equal) + { + // Over-write by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1; + Data data2; + data1.push(input.begin(), input.end()); + data2.push(input.begin(), input.end()); + + CHECK(data1 == data2); + } + + //************************************************************************* + TEST(test_not_equal) + { + // Over-write by 3 + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare input2{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("6"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1; + Data data2; + data1.push(input1.begin(), input1.end()); + data2.push(input2.begin(), input2.end()); + + CHECK(data1 != data2); + } }; } diff --git a/test/test_circular_buffer_external_buffer.cpp b/test/test_circular_buffer_external_buffer.cpp new file mode 100644 index 00000000..54bcb127 --- /dev/null +++ b/test/test_circular_buffer_external_buffer.cpp @@ -0,0 +1,831 @@ +///****************************************************************************** +//The MIT License(MIT) +// +//Embedded Template Library. +//https://github.com/ETLCPP/etl +//https://www.etlcpp.com +// +//Copyright(c) 2020 jwellbelove +// +//Permission is hereby granted, free of charge, to any person obtaining a copy +//of this software and associated documentation files(the "Software"), to deal +//in the Software without restriction, including without limitation the rights +//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +//copies of the Software, and to permit persons to whom the Software is +//furnished to do so, subject to the following conditions : +// +//The above copyright notice and this permission notice shall be included in all +//copies or substantial portions of the Software. +// +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//SOFTWARE. +//******************************************************************************/ + +#include "UnitTest++/UnitTest++.h" + +#include "etl/circular_buffer.h" +#include "etl/integral_limits.h" + +#include "data.h" + +#include +#include +#include +#include + +namespace +{ + SUITE(test_circular_buffer) + { + static const size_t SIZE = 10; + + using ItemM = TestDataM; + using DataM = etl::circular_buffer; + using CompareM = std::vector; + + using Ndc = TestDataNDC; + using Data = etl::circular_buffer; + using Compare = std::vector; + + using BufferM_t = etl::uninitialized_buffer_of; + using Buffer_t = etl::uninitialized_buffer_of; + + BufferM_t bufferm1; + BufferM_t bufferm2; + + Buffer_t buffer1; + Buffer_t buffer2; + + //************************************************************************* + TEST(test_default_constructor) + { + Data data(buffer1.raw, SIZE); + + CHECK_EQUAL(0U, data.size()); + CHECK_EQUAL(SIZE, data.max_size()); + CHECK_EQUAL(SIZE, data.capacity()); + CHECK(data.begin() == data.end()); + CHECK(data.cbegin() == data.cend()); + CHECK(data.rbegin() == data.rend()); + CHECK(data.crbegin() == data.crend()); + } + +#if ETL_USING_STL + //************************************************************************* + TEST(test_constructor_from_literal) + { + Data data({ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }, buffer1.raw, SIZE); + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = etl::equal(data.begin(), data.end(), compare.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_constructor_from_literal_excess) + { + Data data({ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }, buffer1.raw, SIZE); + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(data.begin(), data.end(), compare.begin()); + CHECK(isEqual); + } +#endif + +#if !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED) && ETL_USING_STL + //************************************************************************* + TEST(test_cpp17_deduced_constructor) + { + Data data({ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }, buffer1.raw, SIZE); + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(data.begin(), data.end(), compare.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_cpp17_deduced_constructor_excess) + { + Data data({ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }, buffer1.raw, SIZE); + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(data.begin(), data.end(), compare.begin()); + CHECK(isEqual); + } +#endif + + //************************************************************************* + TEST(test_push) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + for (auto v : test) + { + data.push(v); + } + + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_move_push) + { + DataM data(bufferm1.raw, SIZE); + CompareM compare; + + for (uint32_t i = 0; i < SIZE; ++i) + { + data.push(ItemM(std::to_string(i))); + compare.push_back(ItemM(std::to_string(i))); + } + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_full_range) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_full_range_reverse_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_excess_range) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_excess_range_reverse_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_at_start_of_buffer) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_at_start_of_buffer_reverse_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_at_end_of_buffer) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + data.pop(5); + + Compare compare{ Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_at_end_of_buffer_reverse_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + data.pop(5); + + Compare compare{ Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_middle_of_buffer) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("5"), Ndc("6"), Ndc("7") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + data.pop(3); + data.push(input2.begin(), input2.end()); + + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_middle_of_buffer_reverse_iterator) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("5"), Ndc("6"), Ndc("7") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + data.pop(3); + data.push(input2.begin(), input2.end()); + + Compare compare{ Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_overlap_start_and_end_of_buffer) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + data.pop(7); + data.push(input2.begin(), input2.end()); + + Compare compare{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.begin() != data.end()); + CHECK(data.cbegin() != data.cend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_push_short_range_overlap_start_and_end_of_buffer_reverse_iterator) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + data.pop(7); + data.push(input2.begin(), input2.end()); + + Compare compare{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + CHECK(data.rbegin() != data.rend()); + CHECK(data.crbegin() != data.crend()); + CHECK_EQUAL(compare.size(), data.size()); + + bool isEqual = std::equal(compare.rbegin(), compare.rend(), data.rbegin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_front_const) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + const Ndc& ref = data.front(); + CHECK(ref == compare.front()); + } + + //************************************************************************* + TEST(test_back_const) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(input1.begin(), input1.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + const Ndc& ref = data.back(); + CHECK(ref == compare.back()); + } + + //************************************************************************* + TEST(test_random_iterator_plus) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.begin(); + + int offset = 0; + + while ((offset += step) < int(data.size() - 1)) + { + itr = itr + step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_plus_rollover) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.begin(); + + int offset = 0; + + while ((offset += step) < int(data.size() - 1)) + { + itr = itr + step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_plus_equals) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.begin(); + + int offset = 0; + + while ((offset += step) < int(data.size() - 1)) + { + itr += + step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_plus_equals_rollover) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.begin(); + + int offset = 0; + + while ((offset += step) < int(data.size() - 1)) + { + itr += step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_minus) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.end(); + + int offset = int(data.size()); + + while ((offset -= step) > 0) + { + itr = itr - step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_minus_rollover) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.end(); + + int offset = int(data.size()); + + while ((offset -= step) > 0) + { + itr = itr - step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_minus_equals) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.end(); + + int offset = int(data.size()); + + while ((offset -= step) > 0) + { + itr -= step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_random_iterator_minus_equals_rollover) + { + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(input.begin(), input.end()); + + Compare compare = { Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + + for (int step = 1; step < int(data.size()); ++step) + { + Data::const_iterator itr = data.end(); + + int offset = int(data.size()); + + while ((offset -= step) > 0) + { + itr -= step; + CHECK_EQUAL(compare[offset], *itr); + } + } + } + + //************************************************************************* + TEST(test_copy_constructor) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("9"), Ndc("8"), Ndc("7"), Ndc("6"), Ndc("5"), Ndc("4"), Ndc("3"), Ndc("2"), Ndc("1"), Ndc("0") }; + Data data1(buffer1.raw, SIZE); + data1.push(input1.begin(), input1.end()); + + // Copy construct from data1 + Data data2(data1, buffer2.raw, SIZE); + + // Now change data1 + data1.clear(); + data1.push(input2.begin(), input2.end()); + + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(input1.begin(), input1.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_move_constructor) + { + CompareM input1; + CompareM input2; + CompareM compare; + + for (uint32_t i = 0; i < SIZE; ++i) + { + input1.push_back(ItemM(std::to_string(i))); + input2.push_back(ItemM(std::to_string(SIZE - i))); + compare.push_back(ItemM(std::to_string(i))); + } + + DataM data1(bufferm1.raw, SIZE); + for (auto&& v : input1) + { + data1.push(std::move(v)); + } + + // Move construct from data1 + DataM data2(std::move(data1), bufferm2.raw, SIZE); + + // Now change data1 + data1.clear(); + for (auto&& v : input2) + { + data1.push(std::move(v)); + } + + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(compare.begin(), compare.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_assignment) + { + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Compare input2{ Ndc("9"), Ndc("8"), Ndc("7"), Ndc("6"), Ndc("5"), Ndc("4"), Ndc("3"), Ndc("2"), Ndc("1"), Ndc("0") }; + Data data1(buffer1.raw, SIZE); + data1.push(input1.begin(), input1.end()); + + // Copy construct from data1 + Data data2(buffer2.raw, SIZE); + + data2 = data1; + + // Now change data1 + data1.clear(); + data1.push(input2.begin(), input2.end()); + + CHECK(data2.begin() != data2.end()); + CHECK(data2.cbegin() != data2.cend()); + CHECK_EQUAL(input1.size(), data2.size()); + + bool isEqual = std::equal(input1.begin(), input1.end(), data2.begin()); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_swap_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::iterator itr1 = data.begin() + 2; + Data::iterator itr2 = data.begin() + 3; + + const Ndc& original1 = *itr1; + const Ndc& original2 = *itr2; + + std::swap(itr1, itr2); + + const Ndc& swapped1 = *itr1; + const Ndc& swapped2 = *itr2; + + CHECK(swapped1 == original2); + CHECK(swapped2 == original1); + } + + //************************************************************************* + TEST(test_swap_const_iterator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::const_iterator itr1 = data.begin() + 2; + Data::const_iterator itr2 = data.begin() + 3; + + const Ndc& original1 = *itr1; + const Ndc& original2 = *itr2; + + std::swap(itr1, itr2); + + const Ndc& swapped1 = *itr1; + const Ndc& swapped2 = *itr2; + + CHECK(swapped1 == original2); + CHECK(swapped2 == original1); + } + + //************************************************************************* + TEST(test_iterator_difference) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::iterator begin = data.begin(); + Data::iterator end = data.begin(); + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(i, end - begin); + CHECK_EQUAL(i, -(begin - end)); + ++end; + } + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.size() - i, end - begin); + CHECK_EQUAL(data.size() - i, -(begin - end)); + ++begin; + } + } + + //************************************************************************* + TEST(test_const_iterator_difference) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::const_iterator begin = data.begin(); + Data::const_iterator end = data.begin(); + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(i, end - begin); + CHECK_EQUAL(i, -(begin - end)); + ++end; + } + + for (uint32_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.size() - i, end - begin); + CHECK_EQUAL(data.size() - i, -(begin - end)); + ++begin; + } + } + + //************************************************************************* + TEST(test_swap) + { + // Over-write by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare output{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1(buffer1.raw, SIZE); + Data data2(buffer2.raw, SIZE); + data1.push(input.begin(), input.end()); + data2.push(input.rbegin(), input.rend()); + + swap(data1, data2); + + CHECK(std::equal(output.rbegin() + 3, output.rend(), data1.begin())); + CHECK(std::equal(output.begin() + 3, output.end(), data2.begin())); + } + + //************************************************************************* + TEST(test_equal) + { + // Over-write by 3 + Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1(buffer1.raw, SIZE); + Data data2(buffer1.raw, SIZE); + data1.push(input.begin(), input.end()); + data2.push(input.begin(), input.end()); + + CHECK(data1 == data2); + } + + //************************************************************************* + TEST(test_not_equal) + { + // Over-write by 3 + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare input2{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("6"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1(buffer1.raw, SIZE); + Data data2(buffer2.raw, SIZE); + data1.push(input1.begin(), input1.end()); + data2.push(input2.begin(), input2.end()); + + CHECK(data1 != data2); + } + }; +} diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 567944ef..f2443099 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -1424,6 +1424,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index bc4743a3..546cabd5 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1406,6 +1406,9 @@ Source Files + + Source Files +