LCOV - code coverage report
Current view: top level - 11 - array (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 25 25 100.0 %
Date: 2025-08-24 09:11:10 Functions: 88 97 90.7 %

          Line data    Source code
       1             : // <array> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2021 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @file include/array
      26             :  *  This is a Standard C++ Library header.
      27             :  */
      28             : 
      29             : #ifndef _GLIBCXX_ARRAY
      30             : #define _GLIBCXX_ARRAY 1
      31             : 
      32             : #pragma GCC system_header
      33             : 
      34             : #if __cplusplus < 201103L
      35             : # include <bits/c++0x_warning.h>
      36             : #else
      37             : 
      38             : #include <utility>
      39             : #include <bits/functexcept.h>
      40             : #include <bits/stl_algobase.h>
      41             : #include <bits/range_access.h>
      42             : #include <debug/assertions.h>
      43             : 
      44             : namespace std _GLIBCXX_VISIBILITY(default)
      45             : {
      46             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      47             : 
      48             :   template<typename _Tp, std::size_t _Nm>
      49             :     struct __array_traits
      50             :     {
      51             :       typedef _Tp _Type[_Nm];
      52             :       typedef __is_swappable<_Tp> _Is_swappable;
      53             :       typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
      54             : 
      55             :       static constexpr _Tp&
      56    17516113 :       _S_ref(const _Type& __t, std::size_t __n) noexcept
      57    17516113 :       { return const_cast<_Tp&>(__t[__n]); }
      58             : 
      59             :       static constexpr _Tp*
      60     6481233 :       _S_ptr(const _Type& __t) noexcept
      61     6481233 :       { return const_cast<_Tp*>(__t); }
      62             :     };
      63             : 
      64             :  template<typename _Tp>
      65             :    struct __array_traits<_Tp, 0>
      66             :    {
      67             :      struct _Type { };
      68             :      typedef true_type _Is_swappable;
      69             :      typedef true_type _Is_nothrow_swappable;
      70             : 
      71             :      static constexpr _Tp&
      72             :      _S_ref(const _Type&, std::size_t) noexcept
      73             :      { return *static_cast<_Tp*>(nullptr); }
      74             : 
      75             :      static constexpr _Tp*
      76             :      _S_ptr(const _Type&) noexcept
      77             :      { return nullptr; }
      78             :    };
      79             : 
      80             :   /**
      81             :    *  @brief A standard container for storing a fixed size sequence of elements.
      82             :    *
      83             :    *  @ingroup sequences
      84             :    *
      85             :    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
      86             :    *  <a href="tables.html#66">reversible container</a>, and a
      87             :    *  <a href="tables.html#67">sequence</a>.
      88             :    *
      89             :    *  Sets support random access iterators.
      90             :    *
      91             :    *  @tparam  Tp  Type of element. Required to be a complete type.
      92             :    *  @tparam  Nm  Number of elements.
      93             :   */
      94             :   template<typename _Tp, std::size_t _Nm>
      95             :     struct array
      96             :     {
      97             :       typedef _Tp                                     value_type;
      98             :       typedef value_type*                             pointer;
      99             :       typedef const value_type*                       const_pointer;
     100             :       typedef value_type&                                 reference;
     101             :       typedef const value_type&                           const_reference;
     102             :       typedef value_type*                             iterator;
     103             :       typedef const value_type*                       const_iterator;
     104             :       typedef std::size_t                             size_type;
     105             :       typedef std::ptrdiff_t                          difference_type;
     106             :       typedef std::reverse_iterator<iterator>           reverse_iterator;
     107             :       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
     108             : 
     109             :       // Support for zero-sized arrays mandatory.
     110             :       typedef __array_traits<_Tp, _Nm> _AT_Type;
     111             :       typename _AT_Type::_Type                         _M_elems;
     112             : 
     113             :       // No explicit construct/copy/destroy for aggregate type.
     114             : 
     115             :       // DR 776.
     116             :       _GLIBCXX20_CONSTEXPR void
     117       58224 :       fill(const value_type& __u)
     118       58224 :       { std::fill_n(begin(), size(), __u); }
     119             : 
     120             :       _GLIBCXX20_CONSTEXPR void
     121             :       swap(array& __other)
     122             :       noexcept(_AT_Type::_Is_nothrow_swappable::value)
     123             :       { std::swap_ranges(begin(), end(), __other.begin()); }
     124             : 
     125             :       // Iterators.
     126             :       _GLIBCXX17_CONSTEXPR iterator
     127       64061 :       begin() noexcept
     128       64061 :       { return iterator(data()); }
     129             : 
     130             :       _GLIBCXX17_CONSTEXPR const_iterator
     131      237448 :       begin() const noexcept
     132      237448 :       { return const_iterator(data()); }
     133             : 
     134             :       _GLIBCXX17_CONSTEXPR iterator
     135        5668 :       end() noexcept
     136        5668 :       { return iterator(data() + _Nm); }
     137             : 
     138             :       _GLIBCXX17_CONSTEXPR const_iterator
     139      119659 :       end() const noexcept
     140      119659 :       { return const_iterator(data() + _Nm); }
     141             : 
     142             :       _GLIBCXX17_CONSTEXPR reverse_iterator
     143             :       rbegin() noexcept
     144             :       { return reverse_iterator(end()); }
     145             : 
     146             :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     147             :       rbegin() const noexcept
     148             :       { return const_reverse_iterator(end()); }
     149             : 
     150             :       _GLIBCXX17_CONSTEXPR reverse_iterator
     151             :       rend() noexcept
     152             :       { return reverse_iterator(begin()); }
     153             : 
     154             :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     155             :       rend() const noexcept
     156             :       { return const_reverse_iterator(begin()); }
     157             : 
     158             :       _GLIBCXX17_CONSTEXPR const_iterator
     159             :       cbegin() const noexcept
     160             :       { return const_iterator(data()); }
     161             : 
     162             :       _GLIBCXX17_CONSTEXPR const_iterator
     163             :       cend() const noexcept
     164             :       { return const_iterator(data() + _Nm); }
     165             : 
     166             :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     167             :       crbegin() const noexcept
     168             :       { return const_reverse_iterator(end()); }
     169             : 
     170             :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     171             :       crend() const noexcept
     172             :       { return const_reverse_iterator(begin()); }
     173             : 
     174             :       // Capacity.
     175             :       constexpr size_type
     176       65231 :       size() const noexcept { return _Nm; }
     177             : 
     178             :       constexpr size_type
     179             :       max_size() const noexcept { return _Nm; }
     180             : 
     181             :       _GLIBCXX_NODISCARD constexpr bool
     182             :       empty() const noexcept { return size() == 0; }
     183             : 
     184             :       // Element access.
     185             :       _GLIBCXX17_CONSTEXPR reference
     186     1126503 :       operator[](size_type __n) noexcept
     187             :       {
     188             :         __glibcxx_requires_subscript(__n);
     189     1126503 :         return _AT_Type::_S_ref(_M_elems, __n);
     190             :       }
     191             : 
     192             :       constexpr const_reference
     193    16391151 :       operator[](size_type __n) const noexcept
     194             :       {
     195             : #if __cplusplus >= 201402L
     196             :         __glibcxx_requires_subscript(__n);
     197             : #endif
     198    16391151 :         return _AT_Type::_S_ref(_M_elems, __n);
     199             :       }
     200             : 
     201             :       _GLIBCXX17_CONSTEXPR reference
     202             :       at(size_type __n)
     203             :       {
     204             :         if (__n >= _Nm)
     205             :           std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
     206             :                                             ">= _Nm (which is %zu)"),
     207             :                                         __n, _Nm);
     208             :         return _AT_Type::_S_ref(_M_elems, __n);
     209             :       }
     210             : 
     211             :       constexpr const_reference
     212             :       at(size_type __n) const
     213             :       {
     214             :         // Result of conditional expression must be an lvalue so use
     215             :         // boolean ? lvalue : (throw-expr, lvalue)
     216             :         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
     217             :           : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
     218             :                                                ">= _Nm (which is %zu)"),
     219             :                                            __n, _Nm),
     220             :              _AT_Type::_S_ref(_M_elems, 0));
     221             :       }
     222             : 
     223             :       _GLIBCXX17_CONSTEXPR reference
     224             :       front() noexcept
     225             :       {
     226             :         __glibcxx_requires_nonempty();
     227             :         return *begin();
     228             :       }
     229             : 
     230             :       constexpr const_reference
     231             :       front() const noexcept
     232             :       {
     233             : #if __cplusplus >= 201402L
     234             :         __glibcxx_requires_nonempty();
     235             : #endif
     236             :         return _AT_Type::_S_ref(_M_elems, 0);
     237             :       }
     238             : 
     239             :       _GLIBCXX17_CONSTEXPR reference
     240             :       back() noexcept
     241             :       {
     242             :         __glibcxx_requires_nonempty();
     243             :         return _Nm ? *(end() - 1) : *end();
     244             :       }
     245             : 
     246             :       constexpr const_reference
     247             :       back() const noexcept
     248             :       {
     249             : #if __cplusplus >= 201402L
     250             :         __glibcxx_requires_nonempty();
     251             : #endif
     252             :         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
     253             :                    : _AT_Type::_S_ref(_M_elems, 0);
     254             :       }
     255             : 
     256             :       _GLIBCXX17_CONSTEXPR pointer
     257     5460520 :       data() noexcept
     258     5460520 :       { return _AT_Type::_S_ptr(_M_elems); }
     259             : 
     260             :       _GLIBCXX17_CONSTEXPR const_pointer
     261     1020877 :       data() const noexcept
     262     1020877 :       { return _AT_Type::_S_ptr(_M_elems); }
     263             :     };
     264             : 
     265             : #if __cpp_deduction_guides >= 201606
     266             :   template<typename _Tp, typename... _Up>
     267             :     array(_Tp, _Up...)
     268             :       -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
     269             :                1 + sizeof...(_Up)>;
     270             : #endif
     271             : 
     272             :   // Array comparisons.
     273             :   template<typename _Tp, std::size_t _Nm>
     274             :     _GLIBCXX20_CONSTEXPR
     275             :     inline bool
     276      117810 :     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     277      117810 :     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
     278             : 
     279             : #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
     280             :   template<typename _Tp, size_t _Nm>
     281             :     constexpr __detail::__synth3way_t<_Tp>
     282             :     operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     283             :     {
     284             : #ifdef __cpp_lib_is_constant_evaluated
     285             :       if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
     286             :         if (!std::is_constant_evaluated())
     287             :           {
     288             :             constexpr size_t __n = _Nm * sizeof(_Tp);
     289             :             return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
     290             :           }
     291             : #endif
     292             : 
     293             :       for (size_t __i = 0; __i < _Nm; ++__i)
     294             :         {
     295             :           auto __c = __detail::__synth3way(__a[__i], __b[__i]);
     296             :           if (__c != 0)
     297             :             return __c;
     298             :         }
     299             :       return strong_ordering::equal;
     300             :     }
     301             : #else
     302             :   template<typename _Tp, std::size_t _Nm>
     303             :     _GLIBCXX20_CONSTEXPR
     304             :     inline bool
     305             :     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     306             :     { return !(__one == __two); }
     307             : 
     308             :   template<typename _Tp, std::size_t _Nm>
     309             :     _GLIBCXX20_CONSTEXPR
     310             :     inline bool
     311             :     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     312             :     {
     313             :       return std::lexicographical_compare(__a.begin(), __a.end(),
     314             :                                           __b.begin(), __b.end());
     315             :     }
     316             : 
     317             :   template<typename _Tp, std::size_t _Nm>
     318             :     _GLIBCXX20_CONSTEXPR
     319             :     inline bool
     320             :     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     321             :     { return __two < __one; }
     322             : 
     323             :   template<typename _Tp, std::size_t _Nm>
     324             :     _GLIBCXX20_CONSTEXPR
     325             :     inline bool
     326             :     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     327             :     { return !(__one > __two); }
     328             : 
     329             :   template<typename _Tp, std::size_t _Nm>
     330             :     _GLIBCXX20_CONSTEXPR
     331             :     inline bool
     332             :     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     333             :     { return !(__one < __two); }
     334             : #endif // three_way_comparison && concepts
     335             : 
     336             :   // Specialized algorithms.
     337             :   template<typename _Tp, std::size_t _Nm>
     338             :     _GLIBCXX20_CONSTEXPR
     339             :     inline
     340             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     341             :     // Constrained free swap overload, see p0185r1
     342             :     typename enable_if<
     343             :       __array_traits<_Tp, _Nm>::_Is_swappable::value
     344             :     >::type
     345             : #else
     346             :     void
     347             : #endif
     348             :     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
     349             :     noexcept(noexcept(__one.swap(__two)))
     350             :     { __one.swap(__two); }
     351             : 
     352             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     353             :   template<typename _Tp, std::size_t _Nm>
     354             :     typename enable_if<
     355             :       !__array_traits<_Tp, _Nm>::_Is_swappable::value>::type
     356             :     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
     357             : #endif
     358             : 
     359             :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     360             :     constexpr _Tp&
     361             :     get(array<_Tp, _Nm>& __arr) noexcept
     362             :     {
     363             :       static_assert(_Int < _Nm, "array index is within bounds");
     364             :       return __array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int);
     365             :     }
     366             : 
     367             :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     368             :     constexpr _Tp&&
     369             :     get(array<_Tp, _Nm>&& __arr) noexcept
     370             :     {
     371             :       static_assert(_Int < _Nm, "array index is within bounds");
     372             :       return std::move(std::get<_Int>(__arr));
     373             :     }
     374             : 
     375             :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     376             :     constexpr const _Tp&
     377             :     get(const array<_Tp, _Nm>& __arr) noexcept
     378             :     {
     379             :       static_assert(_Int < _Nm, "array index is within bounds");
     380             :       return __array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int);
     381             :     }
     382             : 
     383             :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     384             :     constexpr const _Tp&&
     385             :     get(const array<_Tp, _Nm>&& __arr) noexcept
     386             :     {
     387             :       static_assert(_Int < _Nm, "array index is within bounds");
     388             :       return std::move(std::get<_Int>(__arr));
     389             :     }
     390             : 
     391             : #if __cplusplus > 201703L
     392             : #define __cpp_lib_to_array 201907L
     393             : 
     394             :   template<bool _Move = false, typename _Tp, size_t... _Idx>
     395             :     constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)>
     396             :     __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>)
     397             :     {
     398             :       if constexpr (_Move)
     399             :         return {{std::move(__a[_Idx])...}};
     400             :       else
     401             :         return {{__a[_Idx]...}};
     402             :     }
     403             : 
     404             :   template<typename _Tp, size_t _Nm>
     405             :     constexpr array<remove_cv_t<_Tp>, _Nm>
     406             :     to_array(_Tp (&__a)[_Nm])
     407             :     noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
     408             :     {
     409             :       static_assert(!is_array_v<_Tp>);
     410             :       static_assert(is_constructible_v<_Tp, _Tp&>);
     411             :       if constexpr (is_constructible_v<_Tp, _Tp&>)
     412             :         return __to_array(__a, make_index_sequence<_Nm>{});
     413             :       __builtin_unreachable(); // FIXME: see PR c++/91388
     414             :     }
     415             : 
     416             :   template<typename _Tp, size_t _Nm>
     417             :     constexpr array<remove_cv_t<_Tp>, _Nm>
     418             :     to_array(_Tp (&&__a)[_Nm])
     419             :     noexcept(is_nothrow_move_constructible_v<_Tp>)
     420             :     {
     421             :       static_assert(!is_array_v<_Tp>);
     422             :       static_assert(is_move_constructible_v<_Tp>);
     423             :       if constexpr (is_move_constructible_v<_Tp>)
     424             :         return __to_array<1>(__a, make_index_sequence<_Nm>{});
     425             :       __builtin_unreachable(); // FIXME: see PR c++/91388
     426             :     }
     427             : #endif // C++20
     428             : 
     429             :   // Tuple interface to class template array.
     430             : 
     431             :   /// tuple_size
     432             :   template<typename _Tp>
     433             :     struct tuple_size;
     434             : 
     435             :   /// Partial specialization for std::array
     436             :   template<typename _Tp, std::size_t _Nm>
     437             :     struct tuple_size<array<_Tp, _Nm>>
     438             :     : public integral_constant<std::size_t, _Nm> { };
     439             : 
     440             :   /// tuple_element
     441             :   template<std::size_t _Int, typename _Tp>
     442             :     struct tuple_element;
     443             : 
     444             :   /// Partial specialization for std::array
     445             :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     446             :     struct tuple_element<_Int, array<_Tp, _Nm>>
     447             :     {
     448             :       static_assert(_Int < _Nm, "index is out of bounds");
     449             :       typedef _Tp type;
     450             :     };
     451             : 
     452             :   template<typename _Tp, std::size_t _Nm>
     453             :     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
     454             :     { };
     455             : 
     456             : _GLIBCXX_END_NAMESPACE_VERSION
     457             : } // namespace std
     458             : 
     459             : #endif // C++11
     460             : 
     461             : #endif // _GLIBCXX_ARRAY

Generated by: LCOV version 1.14