Re: Natural sorted list of files

2017-02-07 Thread Dmitry via Digitalmars-d-learn

On Wednesday, 8 February 2017 at 07:41:29 UTC, Ali Çehreli wrote:
test.naturalSort would sort the array in place before calling 
writeln and 'test' would appear naturally sorted as well. I've 
fixed it like this:


Great! Thank you!



Re: Natural sorted list of files

2017-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 02/06/2017 09:00 PM, Dmitry wrote:
> On Monday, 6 February 2017 at 18:57:17 UTC, Ali Çehreli wrote:
>> I think  it's now std.algorithm.chunkBy. Please fix Rosetta
>
> Thank you!
> I fixed

Thank you!

> but anyway it works incorrect (it doesn't any changes):

The problem was with the following loop:

foreach (test; tests)
writeln(test, "\n", test.naturalSort, "\n");

test.naturalSort would sort the array in place before calling writeln 
and 'test' would appear naturally sorted as well. I've fixed it like this:


foreach (test; tests) {
printTexts("Test strings", test);
printTexts("Normally sorted", test.dup.sort());
printTexts("Naturally sorted", test.dup.naturalSort());
}

I had fun inserting "[sic]"s both in source code and in the output for 
the INDEPENENT typo in the problem description. :D


void printTexts(Range)(string tag, Range range) {
const sic = range.front.canFind("INDEPENENT") ? " [sic]" : "";
writefln("\n%s%s:\n%-(  |%s|%|\n%)", tag, sic, range);
}

I also made the output more readable:

Test strings:
  |ignore leading spaces: 2-2|
  | ignore leading spaces: 2-1|
  |
 ignore leading spaces: 2+1|
  |  ignore leading spaces: 2+0|

Normally sorted:
  |
 ignore leading spaces: 2+1|
  |  ignore leading spaces: 2+0|
  | ignore leading spaces: 2-1|
  |ignore leading spaces: 2-2|

Naturally sorted:
  |  ignore leading spaces: 2+0|
  |
 ignore leading spaces: 2+1|
  | ignore leading spaces: 2-1|
  |ignore leading spaces: 2-2|

[...]

Ali



Re: Pass type directly to a template function?

2017-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 02/07/2017 01:17 AM, Chris Katko wrote:


void function3(T)(T) //hypothetical, specify the datatype in the
argument list
{
T data;
}


Related:

  https://dlang.org/library/object/type_info.html

and

  https://dlang.org/library/object/object.factory.html

This compiles but I'm not sure how to use it effectively:

import std.stdio;

auto function3(TypeInfo ti)
{
return ti.initializer();
}

void main()
{
writeln(function3(typeid(float)));
writeln(function3(typeid(double)));
}

Ali



Re: Pass type directly to a template function?

2017-02-07 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 21:40:04 UTC, Dukc wrote:

On Tuesday, 7 February 2017 at 10:21:20 UTC, Mike Parker wrote:

function2!float(); //?
function3!float(); //?


Yes, this is how it's done.


Not quite with function3, because it takes one unnamed runtime 
parameter. It can be called like function1 however. The value 
of the parameter does not matter because it's unused, only the 
type.


Yes, I missed the runtime parameter.


Re: Array start index

2017-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 02/07/2017 02:04 PM, Bastiaan Veelo wrote:

>> This optimization cannot work if the array is a static array inside
>> the same struct. It would work with a dynamic array but then it would
>> probably be slower than applying the *(ptr+index) technique.
>
> You mean slower than the _payload[index - first] technique? Is that
> because of heap memory versus stack memory?

Mandatory disclaimer: We can't be sure without testing.

Not exactly because stack versus heap because the whole object might be 
sitting in heap memory anyway:


alias S = StaticArray!(/* ... */);

S[] objects;
objects ~= S(/* ... */);

So, all of those are on the heap.

It's more about having everything at hand, near each other, close in 
memory. If the member is a static array, then when we have an S[], all 
members are there to be operated on. If the array in dynamic, then an 
S[] has indirections, reaching out to the heap, which may involve 
long-latency memory reads.


foreach (s; objects) {
s[42];// May have a cache miss and read from memory
}

In the static array case, the entire body of s is already on the cache.

On the other hand, when the objects are large, then few of those can fit 
in the cache. etc. One needs to profile to see what works better.


> Am I correct that the reason that a dynamic array would work is because
> it is allocated independently from the struct, meaning that its address
> stays the same even if the struct is moved?

Yes, that would be a requirement to prevent the self-reference.

> We could .reserve a dynamic
> array in initialize() to prevent it being resized.

Makes sense.

Another solution that came to my mind: You can keep the self-referencing 
solution but make sure that the objects are not moved after initialize():


S[] objects;
objects.reserve(100);
objects.each!(o => o.initialize());
// The objects will not move if you're careful

> Thanks again.
> Bastiaan.

Ali



Re: Array start index

2017-02-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 20:33:35 UTC, Ali Çehreli wrote:

On 02/07/2017 02:11 AM, Bastiaan Veelo wrote:

> We do not need to take measures against the GC?

Of course we have to and the struct that I wrote is illegal 
because it is self-referencing through the _ptr member. (D has 
the right to move structs around, making my _ptr potentially 
pointing to an illegal address.)


Gosh am I glad I brought that up, and for people like you hanging 
out in the learn group. Thanks for pointing this out!


This optimization cannot work if the array is a static array 
inside the same struct. It would work with a dynamic array but 
then it would probably be slower than applying the *(ptr+index) 
technique.


You mean slower than the _payload[index - first] technique? Is 
that because of heap memory versus stack memory?


Am I correct that the reason that a dynamic array would work is 
because it is allocated independently from the struct, meaning 
that its address stays the same even if the struct is moved? We 
could .reserve a dynamic array in initialize() to prevent it 
being resized.


Thanks again.
Bastiaan.


Re: Why File.rawRead is @system?

2017-02-07 Thread Dukc via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 09:21:18 UTC, Kagamin wrote:
Can't find a reason why it's not inferred @safe (on linux). Any 
idea?
Perhaps you are trying to read as a type for which a conversion 
from string to it is @system? Not sure if that's possible.




Re: Pass type directly to a template function?

2017-02-07 Thread Dukc via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 10:21:20 UTC, Mike Parker wrote:

function2!float(); //?
function3!float(); //?


Yes, this is how it's done.


Not quite with function3, because it takes one unnamed runtime 
parameter. It can be called like function1 however. The value of 
the parameter does not matter because it's unused, only the type.





Re: Array start index

2017-02-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 20:28:30 UTC, Ali Çehreli wrote:

You forgot to call that most important function. ;)


