Using gsl::span with range-v3
Asked Answered
S

1

7

I tried a little example to get used to the GSL and range-v3 libraries and I wondered how they could work together. I have this toy example

#include <iostream>
#include <range/v3/all.hpp>

using namespace std;
using namespace ranges;

void example_vector(vector<int> const& v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

int main()
{
   auto seq = vector<int> { 2,2,2,0,0,2,1,2 };
   example_vector(seq);
}

which works. But if I try to use gsl::span<int> as a range it leads to an error message. The compiler tells me that span does not fullfill the view concept.

#include <gsl.h>

// ...

void example_span(gsl::span<const int> v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

Compiler message:

note: candidate template ignored: disabled by 'enable_if'
      [with Rng = gsl::span<const int, -1> &, Rest = <>, _concept_requires_123 = 42]
                    CONCEPT_REQUIRES_(ViewConcept<Rng, Rest...>())>

But in my understanding it should since a span is a particular view and even has begin() and end() iterators (of the same type).

  • Wouldn't it be cool if they work together being composable or are there any reasons for both to be not compatible?
  • I think this is an issue which comes from the strong "concept" usage in range-v3. Does it get automatically solved if some other sort of concept feature is supported by the language?
  • I assume span currently needs some adaption if I would like to use both libraries together in some piece of (non-industrial) software. What should I change to make these work together? (if it is a good idea at all)
  • That also leads me ultimately to the question of "What has a class to fullfill to work with range-v3?" Is inheritance from facades, adaptors or such the only way to tell the compiler currently about these conceptional requirements?
Strunk answered 26/3, 2016 at 10:30 Comment(3)
Check out the gsl github issues page. There are a lot of problems with the iterators right now, and they're going to be completely rewritten. IMO it's not in a production ready state right now.Unbolted
Can you point to an issue which is directly associated with my problem? I went through the ~40 issues but maybe i did not understand everything ;^). I cant even get the iterators working with any function of range-v3.Strunk
Sorry, I meant in general there are a lot of problems, not that there was a solution there.Unbolted
D
9

The View concept in range-v3 (and the ranges TS, for that matter) requires a type R to satisfy both the Range concept -- begin(r) and end(r) delimit an iterator range -- and the Semiregular concept -- R must be copy/move constructible copy/move assignable, and default constructible. The iterator and sentinel types of a Range (what begin and end return) must also be Semiregular (amongst other requirements).

The span family doesn't satisfy the View concept since spans are not default constructible in some cases, and their iterators are not default constructible in any cases. Since even Standard C++ requires default construction for Forward iterators, the current span iterators conform to neither the Ranges TS, range-v3, nor Standard C++.

That said, the changes necessary to meet all these families of requirements are minimal and straight-forward.

20161207 Update:

range-v3 now contains an implementation of span that does properly model the View/Range concepts.

20170128 Update:

gsl::span now has default constructible iterators. Consequently, spans are now usable with range-v3. Spans with dynamic extent (e.g., gsl::span<int>) model the Range & View concepts, spans with static extent (e.g., gsl::span<int, 42>) model only Range since they do not meet View's requirement for default construction.

Digitalize answered 29/3, 2016 at 7:25 Comment(1)
Thank you for this insight and repository!Strunk

© 2022 - 2024 — McMap. All rights reserved.