Re: Simplest multithreading example

2017-08-31 Thread Brian via Digitalmars-d-learn

On Friday, 1 September 2017 at 04:43:29 UTC, Ali Çehreli wrote:

On 08/31/2017 06:59 PM, Brian wrote:
> Hello, I am trying to get the most trivial example of
multithreading
> working, but can't seem to figure it out.
> I want to split a task across threads, and wait for all those
tasks to
> finish before moving to the next line of code.
>
> The following 2 attempts have failed :
>
> -
> Trial 1 :
> -
>
> auto I = std.range.iota(0,500);
> int [] X; // output
> foreach (i; parallel(I) )
> X ~= i;
> core.thread.thread_joinAll(); // Apparently no applicable
here ?

As Michael Coulombe said, parallel() does that implicitly.

If the problem is to generate numbers in parallel, I 
restructured the code by letting each thread touch only its 
element of a results array that has already been resized for 
all the results (so that there is no race condition):


import std.stdio;
import std.parallelism;
import std.range;

void main() {
auto arrs = new int[][](totalCPUs);
const perWorker = 10;
foreach (i, arr; parallel(arrs)) {
const beg = cast(int)i * perWorker;
const end = beg + perWorker;
arrs[i] = std.range.iota(beg,end).array;
}

writeln(arrs);
}

If needed, std.algorithm.joiner can be used to make it a single 
sequence of ints:


import std.algorithm;
writeln(arrs.joiner);

Ali


Hello, thank you very much for your quick replies !

I was trying to make a trivial example, but the 'real' problem is 
trying to split a huge calculation to different threads.


Schematically :

double [] hugeCalc(int i){
// Code that takes a long time
}

so if I do


double[][int] _hugeCalcCache;
foreach(i ; I)
   _hugeCalcCache[i] = hugeCalc(i);

of course the required time is I.length * (a long time), so I 
wanted to shorten this by splitting to different threads :


foreach(i ; parallel(I) )
   _hugeCalcCache[i] = hugeCalc(i);

but as you can guess, it doesn't work that easily.

Very interesting approach about letting only the thread touch a 
particular element, I will try that.


FYI I did manage to make the following work, but not sure if this 
is really still multi-threaded ?



int [] I;
foreach (i; 0 .. 500) I ~= i;
int [] X; // output
class DerivedThread : Thread {
private int [] i;
this(int [] i){
this.i = i;
super();
}
private void run(){
synchronized{ // Need synchronization here !
foreach( i0; i)
X ~= i0;
}
}
}
Thread [] threads;
foreach (i; std.range.chunks( I, 50 ) )
threads ~= new DerivedThread( i);
foreach( thread; threads)
thread.start();

	core.thread.thread_joinAll(); // Does in fact seem to 'join all' 
threads

writeln(X);


Re: Simplest multithreading example

2017-08-31 Thread Ali Çehreli via Digitalmars-d-learn

On 08/31/2017 06:59 PM, Brian wrote:
> Hello, I am trying to get the most trivial example of multithreading
> working, but can't seem to figure it out.
> I want to split a task across threads, and wait for all those tasks to
> finish before moving to the next line of code.
>
> The following 2 attempts have failed :
>
> -
> Trial 1 :
> -
>
> auto I = std.range.iota(0,500);
> int [] X; // output
> foreach (i; parallel(I) )
> X ~= i;
> core.thread.thread_joinAll(); // Apparently no applicable here ?

As Michael Coulombe said, parallel() does that implicitly.

If the problem is to generate numbers in parallel, I restructured the 
code by letting each thread touch only its element of a results array 
that has already been resized for all the results (so that there is no 
race condition):


import std.stdio;
import std.parallelism;
import std.range;

void main() {
auto arrs = new int[][](totalCPUs);
const perWorker = 10;
foreach (i, arr; parallel(arrs)) {
const beg = cast(int)i * perWorker;
const end = beg + perWorker;
arrs[i] = std.range.iota(beg,end).array;
}

writeln(arrs);
}

If needed, std.algorithm.joiner can be used to make it a single sequence 
of ints:


import std.algorithm;
writeln(arrs.joiner);

Ali



Re: Simplest multithreading example

2017-08-31 Thread Michael Coulombe via Digitalmars-d-learn

