| Thread overview | |||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 16, 2015 contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Since C++17, there's a new iterator category: the contiguous iterator. Check it out: http://en.cppreference.com/w/cpp/iterator So, by extension, I think a ContiguousRange would be any RandomAccessRange which has a member called ptr which supports a dereferencing operator * that yields an ElementType!R. This notion is useful for functions which might otherwise perform an element-by-element transfer to an OutputRange via put, instead perform an optimized batch transfer directly to a ContiguousRange via ptr. (Not that Contiguous implies Output; this example assumes the ContigiousRange has enough length to accomodate the transfer or otherwise has mutable length, e.g. builtin arrays.) I've been using the idea implicitly in my code with static if (is (typeof(*R.init.ptr) == ElementType!R)), but seeing that table made me realize it could be formally abstracted out to a range concept. | ||||
February 16, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | Vlad Levenfeld:
> a ContiguousRange would be any RandomAccessRange which has a member called ptr which supports a dereferencing operator * that yields an ElementType!R. This notion is useful for functions which might otherwise perform an element-by-element transfer to an OutputRange via put, instead perform an optimized batch transfer directly to a ContiguousRange via ptr.
Increasing the number of basic ranges will lead to a little more complexity, but this seems a nice idea.
Bye,
bearophile
| |||
February 16, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | On 2015-02-16 at 07:06, Vlad Levenfeld wrote:
> *ContigiousRange* has enough length [...]
LOL. The clearly masochistic C++ committee needs to be applauded for introducing what may become the biggest source of typos. :)
Adjoining would be easier on the non-native English speakers than contiguous. Not to mention that contiguous sounds almost like contagious. Let's better not catch that infection. ;)
| |||
February 16, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FG | On Monday, 16 February 2015 at 11:57:36 UTC, FG wrote: > On 2015-02-16 at 07:06, Vlad Levenfeld wrote: >> *ContigiousRange* has enough length [...] > > LOL. The clearly masochistic C++ committee needs to be applauded for introducing what may become the biggest source of typos. :) > > Adjoining would be easier on the non-native English speakers than contiguous. Not to mention that contiguous sounds almost like contagious. Let's better not catch that infection. ;) If you think you could do a better job than the C++ committee you should submit a proposal. https://isocpp.org/std/submit-a-proposal Cheers, uri. | |||
February 16, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to rupert Attachments: | On Mon, 16 Feb 2015 12:16:50 +0000, rupert wrote:
> If you think you could do a better job than the C++ committee you should submit a proposal.
>
> https://isocpp.org/std/submit-a-proposal
why he *should* to that? he *may* submit it. when someone sees people doing shit, he is not obliged to immediately go and fix that shit.
| |||
February 17, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FG | On Monday, 16 February 2015 at 11:57:36 UTC, FG wrote:
> On 2015-02-16 at 07:06, Vlad Levenfeld wrote:
>> *ContigiousRange* has enough length [...]
>
> LOL. The clearly masochistic C++ committee needs to be applauded for introducing what may become the biggest source of typos. :)
>
> Adjoining would be easier on the non-native English speakers than contiguous. Not to mention that contiguous sounds almost like contagious. Let's better not catch that infection. ;)
Well, if you're that worried about the proximity of the 'i' and 'u' keys, you might be happier with AddressableRange, though you'll want to watch out for those tricky double consonants :)
I think I may do my senior thesis on range/iterator categories, so I make the post more out of curiosity than as a proposal for an addition to Phobos (though I wouldn't mind seeing it formalized, the use cases are certainly there).
| |||
February 17, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | On 2/15/15 10:06 PM, Vlad Levenfeld wrote:
> Since C++17, there's a new iterator category: the contiguous iterator.
> Check it out: http://en.cppreference.com/w/cpp/iterator
>
> So, by extension, I think a ContiguousRange would be any
> RandomAccessRange which has a member called ptr which supports a
> dereferencing operator * that yields an ElementType!R. This notion is
> useful for functions which might otherwise perform an element-by-element
> transfer to an OutputRange via put, instead perform an optimized batch
> transfer directly to a ContiguousRange via ptr. (Not that Contiguous
> implies Output; this example assumes the ContigiousRange has enough
> length to accomodate the transfer or otherwise has mutable length, e.g.
> builtin arrays.)
>
> I've been using the idea implicitly in my code with static if (is
> (typeof(*R.init.ptr) == ElementType!R)), but seeing that table made me
> realize it could be formally abstracted out to a range concept.
Interesting. This needs, however, a few more implementations that motivate the concept. Also, I see potential for misuse already: for an array r, is r.retro contiguous or not? One might argue it is because its layout is still contiguous; however, in that case people shouldn't assume that .ptr necessarily points to the first element.
Contiguous ranges would help two useful primitives: r1.before(r2) yields the portion of r1 before r2 (assumes r2 overlaps r1), and r1.after(r2) yields the portion of r1 after r2 (same assumption). Basically r1.before(r2) is r1[0 .. r2.ptr - r1.ptr] and r1.after(r2) is r1[r2.ptr + r2.length - r1.ptr .. $].
Andrei
| |||
February 17, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu:
> for an array r, is r.retro contiguous or not?
Is the most useful contiguous range forward? So can you name it ForwardContiguousRange?
Bye,
bearophile
| |||
February 17, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2/17/15 8:13 AM, bearophile wrote:
> Andrei Alexandrescu:
>
>> for an array r, is r.retro contiguous or not?
>
> Is the most useful contiguous range forward? So can you name it
> ForwardContiguousRange?
Ehm. Attractiveness of concepts increases with the number of cases (structures + algorithms) they cover successfully and decreases with "shrapnel" - the additional concepts/exceptions they need to define. -- Andrei
| |||
February 18, 2015 Re: contiguous ranges | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 17 February 2015 at 15:50:17 UTC, Andrei Alexandrescu wrote: > for an array r, is r.retro contiguous or not? I would argue that the only operations which preserve contiguity are slicing, concatenating and appending; r.retro, r.stride, r.map!f, etc should yield a RandomAccessRange. I don't think this is a deal breaker, as conceptually its akin to losing random-accessiblity under a filtering or grouping. Input ranges are ubiquitous, RandomAccessRanges are more rare, and ContiguousRanges are rarer still. It stands to reason that contiguity is unlikely to be preserved under a given transformation. > This needs, however, a few more implementations that motivate the concept. The main use cases I had in mind was for optimized data transfers and passing arguments to C APIs, and in this regard the definition of ContiguousRange would need a bit of refinement, maybe like so: A ContiguousRange r of type R is a RandomAccessRange which satisfies hasLValueElements and defines a member called ptr which satisfies the following conditions: 1) *r.ptr == r[0] && r.ptr == &r[0] 2) for all 0 <= i < r.length, *(r.ptr + i) == r[i] && r.ptr + i == &r[i] We could then have: void load_data (R)(R r) { static if (isContiguousRange!R) auto ptr = r.ptr; else { auto cache = r.array; auto ptr = cache.ptr; } some_C_lib_call (r.length, ptr); } and void copy (R,S)(R r, S s) if (allSatisfy!(isContiguousRange, R, S)) { // type and length equality assertions vectorized_blit (ElementType!R.sizeof, r.length r.ptr, s.ptr); } --- Extending the concept to multiple dimensions is thorny, but then, I've found that the same is true for everything but RandomAccessRanges. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply