Re: Implicit cast to const of result returned from findSplit()

2018-11-06 Thread Jacob Carlborg via Digitalmars-d-learn

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()

2018-11-05 Thread Per Nordlöw via Digitalmars-d-learn

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()

2018-11-05 Thread Stanislav Blinov via Digitalmars-d-learn

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()

2018-11-05 Thread Per Nordlöw via Digitalmars-d-learn

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*()

2015-05-16 Thread via Digitalmars-d-learn

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


Better Return Value for findSplit*()

2015-05-16 Thread via Digitalmars-d-learn
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: Better Return Value for findSplit*()

2015-05-16 Thread Jakob Ovrum via Digitalmars-d-learn

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.


Re: Better Return Value for findSplit*()

2015-05-16 Thread Jakob Ovrum via Digitalmars-d-learn

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: More Generic Variants of findSplit.*() in Demangling/Parsing

2014-08-14 Thread Nordlöw

On Thursday, 14 August 2014 at 20:25:20 UTC, Nordlöw wrote:

Destroy!


Correction: These algorithms require ForwardRanges.


More Generic Variants of findSplit.*() in Demangling/Parsing

2014-08-14 Thread Nordlöw
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

2014-08-14 Thread Nordlöw

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?


Re: More Generic Variants of findSplit.*() in Demangling/Parsing

2014-08-14 Thread Nordlöw

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

2014-08-14 Thread Nordlöw

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


findSplit

2014-07-25 Thread Gecko via Digitalmars-d-learn

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).


Re: findSplit

2014-07-25 Thread Jakob Ovrum via Digitalmars-d-learn

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.