On Friday, 1 September 2017 at 01:59:07 UTC, Brian wrote:
Hello, I am trying to get the most trivial example of 
multithreading working, but can't seem to figure it out.
I want to split a task across threads, and wait for all those 
tasks to finish before moving to the next line of code.


The following 2 attempts have failed :

-
Trial 1 :
-

auto I = std.range.iota(0,500);
int [] X; // output
foreach (i; parallel(I) )
X ~= i;
core.thread.thread_joinAll(); // Apparently no applicable here ?
writeln(X); // some random subset of indices


Trial 2 : (closer to Java)

class DerivedThread : Thread
{
int [] X;
int i;
this(int [] X, int i){
this.X = X;
this.i = i;
super();
}

private:
void run(){
X ~= i;
}
}

void main(){
auto I = std.range.iota(0,500);
int [] X; // output
Thread [] threads;
foreach (i; I )
threads ~= new DerivedThread( X,i);
foreach( thread; threads)
thread.start();
foreach( thread; threads)
thread.join(); // does not seem to do anything
core.thread.thread_joinAll(); // also not doing anything

writeln(X); // X contains nothing at all
}

How can I get the program to wait until all threads have 
finished before moving to the next line of code ?


Thank you !


Just like a sequential loop, when you do "foreach (i; parallel(I) 
) { ... }", execution will not continue past the foreach loop 
until all the tasks associated with each element of I have 
finished.


Your particular example of "X ~= i" in the body of the loop is 
not thread-safe, so if that is the code you really intend to run, 
you should protect X with a Mutex or something comparable.


Simplest multithreading example

2017-08-31 Thread Brian via Digitalmars-d-learn
Hello, I am trying to get the most trivial example of 
multithreading working, but can't seem to figure it out.
I want to split a task across threads, and wait for all those 
tasks to finish before moving to the next line of code.


The following 2 attempts have failed :

-
Trial 1 :
-

auto I = std.range.iota(0,500);
int [] X; // output
foreach (i; parallel(I) )
X ~= i;
core.thread.thread_joinAll(); // Apparently no applicable here ?
writeln(X); // some random subset of indices


Trial 2 : (closer to Java)

class DerivedThread : Thread
{
int [] X;
int i;
this(int [] X, int i){
this.X = X;
this.i = i;
super();
}

private:
void run(){
X ~= i;
}
}

void main(){
auto I = std.range.iota(0,500);
int [] X; // output
Thread [] threads;
foreach (i; I )
threads ~= new DerivedThread( X,i);
foreach( thread; threads)
thread.start();
foreach( thread; threads)
thread.join(); // does not seem to do anything
core.thread.thread_joinAll(); // also not doing anything

writeln(X); // X contains nothing at all
}

How can I get the program to wait until all threads have finished 
before moving to the next line of code ?


Thank you !



Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Aug 31, 2017 at 05:37:20PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> On Thursday, August 31, 2017 14:09:55 H. S. Teoh via Digitalmars-d-learn 
[...]
> I know. We've had this argument before.

I know. Let's not rehash that. :-)


[...]
> Even copying ranges in generic code does not have defined behavior,
> because different types have different semantics even if they follow
> the range API and pass isInputRange, isForwardRange, etc.

This is actually one of the prime reasons for my stance that we ought to
always use .save instead of assigning .front to a local variable.

Consider the case where .front returns a subrange.  As you state above,
copying this subrange does not have defined behaviour. One reason is the
difference in semantics between reference types and value types: the
assignment operator `=` means different things for each kind of type.
`x=y;` for a value type makes a new copy of the value in x, but `x=y;`
for a reference type only copies the reference, not the value.  So how
do you ensure that after assigning .front to a local variable, it will
continue to be valid after .popFront is called on the outer range? You
can't.  If you simply assign it, there's no guarantee it isn't just
copying a reference to a buffer reused by .popFront.  But if you try to
copy it, the result is not defined, as you said.

Worse yet, the user can overload opAssign() to do something with
side-effects. So this code:

auto e = r.front;
r.popFront();
userCallback(e);

may potentially have a different result from:

userCallback(r.front);
r.popFront();

