mirror of https://github.com/PentHertz/srsLTE.git
extension of bounded_vector unit test and fix of compilation issues
- now bounded_vector::resize(N) works for move-only types - bounded_vector assertions now print error messages - fixed move ctor/assignment of bounded_vector - created a unit test for bounded_vectors of move-only types
This commit is contained in:
parent
2598989f7d
commit
5cce2e4dc7
|
@ -32,7 +32,7 @@ public:
|
|||
template <typename std::enable_if<std::is_default_constructible<T>::value, int>::type = 0>
|
||||
bounded_vector(size_type N)
|
||||
{
|
||||
append(N, T());
|
||||
append(N);
|
||||
}
|
||||
template <typename U, typename std::enable_if<std::is_constructible<T, U>::value, int>::type = 0>
|
||||
bounded_vector(size_type N, const U& init_val)
|
||||
|
@ -42,9 +42,7 @@ public:
|
|||
bounded_vector(const bounded_vector& other) { append(other.begin(), other.end()); }
|
||||
bounded_vector(bounded_vector&& other) noexcept
|
||||
{
|
||||
for (size_type i = 0; i < other.size(); ++i) {
|
||||
new (&buffer[i]) T(std::move(other[i]));
|
||||
}
|
||||
std::uninitialized_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()), end());
|
||||
size_ = other.size();
|
||||
other.clear();
|
||||
}
|
||||
|
@ -69,12 +67,12 @@ public:
|
|||
// move already constructed elements
|
||||
auto it = std::move(other.begin(), other.begin() + min_common_size, begin());
|
||||
destroy(it, end());
|
||||
size_ = min_common_size;
|
||||
} else {
|
||||
clear();
|
||||
}
|
||||
// append the rest
|
||||
for (size_t i = size_; i < other.size(); ++i) {
|
||||
new (&buffer[i]) T(std::move(other[i]));
|
||||
}
|
||||
std::uninitialized_copy(
|
||||
std::make_move_iterator(other.begin() + min_common_size), std::make_move_iterator(other.end()), end());
|
||||
size_ = other.size();
|
||||
other.clear();
|
||||
return *this;
|
||||
|
@ -95,12 +93,12 @@ public:
|
|||
// Element access
|
||||
T& operator[](std::size_t i)
|
||||
{
|
||||
assert(i < size_);
|
||||
assert(i < size_ && "Array index is out of bounds.");
|
||||
return reinterpret_cast<T&>(buffer[i]);
|
||||
}
|
||||
const T& operator[](std::size_t i) const
|
||||
{
|
||||
assert(i < size_);
|
||||
assert(i < size_ && "Array index is out of bounds.");
|
||||
return reinterpret_cast<const T&>(buffer[i]);
|
||||
}
|
||||
T& back() { return (*this)[size_ - 1]; }
|
||||
|
@ -112,9 +110,9 @@ public:
|
|||
|
||||
// Iterators
|
||||
iterator begin() { return reinterpret_cast<iterator>(&buffer[0]); }
|
||||
iterator end() { return reinterpret_cast<iterator>(&buffer[size_]); }
|
||||
iterator end() { return begin() + size_; }
|
||||
const_iterator begin() const { return reinterpret_cast<const_iterator>(&buffer[0]); }
|
||||
const_iterator end() const { return reinterpret_cast<const_iterator>(&buffer[size_]); }
|
||||
const_iterator end() const { return begin() + size_; }
|
||||
|
||||
// Capacity
|
||||
bool empty() const { return size_ == 0; }
|
||||
|
@ -170,7 +168,7 @@ public:
|
|||
}
|
||||
void pop_back()
|
||||
{
|
||||
assert(size_ > 0);
|
||||
assert(size_ > 0 && "Trying to erase element from empty vector.");
|
||||
back().~T();
|
||||
size_--;
|
||||
}
|
||||
|
@ -189,6 +187,7 @@ public:
|
|||
{
|
||||
return other.size() == size() and std::equal(begin(), end(), other.begin());
|
||||
}
|
||||
bool operator!=(const bounded_vector& other) const { return not(*this == other); }
|
||||
|
||||
private:
|
||||
void destroy(iterator it_start, iterator it_end)
|
||||
|
@ -197,12 +196,6 @@ private:
|
|||
it->~T();
|
||||
}
|
||||
}
|
||||
void construct_(iterator it_start, iterator it_end, const T& value)
|
||||
{
|
||||
for (auto it = it_start; it != it_end; ++it) {
|
||||
new (it) T(value);
|
||||
}
|
||||
}
|
||||
void append(const_iterator it_begin, const_iterator it_end)
|
||||
{
|
||||
size_type N = std::distance(it_begin, it_end);
|
||||
|
@ -216,6 +209,14 @@ private:
|
|||
std::uninitialized_fill_n(end(), N, element);
|
||||
size_ += N;
|
||||
}
|
||||
void append(size_type N)
|
||||
{
|
||||
assert(N + size_ <= MAX_N);
|
||||
for (size_type i = size_; i < size_ + N; ++i) {
|
||||
new (&buffer[i]) T();
|
||||
}
|
||||
size_ += N;
|
||||
}
|
||||
|
||||
std::size_t size_ = 0;
|
||||
typename std::aligned_storage<sizeof(T), alignof(T)>::type buffer[MAX_N];
|
||||
|
|
|
@ -46,6 +46,12 @@ int C::nof_value_ctor = 0;
|
|||
int C::nof_move_ctor = 0;
|
||||
int C::nof_dtor = 0;
|
||||
|
||||
struct moveonly {
|
||||
moveonly() = default;
|
||||
moveonly(moveonly&&) noexcept = default;
|
||||
moveonly& operator=(moveonly&&) noexcept = default;
|
||||
};
|
||||
|
||||
int test_ctor()
|
||||
{
|
||||
// TEST: default ctor
|
||||
|
@ -113,22 +119,24 @@ int test_obj_add_rem()
|
|||
a.back() = 4;
|
||||
TESTASSERT(not std::equal(a.begin(), a.end(), a2.begin()));
|
||||
a2 = a;
|
||||
TESTASSERT(std::equal(a.begin(), a.end(), a2.begin()));
|
||||
TESTASSERT(a == a2);
|
||||
|
||||
// TEST: assign
|
||||
a.resize(5);
|
||||
a2.assign(a.begin(), a.end());
|
||||
TESTASSERT(a2.size() == 5);
|
||||
TESTASSERT(std::equal(a.begin(), a.end(), a2.begin()));
|
||||
TESTASSERT(a == a2);
|
||||
|
||||
// TEST: pop_back
|
||||
int last_nof_dtor = C::nof_dtor;
|
||||
a.pop_back();
|
||||
TESTASSERT(a.size() == 4 and last_nof_dtor == C::nof_dtor - 1);
|
||||
TESTASSERT(a != a2);
|
||||
|
||||
// TEST: erase
|
||||
a.erase(a.begin() + 1);
|
||||
TESTASSERT(std::equal(a.begin(), a.end(), std::initializer_list<C>{1, 3, 3}.begin()));
|
||||
srslte::bounded_vector<C, 10> test = {1, 3, 3};
|
||||
TESTASSERT(a == test);
|
||||
|
||||
// TEST: clear
|
||||
last_nof_dtor = C::nof_dtor;
|
||||
|
@ -139,6 +147,34 @@ int test_obj_add_rem()
|
|||
TESTASSERT(a2.size() == 5);
|
||||
a = std::move(a2);
|
||||
TESTASSERT(a.size() == 5 and a2.empty());
|
||||
test = {1, 2, 3, 3, 3};
|
||||
TESTASSERT(a == test);
|
||||
|
||||
// TEST: move assignment from empty array
|
||||
a2.clear();
|
||||
a = std::move(a2);
|
||||
TESTASSERT(a.empty() and a2.empty());
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int test_move_only_type()
|
||||
{
|
||||
bounded_vector<moveonly, 10> a(5);
|
||||
TESTASSERT(a.size() == 5);
|
||||
|
||||
bounded_vector<moveonly, 10> a2(std::move(a));
|
||||
TESTASSERT(a2.size() == 5 and a.empty());
|
||||
|
||||
a2[0] = moveonly();
|
||||
moveonly c;
|
||||
a2[1] = std::move(c);
|
||||
|
||||
a2.emplace_back();
|
||||
TESTASSERT(a2.size() == 6);
|
||||
|
||||
a2.push_back(moveonly());
|
||||
TESTASSERT(a2.size() == 7);
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
@ -155,6 +191,7 @@ int main()
|
|||
{
|
||||
TESTASSERT(srslte::test_ctor() == SRSLTE_SUCCESS);
|
||||
TESTASSERT(srslte::test_obj_add_rem() == SRSLTE_SUCCESS);
|
||||
TESTASSERT(srslte::test_move_only_type() == SRSLTE_SUCCESS);
|
||||
TESTASSERT(srslte::assert_dtor_consistency() == SRSLTE_SUCCESS);
|
||||
printf("Success\n");
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue