question about the implementation of Variant

2016-01-03 Thread aki via Digitalmars-d-learn
Following function will return the reference to a object Foo 
embedded in a Variant.


class Foo {}
Variant fun() {
Variant v;
v = new Foo();
return v;
}

According to the source code of VariantN.opAssign,
the assignment is done by:

memcpy(&store, &rhs, rhs.sizeof);
fptr = &handler!(T);

where rhs is new Foo(), store is embedded storage in Variant,
and fptr is accessor function also work as data tag.
Very efficient implementation.
But wait, how does GC detect there still be a live reference to 
the object Foo?

Because store is just a fix sized array of bytes.
ubyte[size] store;
GC cannot be aware of the reference, right?

Thanks, aki



Re: question about the implementation of Variant

2016-01-04 Thread aki via Digitalmars-d-learn

Thank you, Jonathan. Now I understand.

On Monday, 4 January 2016 at 17:34:47 UTC, Kapps wrote:

union
{
ubyte[size] store;
// conservatively mark the region as pointers
static if (size >= (void*).sizeof)
void*[size / (void*).sizeof] p;
}


Interesting to know the way to make GC detect the presence of the 
potential pointer.


Regards, aki.



efficient and safe way to iterate on associative array?

2016-03-04 Thread aki via Digitalmars-d-learn

Is it okay to modify associative array while iterating it?

import std.stdio;

void main() {
string[string] hash = [ "k1":"v1", "k2":"v2" ];
auto r = hash.byKeyValue();
while(!r.empty) {
auto key = r.front.key;
auto value = r.front.value;
r.popFront();
writefln("key=%s, value=%s", key, value);
// may not modify 'hash' here ?
hash = null;
}
}

I guess probably it's not.
Then, my question is are there an efficient and safe way to 
iterate on an associative array even if there are possibility to 
be modified while iterating?
I'm writing interpreter and want to make my language to be safe; 
even malicious script cannot fall it in 'core dump' state. It is 
okay if it causes undefined behavior like throw or instant exit 
from loop, but not crash.


Thanks, Aki.



Re: efficient and safe way to iterate on associative array?

2016-03-04 Thread aki via Digitalmars-d-learn
On Friday, 4 March 2016 at 16:46:35 UTC, Steven Schveighoffer 
wrote:


You cannot add or remove keys. You can modify values for 
existing keys.


Note, in your code, this would not cause a problem, since 
setting hash to null just removes the reference from the local 
variable 'hash', it does not alter the AA in any way.


In dcollections, all containers support "purging", or iterating 
through elements, removing the current element if desired 
before moving to the next. But I haven't touched this library 
in ages, I don't know if it still compiles even.


-Steve


Thank you for it. Now I know.
I will copy and modify AA source to customize. (src/rt/aaA.d)
I wonder what if D support safe variant like safeByKeyValue.
Actually it seems easy (in aaA.d):

bool _aaRangeEmpty(Range r)
{
return r.impl is null || r.idx == r.dim;
}

can be changed to:
bool _aaRangeEmptySafe(Range r)
{
if(r.impl is null || r.idx >= r.dim) return true;
if (!r.buckets[r.idx].filled) throw xxxException();
return false;
}
It can become safe by a cost of small overhead.

-- Aki.



how to declare C's static function?

2016-03-27 Thread aki via Digitalmars-d-learn

Hello,

When I porting legacy app. written in C to D,
I have a problem.

file a.d:
extern (C) private void foo() {}

file b.d:
extern (C) private void foo() {}

 Error 1: Previous Definition Different : _foo

In C language, "static void foo(){}" does not
export the symbol out side the compilation unit.
In D, the function foo() above conflicts even if
it is private. How can I declare C's static function?

Regards,
Aki.



Re: how to declare C's static function?

2016-03-27 Thread aki via Digitalmars-d-learn

On Monday, 28 March 2016 at 04:12:56 UTC, Rikki Cattermole wrote:

