std::ranges...ewable_range(3)

πŸ“¦
version 2024.07.05 Β· 3 versions
, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

okay bestie, welcome to the C++ Standard Libary manual page for std::ranges...ewable_range(3) ✨ the whole thing is about std::ranges::viewable_range, and yes the name says it twice, it's giving echo chamber but make it C++ πŸ’…

std::ranges::viewable_range β€” std::ranges::viewable_range

✨ Synopsis ✨

here's the synopsis, copied with love and zero drift, because details are sacred πŸ”₯

          Defined in header <ranges>
          template< class T >

          concept viewable_range =
              ranges::range<T> &&
              ((ranges::view<std::remove_cvref_t<T>> &&
                std::constructible_from<std::remove_cvref_t<T>, T>) ||
       (since C++20)
               (!ranges::view<std::remove_cvref_t<T>> &&
                (std::is_lvalue_reference_v<T> ||

                 (std::movable<std::remove_reference_t<T>> &&
          !/*is-initializer-list*/<T>))));

so the viewable_range concept is a refinement of range β€” it describes a range that can be converted into a view through views::all πŸ’«

and the constant /*is-initializer-list*/<T> is true if and only if std::remove_cvref_t<T> is a specialization of std::initializer_list πŸŽ€

🌸 Example 🌸

the original literally says // Run this code, so run it, bestie:

        #include <ranges>
        #include <string>
        #include <vector>

        struct valid_result {};
        struct invalid_result {};

        template <typename T>
        concept valid_viewable_range = std::same_as<T, valid_result>;

        template <typename T>
        concept invalid_viewable_range = std::same_as<T, invalid_result>;

        auto test_viewable_range(std::ranges::viewable_range auto &&) ->
       valid_result;
        auto test_viewable_range(auto&&) -> invalid_result;

        int main()
        {
            auto il = {1, 2, 3};
            int arr []{1, 2, 3};
            std::vector vec{1, 2, 3};
            std::ranges::ref_view r{arr};
            std::ranges::owning_view o{std::string("Hello")};

            static_assert(requires {
                { test_viewable_range(il) } -> valid_viewable_range;
                { test_viewable_range(std::move(il)) } ->
       invalid_viewable_range;
                { test_viewable_range(arr) } -> valid_viewable_range;
                { test_viewable_range(std::move(arr)) } ->
       invalid_viewable_range;
                { test_viewable_range(vec) } -> valid_viewable_range;
                { test_viewable_range(std::move(vec)) } ->
       valid_viewable_range;
                { test_viewable_range(r) } -> valid_viewable_range;
                { test_viewable_range(std::move(r)) } -> valid_viewable_range;
                { test_viewable_range(o) } -> invalid_viewable_range;
                { test_viewable_range(std::move(o)) } -> valid_viewable_range;
                { test_viewable_range(std::ranges::ref_view(o)) } ->
       valid_viewable_range;
            });
        }

🩹 Defect reports 🩹

these behavior-changing defect reports were applied retroactively to previously published C++ standards β€” the committee said "actually, let's edit" 😭

  • LWG 3481, applied to C++20 β€” behavior as published: viewable_range accepted an lvalue of a move-only view. Correct behavior: rejects.
  • P2415R2, applied to C++20 β€” behavior as published: viewable_range only accepted non-view rvalues that are borrowed_range. Correct behavior: accepts more types.

πŸ‘€ See also πŸ‘€

  • views::all_t β€” a view that includes all elements of a range.
  • views::all β€” (alias template) (range adaptor object) (C++20).

okay that's the whole page, bestie 🫢 source/version/date sign-off: http://cppreference.com Β· 2024.06.10 Β· page std::ranges...ewable_range(3) β€” mwah, go write some ranges πŸ’–

πŸ“¦ where this page comes from