/* mbed Microcontroller Library * Copyright (c) 2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __array #define __array #include // required by standard #include <_move.h> #include // size_t, ptrdiff_t #include // fill and swap_ranges #include // integral_constant namespace std { template struct reverse_iterator; // [array] template struct array { // [array.overview] _TypeT _C_elem[_Size != 0 ? _Size : 1]; using value_type = _TypeT; using size_type = size_t; using difference_type = ptrdiff_t; using reference = _TypeT &; using const_reference = const _TypeT &; using pointer = _TypeT *; using const_pointer = const _TypeT *; using iterator = _TypeT *; using const_iterator = const _TypeT *; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; // [array.size] // ARMC5 complains "a constexpr member function is only permitted in a literal class type" /*constexpr*/ size_type size() const noexcept { return _Size; } // [array.data] _TypeT *data() noexcept { return _C_elem; } const _TypeT *data() const noexcept { return _C_elem; } // [array.fill] void fill(const _TypeT &value) { std::fill(begin(), end(), value); } // [array.swap] void swap(array &__y) { std::swap_ranges(begin(), end(), __y.begin()); } _TypeT &at(size_t pos) { MBED_ASSERT(pos < size()); return _C_elem[pos]; } const _TypeT &at(size_t pos) const { MBED_ASSERT(pos < size()); return _C_elem[pos]; } _TypeT &operator[](size_t pos) { return _C_elem[pos]; } const _TypeT &operator[](size_t pos) const { return _C_elem[pos]; } _TypeT &front() { return _C_elem[0]; } const _TypeT &front() const { return _C_elem[0]; } _TypeT &back() { return _C_elem[_Size - 1]; } const _TypeT &back() const { return _C_elem[_Size - 1]; } /*constexpr*/ bool empty() const noexcept { return false; } /*constexpr*/ size_type max_size() const noexcept { return _Size; } iterator begin() noexcept { return _C_elem; } const_iterator begin() const noexcept { return _C_elem; } const_iterator cbegin() const noexcept { return _C_elem; } iterator end() noexcept { return _C_elem + _Size; } const_iterator end() const noexcept { return _C_elem + _Size; } const_iterator cend() const noexcept { return _C_elem + _Size; } reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } reverse_iterator rend() noexcept { return reverse_iterator(begin()); } const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } }; template bool operator==(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return equal(__x.begin(), __x.end(), __y.begin()); } template bool operator!=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return !(__x == __y); } template bool operator<(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template bool operator>(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return __y < __x; } template bool operator<=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return !(__x > __y); } template bool operator>=(const array<_TypeT, _Size> &__x, const array<_TypeT, _Size> &__y) { return !(__x < __y); } // [array.special] template void swap(array<_TypeT, _Size> &__x, array<_TypeT, _Size> &__y) { __x.swap(__y); } // [array.tuple] template struct tuple_size; template struct tuple_size> : integral_constant { }; template struct tuple_element; template struct tuple_element<_Idx, array<_TypeT, _Size>> : type_identity<_TypeT> { static_assert(_Idx < _Size, "array index out of bounds"); }; template constexpr _TypeT &get(array<_TypeT, _Size> &__a) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); return __a._C_elem[_Idx]; } template _TypeT &&get(array<_TypeT, _Size> &&__a) noexcept { return std::move(get<_Idx>(__a)); } template 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 const _TypeT &&get(const array<_TypeT, _Size> &&__a) noexcept { return std::move(get<_Idx>(__a)); } } // namespace std #endif /* __array */