enum template shorthand and short circuit evaluation

2014-06-09 Thread Byron via Digitalmars-d-learn
Should this work?  It seems like the short circuit booleans are not 
working:


import std.traits;

enum isPrimitive(T) = isBasicType!T || (isArray!T && isBasicType!
(ForeachType!T));

void main() {

assert(isPrimitive!int);
assert(isPrimitive!char);
assert(isPrimitive!string);
assert(isPrimitive!(byte[]));

assert(!isPrimitive!test1);
assert(!isPrimitive!test2);
assert(!isPrimitive!test3);

}

class test1 {}
struct test2 {}
interface test3 {}


dmd test
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid 
foreach aggregate 0
test.d(5): Error: template instance std.traits.ForeachType!int error 
instantiating
test.d(9):instantiated from here: isPrimitive!int
test.d(9): Error: template instance test.isPrimitive!int error 
instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid 
foreach aggregate '\xff'
test.d(5): Error: template instance std.traits.ForeachType!char error 
instantiating
test.d(10):instantiated from here: isPrimitive!char
test.d(10): Error: template instance test.isPrimitive!char error 
instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid 
foreach aggregate null
test.d(5): Error: template instance std.traits.ForeachType!(test1) error 
instantiating
test.d(14):instantiated from here: isPrimitive!(test1)
test.d(14): Error: template instance test.isPrimitive!(test1) error 
instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid 
foreach aggregate test2()
test.d(5): Error: template instance std.traits.ForeachType!(test2) error 
instantiating
test.d(15):instantiated from here: isPrimitive!(test2)
test.d(15): Error: template instance test.isPrimitive!(test2) error 
instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(5762): Error: invalid 
foreach aggregate null
test.d(5): Error: template instance std.traits.ForeachType!(test3) error 
instantiating
test.d(16):instantiated from here: isPrimitive!(test3)
test.d(16): Error: template instance test.isPrimitive!(test3) error 
instantiating


DMD32 D Compiler v2.065


But this style works:

template isPrimitive(T) 
{
static if(isBasicType!T || (isArray!T && isBasicType!(ForeachType!T))) 
{
enum isPrimitive = true;
} else {
enum isPrimitive = false;
}
}



-Byron


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 20:01:05 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 19:47:29 UTC, Chris wrote:
Uh, I see, I misread the signature of std.string.strip(). So 
that's one option now, to strip all trailing hyphens with 
std.string.strip(). Well, I'll give it a shot tomorrow.


No, you read the documentation of std.*STRING*.strip correctly.

I'm suggesting you use the one from std.*ALGORITHM*.

The signatures are mutually exclusive, so you don't need to 
qualify them.


Ah, ok, talking about not seeing the forest for the trees ...


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 19:54:08 UTC, Chris wrote:
I think it makes sense to put any generic range based 
algorithms (split and so forth) into std.algorithm. It's always 
my first port of call, when I have a range. However, that you 
can do


std.string.split([1, 2, 3], 2);

is not exactly a desirable situation.


Right, but "split(hello world)" *is* string specific. It makes 
sense for strings only. It doens't make sense to write "split([1, 
2, 3])", which is why I'm unsatisfied with the current situation.


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 19:47:29 UTC, Chris wrote:
Uh, I see, I misread the signature of std.string.strip(). So 
that's one option now, to strip all trailing hyphens with 
std.string.strip(). Well, I'll give it a shot tomorrow.


No, you read the documentation of std.*STRING*.strip correctly.

I'm suggesting you use the one from std.*ALGORITHM*.

The signatures are mutually exclusive, so you don't need to 
qualify them.


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 18:09:07 UTC, monarch_dodra wrote:
On Monday, 9 June 2014 at 17:57:24 UTC, Steven Schveighoffer 
wrote:
I think we are confusing things here, I was talking about 
strip :)


strip and split are actually both pretty much in the same boat 
actually in regards to that, so just 's/split/strip/g', and the 
same answer will apply.


