]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/std/span
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / span
index fb349403c9ee0297afd1e35a6d0eefc340c3c1c8..43e9cf82a546764d2c71517331137b2218955fad 100644 (file)
@@ -1,6 +1,6 @@
 // Components for manipulating non-owning sequences of objects -*- C++ -*-
 
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2019-2024 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 
 #pragma GCC system_header
 
-#if __cplusplus > 201703L
+#define __glibcxx_want_span
+#include <bits/version.h>
 
-#include <type_traits>
+#ifdef __cpp_lib_span // C++ >= 20 && concepts
 #include <array>
+#include <cstddef>
 #include <bits/stl_iterator.h>
 #include <bits/ranges_base.h>
-
-#if __cpp_lib_concepts
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#define __cpp_lib_span 202002L
-
   inline constexpr size_t dynamic_extent = static_cast<size_t>(-1);
 
   template<typename _Type, size_t _Extent>
@@ -58,21 +56,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   namespace __detail
   {
     template<typename _Tp>
-      struct __is_std_span : false_type { };
+      inline constexpr bool __is_span = false;
 
     template<typename _Tp, size_t _Num>
-      struct __is_std_span<span<_Tp, _Num>> : true_type { };
+      inline constexpr bool __is_span<span<_Tp, _Num>> = true;
 
     template<typename _Tp>
-      struct __is_std_array : false_type { };
+      inline constexpr bool __is_std_array = false;
 
     template<typename _Tp, size_t _Num>
-      struct __is_std_array<_GLIBCXX_STD_C::array<_Tp, _Num>> : true_type { };
-
-#ifdef _GLIBCXX_DEBUG
-    template<typename _Tp, size_t _Num>
-      struct __is_std_array<__debug::array<_Tp, _Num>> : true_type { };
-#endif
+      inline constexpr bool __is_std_array<std::array<_Tp, _Num>> = true;
 
     template<size_t _Extent>
       class __extent_storage
@@ -142,6 +135,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using const_reference        = const element_type&;
       using iterator = __gnu_cxx::__normal_iterator<pointer, span>;
       using reverse_iterator       = std::reverse_iterator<iterator>;
+#if __cplusplus > 202002L
+      using const_iterator         = std::const_iterator<iterator>;
+      using const_reverse_iterator = std::const_iterator<reverse_iterator>;
+#endif
 
       // member constants
       static constexpr size_t extent = _Extent;
@@ -150,8 +147,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       constexpr
       span() noexcept
-      requires ((_Extent + 1u) <= 1u)
-      : _M_extent(0), _M_ptr(nullptr)
+      requires (_Extent == dynamic_extent || _Extent == 0)
+      : _M_ptr(nullptr), _M_extent(0)
       { }
 
       template<contiguous_iterator _It>
@@ -159,12 +156,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        constexpr explicit(extent != dynamic_extent)
        span(_It __first, size_type __count)
        noexcept
-       : _M_extent(__count), _M_ptr(std::to_address(__first))
+       : _M_ptr(std::to_address(__first)), _M_extent(__count)
        {
          if constexpr (_Extent != dynamic_extent)
            {
              __glibcxx_assert(__count == _Extent);
            }
+         __glibcxx_requires_valid_range(__first, __first + __count);
        }
 
       template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
@@ -173,13 +171,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        constexpr explicit(extent != dynamic_extent)
        span(_It __first, _End __last)
        noexcept(noexcept(__last - __first))
-       : _M_extent(static_cast<size_type>(__last - __first)),
-         _M_ptr(std::to_address(__first))
+       : _M_ptr(std::to_address(__first)),
+         _M_extent(static_cast<size_type>(__last - __first))
        {
          if constexpr (_Extent != dynamic_extent)
            {
              __glibcxx_assert((__last - __first) == _Extent);
            }
+         __glibcxx_requires_valid_range(__first, __last);
        }
 
       template<size_t _ArrayExtent>
@@ -204,11 +203,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        { }
 
       template<typename _Range>
-       requires ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
-         && (ranges::borrowed_range<_Range> || is_const_v<element_type>)
-         && (!__detail::__is_std_span<remove_cvref_t<_Range>>::value)
-         && (!__detail::__is_std_array<remove_cvref_t<_Range>>::value)
+       requires (!__detail::__is_span<remove_cvref_t<_Range>>)
+         && (!__detail::__is_std_array<remove_cvref_t<_Range>>)
          && (!is_array_v<remove_cvref_t<_Range>>)
+         && ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
+         && (ranges::borrowed_range<_Range> || is_const_v<element_type>)
          && __is_compatible_ref<ranges::range_reference_t<_Range>>::value
        constexpr explicit(extent != dynamic_extent)
        span(_Range&& __range)
@@ -247,20 +246,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // observers
 
+      [[nodiscard]]
       constexpr size_type
       size() const noexcept
       { return this->_M_extent._M_extent(); }
 
+      [[nodiscard]]
       constexpr size_type
       size_bytes() const noexcept
       { return this->_M_extent._M_extent() * sizeof(element_type); }
 
-      [[nodiscard]] constexpr bool
+      [[nodiscard]]
+      constexpr bool
       empty() const noexcept
       { return size() == 0; }
 
       // element access
 
+      [[nodiscard]]
       constexpr reference
       front() const noexcept
       {
@@ -268,6 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return *this->_M_ptr;
       }
 
+      [[nodiscard]]
       constexpr reference
       back() const noexcept
       {
@@ -275,6 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return *(this->_M_ptr + (size() - 1));
       }
 
+      [[nodiscard]]
       constexpr reference
       operator[](size_type __idx) const noexcept
       {
@@ -282,31 +287,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return *(this->_M_ptr + __idx);
       }
 
+      [[nodiscard]]
+      constexpr reference
+      at(size_type __idx) const
+      {
+       if (__idx >= size())
+         __throw_out_of_range_fmt(__N("span::at(%zu) out-of-range for span "
+                                      "of size %zu"), __idx, this->size());
+       return *(this->_M_ptr + __idx);
+      }
+
+      [[nodiscard]]
       constexpr pointer
       data() const noexcept
       { return this->_M_ptr; }
 
       // iterator support
 
+      [[nodiscard]]
       constexpr iterator
       begin() const noexcept
       { return iterator(this->_M_ptr); }
 
+      [[nodiscard]]
       constexpr iterator
       end() const noexcept
       { return iterator(this->_M_ptr + this->size()); }
 
+      [[nodiscard]]
       constexpr reverse_iterator
       rbegin() const noexcept
       { return reverse_iterator(this->end()); }
 
+      [[nodiscard]]
       constexpr reverse_iterator
       rend() const noexcept
       { return reverse_iterator(this->begin()); }
 
+#if __cplusplus > 202002L
+      [[nodiscard]]
+      constexpr const_iterator
+      cbegin() const noexcept
+      { return begin(); }
+
+      [[nodiscard]]
+      constexpr const_iterator
+      cend() const noexcept
+      { return end(); }
+
+      [[nodiscard]]
+      constexpr const_reverse_iterator
+      crbegin() const noexcept
+      { return rbegin(); }
+
+      [[nodiscard]]
+      constexpr const_reverse_iterator
+      crend() const noexcept
+      { return rend(); }
+#endif
+
       // subviews
 
       template<size_t _Count>
+       [[nodiscard]]
        constexpr span<element_type, _Count>
        first() const noexcept
        {
@@ -318,6 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          return _Sp{ this->data(), _Count };
        }
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       first(size_type __count) const noexcept
       {
@@ -326,6 +370,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<size_t _Count>
+       [[nodiscard]]
        constexpr span<element_type, _Count>
        last() const noexcept
        {
@@ -337,6 +382,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          return _Sp{ this->data() + (this->size() - _Count), _Count };
        }
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       last(size_type __count) const noexcept
       {
@@ -345,6 +391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<size_t _Offset, size_t _Count = dynamic_extent>
+       [[nodiscard]]
        constexpr auto
        subspan() const noexcept
        -> span<element_type, _S_subspan_extent<_Offset, _Count>()>
@@ -376,6 +423,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            }
        }
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       subspan(size_type __offset, size_type __count = dynamic_extent) const
       noexcept
@@ -392,8 +440,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
     private:
-      [[no_unique_address]] __detail::__extent_storage<extent> _M_extent;
       pointer _M_ptr;
+      [[no_unique_address]] __detail::__extent_storage<extent> _M_extent;
     };
 
   // deduction guides