The only safe approach is to make as few assumptions as possible, i.e.,
don't assume that `=` will produce the right result, so avoid saving
anything in local variables completely and always use .save instead if
you need to refer to a previous value of .front after calling .popFront.

Yes this greatly complicates generic code, and I wouldn't impose it on
user code.  But one would expect that Phobos, at the very least, ought
to be of a high enough standard to be able to handle such things
correctly.


Taking a step back from these nitpicky details, though: this seems to be
symptomic of the underlying difficulty of nailing exact range semantics
in an imperative language.  In a pure functional language without
mutation, you wouldn't have such issues, so there you could compose
arbitrarily complex ranges of arbitrarily complex behaviours with
impunity and not have to worry that something might break if one of the
subranges was transient.  We can't kill mutation in D, though, so
unfortunately we have to live with these complications.


T

-- 
Life begins when you can spend your spare time programming instead of watching 
television. -- Cal Keegan


Re: Valid File Path

2017-08-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, August 31, 2017 23:23:17 Vino via Digitalmars-d-learn wrote:
> On Thursday, 31 August 2017 at 21:59:22 UTC, vino wrote:
> > Hi All,
> >
> >   Can you help me what is wrong in the below program, as the
> >
> > output is empty.
> >
> > import std.stdio, std.path;
> >
> > void main ()
> > {
> > version (Windows)
> > {
> > auto Path = `C:\#Users\Admin\Desktop\Script\Test1`;
> > if(!Path.isValidPath) { writeln("Path Not Valid");}
> > }
> > }
> >
> > From,
> > Vino.B
>
> Hi,
>
> The path is not valid as it contains the character # after the
> drive name.

And why would that not be valid? isValidPath and isValidFilename are quite
specific about what they think are valid path/file names, and having a # in
a file name is perfectly legitimate. They do have some extra restrictions
for Windows, since Windows is a lot pickier about its filenames than the
rest of the world, but # is not one of the characters listed as invalid:

https://dlang.org/phobos/std_path.html#isValidPath
https://dlang.org/phobos/std_path.html#isValidFilename

It would be invalid to have # as a drive name, but it's perfectly legal in a
filename or directory name.

- Jonathan M Davis



Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, August 31, 2017 14:09:55 H. S. Teoh via Digitalmars-d-learn 
wrote:
> On Thu, Aug 31, 2017 at 01:34:39PM -0600, Jonathan M Davis via
> Digitalmars-d-learn wrote: [...]
>
> > In general, byLine does not work with other range-based algorithms
> > precisely because it reuses the buffer. I think that it does manage to
> > work for some, but IMHO, it should have just supported foreach via
> > opApply and not been a range at all. It's great for efficiency in a
> > loop but horrible for range chaining.
>
> [...]
>
> Transient ranges are tricky to work with, I agree, but I don't agree
> that they're "horrible for range chaining".  I argue that many range
> algorithms that assume the persistence of .front are inherently wrong,
> and ought to be implemented in a way that does *not* make this
> assumption.  Many std.algorithm algorithms *can* in fact be written in
> this way, and those that aren't, are arguably buggy.
>
> For example, some std.algorithm functions take a forward range but then
> tries to save .front to a local variable. Rather, they should use .save
> to save the previous position of the range so that they can call .front
> on that to access the previous element, instead of making the unfounded
> assumption that whatever the local variable refers to will still remain
> valid after calling .popFront.  It's just sloppy coding IMNSHO.

I know. We've had this argument before. Personally, I think that the range
spec should require that front _not_ be transient and that any ranges that
are be considered non-conformant. Yes, under some set of circumstances, they
can be made to work, but IMHO, it's simply not worth it. As it is, simply
calling save when it's supposed to be called gets totally botched all the
time even if ranges with transient front aren't involved. And adding such
ranges just makes it too complicated. What we have currently with the range
API allows for a lot of stuff to work correctly as long as certain
assumptions are bet, but as soon as folks start doing stuff that doesn't
behave the same way that a dynamic array does, things start falling apart.
Even copying ranges in generic code does not have defined behavior, because
different types have different semantics even if they follow the range API
and pass isInputRange, isForwardRange, etc. The status quo works well enough
that we get by, but it's a mess when you get into the details - especially
if you want code that's actually generic. And IMHO, trying to add ranges
with a transient front into the mix is taking it way to far. It's simply not
worth it. But I know that you don't agree with that.