"split" (and "splitter") actually have it a bit more 
complicated, because historically, if you imported both string 
and algorithm, then "split(myString)" will create an ambiguous 
call. The issue is that you can't do selective imports when you 
already have a local object with the same name, so algorithm 
had:



auto split(String)(String myString) {
   return std.string.split(myString);
}

rather than

public import std.string : split;


I tried to "fix" the issue by removing "split(String)" from 
algorithm, but that created some breakage.


So Andrei just came down and put *everything* in algorithm, and 
added an "public import std.algorithm : split" in std.string.


This works, but it does mean that:
1. string unconditionally pulls algorithm.
2. You can do things like:
   std.string.split([1, 2, 3], 2);

IMO, the "strip" solution is better :/

If we could split up std.algorithm into individual modules, 
that would probably help.


-Steve


Yes.


I think it makes sense to put any generic range based algorithms 
(split and so forth) into std.algorithm. It's always my first 
port of call, when I have a range. However, that you can do


std.string.split([1, 2, 3], 2);

is not exactly a desirable situation.


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 15:52:24 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 15:19:05 UTC, Chris wrote:
On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer 
wrote:
On Mon, 09 Jun 2014 10:39:39 -0400, Chris  
wrote:



Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a => !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the 
module that handles the splitting of hyphenated words should 
be able to deal with cases like "blah-" without the input 
being prepared in a certain way.


It's not mishandled. It's handled exactly as I would have 
expected. If "blah-" and "blah" result in the same thing, 
then how do you know the difference?


Stripping any possible leading or trailing hyphens is much 
more efficient than checking every single word to see if it's 
empty.


However, if you have an instance of "--", your solution will 
remove the extra empty string, whereas mine does not. Not 
sure if that's important.


-Steve


It is important. "blah--" should come out as "blah". The logic 
is along the following lines:


if (canFind(w, "-")) {
 auto parts = appender!(string[]);
 w.splitter('-').filter!(a => !a.empty).copy(parts);
 if (parts.data.length == 1) {
   // false alarm. Trailing hyphen
 }
}

The more common case is that it's not a trailing hyphen. 
std.string.strip() only works for whitespaces. Would be nice 
to have something like that for random characters. strip(s, 
'-') or strip(s, ['-', '+', '@'])


http://dlang.org/phobos/std_algorithm.html#strip

w = w.strip('-');
if (canFind(w, "-")) {
   ...


Uh, I see, I misread the signature of std.string.strip(). So 
that's one option now, to strip all trailing hyphens with 
std.string.strip(). Well, I'll give it a shot tomorrow.


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 9 June 2014 at 17:57:24 UTC, Steven Schveighoffer 
wrote:
I think we are confusing things here, I was talking about strip 
:)


strip and split are actually both pretty much in the same boat 
actually in regards to that, so just 's/split/strip/g', and the 
same answer will apply.


"split" (and "splitter") actually have it a bit more complicated, 
because historically, if you imported both string and algorithm, 
then "split(myString)" will create an ambiguous call. The issue 
is that you can't do selective imports when you already have a 
local object with the same name, so algorithm had:



auto split(String)(String myString) {
   return std.string.split(myString);
}

rather than

public import std.string : split;


I tried to "fix" the issue by removing "split(String)" from 
algorithm, but that created some breakage.


So Andrei just came down and put *everything* in algorithm, and 
added an "public import std.algorithm : split" in std.string.


This works, but it does mean that:
1. string unconditionally pulls algorithm.
2. You can do things like:
   std.string.split([1, 2, 3], 2);

IMO, the "strip" solution is better :/

If we could split up std.algorithm into individual modules, 
that would probably help.


-Steve


Yes.


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 09 Jun 2014 12:06:13 -0400, monarch_dodra   
wrote:



On Monday, 9 June 2014 at 15:54:29 UTC, Steven Schveighoffer wrote:
On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra  
 wrote:



On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:
Just looked at std.string for a strip function that allows custom  
character strippage, but apparently not there. The above is quite  
awkward.


-Steve


It's in algorithm, because it's more generic than just strings.


