(root)/
gcc-13.2.0/
libstdc++-v3/
include/
bits/
range_access.h
       1  // Range access functions for containers -*- C++ -*-
       2  
       3  // Copyright (C) 2010-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 bits/range_access.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{iterator}
      28   */
      29  
      30  #ifndef _GLIBCXX_RANGE_ACCESS_H
      31  #define _GLIBCXX_RANGE_ACCESS_H 1
      32  
      33  #pragma GCC system_header
      34  
      35  #if __cplusplus >= 201103L
      36  #include <initializer_list>
      37  #include <type_traits>	    // common_type_t, make_signed_t
      38  #include <bits/stl_iterator.h> // reverse_iterator
      39  
      40  namespace std _GLIBCXX_VISIBILITY(default)
      41  {
      42  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      43  
      44    /**
      45     *  @brief  Return an iterator pointing to the first element of
      46     *          the container.
      47     *  @param  __cont  Container.
      48     */
      49    template<typename _Container>
      50      [[__nodiscard__, __gnu__::__always_inline__]]
      51      inline _GLIBCXX17_CONSTEXPR auto
      52      begin(_Container& __cont) -> decltype(__cont.begin())
      53      { return __cont.begin(); }
      54  
      55    /**
      56     *  @brief  Return an iterator pointing to the first element of
      57     *          the const container.
      58     *  @param  __cont  Container.
      59     */
      60    template<typename _Container>
      61      [[__nodiscard__, __gnu__::__always_inline__]]
      62      inline _GLIBCXX17_CONSTEXPR auto
      63      begin(const _Container& __cont) -> decltype(__cont.begin())
      64      { return __cont.begin(); }
      65  
      66    /**
      67     *  @brief  Return an iterator pointing to one past the last element of
      68     *          the container.
      69     *  @param  __cont  Container.
      70     */
      71    template<typename _Container>
      72      [[__nodiscard__, __gnu__::__always_inline__]]
      73      inline _GLIBCXX17_CONSTEXPR auto
      74      end(_Container& __cont) -> decltype(__cont.end())
      75      { return __cont.end(); }
      76  
      77    /**
      78     *  @brief  Return an iterator pointing to one past the last element of
      79     *          the const container.
      80     *  @param  __cont  Container.
      81     */
      82    template<typename _Container>
      83      [[__nodiscard__, __gnu__::__always_inline__]]
      84      inline _GLIBCXX17_CONSTEXPR auto
      85      end(const _Container& __cont) -> decltype(__cont.end())
      86      { return __cont.end(); }
      87  
      88    /**
      89     *  @brief  Return an iterator pointing to the first element of the array.
      90     *  @param  __arr  Array.
      91     */
      92    template<typename _Tp, size_t _Nm>
      93      [[__nodiscard__, __gnu__::__always_inline__]]
      94      inline _GLIBCXX14_CONSTEXPR _Tp*
      95      begin(_Tp (&__arr)[_Nm]) noexcept
      96      { return __arr; }
      97  
      98    /**
      99     *  @brief  Return an iterator pointing to one past the last element
     100     *          of the array.
     101     *  @param  __arr  Array.
     102     */
     103    template<typename _Tp, size_t _Nm>
     104      [[__nodiscard__, __gnu__::__always_inline__]]
     105      inline _GLIBCXX14_CONSTEXPR _Tp*
     106      end(_Tp (&__arr)[_Nm]) noexcept
     107      { return __arr + _Nm; }
     108  
     109  #if __cplusplus >= 201402L
     110  
     111    template<typename _Tp> class valarray;
     112    // These overloads must be declared for cbegin and cend to use them.
     113    template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
     114    template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
     115    template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept;
     116    template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
     117  
     118    /**
     119     *  @brief  Return an iterator pointing to the first element of
     120     *          the const container.
     121     *  @param  __cont  Container.
     122     */
     123    template<typename _Container>
     124      [[__nodiscard__, __gnu__::__always_inline__]]
     125      constexpr auto
     126      cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
     127        -> decltype(std::begin(__cont))
     128      { return std::begin(__cont); }
     129  
     130    /**
     131     *  @brief  Return an iterator pointing to one past the last element of
     132     *          the const container.
     133     *  @param  __cont  Container.
     134     */
     135    template<typename _Container>
     136      [[__nodiscard__, __gnu__::__always_inline__]]
     137      constexpr auto
     138      cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
     139        -> decltype(std::end(__cont))
     140      { return std::end(__cont); }
     141  
     142    /**
     143     *  @brief  Return a reverse iterator pointing to the last element of
     144     *          the container.
     145     *  @param  __cont  Container.
     146     */
     147    template<typename _Container>
     148      [[__nodiscard__, __gnu__::__always_inline__]]
     149      inline _GLIBCXX17_CONSTEXPR auto
     150      rbegin(_Container& __cont) -> decltype(__cont.rbegin())
     151      { return __cont.rbegin(); }
     152  
     153    /**
     154     *  @brief  Return a reverse iterator pointing to the last element of
     155     *          the const container.
     156     *  @param  __cont  Container.
     157     */
     158    template<typename _Container>
     159      [[__nodiscard__, __gnu__::__always_inline__]]
     160      inline _GLIBCXX17_CONSTEXPR auto
     161      rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
     162      { return __cont.rbegin(); }
     163  
     164    /**
     165     *  @brief  Return a reverse iterator pointing one past the first element of
     166     *          the container.
     167     *  @param  __cont  Container.
     168     */
     169    template<typename _Container>
     170      [[__nodiscard__, __gnu__::__always_inline__]]
     171      inline _GLIBCXX17_CONSTEXPR auto
     172      rend(_Container& __cont) -> decltype(__cont.rend())
     173      { return __cont.rend(); }
     174  
     175    /**
     176     *  @brief  Return a reverse iterator pointing one past the first element of
     177     *          the const container.
     178     *  @param  __cont  Container.
     179     */
     180    template<typename _Container>
     181      [[__nodiscard__, __gnu__::__always_inline__]]
     182      inline _GLIBCXX17_CONSTEXPR auto
     183      rend(const _Container& __cont) -> decltype(__cont.rend())
     184      { return __cont.rend(); }
     185  
     186    /**
     187     *  @brief  Return a reverse iterator pointing to the last element of
     188     *          the array.
     189     *  @param  __arr  Array.
     190     */
     191    template<typename _Tp, size_t _Nm>
     192      [[__nodiscard__]]
     193      inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
     194      rbegin(_Tp (&__arr)[_Nm]) noexcept
     195      { return reverse_iterator<_Tp*>(__arr + _Nm); }
     196  
     197    /**
     198     *  @brief  Return a reverse iterator pointing one past the first element of
     199     *          the array.
     200     *  @param  __arr  Array.
     201     */
     202    template<typename _Tp, size_t _Nm>
     203      [[__nodiscard__]]
     204      inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
     205      rend(_Tp (&__arr)[_Nm]) noexcept
     206      { return reverse_iterator<_Tp*>(__arr); }
     207  
     208    /**
     209     *  @brief  Return a reverse iterator pointing to the last element of
     210     *          the initializer_list.
     211     *  @param  __il  initializer_list.
     212     */
     213    template<typename _Tp>
     214      [[__nodiscard__]]
     215      inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
     216      rbegin(initializer_list<_Tp> __il) noexcept
     217      { return reverse_iterator<const _Tp*>(__il.end()); }
     218  
     219    /**
     220     *  @brief  Return a reverse iterator pointing one past the first element of
     221     *          the initializer_list.
     222     *  @param  __il  initializer_list.
     223     */
     224    template<typename _Tp>
     225      [[__nodiscard__]]
     226      inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
     227      rend(initializer_list<_Tp> __il) noexcept
     228      { return reverse_iterator<const _Tp*>(__il.begin()); }
     229  
     230    /**
     231     *  @brief  Return a reverse iterator pointing to the last element of
     232     *          the const container.
     233     *  @param  __cont  Container.
     234     */
     235    template<typename _Container>
     236      [[__nodiscard__, __gnu__::__always_inline__]]
     237      inline _GLIBCXX17_CONSTEXPR auto
     238      crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
     239      { return std::rbegin(__cont); }
     240  
     241    /**
     242     *  @brief  Return a reverse iterator pointing one past the first element of
     243     *          the const container.
     244     *  @param  __cont  Container.
     245     */
     246    template<typename _Container>
     247      [[__nodiscard__, __gnu__::__always_inline__]]
     248      inline _GLIBCXX17_CONSTEXPR auto
     249      crend(const _Container& __cont) -> decltype(std::rend(__cont))
     250      { return std::rend(__cont); }
     251  
     252  #endif // C++14
     253  
     254  #if __cplusplus >= 201703L
     255  #define __cpp_lib_nonmember_container_access 201411L
     256  
     257    /**
     258     *  @brief  Return the size of a container.
     259     *  @param  __cont  Container.
     260     */
     261    template <typename _Container>
     262      [[nodiscard, __gnu__::__always_inline__]]
     263      constexpr auto
     264      size(const _Container& __cont) noexcept(noexcept(__cont.size()))
     265      -> decltype(__cont.size())
     266      { return __cont.size(); }
     267  
     268    /**
     269     *  @brief  Return the size of an array.
     270     */
     271    template <typename _Tp, size_t _Nm>
     272      [[nodiscard, __gnu__::__always_inline__]]
     273      constexpr size_t
     274      size(const _Tp (&)[_Nm]) noexcept
     275      { return _Nm; }
     276  
     277    /**
     278     *  @brief  Return whether a container is empty.
     279     *  @param  __cont  Container.
     280     */
     281    template <typename _Container>
     282      [[nodiscard, __gnu__::__always_inline__]]
     283      constexpr auto
     284      empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
     285      -> decltype(__cont.empty())
     286      { return __cont.empty(); }
     287  
     288    /**
     289     *  @brief  Return whether an array is empty (always false).
     290     */
     291    template <typename _Tp, size_t _Nm>
     292      [[nodiscard, __gnu__::__always_inline__]]
     293      constexpr bool
     294      empty(const _Tp (&)[_Nm]) noexcept
     295      { return false; }
     296  
     297    /**
     298     *  @brief  Return whether an initializer_list is empty.
     299     *  @param  __il  Initializer list.
     300     */
     301    template <typename _Tp>
     302      [[nodiscard, __gnu__::__always_inline__]]
     303      constexpr bool
     304      empty(initializer_list<_Tp> __il) noexcept
     305      { return __il.size() == 0;}
     306  
     307    /**
     308     *  @brief  Return the data pointer of a container.
     309     *  @param  __cont  Container.
     310     */
     311    template <typename _Container>
     312      [[nodiscard, __gnu__::__always_inline__]]
     313      constexpr auto
     314      data(_Container& __cont) noexcept(noexcept(__cont.data()))
     315      -> decltype(__cont.data())
     316      { return __cont.data(); }
     317  
     318    /**
     319     *  @brief  Return the data pointer of a const container.
     320     *  @param  __cont  Container.
     321     */
     322    template <typename _Container>
     323      [[nodiscard, __gnu__::__always_inline__]]
     324      constexpr auto
     325      data(const _Container& __cont) noexcept(noexcept(__cont.data()))
     326      -> decltype(__cont.data())
     327      { return __cont.data(); }
     328  
     329    /**
     330     *  @brief  Return the data pointer of an array.
     331     *  @param  __array  Array.
     332     */
     333    template <typename _Tp, size_t _Nm>
     334      [[nodiscard, __gnu__::__always_inline__]]
     335      constexpr _Tp*
     336      data(_Tp (&__array)[_Nm]) noexcept
     337      { return __array; }
     338  
     339    /**
     340     *  @brief  Return the data pointer of an initializer list.
     341     *  @param  __il  Initializer list.
     342     */
     343    template <typename _Tp>
     344      [[nodiscard, __gnu__::__always_inline__]]
     345      constexpr const _Tp*
     346      data(initializer_list<_Tp> __il) noexcept
     347      { return __il.begin(); }
     348  
     349  #if __cplusplus > 201703L
     350  #define __cpp_lib_ssize 201902L
     351    template<typename _Container>
     352      [[nodiscard, __gnu__::__always_inline__]]
     353      constexpr auto
     354      ssize(const _Container& __cont)
     355      noexcept(noexcept(__cont.size()))
     356      -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
     357      {
     358        using type = make_signed_t<decltype(__cont.size())>;
     359        return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
     360      }
     361  
     362    template<typename _Tp, ptrdiff_t _Num>
     363      [[nodiscard, __gnu__::__always_inline__]]
     364      constexpr ptrdiff_t
     365      ssize(const _Tp (&)[_Num]) noexcept
     366      { return _Num; }
     367  #endif // C++20
     368  
     369  #endif // C++17
     370  _GLIBCXX_END_NAMESPACE_VERSION
     371  } // namespace
     372  
     373  #endif // C++11
     374  #endif // _GLIBCXX_RANGE_ACCESS_H