Re: D2 Singleton / Thread Local Storage issue

2009-08-30 Thread Sergey Gromov
Sat, 29 Aug 2009 22:03:47 -0400, sybrandy wrote:

 Hello,
 
 I've been learning D for some time now and I recently was trying to do 
 some work with threads, but I'm having a problem getting it to work. 
 I'm trying to create a singleton that can be accessed between threads, 
 however I get an access violation when I try to run the following code. 
   If I make the variable instance shared, I get a compilation error. 
 Is there something I'm missing?

The thread local/shared storage doesn't seem to work well currently.

Your original snippet doesn't work because there is a separate
instance variable for every thread, but the static ctor is only
executed once, in the main thread.  The Simple.instance stays null in
ThrTest, and that thread crashes.

Making Simple.instance shared is incorrect I think because the class
must be thread-aware as well.  The correct way would be to make the
whole Simple class shared.  When I do this I still get errors though.
One in the constructor which cannot cast this from Simple to
shared(Simple).  Another is in main() which thinks shared is not
mutable.

I think we should wait for another couple compiler releases for this
feature to stabilize enough to be usable.


Re: problem creating a berkeley db binding

2009-08-30 Thread Sergey Gromov
Sun, 30 Aug 2009 11:28:16 -0400, JT wrote:

 i'm trying to create a binding for berkeley db dll and quickly ran
 into some problems, how do i translate statement below.
 
 int DB-open(DB *db, DB_TXN *txnid, const char *file,
 const char *database, DBTYPE type, u_int32_t flags, int mode);

This is not a valid C or C++ statement, nor a declaration.  It's usually
hard to translate an invalid code to a different language.

 my normal approach would be,
 
 extern (C) {
   int function(DB* db, DB_TXN* txnid, char* file, char* database, DBTYPE 
 type, u_int32_t flags, int mode) DB-open;
 }

If open() is a method of DB struct then it uses some sort of C++ calling
convention, probably thiscall.  Thiscall is incompatilbe with cdecl, so
extern(C) won't work.

 but real problem is 'DB-open', can anoybody suggest a workaround for
 this. DB is just a simple struct (struct DB;)

I can only guess here that what you want is

extern(C++) interface DB {
int open(DB_TXN* txnid, char* file, char* database, DBTYPE type, u_int32_t 
flags, int mode);
}

But, without a link to source you try to bind to, it's only a wild
guess.


Re: Export static data

2009-08-22 Thread Sergey Gromov
Fri, 21 Aug 2009 12:01:48 -0400, Jarrett Billingsley wrote:

 On Fri, Aug 21, 2009 at 11:10 AM, Dandan.r.stev...@gmail.com wrote:
 Another issue I had was with the name decoration. I need to be able
 to export an InitProc. The closest I was able to get was
 _InitProc and INITPROC. Is there a way to drop the leading
 underscore?
 
 As far as I know, not within the language.  DMD for some reason thinks
 that all Windows functions are preceded by an underscore when that is
 clearly not the case.  You might be able to do something using a .def
 file (linker script), but I've only had experience linking external
 symbols in, not with exporting internal symbols.

All Windows functions are __stdcall, and that implies a name mangling
scheme, _n...@sizeofarguments.  This is Microsoft's mangling scheme, it
is respected in their .obj files and import libraries.  But they decided
not to follow it in system DLL exported symbol names for some reason.
You overcome this peculiar design decision with .def files both with
Microsoft toolchain and with DMD.


Re: deleting items from 2d arrays

2009-08-14 Thread Sergey Gromov
Thu, 13 Aug 2009 22:59:37 -0400, Michael P. wrote:

 foreach( Block[] ba; level )
 {
   foreach( Block b; ba )
   {
   if( checkCollision( ball, b.p ) )
   {
   //remove the block??
   }
   }
 }

I like Daniel's answer better.  But if order matters you could do this:

for( int i = 0; i  level.length; )
{
for( int j = 0; j  level[ i ].length; )
{
if( checkCollision( ball, level[ i ][ j ].p ) )
{
level[ i ] = level[ i ][ 0 .. j ] ~ level[ i ][ j+1 .. 
$ ];
}
else
{
j++;
}
}
if( level[ i ].length == 0 )
{
level = level[ 0 .. i ] ~ level[ i+1 .. $ ];
}
else
{
i++;
}
}


Re: setIntersection of struct range