Ugh.. This makes things difficult. If I want to work with strings, I  
import std.string.


I understand that the algorithm is applicable to all types, but this  
makes for some awkward coding. What if you wanted to use both? Surely  
we can come up with a better solution than this.


-Steve




I think we are confusing things here, I was talking about strip :)


There's 2 different issues: The first, is that "split(string)" was  
pre-existing in std.string, and *then* split was introduced in  
algorithm. Where ideally (?) everything would have been placed in the  
same module, we true to avoid moving things around now.


The second thing is that "split" without any predicate/item can only  
make sense for strings, but not for generic ranges.


For what it's worth, I find it makes sense.


Well, I suppose it should probably work if you try both strip and  
strip('-')...


and indeed it does. It is not as bad as I thought (I thought they would  
conflict).


It still leaves me a bit uneasy that std.string does not provide  
everything you would need to work with strings. But we don't want  
std.string importing std.algorithm, or at least we don't want it importing  
ALL of std.algorithm.


If we could split up std.algorithm into individual modules, that would  
probably help.


-Steve


Re: DMD Compiler Version Dependent Conditional Compilation

2014-06-09 Thread Nordlöw

Thx


Re: DMD Compiler Version Dependent Conditional Compilation

2014-06-09 Thread David Nadlinger via Digitalmars-d-learn

On Monday, 9 June 2014 at 17:36:10 UTC, Nordlöw wrote:
Can I use the version keyword or static if to perform 
conditional compilation  that depends on the version of DMD?


The __VERSION__ magic token should do the job.

David


DMD Compiler Version Dependent Conditional Compilation

2014-06-09 Thread Nordlöw
Can I use the version keyword or static if to perform conditional 
compilation  that depends on the version of DMD?


I typicall something like

version(>= DMD_2.0.66)
{
// use new byChar, byWchar, byDchar, byCodepoint
}
else
{
// use old style slower version
}

If so how?


Re: findBack: find a needle in a haystack from the back

2014-06-09 Thread Nordlöw

using retro seems inefficient because of all the decodings


Phobos git master just got support for next-gen string processing:

https://github.com/D-Programming-Language/phobos/pull/2043

I believe

x.byChar.retro

is what you want


Re: win64 as orphan?

2014-06-09 Thread lurker via Digitalmars-d-learn
i agree with you, but you should have posted in "announce", so 
that adrei can use it for some marketing.
i too wait now for a long, long time to use it with win64. i am 
also giving up - i guess it will stay a linux/apple show.
maybe, as a multiple os compiler, you can use lazarus or code 
typhon.

cheers.


On Monday, 9 June 2014 at 15:04:19 UTC, trail wrote:

will the sorry state of the win64 headers and programs like dfl
be fixed or is it time to leave the language to linux and move 
on

to something else?




Re: hijacking override from template mixin

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 15:54:21 UTC, Ivan Kazmenko wrote:
I'd expect a "multiple overrides of same function" error, much 
like if I just paste the mixin code by hand.  Is that a bug or 
working by design?  In the latter case, please explain the 
reasoning.


AFAIK, the rationale is that *should* a colision happen, the 
local symbol shadows the mixed-in symbol. Doing this avoid 
breaking your code just because someone added an extra member in 
their mixin, which happened to conflict with one of yours.


The idea is that you can workaround the issue by "naming" your 
mixin templates. Then, when you want to access members of the 
mixin template, you *know* it'll always work, regardless of what 
else may have been declared in your class.


That said, for something like virrtual functions, things get a 
bit trickier, since your *aren't* supposed to call them 
explicitly... I don't know if bug, or just surprising behavior.


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 9 June 2014 at 15:54:29 UTC, Steven Schveighoffer 
wrote:
On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra 
 wrote:


On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer 
wrote:
Just looked at std.string for a strip function that allows 
custom character strippage, but apparently not there. The 
above is quite awkward.


-Steve


It's in algorithm, because it's more generic than just strings.


Ugh.. This makes things difficult. If I want to work with 
strings, I import std.string.