Do you need it to use extern(C)?
Because if you don't, just drop that. D's mangling will fix it.


Yes, I do need extern(C) for some reason like:
alias Hook = extern(C) void function();
void sethook(Hook func) {
...
}
... sethook(&foo) ...

Some function expects such a function as an argument.

Aki.



Re: how to declare C's static function?

2016-03-27 Thread aki via Digitalmars-d-learn

On Monday, 28 March 2016 at 04:33:06 UTC, Rikki Cattermole wrote:
You have two choices. Change the name in code (so manual 
mangling) or use pragma(mangle, ...) to change it instead.


So... You mean there are no way to declare functions
without exporting the symbol?
There are so many instances to change..
But thanks any way.

Aki.



Re: how to declare C's static function?

2016-03-28 Thread aki via Digitalmars-d-learn

On Monday, 28 March 2016 at 14:40:40 UTC, Adam D. Ruppe wrote:

On Monday, 28 March 2016 at 04:53:19 UTC, aki wrote:

So... You mean there are no way to declare functions
without exporting the symbol?


alas, no, even if it is private it can conflict on the outside 
(so stupid btw).


Is it all the same function being referenced? Just importing 
from there would be ok.


Thank you for clarify.
Now I know I have to change the name as a result.

Thanks,
aki.



Re: how to declare C's static function?

2016-03-28 Thread aki via Digitalmars-d-learn

On Tuesday, 29 March 2016 at 01:04:50 UTC, Mike Parker wrote:

On Monday, 28 March 2016 at 14:40:40 UTC, Adam D. Ruppe wrote:

On Monday, 28 March 2016 at 04:53:19 UTC, aki wrote:

So... You mean there are no way to declare functions
without exporting the symbol?


alas, no, even if it is private it can conflict on the outside 
(so stupid btw).




Seems to be fixed in the latest beta (finally):

http://dlang.org/changelog/2.071.0.html#dip22


Good news!



what's the right way to get char* from string?

2016-05-05 Thread aki via Digitalmars-d-learn

Hello,

When I need to call C function, often need to
have char* pointer from string.

"Interfacing to C++" page:
https://dlang.org/spec/cpp_interface.html
have following example.

extern (C) int strcmp(char* string1, char* string2);
import std.string;
int myDfunction(char[] s)
{
return strcmp(std.string.toStringz(s), "foo");
}

but this is incorrect because toStringz() returns immutable 
pointer.

One way is to write mutable version of toStringz()

char* toStringzMutable(string s) @trusted pure nothrow {
auto copy = new char[s.length + 1];
copy[0..s.length] = s[];
copy[s.length] = 0;
return copy.ptr;
}

But I think this is common needs,
why it is not provided by Phobos?
(or tell me if it has)

Thanks,
aki



Re: what's the right way to get char* from string?

2016-05-05 Thread aki via Digitalmars-d-learn

On Thursday, 5 May 2016 at 11:35:09 UTC, Jonathan M Davis wrote:
If you want a different mutability, then use the more general 
function std.utf.toUTFz. e.g. from the documentation:


auto p1 = toUTFz!(char*)("hello world");
auto p2 = toUTFz!(const(char)*)("hello world");
auto p3 = toUTFz!(immutable(char)*)("hello world");
auto p4 = toUTFz!(char*)("hello world"d);
auto p5 = toUTFz!(const(wchar)*)("hello world");
auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);

- Jonathan M Davis


Ah! This can be a solution.
Thanks Jonathan.

-- aki.



how to define a struct without padding

2017-05-24 Thread aki via Digitalmars-d-learn

Hi,

This is a code ported from some windows C program.
It is the Windows WAVE file header definition.
The field layout is the same with C,
but it has extra 2 bytes at the end,
sizeof(WAVEHEADER) in C is 46 while WAVEHEADER.sizeof in D is 48.
Why it still have padding in spite of "align(1)" ?
How can I remove extra padding bytes?