2009-08-12 Thread Sergey Gromov
Tue, 11 Aug 2009 19:35:40 -0400, Jesse Phillips wrote:

 I am trying to obtain a rang that is the intersection of two other ranges. To 
 do this I am using the _setIntersection()_ function.
 
 import std.algorithm;
 import std.stdio;
 
 struct S {
   string label;
 }
 
 void main() {
 auto s1 = new S[2];
 auto s2 = new S[2];
 
 s1[0].label = fish;
 s1[1].label = bar;
 s2[0].label = foo;
 s2[1].label = fish;
 
 foreach(str; setIntersection(s1,s2))
 writeln(str);
 }
 
 The code above generates this error:
 
  C:\opt\dmd\windows\bin\..\..\src\phobos\std\functional.d(191):
   Error: static assert  Bad binary function q{a  b}. 
  You need to use a valid D expression using symbols a of type S 
 and b of type S.

Looks like a compiler bug/feature to me.  The following is a reduced
test case:

import std.functional;

struct S {
string label;
}

void main() {
auto f1 = binaryFunImpl!(a  b, a, b).result!(int, int);
auto f2 = binaryFunImpl!(a.label  b.label, a, b).result!(S, S);
}

Compiled with dmd2 test.d:

C:\opt\dmd.2.031\windows\bin\..\..\src\phobos\std\functional.d(191):
Error: static assert  Bad binary function q{a.label  b.label}. You
need to use a valid D expression using symbols a of ty
pe S and b of type S.

Note that int,int passes while S,S fails.


Re: noob question

2009-08-06 Thread Sergey Gromov
Thu, 06 Aug 2009 10:56:33 -0400, lllTattoolll wrote:

 hi Lars and thx for help. I fix a little the first problem, now I paste a 
 verion in english whit coment because i´m lost here.
 the example is the same only this is in english for your compresion of my 
 problem.
 
 --
 code
 -
 
 import std.stdio;
 import std.string;
 import std.c.stdio;
 
 void main()
 {
 
 string _name, _lastname, _response;
 int _age, _year, _birth;
 _year = 2009;
 
   writef (Name: );
   _name = readln().chomp;
 
   writef (Lastname: );
   _lastname = readln().chomp;
 
   writefln (Hello %s , _name, _lastname );  /* here is my first 
 problem, dont show me the last name or show me in 
 two 
 lines ( this fix whit .chomp ) */

The format string must be Hello %s %s to display both operands.  Or
you can use writeln instead:

writeln(Hello , _name,  , _lastname);

   writefln (Year of birth: );
   scanf (%d,  _birth);

You use scanf here.  Scanf only reads the number, and leaves the Enter
symbol in the input stream.  When you later call readln() it sees that
Enter from the previous question and exits immediately.  You better
use readln() everywhere:

_birth = std.conv.to!int(readln().chomp);

   _age = _year - _birth;
 
   writefln (Your age is %d? \t YES \t NO, _age ); /* here is my second 
 problem, can´t into the response and program*/
   _response = readln();/* show me 
 else line always */
 
   if ( chomp(_response) == yes)
   writefln (thank you %s, _name );
   else
   writefln (Sorry %s you have %d, _name, _age - 1 ); /* this line 
 always show me because can´t validate _response */
 }

The rest seems to work correctly.


Re: Shared Object with DMD v2.031

2009-08-05 Thread Sergey Gromov
Wed, 5 Aug 2009 20:46:53 + (UTC), teo wrote:

 On Tue, 04 Aug 2009 18:41:50 +0400, Sergey Gromov wrote:
 
 Sun, 2 Aug 2009 11:18:24 + (UTC), teo wrote:
 
 On Sun, 02 Aug 2009 02:18:28 +0400, Sergey Gromov wrote:
 
 My guess is that test.di is exactly the same as test.d because all the
 functions are small.  Therefore compiling 'dmd prog.d test.di'
 resolves all symbols statically and the .so is simply not linked. 
 Does your 'prog' have any unresolved symbols in its symbol table?
 
 It looks like this is the case. I found following in the symbols:
 0804b8cc T _D4test6testMeFZi
 0804b8d8 T _D4test9testClassFiZC4test4Test
 
 The whole nm output is too long, but if you want I can send it to you.
 
 When I use the *--undefined-only* option I get: $ nm -u prog
 [snip]
 
 All unresolved symbols seem to be in glibc.
 
 Yes.
 
 I've filed a bug:
 http://d.puremagic.com/issues/show_bug.cgi?id=3226
 
 I don't have the warning you mention.

Try to run

objdump -r test.o

It'll print relocation table for the object file.  In my case almost all
of them are of type R_386_32 which are load-time relocations.  A
position-independent code should not contain them.


Re: Shared Object with DMD v2.031

