136ac495dSmrg// Profile array implementation -*- C++ -*- 236ac495dSmrg 3*c0a68be4Smrg// Copyright (C) 2012-2019 Free Software Foundation, Inc. 436ac495dSmrg// 536ac495dSmrg// This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg// software; you can redistribute it and/or modify it under the 736ac495dSmrg// terms of the GNU General Public License as published by the 836ac495dSmrg// Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg// any later version. 1036ac495dSmrg 1136ac495dSmrg// This library is distributed in the hope that it will be useful, 1236ac495dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg// GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg// Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg// permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg// 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg// You should have received a copy of the GNU General Public License and 2136ac495dSmrg// a copy of the GCC Runtime Library Exception along with this program; 2236ac495dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2336ac495dSmrg// <http://www.gnu.org/licenses/>. 2436ac495dSmrg 2536ac495dSmrg/** @file profile/array 2636ac495dSmrg * This is a Standard C++ Library header. 2736ac495dSmrg */ 2836ac495dSmrg 2936ac495dSmrg#ifndef _GLIBCXX_PROFILE_ARRAY 3036ac495dSmrg#define _GLIBCXX_PROFILE_ARRAY 1 3136ac495dSmrg 3236ac495dSmrg#pragma GCC system_header 3336ac495dSmrg 3436ac495dSmrg#include <array> 3536ac495dSmrg 3636ac495dSmrgnamespace std _GLIBCXX_VISIBILITY(default) 3736ac495dSmrg{ 3836ac495dSmrgnamespace __profile 3936ac495dSmrg{ 4036ac495dSmrg template<typename _Tp, std::size_t _Nm> 4136ac495dSmrg struct array 4236ac495dSmrg { 4336ac495dSmrg typedef _Tp value_type; 4436ac495dSmrg typedef value_type* pointer; 4536ac495dSmrg typedef const value_type* const_pointer; 4636ac495dSmrg typedef value_type& reference; 4736ac495dSmrg typedef const value_type& const_reference; 4836ac495dSmrg typedef value_type* iterator; 4936ac495dSmrg typedef const value_type* const_iterator; 5036ac495dSmrg typedef std::size_t size_type; 5136ac495dSmrg typedef std::ptrdiff_t difference_type; 5236ac495dSmrg typedef std::reverse_iterator<iterator> reverse_iterator; 5336ac495dSmrg typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 5436ac495dSmrg 5536ac495dSmrg // Support for zero-sized arrays mandatory. 5636ac495dSmrg typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; 5736ac495dSmrg typename _AT_Type::_Type _M_elems; 5836ac495dSmrg 5936ac495dSmrg // No explicit construct/copy/destroy for aggregate type. 6036ac495dSmrg 6136ac495dSmrg // DR 776. 6236ac495dSmrg void 6336ac495dSmrg fill(const value_type& __u) 6436ac495dSmrg { std::fill_n(begin(), size(), __u); } 6536ac495dSmrg 6636ac495dSmrg void 6736ac495dSmrg swap(array& __other) 6836ac495dSmrg noexcept(_AT_Type::_Is_nothrow_swappable::value) 6936ac495dSmrg { std::swap_ranges(begin(), end(), __other.begin()); } 7036ac495dSmrg 7136ac495dSmrg // Iterators. 7236ac495dSmrg _GLIBCXX17_CONSTEXPR iterator 7336ac495dSmrg begin() noexcept 7436ac495dSmrg { return iterator(data()); } 7536ac495dSmrg 7636ac495dSmrg _GLIBCXX17_CONSTEXPR const_iterator 7736ac495dSmrg begin() const noexcept 7836ac495dSmrg { return const_iterator(data()); } 7936ac495dSmrg 8036ac495dSmrg _GLIBCXX17_CONSTEXPR iterator 8136ac495dSmrg end() noexcept 8236ac495dSmrg { return iterator(data() + _Nm); } 8336ac495dSmrg 8436ac495dSmrg _GLIBCXX17_CONSTEXPR const_iterator 8536ac495dSmrg end() const noexcept 8636ac495dSmrg { return const_iterator(data() + _Nm); } 8736ac495dSmrg 8836ac495dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator 8936ac495dSmrg rbegin() noexcept 9036ac495dSmrg { return reverse_iterator(end()); } 9136ac495dSmrg 9236ac495dSmrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 9336ac495dSmrg rbegin() const noexcept 9436ac495dSmrg { return const_reverse_iterator(end()); } 9536ac495dSmrg 9636ac495dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator 9736ac495dSmrg rend() noexcept 9836ac495dSmrg { return reverse_iterator(begin()); } 9936ac495dSmrg 10036ac495dSmrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 10136ac495dSmrg rend() const noexcept 10236ac495dSmrg { return const_reverse_iterator(begin()); } 10336ac495dSmrg 10436ac495dSmrg _GLIBCXX17_CONSTEXPR const_iterator 10536ac495dSmrg cbegin() const noexcept 10636ac495dSmrg { return const_iterator(data()); } 10736ac495dSmrg 10836ac495dSmrg _GLIBCXX17_CONSTEXPR const_iterator 10936ac495dSmrg cend() const noexcept 11036ac495dSmrg { return const_iterator(data() + _Nm); } 11136ac495dSmrg 11236ac495dSmrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 11336ac495dSmrg crbegin() const noexcept 11436ac495dSmrg { return const_reverse_iterator(end()); } 11536ac495dSmrg 11636ac495dSmrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 11736ac495dSmrg crend() const noexcept 11836ac495dSmrg { return const_reverse_iterator(begin()); } 11936ac495dSmrg 12036ac495dSmrg // Capacity. 12136ac495dSmrg constexpr size_type 12236ac495dSmrg size() const noexcept { return _Nm; } 12336ac495dSmrg 12436ac495dSmrg constexpr size_type 12536ac495dSmrg max_size() const noexcept { return _Nm; } 12636ac495dSmrg 127*c0a68be4Smrg _GLIBCXX_NODISCARD constexpr bool 12836ac495dSmrg empty() const noexcept { return size() == 0; } 12936ac495dSmrg 13036ac495dSmrg // Element access. 13136ac495dSmrg reference 13236ac495dSmrg operator[](size_type __n) noexcept 13336ac495dSmrg { return _AT_Type::_S_ref(_M_elems, __n); } 13436ac495dSmrg 13536ac495dSmrg constexpr const_reference 13636ac495dSmrg operator[](size_type __n) const noexcept 13736ac495dSmrg { return _AT_Type::_S_ref(_M_elems, __n); } 13836ac495dSmrg 13936ac495dSmrg _GLIBCXX17_CONSTEXPR reference 14036ac495dSmrg at(size_type __n) 14136ac495dSmrg { 14236ac495dSmrg if (__n >= _Nm) 14336ac495dSmrg std::__throw_out_of_range_fmt(__N("array::at: __n " 14436ac495dSmrg "(which is %zu) >= _Nm " 14536ac495dSmrg "(which is %zu)"), 14636ac495dSmrg __n, _Nm); 14736ac495dSmrg return _AT_Type::_S_ref(_M_elems, __n); 14836ac495dSmrg } 14936ac495dSmrg 15036ac495dSmrg constexpr const_reference 15136ac495dSmrg at(size_type __n) const 15236ac495dSmrg { 15336ac495dSmrg // Result of conditional expression must be an lvalue so use 15436ac495dSmrg // boolean ? lvalue : (throw-expr, lvalue) 15536ac495dSmrg return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) 15636ac495dSmrg : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " 15736ac495dSmrg ">= _Nm (which is %zu)"), 15836ac495dSmrg __n, _Nm), 15936ac495dSmrg _AT_Type::_S_ref(_M_elems, 0)); 16036ac495dSmrg } 16136ac495dSmrg 16236ac495dSmrg _GLIBCXX17_CONSTEXPR reference 16336ac495dSmrg front() noexcept 16436ac495dSmrg { return *begin(); } 16536ac495dSmrg 16636ac495dSmrg constexpr const_reference 16736ac495dSmrg front() const noexcept 16836ac495dSmrg { return _AT_Type::_S_ref(_M_elems, 0); } 16936ac495dSmrg 17036ac495dSmrg _GLIBCXX17_CONSTEXPR reference 17136ac495dSmrg back() noexcept 17236ac495dSmrg { return _Nm ? *(end() - 1) : *end(); } 17336ac495dSmrg 17436ac495dSmrg constexpr const_reference 17536ac495dSmrg back() const noexcept 17636ac495dSmrg { 17736ac495dSmrg return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) 17836ac495dSmrg : _AT_Type::_S_ref(_M_elems, 0); 17936ac495dSmrg } 18036ac495dSmrg 18136ac495dSmrg _GLIBCXX17_CONSTEXPR pointer 18236ac495dSmrg data() noexcept 18336ac495dSmrg { return _AT_Type::_S_ptr(_M_elems); } 18436ac495dSmrg 18536ac495dSmrg _GLIBCXX17_CONSTEXPR const_pointer 18636ac495dSmrg data() const noexcept 18736ac495dSmrg { return _AT_Type::_S_ptr(_M_elems); } 18836ac495dSmrg }; 18936ac495dSmrg 19036ac495dSmrg // Array comparisons. 19136ac495dSmrg template<typename _Tp, std::size_t _Nm> 19236ac495dSmrg inline bool 19336ac495dSmrg operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 19436ac495dSmrg { return std::equal(__one.begin(), __one.end(), __two.begin()); } 19536ac495dSmrg 19636ac495dSmrg template<typename _Tp, std::size_t _Nm> 19736ac495dSmrg inline bool 19836ac495dSmrg operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 19936ac495dSmrg { return !(__one == __two); } 20036ac495dSmrg 20136ac495dSmrg template<typename _Tp, std::size_t _Nm> 20236ac495dSmrg inline bool 20336ac495dSmrg operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 20436ac495dSmrg { 20536ac495dSmrg return std::lexicographical_compare(__a.begin(), __a.end(), 20636ac495dSmrg __b.begin(), __b.end()); 20736ac495dSmrg } 20836ac495dSmrg 20936ac495dSmrg template<typename _Tp, std::size_t _Nm> 21036ac495dSmrg inline bool 21136ac495dSmrg operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 21236ac495dSmrg { return __two < __one; } 21336ac495dSmrg 21436ac495dSmrg template<typename _Tp, std::size_t _Nm> 21536ac495dSmrg inline bool 21636ac495dSmrg operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 21736ac495dSmrg { return !(__one > __two); } 21836ac495dSmrg 21936ac495dSmrg template<typename _Tp, std::size_t _Nm> 22036ac495dSmrg inline bool 22136ac495dSmrg operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 22236ac495dSmrg { return !(__one < __two); } 22336ac495dSmrg 22436ac495dSmrg // Specialized algorithms. 22536ac495dSmrg template<typename _Tp, std::size_t _Nm> 22636ac495dSmrg inline void 22736ac495dSmrg swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 22836ac495dSmrg noexcept(noexcept(__one.swap(__two))) 22936ac495dSmrg { __one.swap(__two); } 23036ac495dSmrg 23136ac495dSmrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 23236ac495dSmrg constexpr _Tp& 23336ac495dSmrg get(array<_Tp, _Nm>& __arr) noexcept 23436ac495dSmrg { 23536ac495dSmrg static_assert(_Int < _Nm, "index is out of bounds"); 23636ac495dSmrg return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: 23736ac495dSmrg _S_ref(__arr._M_elems, _Int); 23836ac495dSmrg } 23936ac495dSmrg 24036ac495dSmrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 24136ac495dSmrg constexpr _Tp&& 24236ac495dSmrg get(array<_Tp, _Nm>&& __arr) noexcept 24336ac495dSmrg { 24436ac495dSmrg static_assert(_Int < _Nm, "index is out of bounds"); 24536ac495dSmrg return std::move(__profile::get<_Int>(__arr)); 24636ac495dSmrg } 24736ac495dSmrg 24836ac495dSmrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 24936ac495dSmrg constexpr const _Tp& 25036ac495dSmrg get(const array<_Tp, _Nm>& __arr) noexcept 25136ac495dSmrg { 25236ac495dSmrg static_assert(_Int < _Nm, "index is out of bounds"); 25336ac495dSmrg return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: 25436ac495dSmrg _S_ref(__arr._M_elems, _Int); 25536ac495dSmrg } 25636ac495dSmrg} // namespace __profile 25736ac495dSmrg 25836ac495dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 25936ac495dSmrg // Tuple interface to class template array. 26036ac495dSmrg 26136ac495dSmrg /// tuple_size 26236ac495dSmrg template<typename _Tp, std::size_t _Nm> 26336ac495dSmrg struct tuple_size<std::__profile::array<_Tp, _Nm>> 26436ac495dSmrg : public integral_constant<std::size_t, _Nm> { }; 26536ac495dSmrg 26636ac495dSmrg /// tuple_element 26736ac495dSmrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 26836ac495dSmrg struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>> 26936ac495dSmrg { 27036ac495dSmrg static_assert(_Int < _Nm, "index is out of bounds"); 27136ac495dSmrg typedef _Tp type; 27236ac495dSmrg }; 27336ac495dSmrg 27436ac495dSmrg template<typename _Tp, std::size_t _Nm> 27536ac495dSmrg struct __is_tuple_like_impl<std::__profile::array<_Tp, _Nm>> : true_type 27636ac495dSmrg { }; 27736ac495dSmrg 27836ac495dSmrg_GLIBCXX_END_NAMESPACE_VERSION 27936ac495dSmrg} // namespace std 28036ac495dSmrg 28136ac495dSmrg#endif // _GLIBCXX_PROFILE_ARRAY 282