Compare commits

..

3 Commits

3 changed files with 505 additions and 34 deletions

View File

@ -33,8 +33,8 @@ namespace cc {
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
protected:
T _arr[N] = {};
static constexpr const size_type _len = N;
T _arr[N] = {};
size_type _size = 0;
public:
@ -51,9 +51,13 @@ namespace cc {
template<std::input_iterator InputIt>
constexpr const_vector(InputIt first, InputIt last);
constexpr const_vector(const const_vector& other) noexcept;
constexpr const_vector(const const_vector<value_type, N>& other) noexcept;
template <std::size_t N2>
constexpr const_vector(const const_vector<value_type, N2>& other);
constexpr const_vector(const_vector&& other) noexcept;
constexpr ~const_vector() = default; // elements in static array should be destroyed automatically
constexpr const_vector<T, N>& operator=(const const_vector& other);
constexpr const_vector<T, N>& operator=(const_vector&& other) noexcept;
constexpr const_vector<T, N>& operator=(const value_type (&array)[N]) noexcept;
@ -66,11 +70,68 @@ namespace cc {
constexpr reference at(size_type pos);
constexpr const_reference at(size_type pos) const;
[[nodiscard]] constexpr size_type size() const noexcept { return _size; }
constexpr T& operator[](size_type pos) { return _arr[pos]; }
constexpr const T& operator[](size_type pos) const { return _arr[pos]; }
[[nodiscard]] constexpr reference front() noexcept{ return _arr[0]; }
[[nodiscard]] constexpr const_reference front() const noexcept { return _arr[0]; }
[[nodiscard]] constexpr reference back() noexcept { return _arr[_size]; }
[[nodiscard]] constexpr const_reference back() const noexcept { return _arr[_size]; }
[[nodiscard]] constexpr value_type * data() noexcept { return _arr; }
[[nodiscard]] constexpr const value_type * data() const noexcept { return _arr; }
[[nodiscard]] constexpr iterator begin() noexcept { return _arr; };
[[nodiscard]] constexpr const_iterator begin() const noexcept { return _arr; };
[[nodiscard]] constexpr const_iterator cbegin() const noexcept { return _arr; };
[[nodiscard]] constexpr iterator end() noexcept { return _arr + _size; };
[[nodiscard]] constexpr const_iterator end() const noexcept { return _arr + _size; };
[[nodiscard]] constexpr const_iterator cend() const noexcept { return _arr + _size; };
[[nodiscard]] constexpr reverse_iterator rbegin() noexcept { return std::reverse_iterator<iterator>(_arr + _size); };
[[nodiscard]] constexpr const_reverse_iterator rbegin() const noexcept { return std::reverse_iterator<const_iterator>(_arr + _size); };
[[nodiscard]] constexpr const_reverse_iterator crbegin() const noexcept { return std::reverse_iterator<const_iterator>(_arr + _size); };
[[nodiscard]] constexpr reverse_iterator rend() noexcept { return std::reverse_iterator<iterator>(_arr); };
[[nodiscard]] constexpr const_reverse_iterator rend() const noexcept { return std::reverse_iterator<const_iterator>(_arr); };
[[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return std::reverse_iterator<const_iterator>(_arr); };
[[nodiscard]] constexpr bool empty() const noexcept { return begin() == end(); } // vector standard defines empty as this
[[nodiscard]] constexpr size_type max_size() const noexcept { return _len; }
[[nodiscard]] constexpr size_type capacity() const noexcept { return _len; }
[[nodiscard]] constexpr size_type size() const noexcept { return _size; }
constexpr void clear() { _erase_no_move(std::begin(_arr), std::end(_arr)); }
constexpr iterator insert(const_iterator pos, const T& value);
constexpr iterator insert(const_iterator pos, T&& value);
constexpr iterator insert(const_iterator pos, size_type count, const T& value);
template<std::input_iterator InputIt>
constexpr iterator insert(const_iterator pos, InputIt first, InputIt last);
constexpr iterator insert(const_iterator pos, std::initializer_list<T> values);
template<typename ...Args>
constexpr iterator emplace(const_iterator pos, Args&&... args);
constexpr iterator erase(const_iterator pos);
constexpr iterator erase(const_iterator first, const_iterator last);
constexpr void push_back(const T& value);
constexpr void push_back(T&& value);
template<typename ...Args>
constexpr reference emplace_back(Args&&... args);
constexpr void pop_back();
template<std::size_t N2>
constexpr void swap(const_vector<T, N2>& other);
protected:
constexpr inline void _erase_no_move(const_iterator first, const_iterator last) { std::destroy(first, last); }
#ifdef UNIT_TEST
friend test_const_vector;
#endif
@ -82,7 +143,48 @@ namespace cc {
template<typename ...T>
const_vector(T...) -> const_vector<std::common_type_t<T...>, sizeof...(T)>;
template<typename T1, typename T2, std::size_t N1, std::size_t N2>
constexpr bool operator==(const const_vector<T1, N1>& lhs,
const const_vector<T2, N2>& rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template<typename T1, typename T2, std::size_t N1, std::size_t N2>
constexpr auto operator<=>(const const_vector<T1, N1>& lhs,
const const_vector<T2, N2>& rhs)
{
return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), std::compare_three_way());
}
template<typename T, std::size_t N1, std::size_t N2>
constexpr void swap(const const_vector<T, N1>& lhs,
const const_vector<T, N2>& rhs)
{
return lhs.swap(rhs);
}
template<typename T, std::size_t N, typename U>
constexpr const_vector<T, N>::size_type erase(const_vector<T, N>& vec, const U& value)
{
auto it = std::remove(vec.begin(), vec.end(), value);
auto r = vec.end() - it;
vec.erase(it, vec.end());
return r;
}
template<typename T, std::size_t N, typename Pred>
constexpr const_vector<T, N>::size_type erase(const_vector<T, N>& vec, Pred pred)
{
auto it = std::remove_if(vec.begin(), vec.end(), pred);
auto r = vec.end() - it;
vec.erase(it, vec.end());
return r;
}
template<typename T, std::size_t N>
@ -116,21 +218,34 @@ namespace cc {
template<typename T, std::size_t N>
template<std::input_iterator InputIt>
constexpr const_vector<T, N>::const_vector(InputIt first, InputIt last) {
//static_assert(std::distance(first, last) > N, "tried inserting more elements than const_vector is in size");
_size = std::distance(first, last);
constexpr const_vector<T, N>::const_vector(InputIt first, InputIt last)
: _size(std::distance(first, last))
{
if (std::distance(first, last) > N) throw std::invalid_argument("tried inserting more elements than const_vector is in size");
std::copy(first, last, _arr);
}
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::const_vector(const const_vector &other) noexcept
: _size(other._size)
{
std::copy(other.begin(), other.end(), _arr);
_size = other._size;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::const_vector(const const_vector &other) noexcept {
static_assert(N >= other._size, "size of other has to be equal to or smaller than this");
std::copy(other._arr, other._arr, _arr);
}
template<std::size_t N2>
constexpr const_vector<T, N>::const_vector(const const_vector<const_vector::value_type, N2> &other)
: _size(other.size())
{
if (_len <= other.size()) throw std::invalid_argument("size of other has to be equal to or smaller than this");
std::copy(other.begin(), other.end(), _arr);
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::const_vector(const_vector &&other) noexcept {
static_assert(N == other.N, "size of const_vectors does not match");
constexpr const_vector<T, N>::const_vector(const_vector &&other) noexcept
: _size(other._size)
{
std::move(other.begin(), other.end(), _arr);
}
@ -150,10 +265,12 @@ namespace cc {
constexpr const_vector<T, N> &const_vector<T, N>::operator=(const_vector &&other) noexcept
{
static_assert(N == other._len, "Cannot assign const_vector to other with different size");
if (N != other.N) throw std::exception();
if (N != other._len) throw std::exception();
clear();
std::move(other.begin(), other.end(), _arr);
_size = other._size;
return *this;
}
@ -165,23 +282,28 @@ namespace cc {
}
template<typename T, std::size_t N>
constexpr void const_vector<T, N>::assign(const_vector::size_type count, const value_type &value) noexcept {
constexpr void const_vector<T, N>::assign(const_vector::size_type count, const value_type &value) noexcept
{
if (count > N) count = N;
_size = count;
std::fill(std::begin(_arr), std::end(_arr), value);
}
template<typename T, std::size_t N>
template<std::input_iterator InputIt>
constexpr void const_vector<T, N>::assign(InputIt first, InputIt last) {
constexpr void const_vector<T, N>::assign(InputIt first, InputIt last)
{
auto distance = std::distance(first, last);
if (distance > N) throw std::invalid_argument("Iterator distance in assign surpasses size" + std::to_string(distance) + ">=" + std::to_string(N));
_size = distance;
std::destroy(_arr, _arr + _size);
std::copy(first, last, _arr);
}
template<typename T, std::size_t N>
constexpr void const_vector<T, N>::assign(std::initializer_list<value_type> values) {
constexpr void const_vector<T, N>::assign(std::initializer_list<value_type> values)
{
auto values_size = std::distance(values.begin(), values.end());
if (values_size > N) throw std::invalid_argument("Initializer list in assign has more elements than size" + std::to_string(values_size) + ">=" + std::to_string(N));
_size = values_size;
@ -189,17 +311,157 @@ namespace cc {
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::reference const_vector<T, N>::at(const_vector::size_type pos) {
constexpr const_vector<T, N>::reference const_vector<T, N>::at(const_vector::size_type pos)
{
if (pos >= _size) throw std::out_of_range("Pos " + std::to_string(pos) + " is out of range");
return _arr[pos];
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::const_reference const_vector<T, N>::at(const_vector::size_type pos) const {
constexpr const_vector<T, N>::const_reference const_vector<T, N>::at(const_vector::size_type pos) const
{
if (pos >= _size) throw std::out_of_range("Pos " + std::to_string(pos) + " is out of range");
return _arr[pos];
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator const_vector<T, N>::insert(const_vector::const_iterator pos, const T &value)
{
if (_size == N) throw std::exception();
ptrdiff_t i = pos - _arr;
std::move(_arr + i, _arr + _size, _arr + i + 1);
_arr[i] = value;
++_size;
return pos;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator const_vector<T, N>::insert(const_vector::const_iterator pos, T &&value)
{
if (_size == N) throw std::exception();
ptrdiff_t i = pos - _arr;
std::move(_arr + i, _arr + _size, _arr + i + 1);
_arr[i] = std::move(value);
++_size;
return pos;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator
const_vector<T, N>::insert(const_vector::const_iterator pos, const_vector::size_type count, const T &value)
{
if (count == 0) return pos;
if (_size + count >= N) throw std::exception();
std::move(pos, _arr + _size, pos + count);
std::fill(pos, pos + count, value);
_size += count;
return pos;
}
template<typename T, std::size_t N>
template<std::input_iterator InputIt>
constexpr const_vector<T, N>::iterator
const_vector<T, N>::insert(const_vector::const_iterator pos, InputIt first, InputIt last)
{
auto count = std::distance(first, last);
if (first == last) return pos;
if (_size + count >= N) throw std::exception();
std::move(pos, _arr + _size, pos + count);
std::copy(first, last, pos);
_size += count;
return pos;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator
const_vector<T, N>::insert(const_vector::const_iterator pos, std::initializer_list<T> values)
{
return insert(pos, values.begin(), values.end());
}
template<typename T, std::size_t N>
template<class... Args>
constexpr const_vector<T, N>::iterator const_vector<T, N>::emplace(const_vector::const_iterator pos, Args &&... args)
{
if (_size == N) throw std::exception();
T obj(std::forward<Args>(args)...);
ptrdiff_t i = pos - _arr;
std::move(_arr + i, _arr + _size, _arr + i + 1);
_erase_no_move(pos);
_arr[i] = std::move(obj);
return pos;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator const_vector<T, N>::erase(const_vector::const_iterator pos)
{
_erase_no_move(pos);
std::move(pos + 1, end(), pos);
--_size;
return pos;
}
template<typename T, std::size_t N>
constexpr const_vector<T, N>::iterator
const_vector<T, N>::erase(const_vector::const_iterator first, const_vector::const_iterator last)
{
_erase_no_move(first, last);
std::move(last + 1, end(), first);
_size -= (last - first);
return first;
}
template<typename T, std::size_t N>
constexpr void const_vector<T, N>::push_back(const const_vector::value_type &value)
{
insert(end(), value);
}
template<typename T, std::size_t N>
constexpr void const_vector<T, N>::push_back(T&& value)
{
insert(end(), value);
}
template<typename T, std::size_t N>
template<typename ...Args>
constexpr const_vector<T, N>::reference const_vector<T, N>::emplace_back(Args&&... args)
{
emplace(end(), std::forward(args)...);
}
template<typename T, std::size_t N>
constexpr void const_vector<T, N>::pop_back()
{
_erase_no_move(end() - 1, end());
--_size;
}
template<typename T, std::size_t N>
template<std::size_t N2>
constexpr void const_vector<T, N>::swap(const_vector<T, N2> &other)
{
if (_size > other._len || other._size > N) throw std::exception();
cc::helper::swap_iter_range(begin(), end(), std::end(_arr), other.begin(), other.end(), std::end(other._arr));
std::swap(_size, other._size);
}
}; // cc
#endif //UDIFF_IMMARRAY_H_

View File

@ -8,10 +8,59 @@
#include <cstddef>
namespace cc::helper {
template <std::input_or_output_iterator Iter, typename Distance>
inline auto advanced(Iter i, Distance n) { std::advance(i, n); return i; }
template<typename T, std::size_t N>
constexpr std::size_t array_size(const T(&)[N]) { return N; }
template<std::input_or_output_iterator InputIt1, std::input_or_output_iterator InputIt2, typename T = InputIt1::value_type>
requires ((InputIt1::value_type == InputIt2::value_type)
&& std::indirectly_writable<typename InputIt1::value_type, InputIt1> && std::indirectly_readable<InputIt1>
&& std::indirectly_writable<typename InputIt2::value_type, InputIt1> && std::indirectly_readable<InputIt2>)
constexpr void swap_iter_range(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{
auto dist1 = std::distance(first1, last1);
auto dist2 = std::distance(first2, last2);
if (dist1 == dist2) {
std::swap_ranges(first1, last1, first2);
return;
}
auto swap_dist = std::min(dist1, dist2);
std::swap_ranges(first1, advanced(first1, swap_dist), first2, advanced(first2, swap_dist));
std::advance(first1, swap_dist);
std::advance(first2, swap_dist);
if (dist1 < dist2) {
std::move(first2, last2, last1);
} else {
std::move(first1, last1, last2);
}
}
template<std::input_or_output_iterator InputIt1, std::input_or_output_iterator InputIt2, typename T = InputIt1::value_type>
requires ((InputIt1::value_type == InputIt2::value_type)
&& std::indirectly_writable<typename InputIt1::value_type, InputIt1> && std::indirectly_readable<InputIt1>
&& std::indirectly_writable<typename InputIt2::value_type, InputIt1> && std::indirectly_readable<InputIt2>)
constexpr void swap(InputIt1 first1, InputIt1 last1, InputIt1 end1, InputIt2 first2, InputIt2 last2, InputIt2 end2)
{
auto max_dist = std::min(std::distance(first1, end1), std::distance(first2, end2));
auto dist1 = std::distance(first1, last1);
auto dist2 = std::distance(first2, last2);
if (max_dist < dist1 || max_dist < dist2) throw std::invalid_argument("Distance between iterators does not fit inbetween other "
"(Range 1: " + std::to_string(dist1) + "/" + std::to_string(std::distance(first1, end1)) + ", " +
"Range 2: " + std::to_string(dist2) + "/" + std::to_string(std::distance(first2, end2)) + ")");
swap_iter_range(first1, last1, first2, last2);
}
}; // cc
#endif //UDIFF_HELPER_H_

View File

@ -26,7 +26,8 @@ class test_const_vector;
#define ASSERT_ALL_VEC_EQ(vec, eq) ASSERT_ALL_EQ(vec._arr, vec._arr + vec._len, eq)
#define ASSERT_RANGE_VEC_EQ(vec, startI, endI, eq) ASSERT_ALL_EQ((vec._arr + startI), (vec._arr + endI), eq)
#define ASSERT_VEC_ARR_EQ(vec, eq) ASSERT_ARR_EQ(vec._arr, vec._arr + vec._len, eq)
#define ASSERT_VEC_ARR_EQ(vec, eq) ASSERT_ARR_EQ(vec._arr, vec._arr + vec._size, eq)
#define ASSERT_VEC_EQ(vec1, vec2) ASSERT_ARR_EQ(vec1._arr, vec1._arr + vec1._size, vec2._arr)
#define ASSERT_RANGE_VEC_ARR_EQ(vec, startI, endI, eq) ASSERT_ARR_EQ((vec._arr + startI), (vec._arr + endI), eq)
@ -350,7 +351,7 @@ class test_const_vector {
return true;
}
static consteval bool test_constructor_initializer_list() {
#pragma message("Testing constructor 'const_vector(std::initializer_list<value_type> list)'")
@ -439,8 +440,7 @@ class test_const_vector {
return true;
}
static consteval bool test_constructor_iterator() {
#pragma message("Testing constructor 'const_vector(const_vector(InputIt first, InputIt last)'")
@ -449,7 +449,7 @@ class test_const_vector {
constexpr cc::const_vector<int, TEST_VEC2_CAPACITY> vi2(std::begin(C_VI_TEST_ARR2), std::end(C_VI_TEST_ARR2));
constexpr cc::const_vector<int, TEST_VEC1_CAPACITY> vi3(STD_VI_TEST_ARR1.begin(), STD_VI_TEST_ARR1.end());
constexpr cc::const_vector<int, TEST_VEC2_CAPACITY> vi4(STD_VI_TEST_ARR2.begin(), STD_VI_TEST_ARR2.end());
ASSERT(vi1._len == TEST_VEC1_CAPACITY)
ASSERT(vi2._len == TEST_VEC2_CAPACITY)
ASSERT(vi1._size == VI_TEST_ARR1_LEN)
@ -467,7 +467,7 @@ class test_const_vector {
ASSERT_RANGE_VEC_ARR_EQ(vi4, 0, VI_TEST_ARR2_LEN, C_VI_TEST_ARR2)
ASSERT_RANGE_VEC_EQ(vi4, VI_TEST_ARR2_LEN, TEST_VEC2_CAPACITY, int())
constexpr cc::const_vector<char, TEST_VEC1_CAPACITY> vc1(std::begin(C_VC_TEST_ARR1), std::end(C_VC_TEST_ARR1));
constexpr cc::const_vector<char, TEST_VEC2_CAPACITY> vc2(std::begin(C_VC_TEST_ARR2), std::end(C_VC_TEST_ARR2));
constexpr cc::const_vector<char, TEST_VEC1_CAPACITY> vc3(STD_VC_TEST_ARR1.begin(), STD_VC_TEST_ARR1.end());
@ -490,7 +490,7 @@ class test_const_vector {
ASSERT_RANGE_VEC_ARR_EQ(vc4, 0, VC_TEST_ARR2_LEN, C_VC_TEST_ARR2)
ASSERT_RANGE_VEC_EQ(vc4, VC_TEST_ARR2_LEN, TEST_VEC2_CAPACITY, char())
constexpr cc::const_vector<const char *, TEST_VEC1_CAPACITY> vs1(std::begin(C_VS_TEST_ARR1), std::end(C_VS_TEST_ARR1));
constexpr cc::const_vector<const char *, TEST_VEC2_CAPACITY> vs2(std::begin(C_VS_TEST_ARR2), std::end(C_VS_TEST_ARR2));
constexpr cc::const_vector<const char *, TEST_VEC1_CAPACITY> vs3(STD_VS_TEST_ARR1.begin(), STD_VS_TEST_ARR1.end());
@ -509,7 +509,7 @@ class test_const_vector {
ASSERT_RANGE_VEC_ARR_EQ(vs3, 0, VS_TEST_ARR1_LEN, C_VS_TEST_ARR1)
ASSERT_RANGE_VEC_ARR_EQ(vs4, 0, VS_TEST_ARR2_LEN, C_VS_TEST_ARR2)
constexpr cc::const_vector<TestStruct, TEST_VEC1_CAPACITY> vo1(std::begin(C_VO_TEST_ARR1), std::end(C_VO_TEST_ARR1));
constexpr cc::const_vector<TestStruct, TEST_VEC2_CAPACITY> vo2(std::begin(C_VO_TEST_ARR2), std::end(C_VO_TEST_ARR2));
constexpr cc::const_vector<TestStruct, TEST_VEC1_CAPACITY> vo3(STD_VO_TEST_ARR1.begin(), STD_VO_TEST_ARR1.end());
@ -532,10 +532,169 @@ class test_const_vector {
ASSERT_RANGE_VEC_ARR_EQ(vo4, 0, VO_TEST_ARR2_LEN, C_VO_TEST_ARR2)
ASSERT_RANGE_VEC_EQ(vo4, VO_TEST_ARR2_LEN, TEST_VEC2_CAPACITY, TestStruct {})
return true;
}
static consteval bool test_constructor_copy() {
#pragma message("Testing copy constructors")
constexpr cc::const_vector vi1(C_VI_TEST_ARR1);
constexpr cc::const_vector vi2(C_VI_TEST_ARR2);
constexpr cc::const_vector vi1c(vi1);
constexpr cc::const_vector vi2c(vi2);
constexpr cc::const_vector<int, TEST_VEC1_CAPACITY> vi3(vi1);
constexpr cc::const_vector<int, TEST_VEC2_CAPACITY> vi4(vi2);
ASSERT(vi1c._len == vi1._len)
ASSERT(vi2c._len == vi2._len)
ASSERT(vi1c._size == vi1._size)
ASSERT(vi2c._size == vi2._size)
ASSERT_VEC_EQ(vi1c, vi1)
ASSERT_VEC_EQ(vi2c, vi2)
ASSERT(vi3._len == TEST_VEC1_CAPACITY)
ASSERT(vi4._len == TEST_VEC2_CAPACITY)
ASSERT(vi3._size == vi1._size)
ASSERT(vi4._size == vi2._size)
ASSERT_VEC_EQ(vi3, vi1)
ASSERT_VEC_EQ(vi4, vi2)
constexpr cc::const_vector vc1(C_VC_TEST_ARR1);
constexpr cc::const_vector vc2(C_VC_TEST_ARR2);
constexpr cc::const_vector vc1c(vc1);
constexpr cc::const_vector vc2c(vc2);
constexpr cc::const_vector<char, TEST_VEC1_CAPACITY> vc3(vc1);
constexpr cc::const_vector<char, TEST_VEC2_CAPACITY> vc4(vc2);
ASSERT(vc1c._len == vc1._len)
ASSERT(vc2c._len == vc2._len)
ASSERT(vc1c._size == vc1._size)
ASSERT(vc2c._size == vc2._size)
ASSERT_VEC_EQ(vc1c, vc1)
ASSERT_VEC_EQ(vc2c, vc2)
ASSERT(vc3._len == TEST_VEC1_CAPACITY)
ASSERT(vc4._len == TEST_VEC2_CAPACITY)
ASSERT(vc3._size == vc1._size)
ASSERT(vc4._size == vc2._size)
ASSERT_VEC_EQ(vc3, vc1)
ASSERT_VEC_EQ(vc4, vc2)
constexpr cc::const_vector vs1(C_VS_TEST_ARR1);
constexpr cc::const_vector vs2(C_VS_TEST_ARR2);
constexpr cc::const_vector vs1c(vs1);
constexpr cc::const_vector vs2c(vs2);
constexpr cc::const_vector<const char *, TEST_VEC1_CAPACITY> vs3(vs1);
constexpr cc::const_vector<const char *, TEST_VEC2_CAPACITY> vs4(vs2);
ASSERT(vs1c._len == vs1._len)
ASSERT(vs2c._len == vs2._len)
ASSERT(vs1c._size == vs1._size)
ASSERT(vs2c._size == vs2._size)
ASSERT_VEC_EQ(vs1c, vs1)
ASSERT_VEC_EQ(vs2c, vs2)
ASSERT(vs3._len == TEST_VEC1_CAPACITY)
ASSERT(vs4._len == TEST_VEC2_CAPACITY)
ASSERT(vs3._size == vs1._size)
ASSERT(vs4._size == vs2._size)
ASSERT_VEC_EQ(vs3, vs1)
ASSERT_VEC_EQ(vs4, vs2)
constexpr cc::const_vector vo1(C_VO_TEST_ARR1);
constexpr cc::const_vector vo2(C_VO_TEST_ARR2);
constexpr cc::const_vector vo1c(vo1);
constexpr cc::const_vector vo2c(vo2);
constexpr cc::const_vector<TestStruct, TEST_VEC1_CAPACITY> vo3(vo1);
constexpr cc::const_vector<TestStruct, TEST_VEC2_CAPACITY> vo4(vo2);
ASSERT(vo1c._len == vo1._len)
ASSERT(vo2c._len == vo2._len)
ASSERT(vo1c._size == vo1._size)
ASSERT(vo2c._size == vo2._size)
ASSERT_VEC_EQ(vo1c, vo1)
ASSERT_VEC_EQ(vo2c, vo2)
ASSERT(vo3._len == TEST_VEC1_CAPACITY)
ASSERT(vo4._len == TEST_VEC2_CAPACITY)
ASSERT(vo3._size == vo1._size)
ASSERT(vo4._size == vo2._size)
ASSERT_VEC_EQ(vo3, vo1)
ASSERT_VEC_EQ(vo4, vo2)
return true;
}
static consteval bool test_constructor_move() {
#pragma message("Testing move constructor")
constexpr cc::const_vector vi1(C_VI_TEST_ARR1);
constexpr cc::const_vector vi2(C_VI_TEST_ARR2);
constexpr cc::const_vector vi1c(vi1);
constexpr cc::const_vector vi2c(vi2);
constexpr cc::const_vector vi3(const_cast<cc::const_vector<int, decltype(vi1)::_len>&&>(vi1));
constexpr cc::const_vector vi4(const_cast<cc::const_vector<int, decltype(vi2)::_len>&&>(vi2));
ASSERT(vi3._len == vi1c._len)
ASSERT(vi4._len == vi2c._len)
ASSERT(vi3._size == vi1c._size)
ASSERT(vi4._size == vi2c._size)
ASSERT_VEC_EQ(vi3, vi1c)
ASSERT_VEC_EQ(vi4, vi2c)
constexpr cc::const_vector vc1(C_VC_TEST_ARR1);
constexpr cc::const_vector vc2(C_VC_TEST_ARR2);
constexpr cc::const_vector vc1c(vc1);
constexpr cc::const_vector vc2c(vc2);
constexpr cc::const_vector vc3(const_cast<cc::const_vector<char, decltype(vc1)::_len>&&>(vc1));
constexpr cc::const_vector vc4(const_cast<cc::const_vector<char, decltype(vc2)::_len>&&>(vc2));
ASSERT(vi3._len == vi1c._len)
ASSERT(vi4._len == vi2c._len)
ASSERT(vi3._size == vi1c._size)
ASSERT(vi4._size == vi2c._size)
ASSERT_VEC_EQ(vi3, vi1c)
ASSERT_VEC_EQ(vi4, vi2c)
constexpr cc::const_vector vs1(C_VS_TEST_ARR1);
constexpr cc::const_vector vs2(C_VS_TEST_ARR2);
constexpr cc::const_vector vs1c(vs1);
constexpr cc::const_vector vs2c(vs2);
constexpr cc::const_vector vs3(const_cast<cc::const_vector<const char *, decltype(vs1)::_len>&&>(vs1));
constexpr cc::const_vector vs4(const_cast<cc::const_vector<const char *, decltype(vs2)::_len>&&>(vs2));
ASSERT(vs3._len == vs1c._len)
ASSERT(vs4._len == vs2c._len)
ASSERT(vs3._size == vs1c._size)
ASSERT(vs4._size == vs2c._size)
ASSERT_VEC_EQ(vs3, vs1c)
ASSERT_VEC_EQ(vs4, vs2c)
constexpr cc::const_vector vo1(C_VO_TEST_ARR1);
constexpr cc::const_vector vo2(C_VO_TEST_ARR2);
constexpr cc::const_vector vo1c(vo1);
constexpr cc::const_vector vo2c(vo2);
constexpr cc::const_vector vo3(const_cast<cc::const_vector<TestStruct, decltype(vo1)::_len>&&>(vo1));
constexpr cc::const_vector vo4(const_cast<cc::const_vector<TestStruct, decltype(vo2)::_len>&&>(vo2));
ASSERT(vo3._len == vo1c._len)
ASSERT(vo4._len == vo2c._len)
ASSERT(vo3._size == vo1c._size)
ASSERT(vo4._size == vo2c._size)
ASSERT_VEC_EQ(vo3, vo1c)
ASSERT_VEC_EQ(vo4, vo2c)
return true;
}
};
int main(int, char *[])
@ -548,7 +707,8 @@ int main(int, char *[])
std::cout << "Test of constructor 'const_vector(const value_type (&array)[N])': " << test_const_vector::test_constructor_array() << std::endl;
std::cout << "Test of constructor 'const_vector(std::initializer_list<value_type> values)': " << test_const_vector::test_constructor_initializer_list() << std::endl;
std::cout << "Test of constructor 'const_vector(InputIt first, InputIt last)': " << test_const_vector::test_constructor_iterator() << std::endl;
std::cout << "Test of copy constructors: " << test_const_vector::test_constructor_copy() << std::endl;
std::cout << "Test of move constructor: " << test_const_vector::test_constructor_move() << std::endl;
return 0;
}