2009-08-04 Thread Sergey Gromov
Sun, 2 Aug 2009 11:18:24 + (UTC), teo wrote:

 On Sun, 02 Aug 2009 02:18:28 +0400, Sergey Gromov wrote:
 
 My guess is that test.di is exactly the same as test.d because all the
 functions are small.  Therefore compiling 'dmd prog.d test.di' resolves
 all symbols statically and the .so is simply not linked.  Does your
 'prog' have any unresolved symbols in its symbol table?
 
 It looks like this is the case. I found following in the symbols:
 0804b8cc T _D4test6testMeFZi
 0804b8d8 T _D4test9testClassFiZC4test4Test
 
 The whole nm output is too long, but if you want I can send it to you.
 
 When I use the *--undefined-only* option I get:
 $ nm -u prog
 [snip]

All unresolved symbols seem to be in glibc.

I've filed a bug:
http://d.puremagic.com/issues/show_bug.cgi?id=3226


Re: byte to char safe?

2009-08-02 Thread Sergey Gromov
Sat, 01 Aug 2009 19:58:20 -0400, Harry wrote:

 Sergey Gromov Wrote:
 
 Thu, 30 Jul 2009 19:14:56 -0400, Harry wrote:
 
 Ary Borenszweig Wrote:
 
 Harry escribi��  Again hello, 
 
 char[6] t = ragain ~ cast(char)7 ~ rhello;
 
 If you want the result to be again7hello, then no. You must do:
 
 char[6] t = ragain ~ '7' ~ rhello;
 
 or:
 
 char[6] t = ragain ~ (cast(char)('0' + 7)) ~ rhello;
 
 Hello Ary,
 
 7 is data not string.
 It makes own write function
 need style data in char[]
 Not sure if safe ?
 
 If you use only your own write function then you can put just anything
 into char[].  But if you pass that char[] to any standard function, or
 even foreach, and there are non-UTF-8 sequences in there, the standard
 function will fail.
 
 Also note that values from 0 to 0x7F are valid UTF-8 codes and can be
 safely inserted into char[].
 
 If you want to safely put a larger constant into char[] you can use
 unicode escape sequences: '\u' or '\U', where  and
  are 4 or 8 hexadecimal digits respectively:
 
 char[] foo = hello  ~ \u017e ~ \U00105614;
 foreach (dchar ch; foo)
 writefln(%x, cast(uint) ch);
 
 Finally, if you want to encode a variable into char[], you can use
 std.utf.encode function:
 
 char[] foo;
 uint value = 0x00100534;
 std.utf.encode(foo, value);
 
 Unfortunately all std.utf functions accept only valid UTF characters.
 Currently they're everything from 0 to 0xD7FF and from 0xE000 to
 0x10.  Any other character values will throw a run-time exception if
 passed to standard functions.
 
 thank you!
 
 non-print utf8 is print with writef
 start of text \x02 is smile
 end of text \x03 is heart
 newline \x0a is newline!

Well, sure, standard writef simply outputs those characters to the
console.  Then console prints them according to its own rules.
Therefore special characters will have different representation on
different consoles.  If you want consistent output you should those
special characters to some printable form.

 is difference? utf.encode(foo,value)  foo~\U00100534

A little.  The code:

uint value = 0x00100534;
std.utf.encode(foo, value);

is the same as:

foo ~= \U00100534;


Re: byte to char safe?

2009-08-02 Thread Sergey Gromov
Mon, 3 Aug 2009 04:11:31 +0400, Sergey Gromov wrote:

 If you want consistent output you should those
 special characters to some printable form.

Sorry, this sentence has a typo:

If you want consistent output you should *convert* those special
characters to some printable form.


Re: byte to char safe?

2009-07-31 Thread Sergey Gromov
Thu, 30 Jul 2009 18:29:09 -0400, Harry wrote:

 BCS Wrote:
 
 Reply to Harry,
 
 Again hello,
 
 char[6] t = ragain ~ cast(char)7 ~ rhello;
 
 use only own write functions
 is ok?
 thank you!
 
 
 I think this will also work and you can be shure it's safe.
 
 ragain ~ '\x07' ~ rhello
 
 
 again thank you !
 
 D writef not print utf8 control?
 \x00 .. \x1f and \x7f .. \x9f safe for data?
 where \n \t?
 
 sorry so many questions

No, writef does not escape non-printing characters, if that's what you
mean.  It prints them as is.  You can escape them using std.uri.encode
for instance:

writefln(std.uri.encode(str));


Re: Shared Object with DMD v2.031

