std::ranges::ssize(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… NAME

std::ranges::ssize β€” yes bestie, the page is literally named std::ranges::ssize, straight from the C++ Standard Libary. It’s giving signed-size customization-point-object energy, and we are obsessed. πŸ’–βœ¨

✨ 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 );

πŸ“ž 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. slay. πŸ’…

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. no cap, that part matters. 😭

🫢 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. iykyk ✨

πŸŽ€ Example

The original says // Run this code, so go off bestie:

#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: LWG 3403 β€” applied to C++20; behavior as published: ranges::size worked for some non-range types but ranges::ssize didn’t; correct behavior: made work. periodt. πŸ’€

πŸ‘€ See also

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

Source: http://cppreference.com Β· version/date: 2024.06.10 Β· std::ranges::ssize(3) β€” bye bestie, go get that signed size πŸ’…πŸ«Ά

πŸ“¦ where this page comes from