std::ranges::ssize(3)

NAME
std::ranges::ssize - std::ranges::ssize

Synopsis
   Defined in header <ranges>
   Defined in header <iterator>
   inline namespace /*unspecified*/ {
       inline constexpr /*unspecified*/ ssize = (since C++20)
   /*unspecified*/; (customization point object)
   }
   Call signature
   template< class T >
       requires /* see below */ (since C++20)
   constexpr /*signed-integer-like*/ ssize( T&& t );
   Returns the size of a range converted to a signed type.
   If ranges::size(t) is well-formed, a call to ranges::ssize is expression-equivalent
   to static_cast<MadeSigned>(ranges::size(t)), where MadeSigned denotes
     * the corresponding signed version of decltype(ranges::size(t)), if it is wider
       than std::ptrdiff_t, or
     * std::ptrdiff_t otherwise.
   If ranges::size(t) is ill-formed, a call to ranges::ssize is also ill-formed, which
   can result in substitution failure when ranges::ssize(t) appears in the immediate
   context of a template instantiation.

Notes
   If ranges::ssize(e) is valid for an expression e, the return type is a
   signed-integer-like type, i.e. an integer type for which std::is_signed_v is true,
   or a signed-integer-class type.
   The width of integer-like types can be detected by std::numeric_limits::digits.

Example
// Run this code
 #include <array>
 #include <iostream>
 #include <ranges>
 #include <type_traits>
 int main()
 {
     std::array arr{1, 2, 3, 4, 5};
     auto s = std::ranges::ssize(arr);
     std::cout << "ranges::ssize(arr) = " << s << '\n'
               << "ranges::ssize is "
               << (std::is_signed_v<decltype(s)> ? "signed" : "unsigned")
               << '\n';
     std::cout << "reversed arr: ";
     for (--s; s >= 0; --s)
         std::cout << arr[s] << ' ';
     std::cout << "\n" "s = " << s << '\n';
 }

Output:
 ranges::ssize(arr) = 5
 ranges::ssize is signed
 reversed arr: 5 4 3 2 1
 s = -1
   Defect reports
   The following behavior-changing defect reports were applied retroactively to
   previously published C++ standards.
      DR Applied to Behavior as published Correct behavior
   LWG 3403 C++20 ranges::size worked for some non-range types made work
                       but ranges::ssize didn't

See also
   ranges::size returns an integer equal to the size of a range
   (C++20) (customization point object)
   ranges::sized_range specifies that a range knows its size in constant time
   (C++20) (concept)
   ranges::distance returns the distance between an iterator and a sentinel, or
   (C++20) between the beginning and end of a range
                       (niebloid)
   size
   ssize returns the size of a container or array
   (C++17) (function template)
   (C++20)