module main;
import std.stdio;
alias ushort WORD;
alias uint DWORD;

align(1) struct WAVEFORMATEX {
WORDwFormatTag; /* format type */
WORDnChannels;  /* number of channels (i.e. 
mono, stereo...) */

DWORD   nSamplesPerSec; /* sample rate */
DWORD   nAvgBytesPerSec;/* for buffer estimation */
WORDnBlockAlign;/* block size of data */
WORDwBitsPerSample; /* number of bits per sample 
of mono data */
WORDcbSize; /* the count in bytes of the 
size of */

/* extra information (after cbSize) */
};

align(1) struct WAVEHEADER {
char[4] szRIFF;
int lRIFFSize;
char[4] szWave;
char[4] szFmt;
int lFmtSize;
WAVEFORMATEXwfex;
char[4] szData;
int lDataSize;
};

void main() {
writeln(WAVEHEADER.sizeof); // 48; but it must be 46
}

Thanks,
Aki



Re: how to define a struct without padding

2017-05-24 Thread aki via Digitalmars-d-learn

On Thursday, 25 May 2017 at 01:34:35 UTC, Adam D. Ruppe wrote:

align(1) struct NAME {
   align(1):
  members
}


My problem is resolved. Thank you for the quick reply.

Thanks,
Aki



convert string to ubyte[]

2017-11-11 Thread aki via Digitalmars-d-learn

Hello,

This will be trivial question but I cannot figure out
what's wrong. I want to convert string to an array of ubyte.

import std.conv;
void main() {
auto s = "hello";
ubyte[] b = to!(ubyte[])(s);
}

It compiles but cause run time error:

std.conv.ConvException@C:\APP\D\dmd2\windows\bin\..\..\src\phobos\std\conv.d(3530): Can't 
parse string: "[" is missing

I cannot understand the meaning of this message.
Replacing s with s.dup to remove immutable doesn't help.
Do I need to use cast?

Regards,
Aki



Re: convert string to ubyte[]

2017-11-11 Thread aki via Digitalmars-d-learn

On Saturday, 11 November 2017 at 15:48:59 UTC, Mike Parker wrote:

auto s = "hello";
auto bytes = s.representation;

https://dlang.org/phobos/std_string.html#.representation


Thank you for the replay.
Now I know.

aki



how to iterate on Array?

2015-06-27 Thread aki via Digitalmars-d-learn

I want to print the contents of Array!int

import std.stdio;
import std.container;

void pr(Array!int a) {
foreach(i, v; a[]) {
writeln("%4s: %s\n", i, v);
}
}

But when I compile it by DMD 2.062 on Windows
it says:

testArray.d(5): Error: cannot infer argument types
(line 5 is at "foreach(i, v; a[]) {" )

What's wrong? how can I iterate the array?

Thanks, aki.



Re: how to iterate on Array?

2015-06-27 Thread aki via Digitalmars-d-learn

On Saturday, 27 June 2015 at 18:32:10 UTC, Ali Çehreli wrote:

On 06/27/2015 10:43 AM, aki wrote:
You are rightly assuming that the loop counter is available for 
all container types. Unfortunately, it is the case only for 
arrays.


Now I know. Thanks for it.
aki.




Re: how to iterate on Array?

2015-06-30 Thread aki via Digitalmars-d-learn

On Sunday, 28 June 2015 at 10:16:47 UTC, Marc Schütz wrote:

On Saturday, 27 June 2015 at 17:43:13 UTC, aki wrote:

But when I compile it by DMD 2.062 on Windows
it says:

testArray.d(5): Error: cannot infer argument types
(line 5 is at "foreach(i, v; a[]) {" )


2.062 is really ancient, we're about to release 2.068 soon. 
Consider upgrading, because there have been tons of bugfixes 
since your version.


On current DMD, the error message is slightly clearer:

