Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using gsl::span with range-v3

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?
like image 674
Maikel Avatar asked Mar 26 '16 10:03

Maikel


People also ask

What is Range v3?

Range v3 is a generic library that augments the existing standard library with facilities for working with ranges. A range can be loosely thought of a pair of iterators, although they need not be implemented that way.

What is GSL span?

gsl::span is a replacement for (pointer, length) pairs to refer to a sequence of contiguous objects. It can be thought of as a pointer to an array, but that knows its bounds. For example, a span<int,7> refers to a sequence of seven contiguous integers.

Is Range v3 header only?

The library used in the code examples is not really the C++20 ranges, it's the ranges-v3 open-source library from Eric Niebler, which is the basis of the proposal to add ranges to the C++. It's a header-only library compatible with C++11/14/17.


1 Answers

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.

like image 65
Casey Avatar answered Nov 03 '22 02:11

Casey