Skip to content

ARMC5 <array> extensions #11076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 23, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 85 additions & 5 deletions platform/cxxsupport/TOOLCHAIN_ARMC5/array
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

#include <initializer_list> // required by standard

#include <_move.h>
#include <cstddef> // size_t, ptrdiff_t
#include <algorithm> // fill and swap_ranges
#include <type_traits> // integral_constant

namespace std {
template <typename>
Expand All @@ -30,7 +32,7 @@ struct reverse_iterator;
template <typename _TypeT, size_t _Size>
struct array {
// [array.overview]
_TypeT _C_elem[_Size];
_TypeT _C_elem[_Size != 0 ? _Size : 1];

using value_type = _TypeT;
using size_type = size_t;
Expand All @@ -44,7 +46,8 @@ struct array {
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
// [array.size]
constexpr size_type size() const noexcept
// ARMC5 complains "a constexpr member function is only permitted in a literal class type"
/*constexpr*/ size_type size() const noexcept
{
return _Size;
}
Expand Down Expand Up @@ -101,11 +104,11 @@ struct array {
{
return _C_elem[_Size - 1];
}
constexpr bool empty() const noexcept
/*constexpr*/ bool empty() const noexcept
{
return false;
}
constexpr size_type max_size() const noexcept
/*constexpr*/ size_type max_size() const noexcept
{
return _Size;
}
Expand Down Expand Up @@ -159,13 +162,90 @@ struct array {
}
};

template <typename _TypeT, size_t _Size>
bool operator==(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return equal(__x.begin(), __x.end(), __y.begin());
}

template <typename _TypeT, size_t _Size>
bool operator!=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return !(__x == __y);
}

template <typename _TypeT, size_t _Size>
bool operator<(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
}

template <typename _TypeT, size_t _Size>
bool operator>(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return __y < __x;
}

template <typename _TypeT, size_t _Size>
bool operator<=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return !(__x > __y);
}

template <typename _TypeT, size_t _Size>
bool operator>=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y)
{
return !(__x < __y);
}

// [array.special]
template <class _TypeT, size_t _Size>
template <typename _TypeT, size_t _Size>
void swap(array<_TypeT, _Size> &__x, array<_TypeT, _Size> &__y)
{
__x.swap(__y);
}

// [array.tuple]
template <typename>
struct tuple_size;

template <typename _TypeT, size_t _Size>
struct tuple_size<array<_TypeT, _Size>> : integral_constant<size_t, _Size> { };

template <size_t, typename>
struct tuple_element;

template <size_t _Idx, typename _TypeT, size_t _Size>
struct tuple_element<_Idx, array<_TypeT, _Size>> : type_identity<_TypeT> {
static_assert(_Idx < _Size, "array index out of bounds");
};

template <size_t _Idx, typename _TypeT, size_t _Size>
constexpr _TypeT &get(array<_TypeT, _Size> &__a) noexcept
{
static_assert(_Idx < _Size, "array index out of bounds");
return __a._C_elem[_Idx];
}

template <size_t _Idx, typename _TypeT, size_t _Size>
_TypeT &&get(array<_TypeT, _Size> &&__a) noexcept
{
return std::move(get<_Idx>(__a));
}

template <size_t _Idx, typename _TypeT, size_t _Size>
constexpr const _TypeT &get(const array<_TypeT, _Size> &__a) noexcept
{
static_assert(_Idx < _Size, "array index out of bounds");
return __a._C_elem[_Idx];
}

template <size_t _Idx, typename _TypeT, size_t _Size>
const _TypeT &&get(const array<_TypeT, _Size> &&__a) noexcept
{
return std::move(get<_Idx>(__a));
}

} // namespace std

#endif /* __array */