"Error: cannot infer argument types, expected 1 argument, not 2"


Ah, you answered my another question.
Even if I put all the types like foreach(size_t i, int v; a[])
he still said "cannot infer." I wonder why he need to infer?
Now I got it. I'm looking forward 2.068.
Aki.



proper way to calculate toHash() for string

2015-06-30 Thread aki via Digitalmars-d-learn

I would like to know proper way to calculate
hash for given member fields.

class Foo {
int value;
string str;
override nothrow @safe size_t toHash() {
// calculate hash based on field value.
// value and str in this example.
}
}

boost::hash provides easy and systematic way
to calculate hash.
I found std.digest.crc is useful.

override nothrow @safe size_t toHash() {
if (str is null) return value;
ubyte[4] hash = crc32Of(str);
return value^((hash[0]<<24)|(hash[1]<<16)|(hash[2]<<8)|hash[3]);
}

Please suggest me if anyone have an idea.

Regards, aki.



Re: proper way to calculate toHash() for string

2015-06-30 Thread aki via Digitalmars-d-learn

On Tuesday, 30 June 2015 at 19:36:24 UTC, Jacob Carlborg wrote:

On 30/06/15 16:19, aki wrote:


Please suggest me if anyone have an idea.


You can use TypeInfo.getHash [1] to get the hash of a given 
value. Something like:


string a = "foo";
typeid(a).getHash(&a)

[1] http://dlang.org/phobos/object.html#.TypeInfo.getHash


Wow, this is what I was looking for.
It's generic way. Thank you for good suggestion.
Your 2 lines code is also a good explanation for the
manual of getHash. Because it's not obvious what is
the argument for the getHash.



how to avoid "cycle detected"?

2015-07-01 Thread aki via Digitalmars-d-learn

Following code causes run-time error.
How can I use static this() without causing error?
It's difficult to avoid this situation because
actual code is more complex.

file main.d:
void main() {
}

file a.d:
import b;
class A {
static this() {}
};

file b.d:
import a;
class B {
static this() {}
};

object.Exception@src\rt\minfo.d(162): Aborting: Cycle detected 
between modules w

ith ctors/dtors:
a -> b -> a




Re: how to avoid "cycle detected"?

2015-07-02 Thread aki via Digitalmars-d-learn

On Wednesday, 1 July 2015 at 22:25:48 UTC, Jonathan M Davis wrote:
On Wednesday, July 01, 2015 08:52:38 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
The runtime cannot introspect the code to detect the circular 
dependency, so it makes a conservative decision. I'm waiting 
on an introduction of RTInfo for modules [1] to allow us to 
mark static ctors as standalone, then we can probably fix this 
problem through a sort of "trust the programmer" mechanism.


I wouldn't mind that, but Walter shot that idea down previously 
when I was arguing for adding a way to the language to tell the 
compiler that a static constructor didn't depend on anything 
else. He didn't want a "trust the programmer" mechanism in this 
case. I don't remember what his arguments were though.


- Jonathan M Davis


Thanks for the discussion, now I understand there are
technical difficulties.
I have to give it a name like void staticInit(); and
call it manually from main().

aki.



Re: how to avoid "cycle detected"?

2015-07-02 Thread aki via Digitalmars-d-learn

On Thursday, 2 July 2015 at 17:21:03 UTC, Kapps wrote:
An ugly solution, but the approach used in Phobos is to create 
something like a_init.d which a.d imports, provided that the 
static ctors don't actually rely on things from the static ctor 
of b.


How about this idea?
Allowing to define sub module in a module.

file foo.d:
module foo;

// nameless module, automatically imported by outer module foo
module {
int[] needInitialize;
static this() { needInitialize = ...; }
}
// use statically initialized variable needInitialize...

Basically, d-lang's module has one-to-one correspondence with 
file.

