Thread overview | |||||
---|---|---|---|---|---|
|
March 15, 2021 Can't call splitter with range struct | ||||
---|---|---|---|---|
| ||||
I came across this problem as I was trying to see if could write a quick range-based solution with std.zlib to do what was asked about in a different Learn forum post - read a gzipped file. This seems like it should work: import std.stdio, std.algorithm, std.zlib; import std.range.primitives; void main(string[] args) { auto f = GZippedFile(File(args[1], "rb")); f.splitter("\n").each!writeln; } struct GZippedFile { File file; UnCompress uncompressor; ubyte[] readBuffer; const(char)[] buffer; this(File f) { file = f; uncompressor = new UnCompress(HeaderFormat.gzip); readBuffer = new ubyte[4096]; } dchar front() const { return buffer.front; } void popFront() { if (buffer.empty) { buffer = cast(const(char)[]) uncompressor.uncompress(file.rawRead(readBuffer)); } else { buffer.popFront(); } } bool empty() { return buffer.empty && file.eof(); } } But I get: Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(GZippedFile, string), candidates are: /usr/include/dlang/dmd/std/algorithm/iteration.d(4678): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = string must satisfy the following constraint: is(typeof(binaryFun!pred(r.front, s)) : bool) (...) If I change the newline separator to a character literal, I get: (...) /usr/include/dlang/dmd/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = char must satisfy the following constraint: is(typeof(binaryFun!pred(r.front, s.front)) : bool) It seems like "\n" should pass the second constraint and '\n' should pass the first. Using a dchar or dstring makes no difference. Adding @property to front makes no difference. Is this a bug? |
March 16, 2021 Re: Can't call splitter with range struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Skluzacek | On 3/16/21 1:58 AM, David Skluzacek wrote: > > Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(GZippedFile, string), candidates are: > /usr/include/dlang/dmd/std/algorithm/iteration.d(4678): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) > with pred = "a == b", > Range = GZippedFile, > Separator = string > must satisfy the following constraint: > is(typeof(binaryFun!pred(r.front, s)) : bool) That means that you should be able to call your predicate ("a == b") with GZippedFile.front and separator as arguments (they are dchar and string respectively) > (...) > > If I change the newline separator to a character literal, I get: > > (...) > /usr/include/dlang/dmd/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) > with pred = "a == b", > Range = GZippedFile, > Separator = char > must satisfy the following constraint: > is(typeof(binaryFun!pred(r.front, s.front)) : bool) > > It seems like "\n" should pass the second constraint and '\n' should pass the first. Using a dchar or dstring makes no difference. Adding @property to front makes no difference. Is this a bug? > Also there are other constraints (see https://run.dlang.io/is/rcSJJf) like: /dlang/ldc-1.25.1/bin/../import/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = string must satisfy one of the following constraints: hasSlicing!Range isNarrowString!Range That means that you GZippedRange should provide opSlice operator and should be a narrow string (string of char or wchar) |
March 16, 2021 Re: Can't call splitter with range struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | On Tuesday, 16 March 2021 at 07:43:18 UTC, drug wrote:
> That means that you GZippedRange should provide opSlice operator and should be a narrow string (string of char or wchar)
Yes, I should have looked more carefully at the doc, I was assuming splitter would accept a simple input range, but it doesn't. I really didn't want to provide opSlice because then if it were called with an index higher than the length of the buffer I'd have to read more data and allocate memory to hold it. I'm not actually trying to do this any more though. Thanks.
|
Copyright © 1999-2021 by the D Language Foundation