LCOV - code coverage report
Current view: top level - /usr/include/c++/13 - array (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 8 8
Test Date: 2024-04-30 13:17:26 Functions: 66.7 % 6 4

            Line data    Source code
       1              : // <array> -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2007-2023 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 <compare>
      39              : #include <initializer_list>
      40              : 
      41              : #include <type_traits>
      42              : #include <bits/functexcept.h>
      43              : #include <bits/stl_algobase.h>
      44              : #include <bits/range_access.h> // std::begin, std::end etc.
      45              : #include <bits/utility.h>      // std::index_sequence, std::tuple_size
      46              : #include <debug/assertions.h>
      47              : 
      48              : namespace std _GLIBCXX_VISIBILITY(default)
      49              : {
      50              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      51              : 
      52              :   template<typename _Tp, size_t _Nm>
      53              :     struct __array_traits
      54              :     {
      55              :       using _Type = _Tp[_Nm];
      56              :       using _Is_swappable = __is_swappable<_Tp>;
      57              :       using _Is_nothrow_swappable = __is_nothrow_swappable<_Tp>;
      58              :     };
      59              : 
      60              :  template<typename _Tp>
      61              :    struct __array_traits<_Tp, 0>
      62              :    {
      63              :      // Empty type used instead of _Tp[0] for std::array<_Tp, 0>.
      64              :      struct _Type
      65              :      {
      66              :        // Indexing is undefined.
      67              :        __attribute__((__always_inline__,__noreturn__))
      68              :        _Tp& operator[](size_t) const noexcept { __builtin_trap(); }
      69              : 
      70              :        // Conversion to a pointer produces a null pointer.
      71              :        __attribute__((__always_inline__))
      72              :        constexpr explicit operator _Tp*() const noexcept { return nullptr; }
      73              :      };
      74              : 
      75              :      using _Is_swappable = true_type;
      76              :      using _Is_nothrow_swappable = true_type;
      77              :    };
      78              : 
      79              :   /**
      80              :    *  @brief A standard container for storing a fixed size sequence of elements.
      81              :    *
      82              :    *  @ingroup sequences
      83              :    *
      84              :    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
      85              :    *  <a href="tables.html#66">reversible container</a>, and a
      86              :    *  <a href="tables.html#67">sequence</a>.
      87              :    *
      88              :    *  Sets support random access iterators.
      89              :    *
      90              :    *  @tparam  Tp  Type of element. Required to be a complete type.
      91              :    *  @tparam  Nm  Number of elements.
      92              :   */
      93              :   template<typename _Tp, std::size_t _Nm>
      94              :     struct array
      95              :     {
      96              :       typedef _Tp                                     value_type;
      97              :       typedef value_type*                             pointer;
      98              :       typedef const value_type*                       const_pointer;
      99              :       typedef value_type&                                 reference;
     100              :       typedef const value_type&                           const_reference;
     101              :       typedef value_type*                             iterator;
     102              :       typedef const value_type*                       const_iterator;
     103              :       typedef std::size_t                             size_type;
     104              :       typedef std::ptrdiff_t                          difference_type;
     105              :       typedef std::reverse_iterator<iterator>           reverse_iterator;
     106              :       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
     107              : 
     108              :       // Support for zero-sized arrays mandatory.
     109              :       typename __array_traits<_Tp, _Nm>::_Type        _M_elems;
     110              : 
     111              :       // No explicit construct/copy/destroy for aggregate type.
     112              : 
     113              :       // DR 776.
     114              :       _GLIBCXX20_CONSTEXPR void
     115              :       fill(const value_type& __u)
     116              :       { std::fill_n(begin(), size(), __u); }
     117              : 
     118              :       _GLIBCXX20_CONSTEXPR void
     119              :       swap(array& __other)
     120              :       noexcept(__array_traits<_Tp, _Nm>::_Is_nothrow_swappable::value)
     121              :       { std::swap_ranges(begin(), end(), __other.begin()); }
     122              : 
     123              :       // Iterators.
     124              :       [[__gnu__::__const__, __nodiscard__]]
     125              :       _GLIBCXX17_CONSTEXPR iterator
     126            2 :       begin() noexcept
     127            2 :       { return iterator(data()); }
     128              : 
     129              :       [[__nodiscard__]]
     130              :       _GLIBCXX17_CONSTEXPR const_iterator
     131              :       begin() const noexcept
     132              :       { return const_iterator(data()); }
     133              : 
     134              :       [[__gnu__::__const__, __nodiscard__]]
     135              :       _GLIBCXX17_CONSTEXPR iterator
     136              :       end() noexcept
     137              :       { return iterator(data() + _Nm); }
     138              : 
     139              :       [[__nodiscard__]]
     140              :       _GLIBCXX17_CONSTEXPR const_iterator
     141              :       end() const noexcept
     142              :       { return const_iterator(data() + _Nm); }
     143              : 
     144              :       [[__gnu__::__const__, __nodiscard__]]
     145              :       _GLIBCXX17_CONSTEXPR reverse_iterator
     146              :       rbegin() noexcept
     147              :       { return reverse_iterator(end()); }
     148              : 
     149              :       [[__nodiscard__]]
     150              :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     151              :       rbegin() const noexcept
     152              :       { return const_reverse_iterator(end()); }
     153              : 
     154              :       [[__gnu__::__const__, __nodiscard__]]
     155              :       _GLIBCXX17_CONSTEXPR reverse_iterator
     156              :       rend() noexcept
     157              :       { return reverse_iterator(begin()); }
     158              : 
     159              :       [[__nodiscard__]]
     160              :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     161              :       rend() const noexcept
     162              :       { return const_reverse_iterator(begin()); }
     163              : 
     164              :       [[__nodiscard__]]
     165              :       _GLIBCXX17_CONSTEXPR const_iterator
     166              :       cbegin() const noexcept
     167              :       { return const_iterator(data()); }
     168              : 
     169              :       [[__nodiscard__]]
     170              :       _GLIBCXX17_CONSTEXPR const_iterator
     171              :       cend() const noexcept
     172              :       { return const_iterator(data() + _Nm); }
     173              : 
     174              :       [[__nodiscard__]]
     175              :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     176              :       crbegin() const noexcept
     177              :       { return const_reverse_iterator(end()); }
     178              : 
     179              :       [[__nodiscard__]]
     180              :       _GLIBCXX17_CONSTEXPR const_reverse_iterator
     181              :       crend() const noexcept
     182              :       { return const_reverse_iterator(begin()); }
     183              : 
     184              :       // Capacity.
     185              :       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
     186              :       constexpr size_type
     187         1098 :       size() const noexcept { return _Nm; }
     188              : 
     189              :       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
     190              :       constexpr size_type
     191              :       max_size() const noexcept { return _Nm; }
     192              : 
     193              :       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
     194              :       constexpr bool
     195              :       empty() const noexcept { return size() == 0; }
     196              : 
     197              :       // Element access.
     198              :       [[__nodiscard__]]
     199              :       _GLIBCXX17_CONSTEXPR reference
     200          360 :       operator[](size_type __n) noexcept
     201              :       {
     202              :         __glibcxx_requires_subscript(__n);
     203          360 :         return _M_elems[__n];
     204              :       }
     205              : 
     206              :       [[__nodiscard__]]
     207              :       constexpr const_reference
     208          728 :       operator[](size_type __n) const noexcept
     209              :       {
     210              : #if __cplusplus >= 201402L
     211              :         __glibcxx_requires_subscript(__n);
     212              : #endif
     213          728 :         return _M_elems[__n];
     214              :       }
     215              : 
     216              :       _GLIBCXX17_CONSTEXPR reference
     217              :       at(size_type __n)
     218              :       {
     219              :         if (__n >= _Nm)
     220              :           std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
     221              :                                             ">= _Nm (which is %zu)"),
     222              :                                         __n, _Nm);
     223              :         return _M_elems[__n];
     224              :       }
     225              : 
     226              :       constexpr const_reference
     227              :       at(size_type __n) const
     228              :       {
     229              :         // Result of conditional expression must be an lvalue so use
     230              :         // boolean ? lvalue : (throw-expr, lvalue)
     231              :         return __n < _Nm ? _M_elems[__n]
     232              :           : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
     233              :                                                ">= _Nm (which is %zu)"),
     234              :                                            __n, _Nm),
     235              :              _M_elems[__n]);
     236              :       }
     237              : 
     238              :       [[__nodiscard__]]
     239              :       _GLIBCXX17_CONSTEXPR reference
     240              :       front() noexcept
     241              :       {
     242              :         __glibcxx_requires_nonempty();
     243              :         return _M_elems[(size_type)0];
     244              :       }
     245              : 
     246              :       [[__nodiscard__]]
     247              :       constexpr const_reference
     248              :       front() const noexcept
     249              :       {
     250              : #if __cplusplus >= 201402L
     251              :         __glibcxx_requires_nonempty();
     252              : #endif
     253              :         return _M_elems[(size_type)0];
     254              :       }
     255              : 
     256              :       [[__nodiscard__]]
     257              :       _GLIBCXX17_CONSTEXPR reference
     258              :       back() noexcept
     259              :       {
     260              :         __glibcxx_requires_nonempty();
     261              :         return _M_elems[_Nm - 1];
     262              :       }
     263              : 
     264              :       [[__nodiscard__]]
     265              :       constexpr const_reference
     266              :       back() const noexcept
     267              :       {
     268              : #if __cplusplus >= 201402L
     269              :         __glibcxx_requires_nonempty();
     270              : #endif
     271              :         return _M_elems[_Nm - 1];
     272              :       }
     273              : 
     274              :       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
     275              :       _GLIBCXX17_CONSTEXPR pointer
     276              :       data() noexcept
     277           56 :       { return static_cast<pointer>(_M_elems); }
     278              : 
     279              :       [[__nodiscard__]]
     280              :       _GLIBCXX17_CONSTEXPR const_pointer
     281              :       data() const noexcept
     282              :       { return static_cast<const_pointer>(_M_elems); }
     283              :     };
     284              : 
     285              : #if __cpp_deduction_guides >= 201606
     286              :   template<typename _Tp, typename... _Up>
     287              :     array(_Tp, _Up...)
     288              :       -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
     289              :                1 + sizeof...(_Up)>;
     290              : #endif
     291              : 
     292              :   // Array comparisons.
     293              :   template<typename _Tp, std::size_t _Nm>
     294              :     [[__nodiscard__]]
     295              :     _GLIBCXX20_CONSTEXPR
     296              :     inline bool
     297              :     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     298              :     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
     299              : 
     300              : #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
     301              :   template<typename _Tp, size_t _Nm>
     302              :     [[nodiscard]]
     303              :     constexpr __detail::__synth3way_t<_Tp>
     304              :     operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     305              :     {
     306              :       if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
     307              :         if (!std::__is_constant_evaluated())
     308              :           {
     309              :             constexpr size_t __n = _Nm * sizeof(_Tp);
     310              :             return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
     311              :           }
     312              : 
     313              :       for (size_t __i = 0; __i < _Nm; ++__i)
     314              :         {
     315              :           auto __c = __detail::__synth3way(__a[__i], __b[__i]);
     316              :           if (__c != 0)
     317              :             return __c;
     318              :         }
     319              :       return strong_ordering::equal;
     320              :     }
     321              : #else
     322              :   template<typename _Tp, std::size_t _Nm>
     323              :     [[__nodiscard__]]
     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              :     [[__nodiscard__]]
     331              :     _GLIBCXX20_CONSTEXPR
     332              :     inline bool
     333              :     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     334              :     {
     335              :       return std::lexicographical_compare(__a.begin(), __a.end(),
     336              :                                           __b.begin(), __b.end());
     337              :     }
     338              : 
     339              :   template<typename _Tp, std::size_t _Nm>
     340              :     [[__nodiscard__]]
     341              :     _GLIBCXX20_CONSTEXPR
     342              :     inline bool
     343              :     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     344              :     { return __two < __one; }
     345              : 
     346              :   template<typename _Tp, std::size_t _Nm>
     347              :     [[__nodiscard__]]
     348              :     _GLIBCXX20_CONSTEXPR
     349              :     inline bool
     350              :     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     351              :     { return !(__one > __two); }
     352              : 
     353              :   template<typename _Tp, std::size_t _Nm>
     354              :     [[__nodiscard__]]
     355              :     _GLIBCXX20_CONSTEXPR
     356              :     inline bool
     357              :     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
     358              :     { return !(__one < __two); }
     359              : #endif // three_way_comparison && concepts
     360              : 
     361              :   // Specialized algorithms.
     362              :   template<typename _Tp, std::size_t _Nm>
     363              :     _GLIBCXX20_CONSTEXPR
     364              :     inline
     365              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     366              :     // Constrained free swap overload, see p0185r1
     367              :     __enable_if_t<__array_traits<_Tp, _Nm>::_Is_swappable::value>
     368              : #else
     369              :     void
     370              : #endif
     371              :     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
     372              :     noexcept(noexcept(__one.swap(__two)))
     373              :     { __one.swap(__two); }
     374              : 
     375              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     376              :   template<typename _Tp, std::size_t _Nm>
     377              :     __enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value>
     378              :     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
     379              : #endif
     380              : 
     381              :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     382              :     [[__nodiscard__]]
     383              :     constexpr _Tp&
     384              :     get(array<_Tp, _Nm>& __arr) noexcept
     385              :     {
     386              :       static_assert(_Int < _Nm, "array index is within bounds");
     387              :       return __arr._M_elems[_Int];
     388              :     }
     389              : 
     390              :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     391              :     [[__nodiscard__]]
     392              :     constexpr _Tp&&
     393              :     get(array<_Tp, _Nm>&& __arr) noexcept
     394              :     {
     395              :       static_assert(_Int < _Nm, "array index is within bounds");
     396              :       return std::move(std::get<_Int>(__arr));
     397              :     }
     398              : 
     399              :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     400              :     [[__nodiscard__]]
     401              :     constexpr const _Tp&
     402              :     get(const array<_Tp, _Nm>& __arr) noexcept
     403              :     {
     404              :       static_assert(_Int < _Nm, "array index is within bounds");
     405              :       return __arr._M_elems[_Int];
     406              :     }
     407              : 
     408              :   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     409              :     [[__nodiscard__]]
     410              :     constexpr const _Tp&&
     411              :     get(const array<_Tp, _Nm>&& __arr) noexcept
     412              :     {
     413              :       static_assert(_Int < _Nm, "array index is within bounds");
     414              :       return std::move(std::get<_Int>(__arr));
     415              :     }
     416              : 
     417              : #if __cplusplus >= 202002L && __cpp_generic_lambdas >= 201707L
     418              : #define __cpp_lib_to_array 201907L
     419              :   template<typename _Tp, size_t _Nm>
     420              :     [[nodiscard]]
     421              :     constexpr array<remove_cv_t<_Tp>, _Nm>
     422              :     to_array(_Tp (&__a)[_Nm])
     423              :     noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
     424              :     {
     425              :       static_assert(!is_array_v<_Tp>);
     426              :       static_assert(is_constructible_v<_Tp, _Tp&>);
     427              :       if constexpr (is_constructible_v<_Tp, _Tp&>)
     428              :         {
     429              :           if constexpr (is_trivial_v<_Tp>)
     430              :             {
     431              :               array<remove_cv_t<_Tp>, _Nm> __arr;
     432              :               if (!__is_constant_evaluated() && _Nm != 0)
     433              :                 __builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
     434              :               else
     435              :                 for (size_t __i = 0; __i < _Nm; ++__i)
     436              :                   __arr._M_elems[__i] = __a[__i];
     437              :               return __arr;
     438              :             }
     439              :           else
     440              :             return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
     441              :               return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }};
     442              :             }(make_index_sequence<_Nm>{});
     443              :         }
     444              :       else
     445              :         __builtin_unreachable(); // FIXME: see PR c++/91388
     446              :     }
     447              : 
     448              :   template<typename _Tp, size_t _Nm>
     449              :     [[nodiscard]]
     450              :     constexpr array<remove_cv_t<_Tp>, _Nm>
     451              :     to_array(_Tp (&&__a)[_Nm])
     452              :     noexcept(is_nothrow_move_constructible_v<_Tp>)
     453              :     {
     454              :       static_assert(!is_array_v<_Tp>);
     455              :       static_assert(is_move_constructible_v<_Tp>);
     456              :       if constexpr (is_move_constructible_v<_Tp>)
     457              :         {
     458              :           if constexpr (is_trivial_v<_Tp>)
     459              :             {
     460              :               array<remove_cv_t<_Tp>, _Nm> __arr;
     461              :               if (!__is_constant_evaluated() && _Nm != 0)
     462              :                 __builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
     463              :               else
     464              :                 for (size_t __i = 0; __i < _Nm; ++__i)
     465              :                   __arr._M_elems[__i] = __a[__i];
     466              :               return __arr;
     467              :             }
     468              :           else
     469              :             return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
     470              :               return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }};
     471              :             }(make_index_sequence<_Nm>{});
     472              :         }
     473              :       else
     474              :         __builtin_unreachable(); // FIXME: see PR c++/91388
     475              :     }
     476              : #endif // C++20
     477              : 
     478              :   // Tuple interface to class template array.
     479              : 
     480              :   /// Partial specialization for std::array
     481              :   template<typename _Tp, size_t _Nm>
     482              :     struct tuple_size<array<_Tp, _Nm>>
     483              :     : public integral_constant<size_t, _Nm> { };
     484              : 
     485              :   /// Partial specialization for std::array
     486              :   template<size_t _Ind, typename _Tp, size_t _Nm>
     487              :     struct tuple_element<_Ind, array<_Tp, _Nm>>
     488              :     {
     489              :       static_assert(_Ind < _Nm, "array index is in range");
     490              :       using type = _Tp;
     491              :     };
     492              : 
     493              : #if __cplusplus >= 201703L
     494              :   template<typename _Tp, size_t _Nm>
     495              :     inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;
     496              : 
     497              :   template<typename _Tp, size_t _Nm>
     498              :     inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
     499              : #endif
     500              : 
     501              :   template<typename _Tp, size_t _Nm>
     502              :     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
     503              :     { };
     504              : 
     505              : _GLIBCXX_END_NAMESPACE_VERSION
     506              : } // namespace std
     507              : 
     508              : #endif // C++11
     509              : 
     510              : #endif // _GLIBCXX_ARRAY
        

Generated by: LCOV version 2.0-1