This new feature breaks this rule, but it's safe because
this one is private to module foo.
There are no way to import this nameless module by other modules.
The purpose is just the alternative to making foo_init.d file.

aki.



how to manage the list of immutable objects

2015-07-14 Thread aki via Digitalmars-d-learn

I like to create immutable object
which is identified by name as it's key.
And also need get() to look up named object
which is already created.

class Foo {
static immutable(Foo)[string] map;
string name;
// and other attributes here...

this(string name) immutable {
this.name = name;
map[name] = this;
}
static immutable(Foo) get(string name) {
return map[name];
}
}

But this code causes error:
test.d(8): Error: cannot modify immutable expression map[name]

How can I declare the map so that it contains
immutable object Foo, but the reference to Foo is mutable?
Anyway the goal is to provide get() function.
Tell me how to implement get().

Aki.


Re: how to manage the list of immutable objects

2015-07-14 Thread aki via Digitalmars-d-learn

On Tuesday, 14 July 2015 at 10:46:42 UTC, Andrea Fontana wrote:

Trying on http://dpaste.dzfl.pl/ I don't see that error.
Maybe you mean "const" and not "immutable" ?

Andrea


I used:
DMD32 D Compiler v2.067.1 on Windows8
I believe there are no typo because it is copy-pasted.
I noticed I can use cast.
cast()(map[name]) = cast()this;
Are there any better solution?

Aki.



Re: how to manage the list of immutable objects

2015-07-14 Thread aki via Digitalmars-d-learn
On Tuesday, 14 July 2015 at 11:44:34 UTC, Steven Schveighoffer 
wrote:

static Rebindable!(immutable(Foo))[string] map

-Steve


It all works. And I learned something from
the source code of Rebindable.
Thank you.

Aki.



question about the semantics of unshared variables

2015-07-15 Thread aki via Digitalmars-d-learn

I want to make sure about the semantics of unshared variables.

import std.concurrency;
import core.thread;
ubyte[1024 * 1024] buf1MB;
void fun() { Thread.sleep(5000.msecs); }
void testThread() {
foreach(i; 0..2000) {
spawn(&fun);
}
}

Are instances of buf1MB created for every threads?
Even if it is never accessed by the threads?
If some static variable is defined in other module
or in some library, all of them also instantiated
for every threads?
BTW, calling testThread() above causes following
run time error. Is this an expected result?

core.thread.ThreadError@src\core\thread.d(2903): Error creating 
thread


0x0047B1A7
0x0042ABD4
0x0042AB3B
0x0042AB27
0x0042ADF9
0x00474C22
0x00474BF7
0x00474B0F
0x0042AE13
0x757A7C04 in BaseThreadInitThunk
0x7735AD1F in RtlInitializeExceptionChain
0x7735ACEA in RtlInitializeExceptionChain



Re: question about the semantics of unshared variables

2015-07-15 Thread aki via Digitalmars-d-learn

I noticed just making many threads cause an error.
Are there any limit for the number of threads?

import std.concurrency;
import core.thread;
void fun() { Thread.sleep(5000.msecs); }
void testThread() {
foreach(i; 0..2000) {
spawn(&fun);
}
}

core.thread.ThreadError@src\core\thread.d(2903): Error creating 
thread


Aki.



How to use core.thread.Thread

2015-07-16 Thread aki via Digitalmars-d-learn

I can't resolve the compile errors:

import core.thread;
class DerivedThread : Thread {
int count = 0;
this() {
super(&run);
}
private void run() {
		inc();	//testThread.d(8): Error: shared method 
testThread.DerivedThread.inc is not callable using a non-shared 
object

}
synchronized void inc() {
		++count;	//testThread.d(11): Deprecation: read-modify-write 
operations are not allowed for shared variables. Use 
core.atomic.atomicOp!"+="(this.count, 1) instead.

}
}
void main() {
auto thr = new DerivedThread();
thr.start();
	thr.inc();	//testThread.d(17): Error: shared method 
testThread.DerivedThread.inc is not callable using a non-shared 
object

thr.join();
}