Hah of course. I assumed the name would give it some special 
meaning, like postblit.


1) I don't understand the first assert there, which does not 
pass for me, so I commented it out.


The intention is to check that (_payload.ptr - first) is larger 
than 0.


2) May bad: init() is not a good name for a struct member, so 
it should be renamed:


void initialize() {
// assert( first < cast(size_t)_payload.ptr);
   // Address space underrun.
assert(-first < size_t.max - cast(size_t)_payload.ptr); 
// Address space overrun.

this._ptr = _payload.ptr - first;
}

3) Instead of having to remember to call it, let's introduce a 
function that does it for us:


auto makeStaticArray(T, ptrdiff_t first, ptrdiff_t last)() {
auto s = StaticArray!(T, first, last)();
s.initialize();
return s;
}


OK good.


unittest {
// StaticArray!(int, -10, 10) arr;
auto arr = makeStaticArray!(int, -10, 10);

> foreach (i, ref e; arr)
> e = i;

Unrelated: That line passes because you're building 32-bits. 
Here is the error I got:


  Error: cannot implicitly convert expression (i) of type long 
to int


You can cast it:

e = cast(int)i;

or by

import std.conv : to;
e = i.to!int;


Thanks a lot for your illustrative answers, including the next 
one!


Bastiaan.


Re: Array start index

2017-02-07 Thread Ali Çehreli via Digitalmars-d-learn

Pressed send too soon, before considering your GC question.

On 02/07/2017 02:11 AM, Bastiaan Veelo wrote:

> We do not need to take measures against the GC?

Of course we have to and the struct that I wrote is illegal because it 
is self-referencing through the _ptr member. (D has the right to move 
structs around, making my _ptr potentially pointing to an illegal address.)


This optimization cannot work if the array is a static array inside the 
same struct. It would work with a dynamic array but then it would 
probably be slower than applying the *(ptr+index) technique.


Ali



Re: Array start index

2017-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 02/07/2017 02:11 AM, Bastiaan Veelo wrote:

> void init() {
> assert( first < cast(size_t)_payload.ptr);  //
> Address space underrun.
> assert(-first < size_t.max - cast(size_t)_payload.ptr); //
> Address space overrun.
> this._ptr = _payload.ptr - first;
> }

You forgot to call that most important function. ;)

