Allow zero sized etl::array

This commit is contained in:
John Wellbelove 2025-05-18 13:41:01 +01:00
parent ba31479481
commit c25df24b03
2 changed files with 519 additions and 6 deletions

View File

@ -204,7 +204,7 @@ namespace etl
ETL_CONSTEXPR14
pointer data() ETL_NOEXCEPT
{
return &_buffer[0];
return _buffer;
}
//*************************************************************************
@ -213,7 +213,7 @@ namespace etl
ETL_NODISCARD
ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
{
return &_buffer[0];
return _buffer;
}
//*************************************************************************
@ -227,7 +227,7 @@ namespace etl
ETL_CONSTEXPR14
iterator begin() ETL_NOEXCEPT
{
return &_buffer[0];
return _buffer;
}
//*************************************************************************
@ -236,7 +236,7 @@ namespace etl
ETL_NODISCARD
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
{
return &_buffer[0];
return _buffer;
}
//*************************************************************************
@ -602,6 +602,507 @@ namespace etl
template <typename T, size_t SIZE_>
ETL_CONSTANT size_t array<T, SIZE_>::SIZE;
//***************************************************************************
///\ingroup array
/// A replacement for std::array if you haven't got C++0x11.
/// Specialisation for zero sized array.
//***************************************************************************
template <typename T>
class array<T, 0>
{
private:
typedef typename etl::parameter_type<T>::type parameter_t;
public:
static ETL_CONSTANT size_t SIZE = 0;
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
//*************************************************************************
// Element access
//*************************************************************************
//*************************************************************************
/// Returns a reference to the value at index 'i'.
///\param i The index of the element to access.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reference at(size_t i)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a const reference to the value at index 'i'.
///\param i The index of the element to access.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
const_reference at(size_t i) const
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// [] operator.
/// Returns a reference to the value at index 'i'.
///\param i The index of the element to access.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reference operator[](size_t i)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// [] operator.
/// Returns a const reference to the value at index 'i'.
///\param i The index of the element to access.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reference operator[](size_t i) const
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reference front()
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a const reference to the first element.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reference front() const
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a reference to the last element.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reference back()
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a const reference to the last element.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reference back() const
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return *data();
}
//*************************************************************************
/// Returns a pointer to the first element of the internal buffer.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
pointer data() ETL_NOEXCEPT
{
return (T*)0;
}
//*************************************************************************
/// Returns a const pointer to the first element of the internal buffer.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
{
return (const T*)0;
}
//*************************************************************************
// Iterators
//*************************************************************************
//*************************************************************************
/// Returns an iterator to the beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
iterator begin() ETL_NOEXCEPT
{
return iterator();
}
//*************************************************************************
/// Returns a const iterator to the beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
{
return const_iterator();
}
//*************************************************************************
/// Returns a const iterator to the beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
{
return const_iterator();
}
//*************************************************************************
/// Returns an iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
iterator end() ETL_NOEXCEPT
{
return iterator();
}
//*************************************************************************
/// Returns a const iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
{
return const_iterator();
}
//*************************************************************************
// Returns a const iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
{
return const_iterator();
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reverse_iterator rbegin() ETL_NOEXCEPT
{
return reverse_iterator(end());
}
//*************************************************************************
/// Returns a const reverse iterator to the reverse beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reverse_iterator rbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator(end());
}
//*************************************************************************
/// Returns a const reverse iterator to the reverse beginning of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator(end());
}
//*************************************************************************
/// Returns a reverse iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
reverse_iterator rend() ETL_NOEXCEPT
{
return reverse_iterator(begin());
}
//*************************************************************************
/// Returns a const reverse iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reverse_iterator rend() const ETL_NOEXCEPT
{
return const_reverse_iterator(begin());
}
//*************************************************************************
/// Returns a const reverse iterator to the end of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
{
return const_reverse_iterator(begin());
}
//*************************************************************************
// Capacity
//*************************************************************************
//*************************************************************************
/// Returns <b>true</b> if the array size is zero.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return true;
}
//*************************************************************************
/// Returns the size of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return 0;
}
//*************************************************************************
/// Returns the maximum possible size of the array.
//*************************************************************************
ETL_NODISCARD
ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
{
return 0;
}
//*************************************************************************
// Operations
//*************************************************************************
//*************************************************************************
/// Fills the array with the specified value.
///\param value The value to fill the array with.
//*************************************************************************
ETL_CONSTEXPR14 void fill(parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
}
//*************************************************************************
/// Swaps the contents of this array and another.
///\param other A reference to the other array.
//*************************************************************************
ETL_CONSTEXPR14 void swap(array& other) ETL_NOEXCEPT
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
}
//*************************************************************************
/// Fills the array from the range.
/// If the range is smaller than the array then the unused array elements are left unmodified.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
///\return An iterator to the first unassigned array element, or end().
//*************************************************************************
template <typename TIterator>
iterator assign(TIterator first, const TIterator last)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Fills the array from the range.
/// If the range is smaller than the array then the unused array elements are initialised with the supplied value.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
///\return An iterator to the first array element set to 'value', or end().
//*************************************************************************
template <typename TIterator>
iterator assign(TIterator first, const TIterator last, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Inserts a value into the array.
///\param position The index of the position to insert at.
///\param value The value to insert.
//*************************************************************************
inline iterator insert_at(size_t position, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Inserts a value into the array.
///\param position The iterator to the position to insert at.
///\param value The value to insert.
//*************************************************************************
iterator insert(const_iterator position, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Insert into the array from the range.
///\param position The position to insert at.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
//*************************************************************************
template <typename TIterator>
inline iterator insert_at(size_t position, TIterator first, const TIterator last)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Insert into the array from the range.
///\param position The position to insert at.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
//*************************************************************************
template <typename TIterator>
iterator insert(const_iterator position, TIterator first, const TIterator last)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a value from the array.
/// After erase, the last value in the array will be unmodified.
///\param position The index of the position to erase at.
//*************************************************************************
inline iterator erase_at(size_t position)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a value from the array.
/// After erase, the last value in the array will be unmodified.
///\param position The iterator to the position to erase at.
//*************************************************************************
iterator erase(const_iterator position)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a range of values from the array.
/// After erase, the last values in the array will be unmodified.
///\param first The first item to erase.
///\param last The one past the last item to erase.
//*************************************************************************
iterator erase_range(size_t first, size_t last)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a range of values from the array.
/// After erase, the last values in the array will be unmodified.
///\param first The first item to erase.
///\param last The one past the last item to erase.
//*************************************************************************
iterator erase(const_iterator first, const_iterator last)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a value from the array.
///\param position The index of the position to erase at.
///\param value The value to use to overwrite the last element in the array.
//*************************************************************************
inline iterator erase_at(size_t position, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a value from the array.
///\param position The iterator to the position to erase at.
///\param value The value to use to overwrite the last element in the array.
//*************************************************************************
iterator erase(const_iterator position, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a range of values from the array.
///\param first The first item to erase.
///\param last The one past the last item to erase.
///\param value The value to use to overwrite the last elements in the array.
//*************************************************************************
iterator erase_range(size_t first, size_t last, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
//*************************************************************************
/// Erases a range of values from the array.
///\param position The iterator to the position to erase at.
///\param value The value to use to overwrite the last elements in the array.
//*************************************************************************
iterator erase(const_iterator first, const_iterator last, parameter_t value)
{
ETL_ASSERT_FAIL(ETL_ERROR(array_out_of_range));
return iterator();
}
};
//*************************************************************************
/// Template deduction guides.
//*************************************************************************

View File

@ -47,8 +47,10 @@ namespace
{
static const size_t SIZE = 10UL;
typedef etl::array<int, SIZE> Data;
typedef std::array<int, SIZE> Compare_Data;
using Data = etl::array<int, SIZE>;
using Compare_Data = std::array<int, SIZE>;
using ZeroData = etl::array<int, 0>;
Compare_Data compare_data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Compare_Data swap_data = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
@ -62,6 +64,16 @@ namespace
CHECK_EQUAL(data.max_size(), SIZE);
}
//*************************************************************************
TEST(test_constructor_zero_sized_array)
{
ZeroData data;
CHECK_TRUE(data.empty());
CHECK_EQUAL(data.size(), size_t(0));
CHECK_EQUAL(data.max_size(), 0);
}
#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST && !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED)
//*************************************************************************
TEST(test_cpp17_deduced_constructor)