Re: Simple immutable example doesn't work - why???

2013-11-12 Thread Kenji Hara

On Tuesday, 12 November 2013 at 01:15:02 UTC, Louis Berube wrote:
Thanks, I think I understand. Now, how about an array of 
immutables:


immutable class Test
{
public:
this(in uint value)
{
this.value = value;
}
unittest
{
auto t = new immutable Test(4);
assert (t.value == 4);
}
unittest
{
auto tarray = new immutable(Test)[3];
tarray[0] = new immutable Test(4);
// "Error: cannot modify
// immutable expression
// tarray[0]"
}
private:
uint value;
}

I thought the parantheses in the array declaration would do the 
trick, but apparently not.


Once you initialize an immutable class reference, you won't be 
able to rebind it anymore.

As far as I know there's two straight methods.

immutable class Test
{
this(in uint value)
{
this.value = value;
}
uint value;
}

void main()
{
version(Try1)
{
// 1. concatenate elements
immutable(Test)[] tarray;
tarray ~= new immutable Test(2);
tarray = new immutable Test(1) ~ tarray;
}
else
{
// 2. use array literal syntax
auto tarray = [
new immutable Test(1),
new immutable Test(2),
];
}
static assert(is(typeof(tarray[0]) == immutable(Test)));
assert(tarray.length == 2)
assert(tarray[0].value == 1);
assert(tarray[1].value == 2);
}

In D, you can reserve continuous memory area for array appending 
by using built-in 'reserve' method. Therefore in most cases, 
"reserve elements on empty array, then append created elements" 
would be the efficient way to initialize the array of immutable 
elements.


void main()
{
immutable(Test)[] tarray;

tarray.reserve(2);
auto save_ptr = tarray.ptr;
assert(save_ptr !is null && tarray.capacity >= 2);
// underlying memory is allocated and the appendable number 
is more than 2.


assert(tarray.length == 0);
// but array itself is still empty.

tarray ~= new immutable Test(1);
tarray ~= new immutable Test(2);

assert(tarray.length == 2);
// array is expectedly filled.

assert(tarray.ptr is save_ptr);
// But the two concatenations didn't reallocate underlying 
memory.

}

And I don't recommend to use std.exception.assumeUnique, because 
it is just a cosmetic function to make ugly (but necessary for 
some reason) array cast grep-able and human-readable.


Kenji Hara


Re: dchar literals?

2013-11-12 Thread Kenji Hara

On Monday, 11 November 2013 at 13:20:04 UTC, bearophile wrote:

Philippe Sigaud:

And I agree with you than character literals should default to 
dchar. It's

a perpetual source of friction for me.


99% of my char literals need to be of type char.

On the other hand once you have suffixes to specify the char 
type, most of that problem vanishes, because writing 'x'c or 
'x'w, 'x'd is good.


Bye,
bearophile


Or, uniform construction for built-in types would be another 
better way.


auto c = char('a');
auto w = wchar('a');
auto d = dchar('a');

auto x = char('à');   // compile-time error

Kenji Hara


Re: dchar literals?

2013-11-12 Thread Jonathan M Davis
On Tuesday, November 12, 2013 09:14:54 Kenji Hara wrote:
> On Monday, 11 November 2013 at 13:20:04 UTC, bearophile wrote:
> > Philippe Sigaud:
> >> And I agree with you than character literals should default to
> >> dchar. It's
> >> a perpetual source of friction for me.
> > 
> > 99% of my char literals need to be of type char.
> > 
> > On the other hand once you have suffixes to specify the char
> > type, most of that problem vanishes, because writing 'x'c or
> > 'x'w, 'x'd is good.
> > 
> > Bye,
> > bearophile
> 
> Or, uniform construction for built-in types would be another
> better way.
> 
> auto c = char('a');
> auto w = wchar('a');
> auto d = dchar('a');
> 
> auto x = char('à');   // compile-time error

That's more verbose, but it's something that I think we need anyway, and it 
might be enough to make it not worth adding the suffixes to character literals.

- Jonathan M Davis


Re: bidirectional map

2013-11-12 Thread Andrea Fontana
On Tuesday, 12 November 2013 at 01:14:47 UTC, bioinfornatics 
wrote:

Dear,
I am looking for a bidirectional map i.e 
http://en.wikipedia.org/wiki/Bidirectional_map


My seach into D documentation seem to said to me that this 
structure is not implemented.


Something like (for primary idea):


struct BidirectionalMap(T,U){
private:
T[U] _forwardHash;
U[T] _reverseHash;

public:

@safe
void opIndeyAssign( T k, U v){ // pure?
_forwardHash[k] = v;
_reverseHash[v] = k;
}


@property
BidirectionalMap!(T,U) dup(){
return BidirectionalMap!(T,U)( this );
}
}