@@ -412,11 +460,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     span(_Iter, _End)
       -> span<remove_reference_t<iter_reference_t<_Iter>>>;
 
-  template<typename _Range>
+  template<ranges::contiguous_range _Range>
     span(_Range &&)
       -> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;
 
   template<typename _Type, size_t _Extent>
+    [[nodiscard]]
     inline
     span<const byte, _Extent == dynamic_extent
        ? dynamic_extent : _Extent * sizeof(_Type)>
@@ -430,10 +479,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   template<typename _Type, size_t _Extent>
+    requires (!is_const_v<_Type>)
     inline
     span<byte, _Extent == dynamic_extent
        ? dynamic_extent : _Extent * sizeof(_Type)>
-    as_writable_bytes(span<_Type, _Extent> __sp) noexcept
+    as_writable_bytes [[nodiscard]] (span<_Type, _Extent> __sp) noexcept
     {
       auto data = reinterpret_cast<byte*>(__sp.data());
       auto size = __sp.size_bytes();
@@ -452,11 +502,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Opt-in to view concept
     template<typename _ElementType, size_t _Extent>
       inline constexpr bool
-       enable_view<span<_ElementType, _Extent>>
-         = _Extent == 0 || _Extent == dynamic_extent;
+       enable_view<span<_ElementType, _Extent>> = true;
   }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif // concepts
-#endif // C++20
+#endif // __cpp_lib_span
 #endif // _GLIBCXX_SPAN