libstdc++
range_access.h
Go to the documentation of this file.
00001 // <range_access.h> -*- C++ -*-
00002 
00003 // Copyright (C) 2010-2018 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/range_access.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{iterator}
00028  */
00029 
00030 #ifndef _GLIBCXX_RANGE_ACCESS_H
00031 #define _GLIBCXX_RANGE_ACCESS_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #if __cplusplus >= 201103L
00036 #include <initializer_list>
00037 namespace std _GLIBCXX_VISIBILITY(default)
00038 {
00039 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00040 
00041   /**
00042    *  @brief  Return an iterator pointing to the first element of
00043    *          the container.
00044    *  @param  __cont  Container.
00045    */
00046   template<typename _Container>
00047     inline _GLIBCXX17_CONSTEXPR auto
00048     begin(_Container& __cont) -> decltype(__cont.begin())
00049     { return __cont.begin(); }
00050 
00051   /**
00052    *  @brief  Return an iterator pointing to the first element of
00053    *          the const container.
00054    *  @param  __cont  Container.
00055    */
00056   template<typename _Container>
00057     inline _GLIBCXX17_CONSTEXPR auto
00058     begin(const _Container& __cont) -> decltype(__cont.begin())
00059     { return __cont.begin(); }
00060 
00061   /**
00062    *  @brief  Return an iterator pointing to one past the last element of
00063    *          the container.
00064    *  @param  __cont  Container.
00065    */
00066   template<typename _Container>
00067     inline _GLIBCXX17_CONSTEXPR auto
00068     end(_Container& __cont) -> decltype(__cont.end())
00069     { return __cont.end(); }
00070 
00071   /**
00072    *  @brief  Return an iterator pointing to one past the last element of
00073    *          the const container.
00074    *  @param  __cont  Container.
00075    */
00076   template<typename _Container>
00077     inline _GLIBCXX17_CONSTEXPR auto
00078     end(const _Container& __cont) -> decltype(__cont.end())
00079     { return __cont.end(); }
00080 
00081   /**
00082    *  @brief  Return an iterator pointing to the first element of the array.
00083    *  @param  __arr  Array.
00084    */
00085   template<typename _Tp, size_t _Nm>
00086     inline _GLIBCXX14_CONSTEXPR _Tp*
00087     begin(_Tp (&__arr)[_Nm])
00088     { return __arr; }
00089 
00090   /**
00091    *  @brief  Return an iterator pointing to one past the last element
00092    *          of the array.
00093    *  @param  __arr  Array.
00094    */
00095   template<typename _Tp, size_t _Nm>
00096     inline _GLIBCXX14_CONSTEXPR _Tp*
00097     end(_Tp (&__arr)[_Nm])
00098     { return __arr + _Nm; }
00099 
00100 #if __cplusplus >= 201402L
00101 
00102   template<typename _Tp> class valarray;
00103   // These overloads must be declared for cbegin and cend to use them.
00104   template<typename _Tp> _Tp* begin(valarray<_Tp>&);
00105   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
00106   template<typename _Tp> _Tp* end(valarray<_Tp>&);
00107   template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
00108 
00109   /**
00110    *  @brief  Return an iterator pointing to the first element of
00111    *          the const container.
00112    *  @param  __cont  Container.
00113    */
00114   template<typename _Container>
00115     inline constexpr auto
00116     cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
00117       -> decltype(std::begin(__cont))
00118     { return std::begin(__cont); }
00119 
00120   /**
00121    *  @brief  Return an iterator pointing to one past the last element of
00122    *          the const container.
00123    *  @param  __cont  Container.
00124    */
00125   template<typename _Container>
00126     inline constexpr auto
00127     cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
00128       -> decltype(std::end(__cont))
00129     { return std::end(__cont); }
00130 
00131   /**
00132    *  @brief  Return a reverse iterator pointing to the last element of
00133    *          the container.
00134    *  @param  __cont  Container.
00135    */
00136   template<typename _Container>
00137     inline _GLIBCXX17_CONSTEXPR auto
00138     rbegin(_Container& __cont) -> decltype(__cont.rbegin())
00139     { return __cont.rbegin(); }
00140 
00141   /**
00142    *  @brief  Return a reverse iterator pointing to the last element of
00143    *          the const container.
00144    *  @param  __cont  Container.
00145    */
00146   template<typename _Container>
00147     inline _GLIBCXX17_CONSTEXPR auto
00148     rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
00149     { return __cont.rbegin(); }
00150 
00151   /**
00152    *  @brief  Return a reverse iterator pointing one past the first element of
00153    *          the container.
00154    *  @param  __cont  Container.
00155    */
00156   template<typename _Container>
00157     inline _GLIBCXX17_CONSTEXPR auto
00158     rend(_Container& __cont) -> decltype(__cont.rend())
00159     { return __cont.rend(); }
00160 
00161   /**
00162    *  @brief  Return a reverse iterator pointing one past the first element of
00163    *          the const container.
00164    *  @param  __cont  Container.
00165    */
00166   template<typename _Container>
00167     inline _GLIBCXX17_CONSTEXPR auto
00168     rend(const _Container& __cont) -> decltype(__cont.rend())
00169     { return __cont.rend(); }
00170 
00171   /**
00172    *  @brief  Return a reverse iterator pointing to the last element of
00173    *          the array.
00174    *  @param  __arr  Array.
00175    */
00176   template<typename _Tp, size_t _Nm>
00177     inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
00178     rbegin(_Tp (&__arr)[_Nm])
00179     { return reverse_iterator<_Tp*>(__arr + _Nm); }
00180 
00181   /**
00182    *  @brief  Return a reverse iterator pointing one past the first element of
00183    *          the array.
00184    *  @param  __arr  Array.
00185    */
00186   template<typename _Tp, size_t _Nm>
00187     inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
00188     rend(_Tp (&__arr)[_Nm])
00189     { return reverse_iterator<_Tp*>(__arr); }
00190 
00191   /**
00192    *  @brief  Return a reverse iterator pointing to the last element of
00193    *          the initializer_list.
00194    *  @param  __il  initializer_list.
00195    */
00196   template<typename _Tp>
00197     inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
00198     rbegin(initializer_list<_Tp> __il)
00199     { return reverse_iterator<const _Tp*>(__il.end()); }
00200 
00201   /**
00202    *  @brief  Return a reverse iterator pointing one past the first element of
00203    *          the initializer_list.
00204    *  @param  __il  initializer_list.
00205    */
00206   template<typename _Tp>
00207     inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
00208     rend(initializer_list<_Tp> __il)
00209     { return reverse_iterator<const _Tp*>(__il.begin()); }
00210 
00211   /**
00212    *  @brief  Return a reverse iterator pointing to the last element of
00213    *          the const container.
00214    *  @param  __cont  Container.
00215    */
00216   template<typename _Container>
00217     inline _GLIBCXX17_CONSTEXPR auto
00218     crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
00219     { return std::rbegin(__cont); }
00220 
00221   /**
00222    *  @brief  Return a reverse iterator pointing one past the first element of
00223    *          the const container.
00224    *  @param  __cont  Container.
00225    */
00226   template<typename _Container>
00227     inline _GLIBCXX17_CONSTEXPR auto
00228     crend(const _Container& __cont) -> decltype(std::rend(__cont))
00229     { return std::rend(__cont); }
00230 
00231 #endif // C++14
00232 
00233 #if __cplusplus >= 201703L
00234 #define __cpp_lib_nonmember_container_access 201411
00235 
00236   /**
00237    *  @brief  Return the size of a container.
00238    *  @param  __cont  Container.
00239    */
00240   template <typename _Container>
00241     constexpr auto
00242     size(const _Container& __cont) noexcept(noexcept(__cont.size()))
00243     -> decltype(__cont.size())
00244     { return __cont.size(); }
00245 
00246   /**
00247    *  @brief  Return the size of an array.
00248    *  @param  __array  Array.
00249    */
00250   template <typename _Tp, size_t _Nm>
00251     constexpr size_t
00252     size(const _Tp (&/*__array*/)[_Nm]) noexcept
00253     { return _Nm; }
00254 
00255   /**
00256    *  @brief  Return whether a container is empty.
00257    *  @param  __cont  Container.
00258    */
00259   template <typename _Container>
00260     [[nodiscard]] constexpr auto
00261     empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
00262     -> decltype(__cont.empty())
00263     { return __cont.empty(); }
00264 
00265   /**
00266    *  @brief  Return whether an array is empty (always false).
00267    *  @param  __array  Container.
00268    */
00269   template <typename _Tp, size_t _Nm>
00270     [[nodiscard]] constexpr bool
00271     empty(const _Tp (&/*__array*/)[_Nm]) noexcept
00272     { return false; }
00273 
00274   /**
00275    *  @brief  Return whether an initializer_list is empty.
00276    *  @param  __il  Initializer list.
00277    */
00278   template <typename _Tp>
00279     [[nodiscard]] constexpr bool
00280     empty(initializer_list<_Tp> __il) noexcept
00281     { return __il.size() == 0;}
00282 
00283   /**
00284    *  @brief  Return the data pointer of a container.
00285    *  @param  __cont  Container.
00286    */
00287   template <typename _Container>
00288     constexpr auto
00289     data(_Container& __cont) noexcept(noexcept(__cont.data()))
00290     -> decltype(__cont.data())
00291     { return __cont.data(); }
00292 
00293   /**
00294    *  @brief  Return the data pointer of a const container.
00295    *  @param  __cont  Container.
00296    */
00297   template <typename _Container>
00298     constexpr auto
00299     data(const _Container& __cont) noexcept(noexcept(__cont.data()))
00300     -> decltype(__cont.data())
00301     { return __cont.data(); }
00302 
00303   /**
00304    *  @brief  Return the data pointer of an array.
00305    *  @param  __array  Array.
00306    */
00307   template <typename _Tp, size_t _Nm>
00308     constexpr _Tp*
00309     data(_Tp (&__array)[_Nm]) noexcept
00310     { return __array; }
00311 
00312   /**
00313    *  @brief  Return the data pointer of an initializer list.
00314    *  @param  __il  Initializer list.
00315    */
00316   template <typename _Tp>
00317     constexpr const _Tp*
00318     data(initializer_list<_Tp> __il) noexcept
00319     { return __il.begin(); }
00320 
00321 #endif // C++17
00322 
00323 _GLIBCXX_END_NAMESPACE_VERSION
00324 } // namespace
00325 
00326 #endif // C++11
00327 
00328 #endif // _GLIBCXX_RANGE_ACCESS_H