I understand that the algorithm is applicable to all types, but 
this makes for some awkward coding. What if you wanted to use 
both? Surely we can come up with a better solution than this.


-Steve


There's 2 different issues: The first, is that "split(string)" 
was pre-existing in std.string, and *then* split was introduced 
in algorithm. Where ideally (?) everything would have been placed 
in the same module, we true to avoid moving things around now.


The second thing is that "split" without any predicate/item can 
only make sense for strings, but not for generic ranges.


For what it's worth, I find it makes sense.


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra   
wrote:



On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:
Just looked at std.string for a strip function that allows custom  
character strippage, but apparently not there. The above is quite  
awkward.


-Steve


It's in algorithm, because it's more generic than just strings.


Ugh.. This makes things difficult. If I want to work with strings, I  
import std.string.


I understand that the algorithm is applicable to all types, but this makes  
for some awkward coding. What if you wanted to use both? Surely we can  
come up with a better solution than this.


-Steve


hijacking override from template mixin

2014-06-09 Thread Ivan Kazmenko via Digitalmars-d-learn
The D language pays certain attention to avoiding hijacking [1].  
So I was surprised when I hijacked a function override from a 
template mixin by mistake.  Here is a commented example.  The 
comments explain the relevant part of the life cycle of the 
program.


-
// Start with class A with method fun returning "A".
class A {
string fun () {return "A";}
}

// Subclass B will return "B" instead.
class B: A {
override string fun () {return "B";}
}

// Turns out a common need is to return "MT",
// so we will create a mixin template MT for it
// to reduce boilerplate.
mixin template MT () {
override string fun () {return "MT";}
}

// We use MT in our new subclass C.
class C: A {
mixin MT;
}

// Both a mixed-in override and a regular one
// by a refactoring mistake, what happens?
class D: A {
mixin MT;
override string fun () {return "D";}
}

// Let's find out.
void main () {
import std.stdio;
writeln (new B ().fun ()); // B
writeln (new C ().fun ()); // MT
writeln (new D ().fun ()); // D, not MT
}
-

I'd expect a "multiple overrides of same function" error, much 
like if I just paste the mixin code by hand.  Is that a bug or 
working by design?  In the latter case, please explain the 
reasoning.


Also, if there is a "better" tool than a template mixin in the 
situation explained in the comments, please point me to it.


[1] http://dlang.org/hijack.html


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 15:19:05 UTC, Chris wrote:
On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer 
wrote:
On Mon, 09 Jun 2014 10:39:39 -0400, Chris  
wrote:



Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a => !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the 
module that handles the splitting of hyphenated words should 
be able to deal with cases like "blah-" without the input 
being prepared in a certain way.


It's not mishandled. It's handled exactly as I would have 
expected. If "blah-" and "blah" result in the same thing, then 
how do you know the difference?


Stripping any possible leading or trailing hyphens is much 
more efficient than checking every single word to see if it's 
empty.


However, if you have an instance of "--", your solution will 
remove the extra empty string, whereas mine does not. Not sure 
if that's important.


-Steve


It is important. "blah--" should come out as "blah". The logic 
is along the following lines:


if (canFind(w, "-")) {
  auto parts = appender!(string[]);
  w.splitter('-').filter!(a => !a.empty).copy(parts);
  if (parts.data.length == 1) {
// false alarm. Trailing hyphen
  }
}

The more common case is that it's not a trailing hyphen. 
std.string.strip() only works for whitespaces. Would be nice to 
have something like that for random characters. strip(s, '-') 
or strip(s, ['-', '+', '@'])


http://dlang.org/phobos/std_algorithm.html#strip