- Jonathan M Davis



Re: Valid File Path

2017-08-31 Thread Vino via Digitalmars-d-learn

On Thursday, 31 August 2017 at 21:59:22 UTC, vino wrote:

Hi All,

  Can you help me what is wrong in the below program, as the 
output is empty.


import std.stdio, std.path;

void main ()
{
version (Windows)
{
auto Path = `C:\#Users\Admin\Desktop\Script\Test1`;
if(!Path.isValidPath) { writeln("Path Not Valid");}
}
}

From,
Vino.B

Hi,

The path is not valid as it contains the character # after the 
drive name.




replace switch for mapping

2017-08-31 Thread EntangledQuanta via Digitalmars-d-learn
Generally one has to use a switch to map dynamic components. 
Given a set X and Y one can form a switch to map X to Y:


switch(X)
{
   case x1 : y1; break;
   
   case x1 : y1;
}

Is there any easier way to do this where one simply specifies the 
set's rather than having to create a switch directly?


In my specific case, I have to map a two sets of types

A = {Ta1,...,Tan}
B = {Tb1,...,Tbm}

to a template function that takes two types

foo(Tak, Taj)

so, given an arbitrary (a,b) in AxB, it it maps to foo(F(a),G(b)).

Using switches would require n*m cases.

What I actually have is something like

enum X
{
   Float,
   Int,
   `Etc`
}

and X x, y;

and need to call foo!(x,y) but with x and y replaced by their 
correct D equivalent types.


e.g., if x = X.Float; y = X.Int; then I need to call 
foo!(float,int) rather than foo!(X.Float,x.Int).



This allows me to create a dynamic dispatcher at runtime and use 
a templated function rather than having to handle each type 
independently. One templated function rather than nxm regular 
functions for each type or a nxm switch.