2009-07-31 Thread Sergey Gromov
Thu, 30 Jul 2009 06:52:14 + (UTC), teo wrote:

 I have difficulties creating a Shared Object (.so) with D. Is it 
 possible? Can I use classes defined in the library from the executable?
 
 Here is my library file:
 module test; // file test.d
 export int testMe() { return 1; }
 export class Test
 {
 private int n;
 this(int i) { n = i; }
 int get() { return n; }
 }
 
 I compile like shown below:
 $ dmd -fPIC -c test.d
 $ gcc -shared -o libtest.so test.o
 
 [snip]
 
 And this is the program:
 module main; // file prog.d
 import std.stdio;
 import test;
 void main()
 {
writefln(testMe: %d, testMe());
writefln(Test class: %d, (new Test(3)).get());
 }
 
 I compile it with:
 $ dmd prog.d -L-L`pwd` -L-ltest
 
 And get:
 /usr/bin/ld: dynamic variable `_D4test4Test7__ClassZ' is zero size
 /usr/bin/ld: prog.o(.text._Dmain+0x26): unresolvable R_386_32 relocation 
 against symbol `_D4test4Test7__ClassZ'
 /usr/bin/ld: final link failed: Nonrepresentable section on output
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 Please note that _D4test4Test7__ClassZ is defined in the library.
 
 BTW compiling with following works:
 $ dmd test.d prog.d

I get the same results, i.e. it does not work.  Though with one
clarification: from the command:

 $ gcc -shared -o libtest.so test.o

I get a warning:

 /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/../../../../i686-pc-linux-gnu/bin/ld:
 warning: creating a DT_TEXTREL in object.

Internets say that this is because test.o is *not* position-independent.
Could this mean that -fPIC switch does not work?  Could it be the reason
linking fails?

Reproduced with both DMD 1.046 and 2.031.  GCC is 4.3.3 as you can see
from the warning.


Re: Pointer to method C++ style

2009-07-24 Thread Sergey Gromov
Fri, 24 Jul 2009 09:07:30 -0400, Steven Schveighoffer wrote:

 On Thu, 23 Jul 2009 22:09:12 -0400, Sergey Gromov snake.sc...@gmail.com  
 wrote:
 
 Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:

  LOOKUP_TABLE[0] = Method(method1, Component.method1);
  LOOKUP_TABLE[1] = Method(method2, Component.method2);

 These two lines are weird.  ``pragma(msg)`` shows that type of
 ``method1`` is ``void function()`` while it must be ``void delegate()``
 for a non-static member because of difference in calling convention.
 Actually I think that taking an address of a non-static member in a
 static context must be a compile time error.
 
 It's because I'm taking the address of the function on the type, not on an  
 instance.  It's not a delegate because there's no this pointer yet.
 
 It makes sense to me anyways.  A delegate is a normal function pointer  
 coupled with a hidden context parameter.

The ``Type.`` part does not change anything.  It simply directs compiler
to use overloads from a particular class hierarchy level.   Here:

static Method[] LOOKUP_TABLE2 = [
{ name : method1, method : Component.method1 },
{ name : method2, method : method2 }
];

This code compiled with DMD 1.046 gives the following errors:

test2.d(30): Error: non-constant expression  method1
test2.d(30): Error: non-constant expression  method2

Also if you add this code:

pragma(msg, outside:  ~ typeof(method1).stringof);
void method1() { writefln(method1);
pragma(msg, inmeth:  ~ typeof(method1).stringof);
}

you get:

outside: void function()
inmeth: void delegate()

So the type of a non-static method address taken in a static context is
obviously wrong.


Re: Pointer to method C++ style

2009-07-24 Thread Sergey Gromov
Fri, 24 Jul 2009 02:51:45 +0400, Sergey Gromov wrote:

 Thu, 23 Jul 2009 19:07:43 +0200, BLS wrote:
 
 Sergey Gromov wrote:
 Sorry, I'm not a guru at all, so ActiveX was a misnomer.  What I'm
 writing is a simple in-process server DLL which implements a couple of
 interfaces.
 
 Oh, that's sad. :(
 
 well, especially in this case I would suggest to have a look on this page :
 http://www.dsource.org/projects/juno/wiki/ComProgramming
 
 Thanks, I'll look into it when I have time.

Juno is nice, and implements a lot of boilerplate.  But it doesn't seem
to care enough about exceptions in user code.  My own code wraps every
interface function in an exception catching block, and I'd better leave
it that way.


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 12:37:42 +0200, BLS wrote:

Sergey Gromov wrote:
 Use case: I'm writing an ActiveX plug-in for a dynamic language.  The

 However, I am _very_ interested in having/seeing the source of a very 
 basic ActiveX control. Any chance that you share the core implementation 
 with us ?