1) I don't understand the first assert there, which does not pass for 
me, so I commented it out.


2) May bad: init() is not a good name for a struct member, so it should 
be renamed:


void initialize() {
// assert( first < cast(size_t)_payload.ptr);  // 
Address space underrun.
assert(-first < size_t.max - cast(size_t)_payload.ptr); // 
Address space overrun.

this._ptr = _payload.ptr - first;
}

3) Instead of having to remember to call it, let's introduce a function 
that does it for us:


auto makeStaticArray(T, ptrdiff_t first, ptrdiff_t last)() {
auto s = StaticArray!(T, first, last)();
s.initialize();
return s;
}

unittest {
// StaticArray!(int, -10, 10) arr;
auto arr = makeStaticArray!(int, -10, 10);

> foreach (i, ref e; arr)
> e = i;

Unrelated: That line passes because you're building 32-bits. Here is the 
error I got:


  Error: cannot implicitly convert expression (i) of type long to int

You can cast it:

e = cast(int)i;

or by

import std.conv : to;
e = i.to!int;

Ali



Re: Initialization of dynamic multidimensional array

2017-02-07 Thread berni via Digitalmars-d-learn

auto arr = uninitializedArray!(int[][])(ROWS,COLS);
arr.each!"a[]=-1";


This looks like what I was looking for. At least I think I 
understand what's going on here. The other two suggestions are 
beyond my scope yet, but I'll come back, when I improved on my D 
skills. Thanks for your replies.




Re: Initialization of dynamic multidimensional array

2017-02-07 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Sunday, 5 February 2017 at 20:33:06 UTC, berni wrote:

With X not known at compile time:


auto arr = new int[][](X,X);
for (int i=0;i

Re: How do I call a C++ struct default constructor from D?

2017-02-07 Thread MGW via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 13:37:01 UTC, Atila Neves wrote:

Here still example
https://pp.vk.me/c636630/v636630885/46579/neSdIip1ySI.jpg



Re: How do I call a C++ struct default constructor from D?

2017-02-07 Thread MGW via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 13:37:01 UTC, Atila Neves wrote:

On Tuesday, 7 February 2017 at 10:46:24 UTC, kinke wrote:

I've only every done trivial C++ integration before. As soon as 
I tried something "real" it all broke down incredibly fast. 
Probably going to have to file some bugs on name mangling.



Atila


Perhaps this video will help
https://www.youtube.com/watch?v=HTgJaRRfLPk



Re: How do I call a C++ struct default constructor from D?

2017-02-07 Thread Atila Neves via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 10:46:24 UTC, kinke wrote:

On Tuesday, 7 February 2017 at 10:15:09 UTC, Atila Neves wrote:

I can declare a C++ struct like so:

extern(C++, mynamespace)
struct Foo {
   //...
}

But... I don't want to repeat the initialisation code for that 
struct's default constructor. I can't declare one in D because 
D doesn't allow default constructors for structs. What's my 
way out? Thanks,


Atila


I'm afraid there's no way out. I summarized some of my C++ 
interop findings incl. default constructor here: 
http://forum.dlang.org/thread/nqxsdehlydizatopr...@forum.dlang.org


Ugh, I was afraid of that. I ended up having to write (!) a C++ 
function that returned the default-initialised struct and called 
that from D.


It got uglier soon after...

I've only every done trivial C++ integration before. As soon as I 
tried something "real" it all broke down incredibly fast. 
Probably going to have to file some bugs on name mangling.



Atila




Re: How do I call a C++ struct default constructor from D?

2017-02-07 Thread kinke via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 10:15:09 UTC, Atila Neves wrote:

I can declare a C++ struct like so:

extern(C++, mynamespace)
struct Foo {
   //...
}

But... I don't want to repeat the initialisation code for that 
struct's default constructor. I can't declare one in D because 
D doesn't allow default constructors for structs. What's my way 
out? Thanks,


Atila


I'm afraid there's no way out. I summarized some of my C++ 
interop findings incl. default constructor here: 
http://forum.dlang.org/thread/nqxsdehlydizatopr...@forum.dlang.org


Re: Pass type directly to a template function?

2017-02-07 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 09:17:04 UTC, Chris Katko wrote:
Can I pass a type, instead of a variable of a type, to a 
template function in order to decide the datatype of T in a 
function?


Yes. That's rather the point.



function1(f); //works


That is actually shorthand for this:

function1!float(f);

The compiler is inferring the type of f for you.




function2!float(); //?
function3!float(); //?


Yes, this is how it's done.


function3(float);  //?
function3(double); //?


No. This won't compile.





It seems like this would be a useful construct for Factory 
pattern that assembles any class that you specify as long as 
the called methods work out. (ala Duck Typing, "if it walks() 
and quacks() like a duck, it's a duck")


The range infrastructure is based on this concept.





How do I call a C++ struct default constructor from D?

2017-02-07 Thread Atila Neves via Digitalmars-d-learn

I can declare a C++ struct like so:

extern(C++, mynamespace)
struct Foo {
   //...
}

But... I don't want to repeat the initialisation code for that 
struct's default constructor. I can't declare one in D because D 
doesn't allow default constructors for structs. What's my way 
out? Thanks,


Atila


Re: Array start index

2017-02-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 6 February 2017 at 23:42:55 UTC, Ali Çehreli wrote:

Then you use _ptr when indexing:

// Support e = arr[5];
ref T opIndex(ptrdiff_t index) {
assert(index >= first);
assert(index <= last);
return *(_ptr + index);
}

Ali


Thank you very much for your time. Sadly this gives me an access 
violation. The traceback doesn't seem right though, as it seems 
to jump to opIndexAssign from where opIndex is used. If I'm not 
mistaken, I have confirmed that _ptr is a valid address, see 
below. We do not need to take measures against the GC?


- Bastiaan.


On Windows:

rdmd -main -unittest -debug -g source\epcompat\array.d

object.Error@(0): Access Violation

0x00402057 in void epcompat.array.__unittestL81_1() at 
C:\SARC\Pascal2017\D\epcompat\source\epcompat\array.d(88)
0x0040465C in void epcompat.array.__modtest() at 
C:\SARC\Pascal2017\D\epcompat\source\epcompat\array.d(39)
0x0040A455 in int 
core.runtime.runModuleUnitTests().__foreachbody1(object.ModuleInfo*)
0x0040C007 in int object.ModuleInfo.opApply(scope int 
delegate(object.ModuleInfo*)).__lambda2(immutable(object.ModuleInfo*))

0x00406808 in _d_run_main
0x004046D4 in main at 
C:\SARC\Pascal2017\D\epcompat\source\epcompat\array.d(7)

0x004225DD in mainCRTStartup
0x779C62C4 in BaseThreadInitThunk
0x77B50FD9 in RtlSubscribeWnfStateChangeNotification
0x77B50FA4 in RtlSubscribeWnfStateChangeNotification

The complete source:

module epcompat.array;

// Test with rdmd -main -unittest -debug -g 
source\epcompat\array.d


alias StaticArray_offset StaticArray;

/*
 * A fixed-length array with an index that runs from $(D_PARAM 
first)

 * to $(D_PARAM last) inclusive.
 *
 * Implemented by means of an offset pointer.
 */
struct StaticArray_offset(T, ptrdiff_t first, ptrdiff_t last) {
T[last - first + 1] _payload;
T* _ptr;

void init() {
assert( first < cast(size_t)_payload.ptr);  
// Address space underrun.
assert(-first < size_t.max - cast(size_t)_payload.ptr); 
// Address space overrun.

this._ptr = _payload.ptr - first;
}

size_t length() {
return _payload.length;
}

// Support e = arr[5];
ref T opIndex(ptrdiff_t index) {
assert(index >= first);
assert(index <= last);
return *(_ptr + index);
}

// Support arr[5] = e;
void opIndexAssign(U : T)(auto ref U value, ptrdiff_t index) {
assert(index >= first);
assert(index <= last);
*(_ptr + index) = value;
}   // Line 39

// Support foreach(e; arr).
int opApply(scope int delegate(ref T) dg)
{
int result = 0;

for (int i = 0; i < _payload.length; i++)
{
result = dg(_payload[i]);
if (result)
break;
}
return result;
}

// Support foreach(i, e; arr).
int opApply(scope int delegate(ptrdiff_t index, ref T) dg)
{
int result = 0;

for (int i = first; i <= last; i++)
{
result = dg(i, *(_ptr + i));
if (result)
break;
}
return result;
}

// Write to binary file.
void toFile(string fileName)
{
import std.stdio;
auto f = File(fileName, "wb");
if (f.tryLock)
{
f.rawWrite(_payload);
}
}
}

unittest {
StaticArray!(int, -10, 10) arr;
assert(arr.length == 21);

foreach (ref e; arr)
e = 42;

assert(arr[-10] == 42); // Line 88
assert(arr[0]   == 42);
assert(arr[10]  == 42);

foreach (i, ref e; arr)
e = i;

assert(arr[-10] == -10);
assert(arr[0]   ==   0);
assert(arr[5]   ==   5);
assert(arr[10]  ==  10);

arr[5] = 15;
assert(arr[5]   == 15);
}



Re: Why File.rawRead is @system?

2017-02-07 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 7 February 2017 at 09:21:18 UTC, Kagamin wrote:
Can't find a reason why it's not inferred @safe (on linux). Any 
idea?


Uh ? It's safe

Just tried


import std.stdio;

void main(string[] args) @safe
{
File f;
ubyte[] z;
z = f.rawRead(z);
}


And it compiles (DMD 2.073, Linux, X86_64)


Why File.rawRead is @system?

2017-02-07 Thread Kagamin via Digitalmars-d-learn
Can't find a reason why it's not inferred @safe (on linux). Any 
idea?


Pass type directly to a template function?

2017-02-07 Thread Chris Katko via Digitalmars-d-learn
Can I pass a type, instead of a variable of a type, to a template 
function in order to decide the datatype of T in a function?


void function(T)(T x) //works
 {
T data;
//do stuff with T, ignoring x.
}


void function2(T)() //hypothetical, specify the type... somehow?
{
T data;
}

void function3(T)(T) //hypothetical, specify the datatype in the 
argument list

{
T data;
}


void main()
{
float f=0;
float d=0;
function1(f); //works
function1(d); //works

function2!float(); //?
function3!float(); //?

function3(float);  //?
function3(double); //?
}



It seems like this would be a useful construct for Factory 
pattern that assembles any class that you specify as long as the 
called methods work out. (ala Duck Typing, "if it walks() and 
quacks() like a duck, it's a duck")