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.

Reply via email to