Sorry, I'm not a guru at all, so ActiveX was a misnomer.  What I'm
writing is a simple in-process server DLL which implements a couple of
interfaces.


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 04:11:14 + (UTC), BCS wrote:

 Hello Sergey,
 
 Is there a way to declare and statically initialize some sort of
 pointer to method, and later call it for an actual object instance?
 
 
 dosn't work but might point you in the right direction:
 
 template Pn2Fn(R, char[] method)
 {
  ReturnTypeOf!(mixin(R. ~ method)) Pn2Fn(R r, ArgsOf!(mixin(R. ~ 
 method)) args)
  {
   return mixin(r.~method~(args););
  }
 
 }

Thanks for the advice.  The following code actually works:

import std.stdio;

struct Handler(T)
{
  string name;
  void function(T instance) handler;
}

class A
{
  void method1() { writefln(method1); }
  void method2() { writefln(method2); }

  void call(int i)
  {
LOOKUP_TABLE[i].handler(this);
  }

private:

  static Handler!(A)[] LOOKUP_TABLE =
  [
{ method1, callMethod!(method1) },
{ method2, callMethod!(method2) }
  ];

  static void callMethod(string name)(A instance)
  {
mixin(instance. ~ name ~ (););
  }
}

void main()
{
  A a = new A;
  a.call(0);
  a.call(1);
}


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 19:07:43 +0200, BLS wrote:

 Sergey Gromov wrote:
 Sorry, I'm not a guru at all, so ActiveX was a misnomer.  What I'm
 writing is a simple in-process server DLL which implements a couple of
 interfaces.
 
 Oh, that's sad. :(
 
 well, especially in this case I would suggest to have a look on this page :
 http://www.dsource.org/projects/juno/wiki/ComProgramming

Thanks, I'll look into it when I have time.


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:

 On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov snake.sc...@gmail.com  
 wrote:
 
 Is there a way to declare and statically initialize some sort of pointer
 to method, and later call it for an actual object instance?
 
 I don't know why the non constant expression error happens, but  
 constructing a delegate from function pointers is pretty simple:

It's my understanding that you cannot construct a delegate from a
function pointer because they use different calling conventions.  Though
you show here that it *is* possible to construct a delegate from another
delegate you dissected earlier.

  LOOKUP_TABLE[0] = Method(method1, Component.method1);
  LOOKUP_TABLE[1] = Method(method2, Component.method2);

These two lines are weird.  ``pragma(msg)`` shows that type of
``method1`` is ``void function()`` while it must be ``void delegate()``
for a non-static member because of difference in calling convention.
Actually I think that taking an address of a non-static member in a
static context must be a compile time error.


Pointer to method C++ style

2009-07-22 Thread Sergey Gromov
Is there a way to declare and statically initialize some sort of pointer
to method, and later call it for an actual object instance?

Use case: I'm writing an ActiveX plug-in for a dynamic language.  The
language queries the component for implemented methods, then it requests
these methods to be executed.  I want to implement these methods as the
component class non-static members, and create a lookup table at compile
time, sort of

struct Method
{
string name;
PointerToMember method;  // some magic goes here
}

class Component : IUnknown
{
void method1() {}
void method2() {}

static Method[] LOOKUP_TABLE =
[
{ method1, method1 },  // won't work, method1 is non-const
{ method2, method2 }
];

void call(int i)
{
this-*LOOKUP_TABLE[i].method(); // sort of
}
}


Re: synchronized / cond.wait

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 15:37:33 +0200, Stefan Rohe wrote:

 could someone explain us this synchronize behaviour? We do not understand
 it.
 
 Two Threads.
 First Thread should wait for a condition. This we do in a
 synchronized(mutex) block.
 The second Thread broadcasts then a notify. This also in a synchronized
 block, synchronizing on the same mutex. This should be impossible!? Does the
 condition.wait modify the Mutex object so that it after this has another
 address?

The whole point of a condition variable is to allow other threads to
acquire the same mutex while you're waiting.

What happens is the mutex associated with the conditional variable is
unlocked the same instant you start waiting on that variable.  When the
other thread notifies you, the cond var attempts to lock the mutex again
and therefore waits until the other thread either leaves the critical
section or starts waiting itself.


