0

I have a bunch of typed data in consecutive memory that I got as a T *; and I also know the number of elements (as a std::size_t although it doesn't matter much).

I'd like to use some single type or data structure to represent my stretch of typed data.

Now, what I have is the information for constructing...

  • A gsl::span<T>, but with ownership.
  • A gsl::owner<T *>, but with a size.

What type/structure/container would I use to represent all of my information about this data?

Notes:

  • Obviously I'm ok with using GSL constructs; stuff in C++2a or Boost is also fine.
  • I was thinking of a chimera of owner and span - perhaps gsl::owner<gsl::span<T>>; but I don't really like this idea too much.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Do you need to dispose of the pointer when done? – NathanOliver Oct 25 '18 at 21:45
  • I'm not understanding what you are trying to do. May be a James Coplien level abuse of the language (assuming you've read Advanced C++). – Eljay Oct 25 '18 at 21:46
  • @NathanOliver: Either dispose of it, or return an owning pointer, or a unique pointer etc. But in the mean time, I may want to pass the owning-span around to other functions, e.g. as just-a-span. – einpoklum Oct 25 '18 at 21:48
  • @Eljay: Suppose I'm implementing the function `void process_this_data_and_dispose_of_it(T* ptr, size_t length);` – einpoklum Oct 25 '18 at 21:49
  • Second question: Does this have to be a standard/gsl type/container? If not I'd just fork `span`, call it `owning_span`, and give it a destructor that will clean up the pointer. – NathanOliver Oct 25 '18 at 21:54
  • @NathanOliver: Doesn't _have_ to be, but I want to do what other people are doing, if that's at all a common situation to be in. – einpoklum Oct 25 '18 at 21:57
  • `gsl::owner>` fails because owner checks `std::is_pointer` on it's argument – Caleth Oct 25 '18 at 21:57

1 Answers1

2

You could inherit gsl::span<T> and hold a std::unique_ptr<T[]>

template <typename T, typename D = std::default_delete<T>>
struct owning_span : public gsl::span<T>
{
    owning_span() {}
    owning_span(T* ptr, index_type size, D d = {}) : span(ptr, size), m_ptr(ptr, std::move(d)) {}
    owning_span(T* first, T* last, D d = {}) : span(first, last), m_ptr(first, std::move(d)) {}
    // other constructors ?
private:
    std::unique_ptr<T[], D> m_ptr;
};

One note: you can still copy construct / assign gsl::spans from this, slicing off the ownership. Not sure if that is a pro or a con

Caleth
  • 52,200
  • 2
  • 44
  • 75
  • Perhaps make the `T*` constructors explicit, and have an implicit constructor taking `owner` , and one taking a `unique_ptr`? Also, method(s) for releasing ownership. But it's not half bad. – einpoklum Oct 25 '18 at 22:27