w = w.strip('-');
if (canFind(w, "-")) {
   ...


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer 
wrote:
Just looked at std.string for a strip function that allows 
custom character strippage, but apparently not there. The above 
is quite awkward.


-Steve


It's in algorithm, because it's more generic than just strings.


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn
On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer 
wrote:
On Mon, 09 Jun 2014 10:39:39 -0400, Chris  
wrote:



Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a => !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the 
module that handles the splitting of hyphenated words should 
be able to deal with cases like "blah-" without the input 
being prepared in a certain way.


It's not mishandled. It's handled exactly as I would have 
expected. If "blah-" and "blah" result in the same thing, then 
how do you know the difference?


Stripping any possible leading or trailing hyphens is much more 
efficient than checking every single word to see if it's empty.


However, if you have an instance of "--", your solution will 
remove the extra empty string, whereas mine does not. Not sure 
if that's important.


-Steve


It is important. "blah--" should come out as "blah". The logic is 
along the following lines:


if (canFind(w, "-")) {
  auto parts = appender!(string[]);
  w.splitter('-').filter!(a => !a.empty).copy(parts);
  if (parts.data.length == 1) {
// false alarm. Trailing hyphen
  }
}

The more common case is that it's not a trailing hyphen. 
std.string.strip() only works for whitespaces. Would be nice to 
have something like that for random characters. strip(s, '-') or 
strip(s, ['-', '+', '@'])


win64 as orphan?

2014-06-09 Thread trail via Digitalmars-d-learn

will the sorry state of the win64 headers and programs like dfl
be fixed or is it time to leave the language to linux and move on
to something else?


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 09 Jun 2014 10:39:39 -0400, Chris  wrote:


Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a => !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the module that  
handles the splitting of hyphenated words should be able to deal with  
cases like "blah-" without the input being prepared in a certain way.


It's not mishandled. It's handled exactly as I would have expected. If  
"blah-" and "blah" result in the same thing, then how do you know the  
difference?


Stripping any possible leading or trailing hyphens is much more efficient  
than checking every single word to see if it's empty.


However, if you have an instance of "--", your solution will remove the  
extra empty string, whereas mine does not. Not sure if that's important.


-Steve


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn
On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer 
wrote:
On Mon, 09 Jun 2014 07:04:11 -0400, Chris  
wrote:



On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:


Ok, thanks. I'll keep that in mind for the next version.


Seems to me to also work with 2.065 and 2.064.


From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


Note the 2 spaces between hello and world


and

"If a range with one separator is given, the result is a range 
with two empty elements."


Right, it allows you to distinguish cases where the range 
starts or ends with the separator.



My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to 
check parts.data[1] != "". This is too awkward. I just want 
the parts of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


One thing you could do is strip any leading or trailing hyphens:


assert("-bla-".chomp("-").chompPrefix("-").split('-').length == 
1);


Just looked at std.string for a strip function that allows 
custom character strippage, but apparently not there. The above 
is quite awkward.


-Steve


Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a => !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the 
module that handles the splitting of hyphenated words should be 
able to deal with cases like "blah-" without the input being 
prepared in a certain way. Now I have:


if (parts.data.length == 1) {
  // false alarm. Trailing hyphen
}


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 09 Jun 2014 07:04:11 -0400, Chris  wrote:


On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:


Ok, thanks. I'll keep that in mind for the next version.


Seems to me to also work with 2.065 and 2.064.


 From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", "world" ]));


Note the 2 spaces between hello and world


and

"If a range with one separator is given, the result is a range with two  
empty elements."


Right, it allows you to distinguish cases where the range starts or ends  
with the separator.



My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to check  
parts.data[1] != "". This is too awkward. I just want the parts of the  
word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


One thing you could do is strip any leading or trailing hyphens:


assert("-bla-".chomp("-").chompPrefix("-").split('-').length == 1);

Just looked at std.string for a strip function that allows custom  
character strippage, but apparently not there. The above is quite awkward.


-Steve


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 12:16:30 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 11:40:24 UTC, Chris wrote:

On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:

From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


and

"If a range with one separator is given, the result is a 
range with two empty elements."


My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to 
check parts.data[1] != "". This is too awkward. I just want 
the parts of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


You can just pipe in an extra "filter!(a=>!a.empty)", and 
it'll do what you want:

put(parts, w.splitter('-').filter!(a=>!a.empty)());

The rational for this behavior, is that it preserves the 
"total amount of information" from your input. EG:


assert(equal(myString.spliter(sep).join(sep), myString));

If the empty tokens were all stripped out, that wouldn't 
work, you'd have lost information about how many separators 
there actually were, and where they were.


I see, I've already popped in a filter. I only wonder how much 
of a performance loss that is. Probably negligible.


Arguably, none, since someone has to do the check anyways. If 
it's not done "outside" of splitter, it has to be done inside...


Yes, of course. I just thought if it's done in the library 
function, the optimization might be better than when it is done 
in my code. (filter!() is arguably also in the library :)


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 11:40:24 UTC, Chris wrote:

On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:

From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


and

"If a range with one separator is given, the result is a 
range with two empty elements."


My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to 
check parts.data[1] != "". This is too awkward. I just want 
the parts of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


You can just pipe in an extra "filter!(a=>!a.empty)", and 
it'll do what you want:

put(parts, w.splitter('-').filter!(a=>!a.empty)());

The rational for this behavior, is that it preserves the 
"total amount of information" from your input. EG:


assert(equal(myString.spliter(sep).join(sep), myString));

If the empty tokens were all stripped out, that wouldn't work, 
you'd have lost information about how many separators there 
actually were, and where they were.


I see, I've already popped in a filter. I only wonder how much 
of a performance loss that is. Probably negligible.


Arguably, none, since someone has to do the check anyways. If 
it's not done "outside" of splitter, it has to be done inside...


Re: findBack: find a needle in a haystack from the back

2014-06-09 Thread Tobias Pankrath via Digitalmars-d-learn
On Monday, 9 June 2014 at 07:58:25 UTC, Timothee Cour via 
Digitalmars-d-learn wrote:
Is there a more idiomatic/elegant way to achieve the following, 
while

remaining as efficient as possible?
Same question in the simpler case n==0?

using retro seems inefficient because of all the decodings

// returns the largest suffix of a that contains no more than n 
times c

string findBack(string a, char c, size_t n=0){
  auto b=cast(immutable(ubyte)[])a;
  auto val=cast(ubyte)c;
  size_t counter=0;
  for(ptrdiff_t i=cast(ptrdiff_t)b.length - 1; i>=0; i--){
if(b[i]==c){
  if(counter>=n)
return cast(string)a[i+1..$];
  counter++;
}
  }
  return a;
}

//unittest{
void test3(){
  auto c='\n';
  string a="abc1\nabc2\nabc3";
  assert(a.findBack(c,0)=="abc3");
  assert(a.findBack(c,1)=="abc2\nabc3");
  assert(a.findBack(c,2)=="abc1\nabc2\nabc3");
  assert(a.findBack(c,3)=="abc1\nabc2\nabc3");
}


If you are going to cast the string to ubyte[] anyway, why not 
just do this before using retro?


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:

From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


and

"If a range with one separator is given, the result is a range 
with two empty elements."


My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to 
check parts.data[1] != "". This is too awkward. I just want 
the parts of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


You can just pipe in an extra "filter!(a=>!a.empty)", and it'll 
do what you want:

put(parts, w.splitter('-').filter!(a=>!a.empty)());

The rational for this behavior, is that it preserves the "total 
amount of information" from your input. EG:


assert(equal(myString.spliter(sep).join(sep), myString));

If the empty tokens were all stripped out, that wouldn't work, 
you'd have lost information about how many separators there 
actually were, and where they were.


I see, I've already popped in a filter. I only wonder how much of 
a performance loss that is. Probably negligible.


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:

From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


and

"If a range with one separator is given, the result is a range 
with two empty elements."


My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to check 
parts.data[1] != "". This is too awkward. I just want the parts 
of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


You can just pipe in an extra "filter!(a=>!a.empty)", and it'll 
do what you want:

put(parts, w.splitter('-').filter!(a=>!a.empty)());

The rational for this behavior, is that it preserves the "total 
amount of information" from your input. EG:


assert(equal(myString.spliter(sep).join(sep), myString));

If the empty tokens were all stripped out, that wouldn't work, 
you'd have lost information about how many separators there 
actually were, and where they were.


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:


Ok, thanks. I'll keep that in mind for the next version.


Seems to me to also work with 2.065 and 2.064.


From the library reference:

assert(equal(splitter("hello  world", ' '), [ "hello", "", 
"world" ]));


and

"If a range with one separator is given, the result is a range 
with two empty elements."


My problem was that if I have input like

auto word = "bla-";

it will return parts.data.length == 2, so I would have to check 
parts.data[1] != "". This is too awkward. I just want the parts 
of the word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in "bla-")
length > 2 // do something else