Re: No segfault - null ==

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 16:29:30 +0200, Qian Xu wrote:

 When I was trying to learn how char-array works, I found something
 unexpected.
 
 -- code --
 module string_test;
 
 void main()
 {
   // test 1
   assert(null == , null is empty); // No segfault

When you compare null to an array, null is first converted into an empty
array, then a comparison takes place.  This happens because arguments to
comparison operator are first converted to a common type.


Re: dwt2 help

2009-03-25 Thread Sergey Gromov
Thu, 26 Mar 2009 00:29:44 +0100, Saaa wrote:

 I filled in the Phobos implementation, but I'm not sure if it is all correct 
 as I don't fully understand the exception handling.
 
 [...]

 catch( IllegalArgumentException e ){
 //How does this work? It catches e and gives it as an argument to a new 
 exception.
 throw new NumberFormatException( e );
 }

Obviously NumberFormatException can store another exception object
inside.  This code effectively converts IllegalArgumentException into
NumberFormatException, storing the original argument exception inside so
that one can examine it later if they're curious.

 [...]

 catch(Object e){ // ConvError or ConvOverflowError
 //Is this the correct translation?
 throw new NumberFormatException( e );
 }

It depends on what NumberFormatException can  accept as an argument.  If
it accepts an Object then it's fine.


Re: dwt2 help

2009-03-25 Thread Sergey Gromov
Thu, 26 Mar 2009 01:40:25 +0100, Saaa wrote:

 [...]

 catch(Object e){ // ConvError or ConvOverflowError
 //Is this the correct translation?
 throw new NumberFormatException( e );
 }

 It depends on what NumberFormatException can  accept as an argument.  If
 it accepts an Object then it's fine.
 
 class NumberFormatException : IllegalArgumentException {
 this( String e ){
 super(e);
 }
 this( Exception e ){
 super(e.toString);
 }
 }
 
 Can Object be implicitly converted to Exception?

No it cannot.  Object is the root of the D class hierarchy.  In D1
Exception is derived directly from Object.  In D2 Exception is derived
from Throwable which in turn is derived from Object.  You can cast
Exception to Object but not the other way around.

What's worse, ConvError and ConvOverflowError in D2 are derived from
Error which is a separate class from Exception and cannot be cast
implicitly.  I think you'd want to fix the NumberFormatException to
accept Throwable for instance which is a base of both Exception and
Error in D2.


Re: # operator under C implementation in D1

2009-03-14 Thread Sergey Gromov
Thu, 12 Mar 2009 23:44:40 -0400, Sam Hu wrote:

 Here I found an example form tango.io.Console class Output:
 class Output
 {
 private Buffer  buffer;
 private boolredirect;
 
 public  alias   append opCall;
 public  alias   flush  opCall;
 
 final Output append (char[] x)
 {
 buffer.append (x.ptr, x.length);
 return this;
 } 
 ...
 }
 On above code,
  public  alias   append opCall;
  public  alias   flush  opCall;
 
 How can we do things like this since the opCall is the system defined?
 Thanks.

You are correct in that it's impossible to re-alias an existing type.
Your previous example with Color won't compile.  Where you are wrong is
in assumption that opCall is system defined.  It is not, actually.
Compiler just searches for a function with this name.  It uses one if
found, or performs a default action otherwise.  There is *no*
compiler-generated opCall.

In this example, opCall is made a synonym for append and for flush:

Output o = ...;
o(); // equivalent to o.flush()
o(string); // equivalent to o.append(string)


Re: # operator under C implementation in D1

2009-03-14 Thread Sergey Gromov
Thu, 12 Mar 2009 21:19:11 -0400, Sam Hu wrote:

 I know a little that in C there is a # operator which under a macro
 can return any type's value in character format.Just wanna know
 whether there is an equivelent implementation in D1.Say,in C using
 a/m macro can easily output enum's character value other than
 integer.It would be grateful if anybody would like to paste a few
 lines of code to demostrate such implementation.

I know this doesn't help, but the C preprocessor's # operator does not
return ... value in character format.  All it does it converts a macro
argument into a string literal:

#define STRINGIZE(x) #x
int foo = 43;
const char *s = STRINGIZE(foo); // s now is foo, not 43
const char *s1 = STRINGIZE(foo * 15 + 1); // s1 is foo * 15 + 1

This is exactly what D's .stringof does.


Re: my first link error: Error 42: Symbol Undefined __moduleUnitTests

2009-03-02 Thread Sergey Gromov
Fri, 27 Feb 2009 20:37:56 -0500, Fei wrote:

 I'm trying to compile my first d sample, winsamp.d, using dmd 2.025 for 
 windows.
 
 dmd winsamp.d gdi32.lib
 
 everything seem ok but I got a link error :
 Error 42: Symbol Undefined __moduleUnitTests
 
 what lib should I include for moduleUnitTetst?

We may be able to answer better if you show us winsamp.d content.


Re: loop through specific class members

2009-01-26 Thread Sergey Gromov
Mon, 26 Jan 2009 04:50:10 + (UTC), BCS wrote:

 Hello Sergey,
 
 foreach() is a runtime construct.  It may be *interpreted* at
 compile-time, but it's interpreted as if it were run time
 nevertheless. It dynamically changes the value of 'member' variable.
 
 OTOH a foreach on a tuple is a compile time construct, but it is a distinct 
 construct from the array foreach and is not what you are using (If i'm 
 reading 
 stuff correctly)

I somehow missed that in the specs.  Definitely, this works:

template Tuple(T...)
{
  alias T Tuple;
}
void foo()
{
  foreach (a; Tuple!(int, char, long))
pragma(msg, a.stringof);
}

but this doesn't:

template Tuple(T...)
{
  alias T Tuple;
}
void foo()
{
  foreach (a; Tuple!(a, b, c))
pragma(msg, a);
}

$ dmd -c test.d
test.d(8): Error: string expected for message, not 'a'
test.d(8): Error: string expected for message, not 'a'
test.d(8): Error: string expected for message, not 'a'

*This* seems like a bug to me.


Re: how to use dll

2009-01-25 Thread Sergey Gromov
Wed, 21 Jan 2009 23:19:48 -0500, reimi gibbons wrote:

 I'm currently developing a software with D and Tango. I don't have
 much knowledge on DLL, but i do know when linking to static lib you
 need a .h header file, but do i need .h for linking with DLL as well?
 
 
 also can anybody please provide a quick and small example to link
 with DLL. 

The easiest way is to link with an import library.  It's exactly like
linking with a static library.  Actually you *are* linking with a static
library, but that's a special kind of static library which forwards your
calls to a DLL.  This way runtime automatically loads the DLL before
your program starts and unloads it after main() terminates, so you don't
need to bother yourself with details.

As Daniel pointed out, you can try to convert an existing .h file into a
.d file using htod:

http://www.digitalmars.com/d/2.0/htod.html

The most reliable way to get an import library for your DLL is to get a
.lib file in COFF format provided with the DLL and convert it into OMF
format using coffimplib:

ftp://ftp.digitalmars.com/coffimplib.zip


Re: Is there a way to remove the requirement for parenthesis?

2009-01-25 Thread Sergey Gromov
Wed, 21 Jan 2009 09:24:01 -0800, Charles Hixson wrote:

 In this test I'm trying to emulate how I want a typedef to act, but I 
 run into a problem:
 
 import   std.stdio;
 
 struct   BlockNum
 {  uint   value;
 
 uint   opCast()   {   return   value;   }
 void   opAssign (uint val)   {   value = val;   }
 uint   opCall()   {   return   value;   }
 }
 
 void   main()
 {  BlockNum   test;
 test   =   42;
 uint   tst2   =   test();  // == if I don't have the parenthesis I
//get a compiler error (cast
//required).
//  kfile.d(15): Error: cannot implicitly convert expression
//  (test) of type BlockNum to uint
 
 writef (tst2 = %d\n, tst2);
 }
 
 It seemed to me as if the parens shouldn't be required here, but I seem 
 mistaken.  Which leads to ugly code.  Is there a way around this?

test is an expression of type BlockNum.  opCall() is called when you use
parentheses syntax on it.  opCast() is called when you use cast() syntax
for it.  Otherwise it stays BlockNum and therefore is not convertible to
uint.


Re: loop through specific class members

2009-01-25 Thread Sergey Gromov
Wed, 21 Jan 2009 12:48:07 +0100, Trass3r wrote:

 Christopher Wright schrieb:
 On the other hand, you can get the non-final, non-private methods of a 
 class with something like:
 foreach (member; __traits (allMembers, Class))
 {
 foreach (overload; __traits (getVirtualFunctions, Class, member))
 {
 // do stuff
 }
 }
 
 Naturally, __traits and foreach don't mix, so you'll have to use 
 template recursion. This is pretty damn ugly.
 
 
 But why doesn't that work? It doesn't even work when forced to run at 
 compile time by CTFE.
 Had a look at the compiler code, it uses the same mechanism as 
 pragma(msg, for example, so shouldn't something like the above 
 theoretically be possible?

foreach() is a runtime construct.  It may be *interpreted* at
compile-time, but it's interpreted as if it were run time nevertheless.
It dynamically changes the value of 'member' variable.

pragma() and __traits() are compile-time constructs.  They are fully and
statically expanded before anything is being interpreted and cannot
handle dynamically changing variables.


Re: compile time output

2009-01-20 Thread Sergey Gromov
Tue, 20 Jan 2009 16:36:09 +0100, Trass3r wrote:

 Is there any way to output information at compile time other than 
 pragma(msg?
 pragma is driving me crazy, the following doesn't work:
 
 auto members = __traits(allMembers, typeof(this));
 foreach(m; members)
 {
   pragma(msg, m);
 }
 
 - Error: string expected for message, not 'm'
 
 Though the docs clearly state:
 allMembers: An array of string literals is returned
 Also checked that, m is of type invariant(char)[].
 
 Any ideas? -.-

Weird.  The following code does not compile:

class Cls
{
  int bar;
  char[] baz;
}
string foo()
{
  auto members = __traits(allMembers, Cls);
  return ;
}
pragma(msg, foo());

dmd -c test.d
test.d(11): Error: cannot evaluate foo() at compile time
test.d(11): pragma msg string expected for message, not 'foo()'

Comment out the traits and it compiles.  Traits are supposed to be
compile-time.  How's that possible for them to prevent compile-time
evaluation?


Re: Getting line number where error occured?

2009-01-14 Thread Sergey Gromov
Thu, 15 Jan 2009 02:47:07 +0100, Hoenir wrote:

 Might be a dumb question, but is it possible in any way to get the line 
 number where an error occured?
 Don't think so, but maybe I'm missing something.

assert gives a line number.  There's also a keyword, __LINE__, which is
an expression evaluating to the current line number, like in

writefln(__LINE__);

If you mean an exception stack trace then no, there's no such thing,
though it's a very popular feature request.


Re: timezone problem

2009-01-13 Thread Sergey Gromov
Tue, 13 Jan 2009 11:27:40 +0100, Qian Xu wrote:

 Hi All,
 
 I am fighting with date time conversion and have a problem right now:
 I want to convert a local timestamp to UTC timestamp.
 So I have to get the time zone information.
 However in some countries (ie. German, US), the offset is not constant,
 because of daylight saving issue.
 
 Is there any hidden routine can tell the correct time zone information
 (cross platform, esp. open suse)
 
 Any hints are apprecated ^^)
 
 --Qian

I thought that std.date.getUTCtime(), std.date.UTCtoLocalTime() and
std.date.LocalTimetoUTC() were quite enough.


Re: array questions

2009-01-11 Thread Sergey Gromov
Sun, 11 Jan 2009 17:17:54 -0500, yes wrote:

 Hello again
 
 is it possible to make a dynamic array less dynamic?
 
 int[][] array;
 
 array[0].length = 10; //has to be set at runtime

Um, if that's your code, everything should crash at this point (or throw
in debug mode): array is null, that is, empty, so there is no array[0].

You should array.length = 10; first.  Then you'll get an array of 10
empty arrays of int, and will be able to set their lengths separately:

array[0].length = 10; // OK
assert(array[1].length == 0); // OK

If you want to set up quickly you can write

int[][] array = new int[][](10, 10);

This will give you a sort of square matrix, bit internally it will be an
array of arrays nevertheless.

 also, can this be done?
 
 int size;
 size = 10; //runtime
 void function( int[size][] array){}

No, static arrays are static, i.e. compile time.


Re: why the array bounds array

2008-12-08 Thread Sergey Gromov
Mon, 8 Dec 2008 06:59:40 + (UTC), BCS wrote:

 Reply to Bill,
 
 On Mon, Dec 8, 2008 at 2:57 PM, BCS [EMAIL PROTECTED] wrote:
 
 Reply to Michael P.,
 
 rand()  TYPES_OF_TILES
 
 never use rand like that (the low order bit on many rands toggles
 every
 single time)
 better (I think):
 rand() / (TYPES_OF_TILES / RAND_MAX)
 
 That's a divide by zero, so I don't think that's what you meant.
 
 --bb
 
 
 Oops  x-p
 
 rand() / (RAND_MAX / TYPES_OF_TILES)

Don't use rand() like this, ever.  ;)  RAND_MAX / TYPES_OF_TILES is an
integer expression, it rounds down, therefore your formula gives a
slightly greater range of values than you expect.  You'll get all sorts
of out of bounds errors.

Your best bet is to use a uniform distribution method of the same random
number generator implementation.  There is std.random.uniform() in D2's
Phobos which serves this purpose.  If you don't have an equivalent, your
next stop is rand() % TYPES_OF_TILES.  It's not strictly uniform but
close if TYPES_OF_TILES is small.