Maybe we can get a better (faster/lighter) implementation if T==U 
(using sorted (T,T) tuples?)


By the way:

map[10] = 5; //   =>  _forwardHash[10] = 5; _reverseHash[5] = 10;
map[10] = 3; //   =>  _forwardHash[10] = 3; _reverseHash[3] = 10;

So:
_reverseHash[5] == 10; // True, it should not, should it?








Re: dchar literals?

2013-11-12 Thread bearophile

Kenji Hara:

Or, uniform construction for built-in types would be another 
better way.


auto c = char('a');
auto w = wchar('a');
auto d = dchar('a');

auto x = char('à');   // compile-time error


Yes, uniform construction syntax for all types seems a good idea. 
But the suffixes for chars, as the strings, could be a good idea 
any way, it's shorter, and it's symmetric with strings.


Bye,
bearophile


how use lowerBound with just sorting key, not complete values

2013-11-12 Thread Daniel Davidson
The following code works for finding the lower bound based on 
needle. But I have to create a needle which I don't want to do. 
How can I use lowerBound with just the sortKey, date in this 
case?  So I want to do something like the following - but it 
won't work. Is there a way to search an array I know is ordered 
by date by only supplying date?


assumeSorted!q{ a.date < b.date }(sarr)
  .lowerBound(Date(2000,2,1));

Thanks
Dan
---

import std.stdio;
import std.range;
import std.datetime;
import std.algorithm;
import std.array;

struct S {
  Date date;
  string foo;
}

void main() {
  auto sarr = [ S(Date(2000,1,1), "x"),
S(Date(2000,2,1), "a"),
S(Date(2000,3,1), "foo") ];
  assert(sort!q{ a.date < b.date }(sarr).array == sarr);

  auto needle = S(Date(2000,2,1));
  writeln(assumeSorted!q{ a.date < b.date }(sarr)
  .lowerBound(needle));

  writeln(sarr);
}




Re: bidirectional map

2013-11-12 Thread bioinfornatics
On Tuesday, 12 November 2013 at 09:10:07 UTC, Andrea Fontana 
wrote:
On Tuesday, 12 November 2013 at 01:14:47 UTC, bioinfornatics 
wrote:

Dear,
I am looking for a bidirectional map i.e 
http://en.wikipedia.org/wiki/Bidirectional_map


My seach into D documentation seem to said to me that this 
structure is not implemented.


Something like (for primary idea):


struct BidirectionalMap(T,U){
   private:
   T[U] _forwardHash;
   U[T] _reverseHash;

   public:

   @safe
   void opIndeyAssign( T k, U v){ // pure?
   _forwardHash[k] = v;
   _reverseHash[v] = k;
   }


   @property
   BidirectionalMap!(T,U) dup(){
   return BidirectionalMap!(T,U)( this );
   }
}


Maybe we can get a better (faster/lighter) implementation if 
T==U (using sorted (T,T) tuples?)


By the way:

map[10] = 5; //   =>  _forwardHash[10] = 5; _reverseHash[5] = 
10;
map[10] = 3; //   =>  _forwardHash[10] = 3; _reverseHash[3] = 
10;


So:
_reverseHash[5] == 10; // True, it should not, should it?


Maybe using Variant will allow to use 1 associative array


Re: how use lowerBound with just sorting key, not complete values

2013-11-12 Thread bearophile

Daniel Davidson:

Is there a way to search an array I know is ordered by date by 
only supplying date?


You can use a map to perform a projection:


import std.stdio, std.range, std.datetime, std.algorithm,
   std.array;

struct S {
Date date;
string foo;
}

void main() {
auto sarr = [S(Date(2000, 1, 1), "x"),
 S(Date(2000, 2, 1), "a"),
 S(Date(2000, 3, 1), "foo")];
assert(sarr.isSorted!q{ a.date < b.date });

auto needle = S(Date(2000, 2, 1));

sarr
.assumeSorted!q{ a.date < b.date }
.lowerBound(needle)
.writeln;

sarr.writeln;

sarr
.map!(s => s.date)
.assumeSorted
.lowerBound(Date(2000, 2, 1))
.writeln;
}


Output:

