Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use gsl::span and indicate ownership?

I want to write a function which:

  1. Takes a pointer as a parameter
  2. Takes a length as a parameter
  3. Owns the memory pointed to by the pointer (e.g. maybe it releases it, or constructs a unique_ptr to it in some data structure etc.)

Now, if I wanted 1+2 I would just use gsl::span. And if wanted 1+3 I would use owner<T*>. But what should I do when I want all three? Should I pass an owner<gsl::span<T>>? Something else?

Notes:

  • You may not assume the pointer is into the heap.
  • std::vector is requiring too much. The function should not require the caller to construct an std::vector.
like image 784
einpoklum Avatar asked Nov 08 '22 08:11

einpoklum


1 Answers

One option would be to define your own abstract base class to encapsulate the data. Something like:

template<typename T>
class DataHolder {
public:
  virtual ~DataHolder() = default;
  virtual gsl::span<T> get() const = 0;
};

Then your function could look something like:

void foo(std::unique_ptr<DataHolder<int>> data) {
  if (!data)
    return;
  for (auto v : data->get())
    std::cout << v << " ";
}

The caller can then implement the base class with any container they want to. There will be a small cost of polymophism but not on a per-element basis.

If you don't want to pay for polymorphism, perhaps you could make your function accept a template parameter.

template<typename DataHolder>
void foo(DataHolder data) {
  for (auto v : data())
    std::cout << v << " ";
}

where the implicit interface for DataHolder could be satisfied by something like:

struct VectorHolder {
    std::vector<int> data;
    gsl::span<const int> operator()() const { return data; }
};

or if you really don't want to use vector. You could use something like this (as suggested by @utnapistim):

struct ArrayHolder {
    std::unique_ptr<int[]> data;
    ptrdiff_t              length;
    gsl::span<const int> operator()() const { return {data.get(), length}; }
};
like image 127
Chris Drew Avatar answered Nov 14 '22 21:11

Chris Drew