1. Should I declare thr as shared? But
auto thr = new shared DerivedThread();
does not resolve it.

2. Why "++count" cause an error? I think it is safe because
it is marked as synchronized. If it is forced to use atomicOp
all the time, it's painful.

3. Are there any tutorials about using Thread class?

Aki.



Re: question about the semantics of unshared variables

2015-07-16 Thread aki via Digitalmars-d-learn

On Thursday, 16 July 2015 at 07:36:39 UTC, Jonathan M Davis wrote:
Yes. Every thread gets a copy of the non-shared static 
variables, and all of the non-shared static constructors get 
run for each thread.


- Jonathan M Davis


Thank you for reply. Now i know.
I did some test using C++ as you said, then there are some
different problem occurred. Anyway no need to make so
many threads. Please just forget it.

Aki.



Re: How to use core.thread.Thread

2015-07-16 Thread aki via Digitalmars-d-learn
On Thursday, 16 July 2015 at 08:21:26 UTC, maarten van damme 
wrote:

Have you checked out std.parallelism and std.concurrency?


I know std.concurrency to use spawn. If I cannot use Thread,
I'll implement by spawn. But want to try Thread class because
it seems similar to Java's Thread class.
I don't know std.parallelism. It seems for the different case.

Aki.



Re: How to use core.thread.Thread

2015-07-17 Thread aki via Digitalmars-d-learn

On Thursday, 16 July 2015 at 09:17:47 UTC, Daniel Kozák wrote:

class DerivedThread : Thread {
shared int count = 0;
}


I thought shared is only for whole of the object.
auto thr = new DerivedThread();
Here, "thr" is not shared but it's member thr.count is shared?
But if it's not shared, thr object referred by main thread and
"this" reference of DerivedThread.run() are different?
What happen if there are both shared and unshared member exists?

class DerivedThread : Thread {
shared int count = 0;
int foo = 0;
}

Umm. I can't imagine what's the memory layout of this object.



Re: How to use core.thread.Thread

2015-07-17 Thread aki via Digitalmars-d-learn

On Friday, 17 July 2015 at 14:14:41 UTC, byron wrote:
Since I have yet to use or see anyone use shared in a useful 
way I avoid it.

It's one way to avoid it. So, you mean you always use send/receive
when you need threading?

I did small test to know the memory layout.

import core.atomic;
int foo;
shared int sfoo;
class DerivedThread : Thread {
int count;
shared int scount;
this() {
super(&run);
}
private void run() {
inc();
writefln("at thread: foo=%s, &foo=%s, sfoo=%s, &sfoo=%s", 
foo, &foo, sfoo, &sfoo);
writefln("at thread: count=%s, &count=%s, scount=%s, 
&scount=%s", count, &count, scount, &scount);

}
void inc() {
++foo;
atomicOp!"+="(sfoo, 1);
++count;
atomicOp!"+="(scount, 1);
}
}
void main() {
auto thr = new DerivedThread();
thr.start();
thr.inc();
thr.join();
writefln("  at main: foo=%s, &foo=%s, sfoo=%s, &sfoo=%s", 
foo, &foo, sfoo, &sfoo);
writefln("  at main: count=%s, &count=%s, scount=%s, 
&scount=%s", thr.count, &thr.count, thr.scount, &thr.scount);

}

at thread: foo=1, &foo=A33580, sfoo=2, &sfoo=5541E4
at thread: count=2, &count=240178, scount=2, &scount=24017C
  at main: foo=1, &foo=984B28, sfoo=2, &sfoo=5541E4
  at main: count=2, &count=240178, scount=2, &scount=24017C

That means Thread object "thr" is always shared while
global foo is not shared because it has different memory location.
In my understanding, shared is not only checking something at 
compile time,

but also it affects on the memory layout.

Aki.