[S(2000-Jan-01, "x")]
[S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")]
[2000-Jan-01]

Bye,
bearophile


Re: how use lowerBound with just sorting key, not complete values

2013-11-12 Thread Daniel Davidson

On Tuesday, 12 November 2013 at 15:51:53 UTC, bearophile wrote:

Daniel Davidson:

Is there a way to search an array I know is ordered by date by 
only supplying date?


You can use a map to perform a projection:


import std.stdio, std.range, std.datetime, std.algorithm,
   std.array;

struct S {
Date date;
string foo;
}

void main() {
auto sarr = [S(Date(2000, 1, 1), "x"),
 S(Date(2000, 2, 1), "a"),
 S(Date(2000, 3, 1), "foo")];
assert(sarr.isSorted!q{ a.date < b.date });

auto needle = S(Date(2000, 2, 1));

sarr
.assumeSorted!q{ a.date < b.date }
.lowerBound(needle)
.writeln;

sarr.writeln;

sarr
.map!(s => s.date)
.assumeSorted
.lowerBound(Date(2000, 2, 1))
.writeln;
}


Output:

[S(2000-Jan-01, "x")]
[S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, 
"foo")]

[2000-Jan-01]

Bye,
bearophile


Yes, but that is only giving the dates. I want the actual array 
elements. Suppose S is a large object with lots of extra fields 
in addition to `string foo`. There should be a way to pull out 
the lower bound based on a date without creating a needle (S). 
Maybe lowerBound is not the right function?


Thanks
Dan


Re: how use lowerBound with just sorting key, not complete values

2013-11-12 Thread bearophile

Daniel Davidson:

Yes, but that is only giving the dates. I want the actual array 
elements. Suppose S is a large object with lots of extra fields 
in addition to `string foo`. There should be a way to pull out 
the lower bound based on a date without creating a needle (S). 
Maybe lowerBound is not the right function?


Second try:

import std.stdio, std.range, std.datetime, std.algorithm,
   std.array, std.typecons;

struct S {
Date date;
string foo;
}

void main() {
auto sarr = [S(Date(2000, 1, 1), "x"),
 S(Date(2000, 2, 1), "a"),
 S(Date(2000, 3, 1), "foo")];
assert(sarr.isSorted!q{ a.date < b.date });

sarr.writeln;
auto needle = S(Date(2000, 2, 1));

sarr
.map!(s => s.date)
.zip(sarr.length.iota)
.assumeSorted!q{ a[0] < b[0] }
.lowerBound(tuple(needle.date, 0))
.map!(p => sarr[p[1]])
.writeln;
}


Output:

[S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")]
[S(2000-Jan-01, "x")]

Bye,
bearophile


Re: how use lowerBound with just sorting key, not complete values

2013-11-12 Thread Daniel Davidson

On Tuesday, 12 November 2013 at 16:34:30 UTC, bearophile wrote:

Daniel Davidson:

Yes, but that is only giving the dates. I want the actual 
array elements. Suppose S is a large object with lots of extra 
fields in addition to `string foo`. There should be a way to 
pull out the lower bound based on a date without creating a 
needle (S). Maybe lowerBound is not the right function?


Second try:

import std.stdio, std.range, std.datetime, std.algorithm,
   std.array, std.typecons;

struct S {
Date date;
string foo;
}

void main() {
auto sarr = [S(Date(2000, 1, 1), "x"),
 S(Date(2000, 2, 1), "a"),
 S(Date(2000, 3, 1), "foo")];
assert(sarr.isSorted!q{ a.date < b.date });

sarr.writeln;
auto needle = S(Date(2000, 2, 1));

sarr
.map!(s => s.date)
.zip(sarr.length.iota)
.assumeSorted!q{ a[0] < b[0] }
.lowerBound(tuple(needle.date, 0))
.map!(p => sarr[p[1]])
.writeln;
}


Output:

[S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, 
"foo")]

[S(2000-Jan-01, "x")]

Bye,
bearophile


Well, I think that is it. Thanks, bearophile!

Pardon the redirect, but while you are at it, I would appreciate 
your take on this one 
(http://forum.dlang.org/post/gofijmqwhfcwgbruz...@forum.dlang.org). 
I'm sure you'll improve it and teach me a few things on the way 
;-)


Thanks
Dan


Re: Unexpected behavior when misusing inline assembly

2013-11-12 Thread Noah

Just realized I forgot to delete the 7 and the x from inside the
function calls.  Question is the same, though.

On Tuesday, 12 November 2013 at 18:22:46 UTC, Noah wrote:

When running the following code:

__gshared void* return_ptr;
__gshared void* injected_fn = &fn;

void main() {
buffer(7);
printf("End main\n");
}

void buffer() {
test(x);
printf("End buffer\n");
}

void test() {
printf("This is a test!\n");
inject();
printf("End of the test!\n");
}