Unfortunately, a complicating factor is that the enum's names do 
not directly correspond to the D types through some simple 
transformation(e.g., lowerCase). D doesn't seem to support 
attributes on enum members for some inane reason and using 
strings will complicate 
things[https://forum.dlang.org/post/nmgloo$bd1$1...@digitalmars.com]. I think I could use a struct though to solve that.


So, given something like

struct A
{
   @("float") enum Float = 0,
   @("int") enum Int = 1,
}

struct B
{
   @("double") enum Double = 0,
   @("short") enum Short = 1,
}

foo(T1,T2)();

create a mapping that takes an A and B and maps AxB to foo that 
does something like the following internally.


fooDispatch(A a, B b)
{
switch(a) // Actually needs to be over attributes
{
case "float" :
switch(b) // Actually needs to be over attributes
{
   case "double" : return foo!(float, double)();
}
...
}
}


or whatever. I could write a string mixin that generates the 
above code but I'm hoping I don't have to and some genius will 
find a simple way to do it quickly, efficiently, and performant.







Re: Valid File Path

2017-08-31 Thread Cym13 via Digitalmars-d-learn

On Thursday, 31 August 2017 at 21:59:22 UTC, vino wrote:

Hi All,

  Can you help me what is wrong in the below program, as the 
output is empty.


import std.stdio, std.path;

void main ()
{
version (Windows)
{
auto Path = `C:\#Users\Admin\Desktop\Script\Test1`;
if(!Path.isValidPath) { writeln("Path Not Valid");}
}
}

From,
Vino.B


It doesn't print anything because the path is valid. Why do you 
expect otherwise?


Note that isValidPath is only used for syntax check, it does not 
checks that the file or directory exists. If that is what you 
want use std.file.exists instead.


Valid File Path

2017-08-31 Thread vino via Digitalmars-d-learn

Hi All,

  Can you help me what is wrong in the below program, as the 
output is empty.


import std.stdio, std.path;

void main ()
{
version (Windows)
{
auto Path = `C:\#Users\Admin\Desktop\Script\Test1`;
if(!Path.isValidPath) { writeln("Path Not Valid");}
}
}

From,
Vino.B


Re: Remove all blank lines from a file

2017-08-31 Thread vino via Digitalmars-d-learn
On Thursday, 31 August 2017 at 15:48:31 UTC, Rene Zwanenburg 
wrote:

On Thursday, 31 August 2017 at 14:44:07 UTC, vino wrote:

Hi All,

  Can some provide me a example of how to remove all blank 
lines from a file.


From,
Vino.B


This one doesn't read the entire file into memory:

import std.stdio;
import std.array;
import std.algorithm;
import std.uni;

void main(string[] args)
{
auto inputFile = File(args[1]);
auto outputFile = File(args[2], "wb");

inputFile
.byLine
.filter!(line => !line.all!isWhite)
.copy(outputFile.lockingTextWriter);
}

But if you want to replace the input file, you'd have to write 
to a temp file, remove the original, then move the temp file.


Hi All,

  Thank you very much, was able to resolve the issue.

From,
Vino.B


Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Aug 31, 2017 at 01:34:39PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
[...]
> In general, byLine does not work with other range-based algorithms
> precisely because it reuses the buffer. I think that it does manage to
> work for some, but IMHO, it should have just supported foreach via
> opApply and not been a range at all. It's great for efficiency in a
> loop but horrible for range chaining.
[...]

Transient ranges are tricky to work with, I agree, but I don't agree
that they're "horrible for range chaining".  I argue that many range
algorithms that assume the persistence of .front are inherently wrong,
and ought to be implemented in a way that does *not* make this
assumption.  Many std.algorithm algorithms *can* in fact be written in
this way, and those that aren't, are arguably buggy.

For example, some std.algorithm functions take a forward range but then
tries to save .front to a local variable. Rather, they should use .save
to save the previous position of the range so that they can call .front
on that to access the previous element, instead of making the unfounded
assumption that whatever the local variable refers to will still remain
valid after calling .popFront.  It's just sloppy coding IMNSHO.


T

-- 
MS Windows: 64-bit rehash of 32-bit extensions and a graphical shell for a 
16-bit patch to an 8-bit operating system originally coded for a 4-bit 
microprocessor, written by a 2-bit company that can't stand 1-bit of 
competition.


Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-31 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 31 August 2017 at 14:43:39 UTC, Steven Schveighoffer 
wrote:
Just a thought, but the "double printing" could be a 
misunderstanding. It could be printing Output\nOutput2, but not 
getting the 2 out there.


No no, it's four lines instead of three.  If we change the lines 
to disjoint sets of letters, the problem persists.


Note that DMD 32-bit is using DMC libc. It might be that it 
gets hung up somehow when expecting input, like it locks the 
console somehow.


I would say that byLineCopy puts the thread to sleep waiting 
for input, and it doesn't get out of that state. So it could be 
that the bug only appears when it gets to that state at some 
point in the output. I'd pepper some sleeps around the outputs 
to see if you can make the context switches more predictable.


Inserting different sleeps into the threads makes the problem go 
away (cannot reproduce).  Inserting identical sleeps produces the 
error with roughly the same probability.


Anyway, I've reported it 
(https://issues.dlang.org/show_bug.cgi?id=17797), along with a 
more or less exact version (2.073.2) where the problem was 
introduced.


Ivan Kazmenko.



Re: Deprecation of toUTF16

2017-08-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/31/17 12:12 PM, Andre Pany wrote:

Hi,

I have some problems to find out what to use instead of the deprecated 
toUTF16 function.


I am calling a shared library written in Delphi.
While this coding is working fine (with german ü)

import std.utf: toUTF16;
wstring ws = toUTF16(s);
BSTR bStr = SysAllocStringLen(ws.ptr, cast(UINT) ws.length);

This coding fails to display the german ü correctly:

import std.utf: encode;
wchar[] ws;
s.each!(c => encode(ws, c));
BSTR bStr = SysAllocStringLen(ws.ptr, cast(UINT) ws.length);


Variable s is of type string. On delphi side WideString is used as type 
for the string.

Where is the error?



The error is actually in the compiler -- the toUTF16 function you are 
calling is NOT being deprecated. But the compiler mistakenly is marking 
it as deprecated.


See here:

https://issues.dlang.org/show_bug.cgi?id=17193

-Steve


Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, August 31, 2017 18:43:40 Jesse Phillips via Digitalmars-d-learn 
wrote:
> On Thursday, 31 August 2017 at 18:26:33 UTC, Sergei Degtiarev
>
> wrote:
> > Hi,
> > I tried to create a simple range concatenating several files,
> >
> > something like this:
> > File[] files;
> > 
> > foreach(ln; joiner(files.map!(a => a.byLine)))
> >
> > writeln(ln);
> >
> > and I see every first line of each file is missing.
> >
> > However, when I do same thing with separator:
> > char[][] separator=[" new file ".dup];
> > foreach(ln; joiner(files.map!(a => a.byLine), separator))
> >
> > writeln(ln);
> >
> > everything works fine, both separator and first lines are
> > printed.
> > It looks pretty much as a bug for me, but I'm not sure I use it
> > correctly.
>
> Doesn't byLine() reuse a buffer, joiner probably caches the first
> line and calls .popFront()

In general, byLine does not work with other range-based algorithms precisely
because it reuses the buffer. I think that it does manage to work for some,
but IMHO, it should have just supported foreach via opApply and not been a
range at all. It's great for efficiency in a loop but horrible for range
chaining. Folks get bit by this problem all the time. Fortunately, we now
have byLineCopy which actually uses a separate dynamic array for each line,
but even still, often, someone grabs byLine and then gets weird behavior
that they don't understand.

- Jonathan M Davis



Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Aug 31, 2017 at 06:26:33PM +, Sergei Degtiarev via 
Digitalmars-d-learn wrote:
[...]
>   File[] files;
>   
>   foreach(ln; joiner(files.map!(a => a.byLine)))
>   writeln(ln);

You probably want to use byLineCopy instead.

The problem here is that .byLine returns a transient range (i.e., the
value returned by .front changes after .popFront is called), which can
cause unexpected behaviour when used with certain algorithms.


T

-- 
I don't trust computers, I've spent too long programming to think that they can 
get anything right. -- James Miller


Re: std.algorithm.joiner unexpected behavior

2017-08-31 Thread Jesse Phillips via Digitalmars-d-learn
On Thursday, 31 August 2017 at 18:26:33 UTC, Sergei Degtiarev 
wrote:

Hi,
I tried to create a simple range concatenating several files, 
something like this:


File[] files;

foreach(ln; joiner(files.map!(a => a.byLine)))
writeln(ln);

and I see every first line of each file is missing.
However, when I do same thing with separator:

char[][] separator=[" new file ".dup];
foreach(ln; joiner(files.map!(a => a.byLine), separator))
writeln(ln);

everything works fine, both separator and first lines are 
printed.
It looks pretty much as a bug for me, but I'm not sure I use it 
correctly.


Doesn't byLine() reuse a buffer, joiner probably caches the first 
line and calls .popFront()


std.algorithm.joiner unexpected behavior

2017-08-31 Thread Sergei Degtiarev via Digitalmars-d-learn

Hi,
I tried to create a simple range concatenating several files, 
something like this:


File[] files;

foreach(ln; joiner(files.map!(a => a.byLine)))
writeln(ln);

and I see every first line of each file is missing.
However, when I do same thing with separator:

char[][] separator=[" new file ".dup];
foreach(ln; joiner(files.map!(a => a.byLine), separator))
writeln(ln);

everything works fine, both separator and first lines are printed.
It looks pretty much as a bug for me, but I'm not sure I use it 
correctly.




Re: Deprecation of toUTF16

2017-08-31 Thread Kagamin via Digitalmars-d-learn

import std.conv;
auto ws=s.to!wstring;


Deprecation of toUTF16

2017-08-31 Thread Andre Pany via Digitalmars-d-learn

Hi,

I have some problems to find out what to use instead of the 
deprecated toUTF16 function.


I am calling a shared library written in Delphi.
While this coding is working fine (with german ü)

import std.utf: toUTF16;
wstring ws = toUTF16(s);
BSTR bStr = SysAllocStringLen(ws.ptr, cast(UINT) ws.length);

This coding fails to display the german ü correctly:

import std.utf: encode;
wchar[] ws;
s.each!(c => encode(ws, c));
BSTR bStr = SysAllocStringLen(ws.ptr, cast(UINT) ws.length);


Variable s is of type string. On delphi side WideString is used 
as type for the string.

Where is the error?

Kind regards
André


Re: Parse tree node allocator

2017-08-31 Thread Stefan Koch via Digitalmars-d-learn

On Thursday, 31 August 2017 at 15:43:05 UTC, Per Nordlöw wrote:
Which allocator is best suited for allocating tree nodes (all 
of equal size around 40-60 bytes in size) in one shot and then 
delete them all in one go? My use case is parse trees.


Region Allocator.


Re: Remove all blank lines from a file

2017-08-31 Thread Rene Zwanenburg via Digitalmars-d-learn

On Thursday, 31 August 2017 at 14:44:07 UTC, vino wrote:

Hi All,

  Can some provide me a example of how to remove all blank 
lines from a file.


From,
Vino.B


This one doesn't read the entire file into memory:

import std.stdio;
import std.array;
import std.algorithm;
import std.uni;

void main(string[] args)
{
auto inputFile = File(args[1]);
auto outputFile = File(args[2], "wb");

inputFile
.byLine
.filter!(line => !line.all!isWhite)
.copy(outputFile.lockingTextWriter);
}

But if you want to replace the input file, you'd have to write to 
a temp file, remove the original, then move the temp file.


Re: Bug in D!!!

2017-08-31 Thread EntangledQuanta via Digitalmars-d-learn

On Thursday, 31 August 2017 at 10:34:14 UTC, Kagamin wrote:
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta 
wrote:

I've already implemented a half ass library solution.


It can be improved alot.


Then, by all means, genius!


Parse tree node allocator

2017-08-31 Thread Per Nordlöw via Digitalmars-d-learn
Which allocator is best suited for allocating tree nodes (all of 
equal size around 40-60 bytes in size) in one shot and then 
delete them all in one go? My use case is parse trees.


Re: Remove all blank lines from a file

2017-08-31 Thread Anonymouse via Digitalmars-d-learn

On Thursday, 31 August 2017 at 14:44:07 UTC, vino wrote:

Hi All,

  Can some provide me a example of how to remove all blank 
lines from a file.


From,
Vino.B


Super verbose, but:

import std.stdio;
import std.file;
import std.algorithm.iteration;

enum inFilename = "in.txt";
enum outFilename = "out.txt";

void main()
{
immutable lines = readText(inFilename);

char[] outbuffer;
outbuffer.reserve(lines.length);

foreach (line; lines.splitter("\n"))
{
if (!line.length) continue;

outbuffer ~= line;
outbuffer ~= "\n";
}

auto outfile = File(outFilename, "w");
outfile.write(outbuffer);
}



Re: Remove all blank lines from a file

2017-08-31 Thread Stefan Koch via Digitalmars-d-learn

On Thursday, 31 August 2017 at 14:44:07 UTC, vino wrote:

Hi All,

  Can some provide me a example of how to remove all blank 
lines from a file.


From,
Vino.B


ubyte[] fileData;
ubyte[] writeThis;
uint lastP;

fileData = readRaw(fileName);

foreach(uint p; ubyte b;fileData)
{
if (b == '\n')
{
writeThis ~= fileData[lastP .. p];
lastP = p;
}
}

write(fileName, fileData);


Remove all blank lines from a file

2017-08-31 Thread vino via Digitalmars-d-learn

Hi All,

  Can some provide me a example of how to remove all blank lines 
from a file.


From,
Vino.B


Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/30/17 9:33 AM, Ivan Kazmenko wrote:

On Wednesday, 30 August 2017 at 13:24:55 UTC, Ivan Kazmenko wrote:

On Wednesday, 30 August 2017 at 10:55:20 UTC, Timothy Foster wrote:

import std.stdio, core.thread;

void main(){
auto thread = new Thread().start;
    writeln("Output");
writeln("Output2");
writeln("Output3");
while(true){}
}

void func(){
    foreach(line; stdin.byLineCopy){}
}


I also cannot reproduce this.

My current system is Win7 64-bit.  I tried 32-bit dmd 2.072.0 and 
2.075.1, with optimizations turned on and off, but it prints correctly 
tens of times in each case.


Try running the program in a bare console (cmd.exe on Windows, or some 
*sh on Linux).  If the problem goes away, your usual environment is 
likely at fault.  If not,.. well, no idea for now.


Hey, I followed my own advice and do see the same issue! when:
1. compiling with dmd 2.075.1 (optimization switches seem to be 
irrelevant but the issue does not reproduce with 2.072.0),

2. running in a bare cmd.exe, and
3. running the program as just "a.exe", so that it waits for console 
input (previously I redirected some input to it, like "a.exe 

Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 13:33:06 UTC, Ivan Kazmenko wrote:
Interesting.  As to what to do with it, no idea for now.  At 
the very least we can issue a bug report, now that at least two 
people can reproduce it, so it is unlikely to be 
environment-dependent.


Reported: https://issues.dlang.org/show_bug.cgi?id=17797 .



Re: Output range with custom string type

2017-08-31 Thread Moritz Maxeiner via Digitalmars-d-learn

On Thursday, 31 August 2017 at 07:06:26 UTC, Jacob Carlborg wrote:

On 2017-08-29 19:35, Moritz Maxeiner wrote:


 void put(T t)
 {
     if (!store)
     {
     // Allocate only once for "small" vectors
     store = alloc.makeArray!T(8);
     if (!store) onOutOfMemoryError();
     }
     else if (length == store.length)
     {
     // Growth factor of 1.5
     auto expanded = alloc.expandArray!char(store, 
store.length / 2);

     if (!expanded) onOutOfMemoryError();
     }
     assert (length < store.length);
     moveEmplace(t, store[length++]);
 }


What's the reason to use "moveEmplace" instead of just 
assigning to the array: "store[length++] = t" ?


The `move` part is to support non-copyable types (i.e. T with 
`@disable this(this)`), such as another owning container 
(assigning would generally try to create a copy).
The `emplace` part is because the destination `store[length]` has 
been default initialized either by makeArray or expandArray and 
it doesn't need to be destroyed (a pure move would destroy 
`store[length]` if T has a destructor).


Re: Transitive const and function pointers/delegates

2017-08-31 Thread Kagamin via Digitalmars-d-learn

It's const(int delegate(char))


Re: Bug in D!!!

2017-08-31 Thread Kagamin via Digitalmars-d-learn
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta 
wrote:

I've already implemented a half ass library solution.


It can be improved alot.


Re: "Range invalidation" ?

2017-08-31 Thread Mark via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 15:06:12 UTC, Jonathan M Davis 
wrote:

[...]


Thank you for the detailed response.


Re: Output range with custom string type

2017-08-31 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-08-29 19:35, Moritz Maxeiner wrote:


 void put(T t)
 {
     if (!store)
     {
     // Allocate only once for "small" vectors
     store = alloc.makeArray!T(8);
     if (!store) onOutOfMemoryError();
     }
     else if (length == store.length)
     {
     // Growth factor of 1.5
     auto expanded = alloc.expandArray!char(store, store.length 
/ 2);

     if (!expanded) onOutOfMemoryError();
     }
     assert (length < store.length);
     moveEmplace(t, store[length++]);
 }


What's the reason to use "moveEmplace" instead of just assigning to the 
array: "store[length++] = t" ?


--
/Jacob Carlborg


Re: hijack dub test

2017-08-31 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-08-31 08:41, Nicholas Wilson wrote:
My project is a library, but I also need to test it and unit tests won't 
cut it (external hardware).


How do you set up the dub.json to build the library normally but when it 
is invoked with `dub test` it runs a separate configuration that also 
includes files in the `source/test` folder, but are excluded when not 
testing.


"The configuration name "unittest" has a special meaning - if a 
configuration with this name is present, it will be used by default when 
executing dub test." [1]


[1] http://code.dlang.org/package-format?lang=json#configurations

--
/Jacob Carlborg


hijack dub test

2017-08-31 Thread Nicholas Wilson via Digitalmars-d-learn
My project is a library, but I also need to test it and unit 
tests won't cut it (external hardware).


How do you set up the dub.json to build the library normally but 
when it is invoked with `dub test` it runs a separate 
configuration that also includes files in the `source/test` 
folder, but are excluded when not testing.


If thats not possible how does one specify that `source/test` 
should not be built when building a library and only 
`source/test` should be built when doing tests, but the tester 
depend in the library?


Thanks
Nic