Re: splitter for strings

2014-06-09 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:


Ok, thanks. I'll keep that in mind for the next version.


Seems to me to also work with 2.065 and 2.064.


Re: splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn

On Monday, 9 June 2014 at 10:14:40 UTC, bearophile wrote:

Chris:


auto word = "bla-bla";
auto parts = appender!(string[]);
w.splitter('-').copy(parts);
// parts.data.length == 3 ["bla", "", "bla"]


With the current dmd 2.066alpha this code:

void main() {
import std.stdio, std.string, std.algorithm;
const txt = "bla-bla";
txt.split("-").writeln;
txt.splitter("-").writeln;
txt.splitter('-').writeln;
}

Prints:

["bla", "bla"]
["bla", "bla"]
["bla", "bla"]

Bye,
bearophile


Ok, thanks. I'll keep that in mind for the next version.


Re: splitter for strings

2014-06-09 Thread bearophile via Digitalmars-d-learn

Chris:


auto word = "bla-bla";
auto parts = appender!(string[]);
w.splitter('-').copy(parts);
// parts.data.length == 3 ["bla", "", "bla"]


With the current dmd 2.066alpha this code:

void main() {
import std.stdio, std.string, std.algorithm;
const txt = "bla-bla";
txt.split("-").writeln;
txt.splitter("-").writeln;
txt.splitter('-').writeln;
}