void fn() {
printf("Hello, world!\n");
asm {
mov RAX, return_ptr;
mov [RBP+8], RAX;
}
}

void inject() {
asm {
naked;
push RAX;
mov RAX, [RBP+8];
mov return_ptr, RAX;
mov RAX, injected_fn;
mov [RBP+8], RAX;
pop RAX;
ret;
}
}

The program behaves as expected, that is, the program prints
This is a test!
End of the test!
Hello, world!
End buffer
End main

However, if I call test directly from main, it results in a 
segfault.

If I call inject directly from main, it works.
And, oddly, if I add any amount of inline assembler to main, 
and call test there, it works.


Could anyone explain to me what's going on?


Unexpected behavior when misusing inline assembly

2013-11-12 Thread Noah

When running the following code:

__gshared void* return_ptr;
__gshared void* injected_fn = &fn;

void main() {
buffer(7);
printf("End main\n");
}

void buffer() {
test(x);
printf("End buffer\n");
}

void test() {
printf("This is a test!\n");
inject();
printf("End of the test!\n");
}

void fn() {
printf("Hello, world!\n");
asm {
mov RAX, return_ptr;
mov [RBP+8], RAX;
}
}

void inject() {
asm {
naked;
push RAX;
mov RAX, [RBP+8];
mov return_ptr, RAX;
mov RAX, injected_fn;
mov [RBP+8], RAX;
pop RAX;
ret;
}
}

The program behaves as expected, that is, the program prints
This is a test!
End of the test!
Hello, world!
End buffer
End main

However, if I call test directly from main, it results in a 
segfault.

If I call inject directly from main, it works.
And, oddly, if I add any amount of inline assembler to main, and 
call test there, it works.


Could anyone explain to me what's going on?


Re: Unexpected behavior when misusing inline assembly

2013-11-12 Thread Noah
Of course after I post this I realize the answer.  The function 
only works when the surrounding function has at least one 
argument.  Probably has something to do with the way the compiler 
emits no-argument functions, I'll have to look at some 
disassembly.


__gshared immutable array of immutable elements

2013-11-12 Thread Nicolas Sicard

In this declaration (tango.io.Console.d from Tango2):

__gshared immutable immutable(char)[] Eol = "\r\n";

Aren't the two `immutable` keywords redundant? Why would 
`__gshared` be necessary for such an immutable type?


Thanks


Re: __gshared immutable array of immutable elements

2013-11-12 Thread Martin Drašar

Dne 12.11.2013 19:49, Nicolas Sicard napsal(a):

In this declaration (tango.io.Console.d from Tango2):

__gshared immutable immutable(char)[] Eol = "\r\n";

Aren't the two `immutable` keywords redundant? Why would `__gshared` be
necessary for such an immutable type?

Thanks


Hi,

this declaration is equal to

__gshared immutable string Eol = "\r\n";

Those two immutables are not redundant, because it is an array of 
immutable chars (string), that is itself immutable.


The __gshared should not be necessary, but given some quirks with type 
system and concurrency, it may be necessary to have it. But this is just 
a guess from me.


Drasha


Object destruction versus finalization

2013-11-12 Thread Florian
I played around a little and figured out, that destructors in D 
work quite similarily to destructors in C++. They are invoked, 
after the members of the instance being destructed have been 
destroyed themselfes (or at least have been brought into an 
invalid state). Therefore, these members cannot be accessed 
savely from inside the destructor.


In contrast, Java and C# offer a concept called finalizer. When 
the finalizer is called, all members of the instance itself are 
still valid and are guaranteed to be freely accessible. This 
behaviour can be useful for some cleanup operations.


Managed C++ offers both, C#-like finalizers and conventional C++ 
destructors, where the destructor is called ~className and the 
finalizer is called !className. Is their a best practice to 
mimikry this behaviour, i.e. to call a certain block of code when 
an object is being garbage collected, but before its contents 
render invalid?


Any hints would be greatly appreciated.


Re: __gshared immutable array of immutable elements

2013-11-12 Thread Dicebot

On Tuesday, 12 November 2013 at 20:09:57 UTC, Martin Drašar wrote:
Those two immutables are not redundant, because it is an array 
of immutable chars (string), that is itself immutable.


It is redundant because "immutable" is transitive. "immutable 
char[]" is equivalent.


But Tango has lot of meaningless and redundant attributes ( 
"final private" ;) )


Re: Object destruction versus finalization

2013-11-12 Thread Dicebot

On Tuesday, 12 November 2013 at 20:15:02 UTC, Florian wrote:
I played around a little and figured out, that destructors in D 
work quite similarily to destructors in C++. They are invoked, 
after the members of the instance being destructed have been 
destroyed themselfes (or at least have been brought into an 
invalid state). Therefore, these members cannot be accessed 
savely from inside the destructor.


