www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Wrapping a forward range in another forward range

reply Rudy Raab <TransientResponse outlook.com> writes:
So I have an XLSX (MS Excel 2007+ file format) library that I 
wrote  (https://github.com/TransientResponse/dlang-xlsx) that I 
recently converted from std.xml to dxml. That went well and it 
still works (much faster too).

Now I had the idea that a lazy forward range API (like dxml 
itself or std.csv) would be more convenient than my current API, 
which reads an XLSX sheet in its entirety as a giant array of 
arrays (string[][]).

So I set about creating a wrapper class that implements front 
(returns a string[], the current row), popFront (runs through the 
dxml range until it reaches the end of the next row and populates 
the current row array from that), and empty.

I've figured out that my wrapper Sheet class has to be a 
templated class (don't know why) in order for my empty method to 
not fail on matching std.range.primitive's definition of empty.

Since I'm trying to create a range of string[]s, I templated my 
class as
```
class XLSheet(R) if(isRandomAccessRange!R && 
isSomeChar!(ElementType!R))
```

And now when I go to use it, if I declare it as say:
```
auto sheetRange = new XLSheet!(string[])();
```

DMD (2.080.1 Win10 x64) gives me the error:
```
source\xlsx.d(203,27): Error: template instance 
`xlsx.XLSheet!(string[])` does not match template declaration 
XLSheet(R) if (isRandomAccessRange!R && 
isSomeChar!(ElementType!R))
```

I'm guessing that `string[]` doesn't satisfy the requirements of 
`isRandomAccessRange` and such.

Can anyone smarter than me (or at least better at D than me) 
educate me as to why this doesn't compile, and how I might go 
about defining my wrapper class?

Full source code is on GitHub as I mentioned, in the `rangeAPI` 
branch.
Jun 24 2018
parent reply aliak <something something.com> writes:
On Sunday, 24 June 2018 at 20:33:32 UTC, Rudy Raab wrote:
 So I have an XLSX (MS Excel 2007+ file format) library that I 
 wrote  (https://github.com/TransientResponse/dlang-xlsx) that I 
 recently converted from std.xml to dxml. That went well and it 
 still works (much faster too).

 [...]
I think it's the isSomeChar!(ElementType!R), not the isRandomAccessRange (because string isSomeString and !isSomeChar)? Cheers, - Ali
Jun 24 2018
parent Rudy Raab <TransientResponse outlook.com> writes:
On Sunday, 24 June 2018 at 21:28:06 UTC, aliak wrote:
 On Sunday, 24 June 2018 at 20:33:32 UTC, Rudy Raab wrote:
 So I have an XLSX (MS Excel 2007+ file format) library that I 
 wrote  (https://github.com/TransientResponse/dlang-xlsx) that 
 I recently converted from std.xml to dxml. That went well and 
 it still works (much faster too).

 [...]
I think it's the isSomeChar!(ElementType!R), not the isRandomAccessRange (because string isSomeString and !isSomeChar)? Cheers, - Ali
Changing it to isSomeString!(ElementType!R) moves the error to my empty() function: ``` source\xlsx.d(205,22): Error: template std.range.primitives.empty cannot deduce function from argument types !()(XLSheet!(string[])), candidates are: C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\primitives.d(2090,16): std.range.primitives.empty(T)(auto ref scope const(T) a) if (is(typeof(a.length) : size_t) || isNarrowString!T) ``` I tried implementing a length() function (the number of rows remaining in the range, which is known at runtime), but the error remains.
Jun 25 2018