c++20: Opt-in to modeling view and borrowed_range for Span #23226

pull theuni wants to merge 1 commits into bitcoin:master from theuni:borrowed-span changing 1 files +16 −0
  1. theuni commented at 0:16 am on October 8, 2021: member

    This is a c++20 feature, so it’s obviously not a rush to get in, but it may be useful while we play around with ranges in the codebase before actually switching to c++20.

    This matches the behavior of std::span.

    The below sample program demonstrates what these enable:

     0#include <vector>
     1#include <ranges>
     2#include <cstdio>
     3#include "span.h"
     4
     5static std::vector<int> g_vec{1, 2, 3, 4, 5, 6};
     6
     7void span_view_filter() {
     8    auto even = [](int i) { return 0 == i % 2; };
     9    printf("evens: ");
    10    for (int i : Span<int>(g_vec) | std::views::filter(even)) {
    11        printf("%i ", i);
    12    }
    13    printf("\n");
    14}
    15
    16void span_no_dangle()
    17{
    18    auto get_span = [] {
    19        return Span<int>(g_vec);
    20    };
    21    auto iter = std::ranges::max_element(get_span());
    22    static_assert(std::is_same_v<int*, decltype(iter)>);
    23    printf("max: %i\n", *iter);
    24}
    25
    26int main()
    27{
    28    span_no_dangle();
    29    span_view_filter();
    30}
    

    Compiled with: g++-10 -O2 -std=c++2a span.cpp -o span

    If enable_view is disabled, the first example will fail to compile. If enable_borrowed_range is disabled, the second will fail to compile.

    Sidenote: std::ranges::dangling is neat :)

  2. Opt-in to modeling view and borrowed_range for Span
    This matches the behavior of std::span, as Span satisfies the same concepts.
    2ae61cfafb
  3. fanquake added the label Brainstorming on Oct 8, 2021
  4. laanwj commented at 3:59 pm on October 8, 2021: member
    So the idea, as I understand, is that this adds compile-time checking capabilities a bit like rust? Yes that’s really neat.
  5. theuni commented at 4:07 pm on October 12, 2021: member

    @laanwj Yes, but in this case we’re actually opting out of some of those protections because of the semantics of Span. By default, the returned iterator type for a potentially dangling reference is a std::ranges::dangling. By opting in to enable_borrowed_range, we get a real return type. Otherwise it’d fail to compile the *iter dereference in the printf. This is also used by std::string_view, for example.

    The enable_view seems to be another way of saying pretty much the same thing but for a different semantic reason.

    I found it useful to copy/paste a little cheat-sheet of these concepts from libstdc++’s implementation:

     0/// [range.range] The range concept.
     1template<typename _Tp>
     2  concept range = requires(_Tp& __t)
     3    {
     4  ranges::begin(__t);
     5  ranges::end(__t);
     6    };
     7
     8template<typename _Tp>
     9  concept view
    10    = range<_Tp> && movable<_Tp> && default_initializable<_Tp>
    11  && enable_view<_Tp>;
    12
    13// Part of the constraints of ranges::borrowed_range
    14template<typename _Tp>
    15  concept __maybe_borrowed_range
    16  = is_lvalue_reference_v<_Tp>
    17    || enable_borrowed_range<remove_cvref_t<_Tp>>;
    18
    19template<typename _Tp>
    20  concept borrowed_range
    21    = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
    22
    23/// A range which can be safely converted to a view.
    24template<typename _Tp>
    25  concept viewable_range = range<_Tp>
    26    && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
    

    In the above example, enabling enable_borrowed_range alone is enough to make both examples compile, because (I believe) the first only requires a viewable_range.

    ~Interestingly, libstdc++’s definitions line up with the c++20 final draft spec, but differ from cppreference. I’m assuming that the latter is stale, so it’s probably worth using the draft spec for reference for now.~ I actually had this backwards. cppreference incorporates LWG 3481, which libstdc++ includes as of last week and P2415R2, which has not yet been integrated.

  6. DrahtBot commented at 10:46 pm on November 1, 2021: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #23413 (Replace MakeSpan helper with Span deduction guide by sipa)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  7. DrahtBot added the label Needs rebase on Dec 3, 2021
  8. DrahtBot commented at 10:16 am on December 3, 2021: contributor

    🐙 This pull request conflicts with the target branch and needs rebase.

    Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a “draft”.

  9. DrahtBot commented at 12:15 pm on March 21, 2022: contributor
    • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
    • Is it no longer relevant? ➡️ Please close.
    • Did the author lose interest or time to work on this? ➡️ Please close it and mark it ‘Up for grabs’ with the label, so that it can be picked up in the future.
  10. DrahtBot commented at 7:03 am on July 25, 2022: contributor
    • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
    • Is it no longer relevant? ➡️ Please close.
    • Did the author lose interest or time to work on this? ➡️ Please close it and mark it ‘Up for grabs’ with the label, so that it can be picked up in the future.
  11. MarcoFalke commented at 7:15 am on July 25, 2022: member
    Closing for now. Let us know when you are working on this again and if it should be reopened.
  12. MarcoFalke closed this on Jul 25, 2022

  13. bitcoin locked this on Jul 25, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-09-28 22:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me