// array standard header // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #pragma once #ifndef _ARRAY_ #define _ARRAY_ #include #if _STL_COMPILER_PREPROCESSOR #include #include #include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) #pragma warning(disable : _STL_DISABLED_WARNINGS) _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new _STD_BEGIN // CLASS TEMPLATE array template class array { // fixed size array of values public: using value_type = _Ty; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Ty*; using const_pointer = const _Ty*; using reference = _Ty&; using const_reference = const _Ty&; using iterator = _Array_iterator<_Ty, _Size>; using const_iterator = _Array_const_iterator<_Ty, _Size>; using reverse_iterator = _STD reverse_iterator; using const_reverse_iterator = _STD reverse_iterator; #if _HAS_TR1_NAMESPACE _DEPRECATE_TR1_NAMESPACE void assign(const _Ty& _Value) { _STD fill_n(_Elems, _Size, _Value); } #endif // _HAS_TR1_NAMESPACE void fill(const _Ty& _Value) { _STD fill_n(_Elems, _Size, _Value); } void swap(array& _Other) noexcept(_Is_nothrow_swappable<_Ty>::value) { _Swap_ranges_unchecked(_Elems, _Elems + _Size, _Other._Elems); } _NODISCARD _CONSTEXPR17 iterator begin() noexcept { return iterator(_Elems, 0); } _NODISCARD _CONSTEXPR17 const_iterator begin() const noexcept { return const_iterator(_Elems, 0); } _NODISCARD _CONSTEXPR17 iterator end() noexcept { return iterator(_Elems, _Size); } _NODISCARD _CONSTEXPR17 const_iterator end() const noexcept { return const_iterator(_Elems, _Size); } _NODISCARD _CONSTEXPR17 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } _NODISCARD _CONSTEXPR17 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } _NODISCARD _CONSTEXPR17 reverse_iterator rend() noexcept { return reverse_iterator(begin()); } _NODISCARD _CONSTEXPR17 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } _NODISCARD _CONSTEXPR17 const_iterator cbegin() const noexcept { return begin(); } _NODISCARD _CONSTEXPR17 const_iterator cend() const noexcept { return end(); } _NODISCARD _CONSTEXPR17 const_reverse_iterator crbegin() const noexcept { return rbegin(); } _NODISCARD _CONSTEXPR17 const_reverse_iterator crend() const noexcept { return rend(); } _CONSTEXPR17 _Ty* _Unchecked_begin() noexcept { return _Elems; } _CONSTEXPR17 const _Ty* _Unchecked_begin() const noexcept { return _Elems; } _CONSTEXPR17 _Ty* _Unchecked_end() noexcept { return _Elems + _Size; } _CONSTEXPR17 const _Ty* _Unchecked_end() const noexcept { return _Elems + _Size; } _NODISCARD constexpr size_type size() const noexcept { return _Size; } _NODISCARD constexpr size_type max_size() const noexcept { return _Size; } _NODISCARD constexpr bool empty() const noexcept { return false; } _NODISCARD _CONSTEXPR17 reference at(size_type _Pos) { if (_Size <= _Pos) { _Xran(); } return _Elems[_Pos]; } _NODISCARD constexpr const_reference at(size_type _Pos) const { if (_Size <= _Pos) { _Xran(); } return _Elems[_Pos]; } _NODISCARD _CONSTEXPR17 reference operator[](_In_range_(0, _Size - 1) size_type _Pos) noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_VERIFY(_Pos < _Size, "array subscript out of range"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[_Pos]; } _NODISCARD constexpr const_reference operator[](_In_range_(0, _Size - 1) size_type _Pos) const noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_VERIFY(_Pos < _Size, "array subscript out of range"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[_Pos]; } _NODISCARD _CONSTEXPR17 reference front() noexcept /* strengthened */ { return _Elems[0]; } _NODISCARD constexpr const_reference front() const noexcept /* strengthened */ { return _Elems[0]; } _NODISCARD _CONSTEXPR17 reference back() noexcept /* strengthened */ { return _Elems[_Size - 1]; } _NODISCARD constexpr const_reference back() const noexcept /* strengthened */ { return _Elems[_Size - 1]; } _NODISCARD _CONSTEXPR17 _Ty* data() noexcept { return _Elems; } _NODISCARD _CONSTEXPR17 const _Ty* data() const noexcept { return _Elems; } [[noreturn]] void _Xran() const { _Xout_of_range("invalid array subscript"); } _Ty _Elems[_Size]; }; #if _HAS_CXX17 template struct _Enforce_same { static_assert(conjunction_v...>, "N4687 26.3.7.2 [array.cons]/2: " "Requires: (is_same_v && ...) is true. Otherwise the program is ill-formed."); using type = _First; }; template array(_First, _Rest...)->array::type, 1 + sizeof...(_Rest)>; #endif // _HAS_CXX17 template class array<_Ty, 0> { public: using value_type = _Ty; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Ty*; using const_pointer = const _Ty*; using reference = _Ty&; using const_reference = const _Ty&; using iterator = _Array_iterator<_Ty, 0>; using const_iterator = _Array_const_iterator<_Ty, 0>; using reverse_iterator = _STD reverse_iterator; using const_reverse_iterator = _STD reverse_iterator; #if _HAS_TR1_NAMESPACE _DEPRECATE_TR1_NAMESPACE void assign(const _Ty&) {} #endif // _HAS_TR1_NAMESPACE void fill(const _Ty&) {} void swap(array&) noexcept {} _NODISCARD _CONSTEXPR17 iterator begin() noexcept { return iterator{}; } _NODISCARD _CONSTEXPR17 const_iterator begin() const noexcept { return const_iterator{}; } _NODISCARD _CONSTEXPR17 iterator end() noexcept { return iterator{}; } _NODISCARD _CONSTEXPR17 const_iterator end() const noexcept { return const_iterator{}; } _NODISCARD _CONSTEXPR17 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } _NODISCARD _CONSTEXPR17 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } _NODISCARD _CONSTEXPR17 reverse_iterator rend() noexcept { return reverse_iterator(begin()); } _NODISCARD _CONSTEXPR17 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } _NODISCARD _CONSTEXPR17 const_iterator cbegin() const noexcept { return begin(); } _NODISCARD _CONSTEXPR17 const_iterator cend() const noexcept { return end(); } _NODISCARD _CONSTEXPR17 const_reverse_iterator crbegin() const noexcept { return rbegin(); } _NODISCARD _CONSTEXPR17 const_reverse_iterator crend() const noexcept { return rend(); } _CONSTEXPR17 _Ty* _Unchecked_begin() noexcept { return nullptr; } _CONSTEXPR17 const _Ty* _Unchecked_begin() const noexcept { return nullptr; } _CONSTEXPR17 _Ty* _Unchecked_end() noexcept { return nullptr; } _CONSTEXPR17 const _Ty* _Unchecked_end() const noexcept { return nullptr; } _NODISCARD constexpr size_type size() const noexcept { return 0; } _NODISCARD constexpr size_type max_size() const noexcept { return 0; } _NODISCARD constexpr bool empty() const noexcept { return true; } [[noreturn]] reference at(size_type) { _Xran(); } [[noreturn]] const_reference at(size_type) const { _Xran(); } _NODISCARD reference operator[](size_type) noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array subscript out of range"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD const_reference operator[](size_type) const noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array subscript out of range"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD reference front() noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array::front() invalid"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD const_reference front() const noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array::front() invalid"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD reference back() noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array::back() invalid"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD const_reference back() const noexcept /* strengthened */ { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_REPORT_ERROR("array::back() invalid"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _Elems[0]; } _NODISCARD _CONSTEXPR17 _Ty* data() noexcept { return nullptr; } _NODISCARD _CONSTEXPR17 const _Ty* data() const noexcept { return nullptr; } [[noreturn]] void _Xran() const { _Xout_of_range("invalid array subscript"); } _Ty _Elems[1]; }; template ::value>> void swap(array<_Ty, _Size>& _Left, array<_Ty, _Size>& _Right) noexcept(noexcept(_Left.swap(_Right))) { return _Left.swap(_Right); } template _NODISCARD bool operator==(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _STD equal(_Left.begin(), _Left.end(), _Right.begin()); } template _NODISCARD bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Left == _Right); } template _NODISCARD bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end()); } template _NODISCARD bool operator>(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _Right < _Left; } template _NODISCARD bool operator<=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Right < _Left); } template _NODISCARD bool operator>=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Left < _Right); } // TUPLE INTERFACE TO array template _NODISCARD constexpr _Ty& get(array<_Ty, _Size>& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); return _Arr._Elems[_Idx]; } template _NODISCARD constexpr const _Ty& get(const array<_Ty, _Size>& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); return _Arr._Elems[_Idx]; } template _NODISCARD constexpr _Ty&& get(array<_Ty, _Size>&& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); return _STD move(_Arr._Elems[_Idx]); } template _NODISCARD constexpr const _Ty&& get(const array<_Ty, _Size>&& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); return _STD move(_Arr._Elems[_Idx]); } #if _HAS_TR1_NAMESPACE namespace _DEPRECATE_TR1_NAMESPACE tr1 { using _STD array; using _STD get; } // namespace tr1 #endif // _HAS_TR1_NAMESPACE _STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) #endif // _STL_COMPILER_PREPROCESSOR #endif // _ARRAY_