Prints:

["bla", "bla"]
["bla", "bla"]
["bla", "bla"]

Bye,
bearophile


splitter for strings

2014-06-09 Thread Chris via Digitalmars-d-learn
Say I wanna split a string that contains hyphens. If I use 
std.algorithm.splitter I end up with empty elements for each 
hyphen, e.g.:


auto word = "bla-bla";
auto parts = appender!(string[]);
w.splitter('-').copy(parts);
// parts.data.length == 3 ["bla", "", "bla"]

This is not ideal for my purposes, so I filter like so:

auto parts = appender!(string[]);
foreach (p; word.splitter('-')) {
  if (p != "") {
parts ~= p;
  }
}

or even better like so:

w.splitter('-').filter!(a => a != "").copy(parts);

I wonder, however, whether this is ideal or whether regex's split 
would be a better match (pardon the pun!). I try to avoid regex 
when ever possible since they are more awkward to use and usually 
more expensive.


findBack: find a needle in a haystack from the back

2014-06-09 Thread Timothee Cour via Digitalmars-d-learn
Is there a more idiomatic/elegant way to achieve the following, while
remaining as efficient as possible?
Same question in the simpler case n==0?

using retro seems inefficient because of all the decodings

// returns the largest suffix of a that contains no more than n times c
string findBack(string a, char c, size_t n=0){
  auto b=cast(immutable(ubyte)[])a;
  auto val=cast(ubyte)c;
  size_t counter=0;
  for(ptrdiff_t i=cast(ptrdiff_t)b.length - 1; i>=0; i--){
if(b[i]==c){
  if(counter>=n)
return cast(string)a[i+1..$];
  counter++;
}
  }
  return a;
}

//unittest{
void test3(){
  auto c='\n';
  string a="abc1\nabc2\nabc3";
  assert(a.findBack(c,0)=="abc3");
  assert(a.findBack(c,1)=="abc2\nabc3");
  assert(a.findBack(c,2)=="abc1\nabc2\nabc3");
  assert(a.findBack(c,3)=="abc1\nabc2\nabc3");
}