What made you think so? It must be other way around. Destructor 
is expected to release resources held by object, it is necessary 
that those resources are still valid at destructor call point. It 
would have been completely against the mode of operations of 
garbage collector.


opCmp on a struct keyed by an array of bytes

2013-11-12 Thread Charles Hixson

Is there any better way to write the method than:
(cmp doesn't seem to work, and byte arrays don't have an opCmp method.)

 int opCmp(ref const B24 b) const
{for(int i = 0;i < 24;i++)
  {if(bytes[i] < b.bytes[i])return-1;
if(bytes[i] > b.bytes[i])return1;
   }
   return0;
}//opCmp

FWIW, the key is a fixed length array of ubyte, but similar structs have 
differing lengths.   If it's not supported by the system I don't want to 
do something like casting the pieces
to ulongs and comparing those rather than the bytes.  The added 
complexity isn't worth it.


--
Charles Hixson



Re: opCmp on a struct keyed by an array of bytes

2013-11-12 Thread Ali Çehreli

On 11/12/2013 01:06 PM, Charles Hixson wrote:

Is there any better way to write the method than:
(cmp doesn't seem to work, and byte arrays don't have an opCmp method.)

  int opCmp(ref const B24 b) const
{for(int i = 0;i < 24;i++)
   {if(bytes[i] < b.bytes[i])return-1;
 if(bytes[i] > b.bytes[i])return1;
}
return0;
}//opCmp

FWIW, the key is a fixed length array of ubyte, but similar structs have
differing lengths.   If it's not supported by the system I don't want to
do something like casting the pieces
to ulongs and comparing those rather than the bytes.  The added
complexity isn't worth it.



There is std.algorithm.cmp:

import std.algorithm;

struct B24
{
byte[24] bytes;

int opCmp(ref const B24 b) const
{
return bytes[].cmp(b.bytes[]);
}
}

void main()
{
auto a = B24();
auto b = B24();

assert(a == b);

a.bytes[23] = 1;
assert(a > b);

b.bytes[22] = 1;
assert(b > a);
}

Ali



Re: [Font] Getting font folder on all platforms

2013-11-12 Thread Xavier Bigand

Le 08/11/2013 21:05, Flamaros a écrit :

On Tuesday, 15 October 2013 at 23:10:32 UTC, Flamaros wrote:

On Friday, 6 September 2013 at 20:54:53 UTC, Flamaros wrote:

On Friday, 6 September 2013 at 16:05:43 UTC, Tourist wrote:

On Thursday, 5 September 2013 at 19:48:07 UTC, Flamaros wrote:

I am searching the right way to find fonts folder for each
platforms (Windows, linux, macOS X)

On Windows it's generally "C:\Windows\Fonts" but a direct access
seems brutal, it's certainly expected to retrieve this path by
using some register keys?

Is someone know how it works for linux and/or macOS X?

I need to be able to retrieve fastest as possible the right file
from the font and family name.


Windows: call SHGetKnownFolderPath with FOLDERID_Fonts as rfid.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188%28v=vs.85%29.aspx



Nice, thx.

Do you know if there is a table of fonts and there family, or need
open all font file my self?


I need to do some more tests, but scanning the registry seems working
under Windows.
Here is my test code :

