Re: Implicit cast to const of result returned from findSplit()
On 2018-11-05 14:26, Per Nordlöw wrote: Why does @safe pure unittest { import std.algorithm.searching : findSplit; if (const split = "a b".findSplit(" ")) { } } error as f.d(4,5): Error: mutable method `std.algorithm.searching.findSplit!("a == b", string, string).findSplit.Result!(string, string).Result.opCast!bool.opCast` is not callable using a `const` object f.d(4,5): Consider adding `const` or `inout` to std.algorithm.searching.findSplit!("a == b", string, string).findSplit.Result!(string, string).Result.opCast!bool.opCast when @safe pure unittest { import std.algorithm.searching : findSplit; if (auto split = "a b".findSplit(" ")) { } } doesn't? AFAICT, it looks like a missing bool qualifier on `opCast!bool`, right? If the first example you declare a const variable of the type that "findSplit" returns. Then the compiler will call opCast since the variable is defined in the if condition. But you can only call methods marked as "const" if you have a const variable. The opCast method in the struct returned by "findSplit" is missing a const attribute. -- /Jacob Carlborg
Re: Implicit cast to const of result returned from findSplit()
On Monday, 5 November 2018 at 13:26:18 UTC, Per Nordlöw wrote: AFAICT, it looks like a missing bool qualifier on `opCast!bool`, right? Fixed at https://github.com/dlang/phobos/pull/6749
Re: Implicit cast to const of result returned from findSplit()
On Monday, 5 November 2018 at 13:26:18 UTC, Per Nordlöw wrote: AFAICT, it looks like a missing bool qualifier on `opCast!bool`, right? ...Like a missing 'const' qualifier ;) auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) // ... static struct Result(S1, S2) if (isForwardRange!S1 && isForwardRange!S2) { // ... bool opCast(T : bool)() { return !asTuple[1].empty; } // ... }
Implicit cast to const of result returned from findSplit()
Why does @safe pure unittest { import std.algorithm.searching : findSplit; if (const split = "a b".findSplit(" ")) { } } error as f.d(4,5): Error: mutable method `std.algorithm.searching.findSplit!("a == b", string, string).findSplit.Result!(string, string).Result.opCast!bool.opCast` is not callable using a `const` object f.d(4,5):Consider adding `const` or `inout` to std.algorithm.searching.findSplit!("a == b", string, string).findSplit.Result!(string, string).Result.opCast!bool.opCast when @safe pure unittest { import std.algorithm.searching : findSplit; if (auto split = "a b".findSplit(" ")) { } } doesn't? AFAICT, it looks like a missing bool qualifier on `opCast!bool`, right?
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 10:47:36 UTC, Jakob Ovrum wrote: Nice! Should I make a PR? I think that would be very welcome. https://github.com/D-Programming-Language/phobos/pull/3288
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 10:28:11 UTC, Per Nordlöw wrote: Nice! Should I make a PR? I think that would be very welcome.
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 09:56:22 UTC, Jakob Ovrum wrote: It can be implemented in a backwards-compatible way as a subtype of a Tuple. struct FindSplit(R) { Tuple!(R, "pre", R, "separator", R, "post") asTuple; bool opCast(T : bool)() { return !asTuple.separator.empty; } alias asTuple this; } Tuple!(R, "pre", R, "separator", R, "post") is a subtype of Tuple!(R, R, R), which should be the current return type. Nice! Should I make a PR?
Re: Better Return Value for findSplit*()
On Saturday, 16 May 2015 at 09:36:30 UTC, Per Nordlöw wrote: After having written a lot of text pattern matching functions using Phobos' findSplit, findSplitBefore, findSplitAfter, and some more I've written myself I've come to the conclusion that I would like to enhance these functions to instead return a struct instead of tuples. This struct would typically look like struct FindSplit(T) { T[3] data; T first() { return data[0]; } T separator() { return data[1]; } T second() { return data[2]; } T opIndex(size_t i) return { return data[i]; } cast(T : bool)() { return !separator.empty; } } This would enable the following useful syntax: if (const split = line.findSplit(`-`)) { // do something with split } instead of current const split = line.findSplit(`-`) if (!split[1].empty) { } which is a constantly reoccurring pattern in D code processing text. The cons I can think of is that split[N] (N being a CT-constant) will occurr in run-time instead of compile-time and of course that people relying on that return-type of findSplit() being a tuple will cause code-breakage. What do you guys think; - Add extra template-param that returns struct instead and make the current behaviour deprecated? - Will happen for D3? :) - Will never happen? Destroy! It can be implemented in a backwards-compatible way as a subtype of a Tuple. struct FindSplit(R) { Tuple!(R, "pre", R, "separator", R, "post") asTuple; bool opCast(T : bool)() { return !asTuple.separator.empty; } alias asTuple this; } Tuple!(R, "pre", R, "separator", R, "post") is a subtype of Tuple!(R, R, R), which should be the current return type.
Better Return Value for findSplit*()
After having written a lot of text pattern matching functions using Phobos' findSplit, findSplitBefore, findSplitAfter, and some more I've written myself I've come to the conclusion that I would like to enhance these functions to instead return a struct instead of tuples. This struct would typically look like struct FindSplit(T) { T[3] data; T first() { return data[0]; } T separator() { return data[1]; } T second() { return data[2]; } T opIndex(size_t i) return { return data[i]; } cast(T : bool)() { return !separator.empty; } } This would enable the following useful syntax: if (const split = line.findSplit(`-`)) { // do something with split } instead of current const split = line.findSplit(`-`) if (!split[1].empty) { } which is a constantly reoccurring pattern in D code processing text. The cons I can think of is that split[N] (N being a CT-constant) will occurr in run-time instead of compile-time and of course that people relying on that return-type of findSplit() being a tuple will cause code-breakage. What do you guys think; - Add extra template-param that returns struct instead and make the current behaviour deprecated? - Will happen for D3? :) - Will never happen? Destroy!
Re: More Generic Variants of findSplit.*() in Demangling/Parsing
On Thursday, 14 August 2014 at 21:04:06 UTC, Nordlöw wrote: Should this go into Phobos? My variants can be found at the bottom of https://github.com/nordlow/justd/blob/master/algorithm_ex.d
Re: More Generic Variants of findSplit.*() in Demangling/Parsing
On Thursday, 14 August 2014 at 20:48:42 UTC, Nordlöw wrote: Ooops, I just realized that we can't express current Phobos implementations using my variant. Current algorithms take ranges not range values as a needle. My mistake. Are my overloads still wanted? Ok. I finally understood that a simplification was the way to go: /** Simpler Variant of Phobos' findSplitBefore. */ auto findSplitBefore(alias pred, R1)(R1 haystack) if (isForwardRange!R1) { static if (isSomeString!R1 || sRandomAccessRange!R1) { auto balance = haystack.find!pred; immutable pos = haystack.length - balance.length; return tuple(haystack[0 .. pos], haystack[pos .. haystack.length]); } else { auto original = haystack.save; auto h = haystack.save; size_t pos; while (!h.empty) { if (unaryFun!pred(h.front)) { h.popFront(); } else { haystack.popFront(); h = haystack.save; ++pos; } } return tuple(takeExactly(original, pos), haystack); } } unittest { import std.algorithm: equal; import std.ascii: isDigit; auto x = "11ab".findSplitBefore!(a => !a.isDigit); assert(equal(x[0], "11")); assert(equal(x[1], "ab")); } Should this go into Phobos?
Re: More Generic Variants of findSplit.*() in Demangling/Parsing
On Thursday, 14 August 2014 at 20:28:38 UTC, Nordlöw wrote: On Thursday, 14 August 2014 at 20:25:20 UTC, Nordlöw wrote: Destroy! Correction: These algorithms require ForwardRanges. Ooops, I just realized that we can't express current Phobos implementations using my variant. Current algorithms take ranges not range values as a needle. My mistake. Are my overloads still wanted?
More Generic Variants of findSplit.*() in Demangling/Parsing
I'm currently working on implementing demangling of ELF C++ symbols according to https://en.wikipedia.org/wiki/Name_mangling A reoccurring pattern high-level pattern is to use the std.algorithm: findSplit.* functions to make algorithm single-pass when possible. I'm however lacking a variant of this that takes a condition template argument instead of an input range element as function parameter. Something like auto findSplitBefore(alias condition, R)(R range) if (isInputRange!R) { import std.algorithm: until; auto hit = range.until!condition; auto rest = ""; return tuple(hit, rest); } unittest { import std.algorithm: equal; import std.ascii: isDigit; auto x = "11ab".findSplitBefore!(a => !a.isDigit); assert(equal(x[0], "11")); /* assert(equal(x[1], "ab")); */ } But how do I get the second part in a single pass? Is copying (duplicating) the existing Phobos implementations the only alternative here? If so I believe we should generalize these Phobos algorithms into the variants described above and implement the old ones by calling the generalized ones typically as auto findSplit(R)(R range, E element) if (isInputRange!R) { return range.findSplit!(a => a == element); } BTW: Does anybody have any good refs on ELF C++ demangling. The wikipedia article is a bit sparse. Destroy!
Re: More Generic Variants of findSplit.*() in Demangling/Parsing
On Thursday, 14 August 2014 at 20:25:20 UTC, Nordlöw wrote: Destroy! Correction: These algorithms require ForwardRanges.
Re: findSplit
On Friday, 25 July 2014 at 18:56:44 UTC, Gecko wrote: findSplit accepts a predicate but it doesnt compile for me if i use an other function than ((a,b) => a == b). Not at the moment. I've been working on a patch that makes the `findSplit*` family of algorithms as powerful as `find`, including support for your use case.
findSplit
Hello, is there a pretty way to split a range into 3 pieces, like findSplit, just with a predicate instead of comparing it with an element. Like this : void main() { import std.algorithm, std.stdio; auto list = [1,2,3,4,5,6,7]; writeln(findSplit!(x => x == 3 )(list)); //should print Tuple!() ([1,2], [3], [4,5,6,7]) } findSplit accepts a predicate but it doesnt compile for me if i use an other function than ((a,b) => a == b).