shared arrray problem

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Nov 20 12:41:59 PST 2016


On 11/20/2016 09:09 PM, Charles Hixson via Digitalmars-d-learn wrote:
> Thinking it over a bit more, the item returned would need to be a
> struct, but the struct wouldn't contain the array, it would just contain
> a reference to the array and a start and end offset.  The array would
> need to live somewhere else, in the class (or struct...but class is
> better as you don't want the array evaporating by accident) that created
> the returned value.  This means you are dealing with multiple levels of
> indirection, so it's costly compared to array access, but cheap compared
> to lots of large copies.  So the returned value would be something like:
> struct
> {
>     private:
>     /** this is a reference to the data that lives elsewhere.  It should
> be a pointer, but I don't like the syntax*/
>     ubyte[]  data;
>     int    start, end;    ///    first and last valid indicies into data
>     public:
>     this (ubyte[] data, int start, int end)
>     {    this.data = data; this.start = start; this.end = end;}
>     ...
>     // various routines to access the data, but to limit the access to
> the spec'd range, and
>     // nothing to change the bounds
> }

Instead of extra 'start' and 'end' fields you can slice the array. A 
dynamic array already is just a reference coupled with a length, i.e. a 
pointer with restricted indexing. So you can slice the original array 
with your offsets and create the struct with that slice.

I feel like there is a misunderstanding somewhere, but I'm not sure on 
whose side. As far as I can tell, your understanding of dynamic arrays 
may be lacking, or maybe I don't understand what you're getting at.

> Which is really the answer you already posted, but just a bit more
> detail on the construct, and what it meant.  (Yeah, I could allow types
> other than ubyte as the base case, but I don't want to.  I'm thinking of
> this mainly as a means of sharing a buffer between applications where
> different parts have exclusive access to different parts of the buffer,
> and where the buffer will be written to a file with a single fwrite, or
> since the underlying storage will be an array, it could even be
> rawwrite).  I don't want to specify any more than I must about how the
> methods calling this will format the storage, and this means that those
> with access to different parts may well use different collections of
> types, but all types eventually map down to ubytes (or bytes), so ubytes
> is the common ground.  Perhaps I'll need to write inbuffer,outbuffer
> methods/wrappings, but that's far in the future.

Sure, go with a specialized type instead of a template, if that makes 
more sense for your use case. As far as I see, the concept is 
independent of the element type, so it seemed natural to make it a 
template, but a special type is perfectly fine and probably has less 
pitfalls.

> P.S.:  The traits that I mentioned previously were those given by:
>     static assert(!__traits(compiles, cla.length = 3));
>     static assert(!__traits(compiles, cla ~= 6));
> in your main routine.  I assumed that they were validity tests.  I don't
> understand why they were static.  I've never happened to use static
> asserts, but I would assume that when they ran cla wouldn't be defined.

Those are tests to ensure that cla's length cannot be set and that it 
cannot be appended to. The asserts check that the code does not compile, 
i.e. that you cannot do those things. They're static simply because they 
can be. The code inside is not executed at run-time.



More information about the Digitalmars-d-learn mailing list