stringfontPathFromName(in string name, in Font.Family family =
Font.Family.Regular)
{
version(Windows)
{
import std.windows.registry;

stringfontPath = "C:/Windows/Fonts/";
stringfontFileName;
KeyfontKey;

fontKey =
Registry.localMachine().getKey("Software\\Microsoft\\Windows
NT\\CurrentVersion\\Fonts");

if (family == Font.Family.Regular)
fontFileName = fontKey.getValue(name ~ "
(TrueType)").value_EXPAND_SZ();
else if (family == Font.Family.Bold)
fontFileName = fontKey.getValue(name ~ " Bold
(TrueType)").value_EXPAND_SZ();
else if (family == Font.Family.Italic)
fontFileName = fontKey.getValue(name ~ " Italic
(TrueType)").value_EXPAND_SZ();
else if (family == (Font.Family.Bold | Font.Family.Italic))
fontFileName = fontKey.getValue(name ~ " Bold Italic
(TrueType)").value_EXPAND_SZ();
return fontPath ~ fontFileName;
}
}

unittest
{
assert(fontPathFromName("Arial") == "C:/Windows/Fonts/arial.ttf");
assert(fontPathFromName("arial") ==
"C:/Windows/Fonts/arial.ttf");// Test with wrong case
assert(fontPathFromName("Arial", Font.Family.Bold |
Font.Family.Italic) == "C:/Windows/Fonts/arialbi.ttf");
}


I did some progress with fontconfig under linux, I'll try to use it for
Windows too.


I find a way to make it work under Windows.
I also bind almost all fontconfig API in a similar way of Derelict.

If someone is interested look font.d at :
https://github.com/D-Quick/DQuick

PS : I took fontconfig dll from GTK packages


Re: Object destruction versus finalization

2013-11-12 Thread Florian

On Tuesday, 12 November 2013 at 20:29:13 UTC, Dicebot wrote:

On Tuesday, 12 November 2013 at 20:15:02 UTC, Florian wrote:
I played around a little and figured out, that destructors in 
D work quite similarily to destructors in C++. They are 
invoked, after the members of the instance being destructed 
have been destroyed themselfes (or at least have been brought 
into an invalid state). Therefore, these members cannot be 
accessed savely from inside the destructor.


What made you think so? It must be other way around. Destructor 
is expected to release resources held by object, it is 
necessary that those resources are still valid at destructor 
call point. It would have been completely against the mode of 
operations of garbage collector.


Let me explain this by discussing the example below. I created 
method stubs, which write single lines to the console, so it is 
quite easy to follow the control flow.


The main method creates an instance of a type "Session", which 
itself has a member of type "Connection". Let us assume, that I 
want to properly shutdown the "Connection" instance by invoking 
its methods, when the "Session" is torn down. The example below 
prints the following output:

~Connection
~Session
segmentation fault
This means, the destructor of "Connection" is invoked *BEFORE* 
the destructor of "Session" is called. This yields to an invalid 
reference for the call of the shutdown() method, leading to the 
segmentation fault. Of course, in a scenario as simple as that, 
it would be possible to move the shutdown() sequence into the 
destructor of the "Connection" class. However, doing so is not 
desirable. Just picture, that we want to set some timeout 
parameters or the like for the shutdown depending on the state of 
the "Session". This would become really messy. And be assured, I 
have a more complex scenario, where I definitely want to invoke 
methods on memeber instances when an instance is destroyed. I am 
convinced there is a reason for finalizing objects like Java, C# 
and managed C++ do.


Example:

import std.stdio;

class Connection {
this() { }
void shutdown() { writeln("shutdown"); }
~this() { writeln("~Connection"); }
}

class Session {
Connection connection;
this() { connection = new Connection(); }
~this() {
writeln("~Session");
connection.shutdown();  // -> segmentation fault
}
}

void main() { auto session = new Session(); }


Re: __gshared immutable array of immutable elements

2013-11-12 Thread Nicolas Sicard

On Tuesday, 12 November 2013 at 20:16:31 UTC, Dicebot wrote:
On Tuesday, 12 November 2013 at 20:09:57 UTC, Martin Drašar 
wrote:
Those two immutables are not redundant, because it is an array 
of immutable chars (string), that is itself immutable.


It is redundant because "immutable" is transitive. "immutable 
char[]" is equivalent.


But Tango has lot of meaningless and redundant attributes ( 
"final private" ;) )


That´s what I thought. So no hidden subtlety here, just 
hyperprotection :)

Thanks


Re: opCmp on a struct keyed by an array of bytes

2013-11-12 Thread bearophile

Ali Çehreli:


int opCmp(ref const B24 b) const
{
return bytes[].cmp(b.bytes[]);


Few months ago I have written a small rant about that. That 
little [] at the end of those arrays is not innocuous, it 
essentially throws away a very precious compile-time amount of 
information: the static length of the arrays. So for the compiler 
it becomes much harder to optimize those loops. In my opinion 
this is an unacceptable part of the design of Phobos (mostly 
std.algorithm).


Bye,
bearophile


Re: Object destruction versus finalization

2013-11-12 Thread Jonathan M Davis
On Tuesday, November 12, 2013 23:40:24 Florian wrote:
> it would be possible to move the shutdown() sequence into the
> destructor of the "Connection" class.

Classes in D do not have destructors. Only structs to. ~this is a destructor 
in a struct, but it's a finalizer in a class. Finalizers are not guaranteed to 
be run, and they can't do anything with GC memory (be it allocating it, 
deallocating it, or using it) unless they're begging for trouble, because the 
GC is free to collect any GC-allocated objects before calling any finalizers 
(which avoids circular reference problems). As such, class finalizers are 
really only good for managing non-GC resources.

- Jonathan M Davis


Re: Object destruction versus finalization

2013-11-12 Thread Florian
I understood very well, that the garbage collector is not 
guaranteed to run. However, it does not explain the segmentation 
fault in my example, does it?


Re: Object destruction versus finalization

2013-11-12 Thread Jonathan M Davis
On Wednesday, November 13, 2013 00:07:12 Florian wrote:
> I understood very well, that the garbage collector is not
> guaranteed to run. However, it does not explain the segmentation
> fault in my example, does it?

You're getting a segfault, because you're using something which is on the GC 
heap - namely the Connection that you allocated with new. You can't do that in 
finalizer, because the GC can choose to free it before the finalizer even runs 
(this avoids issues with circular references). You can only access stuff in the 
finalizer which is part of the class (and not on the GC heap aside from the 
fact that the instance of the class is itself on the GC heap) or which is not 
managed by the GC at all (e.g. it was malloced, or it was some other sort of 
system resource that the GC doesn't manage).

If you want your Connection object to shutdown when it's collected, you're 
going to need to do that in its own finalizer, not in the finalizer of a class 
that's using it.

- Jonathan M Davis


Re: Object destruction versus finalization

2013-11-12 Thread Dicebot
On Tuesday, 12 November 2013 at 23:18:11 UTC, Jonathan M Davis 
wrote:

You can't do that in
finalizer, because the GC can choose to free it before the 
finalizer even runs

(this avoids issues with circular references).


Ah, damn, have forgotten about it. Disregard previous post.


Re: Object destruction versus finalization

2013-11-12 Thread Dicebot

On Tuesday, 12 November 2013 at 22:40:26 UTC, Florian wrote:

The example below prints the following output:
~Connection
~Session
segmentation fault


Same example prints this for me (no segfault):

~Session
shutdown
~Connection

2.064.2 @ linux-64

What is your system / compiler? Output does not seem right at all.


Re: Odd compiler complaints with import declarations

2013-11-12 Thread Orfeo

See also
http://d.puremagic.com/issues/show_bug.cgi?id=11451


Re: opCmp on a struct keyed by an array of bytes

2013-11-12 Thread Charles Hixson

On 11/12/2013 01:38 PM, Ali Çehreli wrote:

On 11/12/2013 01:06 PM, Charles Hixson wrote:

Is there any better way to write the method than:
(cmp doesn't seem to work, and byte arrays don't have an opCmp method.)

  int opCmp(ref const B24 b) const
{for(int i = 0;i < 24;i++)
   {if(bytes[i] < b.bytes[i])return-1;
 if(bytes[i] > b.bytes[i])return1;
}
return0;
}//opCmp

FWIW, the key is a fixed length array of ubyte, but similar structs have
differing lengths.   If it's not supported by the system I don't want to
do something like casting the pieces
to ulongs and comparing those rather than the bytes.  The added
complexity isn't worth it.



There is std.algorithm.cmp:

import std.algorithm;

struct B24
{
byte[24] bytes;

int opCmp(ref const B24 b) const
{
return bytes[].cmp(b.bytes[]);
}
}

void main()
{
auto a = B24();
auto b = B24();

assert(a == b);

a.bytes[23] = 1;
assert(a > b);

b.bytes[22] = 1;
assert(b > a);
}

Ali

Thank you.  That's exactly the answer I was looking for.  (

I had tried "return bytes.cmp(b.bytes);" , but it didn't occur to me 
that the error meant I should have used a copy?  Does this syntax mean 
that what's being compared is a dynamic array copy of the original 
static array?  Even if it is, that's the answer I wanted.



--
Charles Hixson



Re: opCmp on a struct keyed by an array of bytes

2013-11-12 Thread bearophile

Charles Hixson:

I had tried "return bytes.cmp(b.bytes);" , but it didn't occur 
to me that the error meant I should have used a copy?  Does 
this syntax mean that what's being compared is a dynamic array 
copy of the original static array?


They are not copies, just slices. In case of doubts take a look 
at the generated assembly.


Bye,
bearophile


Re: bidirectional map

2013-11-12 Thread Ellery Newcomer

On 11/11/2013 05:14 PM, bioinfornatics wrote:

Dear,
I am looking for a bidirectional map i.e
http://en.wikipedia.org/wiki/Bidirectional_map

My seach into D documentation seem to said to me that this structure is
not implemented.

Something like (for primary idea):


struct BidirectionalMap(T,U){
 private:
 T[U] _forwardHash;
 U[T] _reverseHash;

 public:

 @safe
 void opIndeyAssign( T k, U v){ // pure?
 _forwardHash[k] = v;
 _reverseHash[v] = k;
 }


 @property
 BidirectionalMap!(T,U) dup(){
 return BidirectionalMap!(T,U)( this );
 }
}


you could build one using multi_index.

https://bitbucket.org/ariovistus/multi_index

at least, that is how boost::bimap was done. I always assumed it would 
be trivial in D, but I haven't tried doing it. Something like


alias MultiIndexContainer!(Tuple!(T,"t",U,"u"), 
IndexedBy!(HashedUnique!("a.t"), HashedUnique!("a.u"))) BiMap;


and then wrap as you see fit.


Re: Simple immutable example doesn't work - why???

2013-11-12 Thread Louis Berube
Thanks to both TFF and Kenji for their excellent explanations. I 
think my head is going to explode ;).


So, as I understand it, there are two sorts of immutable entities 
in D.


The first is probably the one most familiar to the majority of 
us, which is an entity with immutable contents but with mutable 
binding. This is what TFF illustrated so well in his post above 
and what we are all familiar with as "string".


The second will take me longer to get used to, which is an entity 
with immutable contents *and* with immutable binding. This is 
what I tripped over in my example and what Kenji adroitly showed 
how to deal with in his post.


Does this correctly sum up what I have read? If so, this 
conversation has cleared up a great deal of my misunderstanding 
of how "immutable" works. It would be great to see the above 
examples in a D reference or tutorial (maybe the second edition 
of Andrei's book?).


Many thanks.


cannot infer argument types

2013-11-12 Thread bioinfornatics

Hi,

I have this error message ( i.e title ) and i do not see where i 
am wrong:



this( in ubyte wordLength, in string sequence ){
kMer = wordLength;
bytePerChar = cast(ubyte)(T.sizeof / kMer);

char[ubyte] toCharTmp;
ubyte[char] toNumTmp;
foreach( ubyte i, const char letter; 
sequence.dup.sort.uniq() ){

if(i !in toCharTmp)
toCharTmp[ i ]  = letter;
toNumTmp[ letter ]  = i;
}
toChar  = toCharTmp.rehash;
toNum   = toNumTmp.rehash;
}

Error is given at 

I have removed explicit type on this line… but I have always same 
error!


Re: cannot infer argument types

2013-11-12 Thread Jonathan M Davis
On Wednesday, November 13, 2013 03:43:40 bioinfornatics wrote:
> Hi,
> 
> I have this error message ( i.e title ) and i do not see where i
> am wrong:
> 
> 
>  this( in ubyte wordLength, in string sequence ){
>  kMer = wordLength;
>  bytePerChar = cast(ubyte)(T.sizeof / kMer);
> 
>  char[ubyte] toCharTmp;
>  ubyte[char] toNumTmp;
>  foreach( ubyte i, const char letter;
> sequence.dup.sort.uniq() ){
>  if(i !in toCharTmp)
>  toCharTmp[ i ]  = letter;
>  toNumTmp[ letter ]  = i;
>  }
>  toChar  = toCharTmp.rehash;
>  toNum   = toNumTmp.rehash;
>  }
> 
> Error is given at 
> 
> I have removed explicit type on this line… but I have always same
> error!

You have two variables to the left to the ; in the foreach. If you were 
iterating over an array, then the first one would be the index, and the second 
one would be the element. However, the result of sequence.dup.sort.uniq() is a 
range that is _not_ an array, and foreach does not support an index for 
ranges. You can fake it with lockstep if you want, since it does something 
with tuples to make it so that you get multiple elements on the left-hand side 
of the semicolon.

http://dlang.org/phobos/std_range.html#lockstep

In addition, I would point out that sequence.dup.sort is using the built-in 
sort for arrays rather than std.algorithm.sort (you have to have the parens 
when calling sort on array, or it'll use the built-in one), and the built-in 
sort for arrays is not only buggy, but it's going to be deprecated, so I 
wouldn't advise using it. And yes, the means that you'll have to have a 
random-access range, meaning that you'll need to convert your string to 
dchar[], but at least then you'll get a sort that works and isn't going to be 
removed from the language (IIRC, the built-in sort doesn't sort Unicode 
properly anyway). If you know that you only have ASCII characters, then you 
can use ubyte[] instead, but char[] isn't going to work, since it's not a 
random-access range.

- Jonathan M Davis


ddoc - modules with same name

2013-11-12 Thread rumbu

Let's suppose I have a module structure:

- package.module1.core
- package.module2.core

Building documentation with dmd will generate a sigle core.html 
file with content related only to package.module2.core, 
overwriting the first one.


Is there any way that dmd can recreate directory structure for 
documentation, obtaining two files: package\module1\core.html and 
package\module2\core.html?