Re: Synchronized const methods
immutable means no one can modify this. const means someone might be able to modify this, but not you can't.
Re: Yet more OPTLINK woes
Some general replies: There have been three responses along the lines of are you sure OPTLINK is running?. Quoting myself: Invoking OPTLINK directly changes nothing. Or to be more specific: link AstTest,AstTest,,user32+kernel32/noi+tango.lib; (zero-byte .map file pops into existence) Yes, I'm sure. I'm also sure it's the DigitalMars link.exe and in the correct directory. I've had problems before with DMD silently exiting without an error message and with error success and leaving behind a corrupt .obj. I had a look at the .obj file (I actually used lib to stuff it into a .lib file and then dump the symbols), and it looked fine. Well, except for this: _D11TokenStream808d8d5_ctorMFC6Sourcef6P809091 DFS8Location808989AaYvJS68085cfs5f4Zb80 99aaZC819a87 (broken across 3 lines; xx are bytes in hex since several of them were non-printable.) The same had happened to a number of symbols from tango.io.stream.Format. In the case of the first one, the appropriate declarations (with fully-qualified module name commented) are: final class /*TokenStream.*/TokenStream { alias bool function(Source, LocErr, out Token) NextToken; this(Source src, NextToken next, LocErr err) { ... } } final class /*Source.*/Source { ... } alias void delegate(Location, char[], ...) /*Location.*/LocErr; struct /*Location.*/Location { ... } As far as I understand D's name mangling, that symbol name is corrupt. CTFE recursion is the only reported unfixed bug that does that ... There is exactly one CTFE function that calls itself. However, it cannot recurse more than once (it does so to change types) *and* this function is used in the LexerTest program which does compile. AstTest uses an additional CTFE function, but this just concatenates some strings together. Try and remove stuff until it starts working I've gutted the changes between LexerTest and AstTest to the point that I get an .exe. This involved stripping out more or less every global and member function that was added and every derived class. What tipped it over into compiling was removing the reference to StructuredOutput from AstDumpVisitor. Which is odd, because StructuredOutput is still being used in AstTest. StructuredOutput, once gutted, is this: module StructuredOutput; import tango.io.model.IConduit : OutputStream; import tango.io.stream.Format : FormatOutput; final class StructuredOutput { alias StructuredOutput This; this(OutputStream os) { } } I honestly can't see what it could be upset about. Post the source and I'll try to help. I like debugging weird problems. :) Attached both regular and decaffeinated^Hgutted versions. matheval.7z Description: Binary data matheval-gutted.7z Description: Binary data
Yet more OPTLINK woes
That's right, it's time for everyone's favourite [1] game: guess why OPTLINK's not working! [2] *sigh* I'm writing a math eval library. There are two test applications. LexerTest only touches part of the code. AstTest touches everything. Now, the following works and creates an executable: dmd -ofLexerTest (appropriate .d files) So far, so good. I get LexerTest.map, LexerTest.obj and LexerTest.exe. Let's try the other one... dmd -ofAstTest (more .d files) This creates a legitimate-looking AstTest.obj and a completely empty AstTest.map file. That's it. No executable, no error message, no register dump, nothing. Adding or removing -g, -debug, -unittest, -release, -inline, -O does nothing. Changing the target filename does nothing useful. There are no spurious link.exe or dmd.exe processes running. Invoking OPTLINK directly changes nothing. Does anyone have any idea, any idea at all, on what could be causing this? I've tried everything myself and several others on #d could think of. *miserable sob* After over five years of this sort of shit, I am so, so completely and utterly sick to death of OPTLINK. [1] I am, of course, being sarcastic. [2] It is, of course, entirely possible that it's not OPTLINK's fault. Frankly though, I find that hard to believe.
Re: metaprogramming question
http://while-nan.blogspot.com/2007/06/wrapping-functions-for-fun-and-profit.html It shouldn't be too difficult to inject an extra parameter; just add it to the end of the call to the wrapped function after args.
Re: gdc and Make
bud, rebuild and xfbuild were designed so we wouldn't NEED Makefiles in the first place. Unless you've got a good reason, just use a recent dmd and xfbuild.
Re: enum values without initializer
bearophile wrote: Nick Sabalausky: If you don't want that doplication you can also write: enum auto f = Foo(); Can't you do: enum f = Foo(); ? In my opinion that's a semantic mess, I don't write that. auto is for automatic local type inference and enum is to ask for a compile time constant. No it isn't. 'auto' is a storage class, it has NOTHING to do with type inference. Type inference is triggered when the type is omitted from a declaration. It just turns out that in the majority of cases (variables), the easiest way to do this is to use the default storage class which is used if you don't otherwise specify one: auto. This is why 'const blah = 42;' works: const is used as a storage class and the type is omitted.
Re: is pointer
bearophile wrote: (I am looking for rough corners in D, or in my knowledge of D.) In this page: http://www.digitalmars.com/d/2.0/templates-revisited.html In the section Template Parameters there is written: P:P*, // P must be a pointer type - So I have written this D2 program: template IsPointer1(T) { enum bool IsPointer1 = is(T : T*); } void main() { int* ptr; static assert(IsPointer1!(typeof(ptr))); // Err } But it asserts, do you know why? You do realise that Template Parameters are a completely different thing to is expressions, right?
Re: exceptions
Ellery Newcomer wrote: On 02/24/2010 03:10 AM, bearophile wrote: Ellery Newcomer: Okay, does anyone know a good way to figure out where something like this is coming from: object.Exception: lengths don't match for array copy void main() { auto a1 = new int[5]; auto a2 = new int[4]; a1[] = a2; } Bye, bearophile I want line numbers You could use Tango and enable stack tracing. That or hook up a debugger.
Re: When is array-to-array cast legal, and what does actually happen?
... I see that neither the constructor nor the postblit is called. Apparently the bit representation is used. This has the risk of violating struct invariants. Is it legal? Thank you, Ali cast is to value conversions what a tactical nuclear strike is to peaceful negotiations. cast is specifically *designed* to circumvent the type system's protections [1]. If you want to do a value conversion, *do a value conversion*. Allocate a new array and convert each member. cast doesn't call the constructor or the postblit because it's doing a pointer conversion. Your code is basically equivalent to this: void main() { auto tmp = hellod; auto mine = cast(MyChar*)(tmp.ptr) [0..(tmp.length*typeof(tmp[0]).sizeof)/MyChar.sizeof)]; } That is, it's doing an unsafe, unchecked pointer cast, then re-slicing the array. To answer your question: yes, it's legal. Not what you wanted, but legal. [1] Except for int-float. Oh, and objects. Really, this is one thing I could just about strangle KR for: conflating value-preserving, non-value-preserving *AND* unsafe conversions all into a single construct. Walter, gets slapped with a fish for not putting a bullet in cast's head when he had the chance. Argh!
Re: immutable string literal?
strtr wrote: On winXP (D1) I can compile/run this code without a problem. Not even a warning. void main() { char[] s= immutable literal?; s[$-1] = '!'; writefln(s); } Codepad runs into a segmentation fault. http://codepad.org/NQfsRoR5 Why doesn't it result in a compiler error or warning? If it did I would have noticed this quirk earlier. There's no compiler error because D1 doesn't have a const/immutable system. There's no crash because Windows doesn't write-protect the data segment which contains the literal.
Re: Commmandline arguments and UTF8 error
Nils Hensel wrote: Hello, group! I have a problem writing a small console tool that needs to be given file names as commandline arguments. Not a difficult task one might assume. But everytime a filename contains an Umlaut (ä, ö, ü etc.) I receive Error: 4invalid UTF-8 sequence. Here's the sample code: import std.stdio; int main(string[] argv) { foreach (arg; argv) { writef(arg); } return 0; } I use dmd v1.046 by the way. How do I make the argument valid? I need to be able to use std.path and std.file methods on the file names. Any help would be greatly appreciated. Regards, Nils Hensel If you look at the real main function in src\phobos\internal\dmain2.d, you'll see this somewhere around line 109 (I'm using 1.051, but it's unlikely to be much different in an earlier version): for (size_t i = 0; i argc; i++) { auto len = strlen(argv[i]); am[i] = argv[i][0 .. len]; } args = am[0 .. argc]; result = main(args); In other words, Phobos never bothers to actually convert the arguments to UTF-8. Tango does (tango\core\rt\compiler\dmd\rt\dmain2.d:238 for a recent-ish trunk).
Re: use variant as associative array
Daniel Keep wrote: I got the following to work with Tango's Variant (dmd 1.051 + pre-0.99.9 trunk): Variant[char[]][int] aa; aa[0] = typeof(aa[0]).init; aa[0][Month] = Variant(Jan); aa[0][Profit] = Variant(500); aa[1] = typeof(aa[0]).init; aa[1][Month] = Variant(Feb); aa[1][Profit] = Variant(800); There's actually two problems at work here: 1. You can't use a nested associative array without initialising it. Scratch that; it does work. Huh. Fancy that. 2. You apparently can't assign to an aa of Variants for some reason. Keep in mind that Variants are basically a hack on the language; that assigning to a Variant value in an AA doesn't work isn't entirely surprising. Another thing that occurred to me; is there any reason you can't do this: struct Record { char[] month; int profit; } Record[int] aa; aa[0] = Record(Jan, 500); aa[1] = Record(Feb, 800); Or even this: Record[] arr; arr ~= Record(Jan, 500); arr ~= Record(Feb, 800); Or even even this: enum Month { Jan, Feb, Mar, /* and the rest */ } struct Record { Month month; int profit } Record[] arr; arr ~= Record(Month.Jan, 500); arr ~= Record(Month.Feb, 800); ?
Re: D memory consumption/runtime speed problem
sybrandy wrote: Hello, I've been writing a bit of compression code and I noticed some strange behavior that's driving me a bit batty. I don't know if it's a bug with D or something I did. All I know is I can't figure it out. ... Am I doing something wrong? I've tried every trick that I could find by reading the documentation. Btw: The last time I tried this was with the latest version of D released at the beginning of the month. I haven't verified this, but I'd be *deeply* suspicious of encodeNumber. I don't usually use array literals but, if I remember correctly, every time it is called you're performing a heap allocation. Even worse, those concatentations might be performing separate allocations, too. You could eliminate the overhead by using a passed-in buffer design like so: ubyte[] encodeNumber(in uint count, ref ubyte[4] buffer) { if (count = ONE_BYTE_VAL) { buffer[0] = cast(ubyte)(ONE_BYTE_MASK | count); return buffer[0..1]; } // ... } Then, in the calling function: { ubyte[4] temp; foreach( ... ) { appOutput.put(encodeNumber(count, temp)); } } See if that helps.
Re: Getting access to the variables of an imported class
jicman wrote: aalm Wrote: import dfl.all; import myform2; void main() { //Form d = new MyForm(); //MyForm d = new MyForm(); auto d = new MyForm(); d.text = Hello...; d.Name.text = name; d.show(); } thanks. That worked. Would you care to explain? :-) I know what auto does, but I thought that a Form was a form and a Class was a class. Does auto here would suffice for all other kinds of variables? Thanks for the help. jos� Sometimes, I think all compiler errors should be replaced with Something went wrong. No one ever seems to *read* them. :| testDFL.d(8): Error: no property 'Name' for type 'dfl.form.Form' You were trying to access a 'Name' property for an object of type 'Form'. But 'Form's do not have a 'Name' property. Objects of type 'MyForm' do, but you've explicitly told the compiler that 'd' is of type 'Form' not 'MyForm'.
Re: why can't structs implement interfaces?
Bill Baxter wrote: On Tue, Nov 24, 2009 at 3:09 PM, Saaa em...@needmail.com wrote: I wanted to do something like this: class C : I {}; struct S : I {}; S s; I[] i =[new C(), s ]; Yeh, that's never going to work because that's acting as a dynamic polymorphic interaface. Referring polymorphically to a struct like that pretty much makes it not a struct anymore, and requires having the hidden pointer to a vtable that was mentioned. That's what classes are for. Why is a hidden pointer necessary? (Just curious :) My simplistic view was like this: i[1] would just hold the location of s and s would be checked to have all it needs to be an I. I think it could be done with a different implementation of interfaces from the one D uses, one based on fat pointers. With that design an I referring to an S would be a fat pointer, one pointer pointing to the S and one pointing to S's table of function pointers (vtable) for the I interface. That's not how D does it AFAIR, but I don't actually recall how D does it. --bb (This is all off the top of my head.) In D, interfaces are pointers to the vtable which implements the interface for a particular class. In order to actually get the this reference, D stores a pointer to the class' InterfaceInfo (or something) for that interface in the first slot of the vtable. This InterfaceInfo indicates how far from the start of an instance the pointer to the vtable is contained. To get this, you take the pointer to the interface vtable and subtract this offset. This is why interfaces cannot be implemented by structs in D: it would require structs to grow magical hidden fields, which is explicitly against the stated purpose of structs: plain old data. Even then, there's a worse problem. All interfaces can be cast to Object, and then upcast to any valid class. This is done via the use of the first slot of the object's vtable, which contains the ClassInfo. But if you allow structs as interfaces, you're suddenly in the position where you might not actually have an object at all. If you tried to cast a struct to an Object, it might not actually fail; if you're lucky, you'll get a segfault. The only solution there is to give structs a vtable. At which point, congratulations, you've just re-invented classes. To allow structs to implement interfaces would require redesigning how interfaces are actually implemented. You'd probably have to also redesign RTTI as well, object casting, etc.
Re: Using ANSI codes
funog wrote: Stewart Gordon Wrote: Funog wrote: How can I get a D1 console program to use ANSI codes? Currently it just prints the escape character like any other... At first I thought you meant the ANSI character set, but then I realised you're probably talking about ANSI.SYS. This is an operating system issue, not a D issue. What OS version are you using? Try searching the web for info related to yours. Alternatively, check out disp.h, which comes with DMC, and use that instead. I once began writing D bindings for it Stewart. You are right. I was using Vista Premium, but it works fine on linux. http://github.com/DanielKeep/gb/blob/master/src/gb/io/Ansi.d Should stand on its own, but only works with Tango. -- Daniel
Re: The length of strings vs. # of chars vs. sizeof
Rainer Deyke wrote: Jesse Phillips wrote: I believe the documentation you are looking for is: http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD It is more about understanding UTF than it is about learning strings. One thing that page fails to mention is that D has no awareness of anything higher-level than code points. In particular: - dchar contains a code point, not a logical character. - D has no awareness of canonical forms and precomposed/decomposed characters (at the language level). (Some characters can be represented as either one or two code points. D does not know that these are supposed to represent the same character.) - Although D stops you from outputting an incomplete code point, it does not stop you from outputting an incomplete logical character. Also, some D library functions only work on the ASCII subset of utf-8. Well, it *is* on a Wiki.
Re: version specific enum members
Phil Deets wrote: Hi, is there a way to add members to an enum based on conditional compilation symbols. I tried enum Tag { A, B, version (symbol) { C, D, } E, } but it doesn't work. I know I could do version (symbol) { enum Tag { A, B, C, D, E } } else { enum Tag { A, B, E } } but I don't want to do that since in my case, there can be quite a few elements outside of the version, and I don't want to repeat them all. template Version(char[] ident) { mixin(`version(`~ident~`) const Version = true; else const Version = false;`); } char[] genEnum(bool flag1, bool flag2) { return A, B, ~ (flag1 ? C, D, : ) ~ E, F, ~ (flag2 ? G, H, : ) ~ G, ; } mixin(genEnum( Version!(`symbol`), Version!(`somethingElse`) )); ... is about the best you can do, I think.
Re: amazing function behavior
Zarathustra wrote: Function is never called but why? It shouldn't even COMPILE. You can't use member functions as Windows callbacks. You haven't even used the correct calling convention on it. Callbacks for Win API functions have to be, I believe, extern(Windows), and they have to be free functions or static members.
Re: Getting started - D meta-program question
Justin Johansson wrote: There was mention** on the general discussion group that the D foreach_reverse language construct could be replaced (emulated?) with a (D) meta-program. ** Even a novice programmer can write a meta-program to replace foreach_reverse without any runtime performance hit. http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=97362 As I'm less than a novice with the D meta-programming facilities (at this stage of my journey into D), if someone would kindly show me the D meta-program solution to do this, I'd really appreciate the enlightenment. Thanks again. Short answer: you can't. Long answer: you can, provided you aren't trying to reverse an opApply, which is patently impossible. As for the meta-program, I would suspect whoever said that was talking about writing a templated type or function to handle it. You would need to use template specialisation or static ifs to switch on what type you've been given to reverse. http://digitalmars.com/d/1.0/template.html http://digitalmars.com/d/1.0/version.html#staticif
Re: Sizeof class instance
Jarrett Billingsley wrote: On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson n...@spam.com wrote: How does one determine the sizeof (in bytes) of an instance of a class in D? .sizeof works as advertised for structs, but for reference types, .sizeof yields the sizeof the referencing variable (effectively same as size of a pointer) and not the size of the underlying instance. I did try scanning the NG and read spec_D1.00.pdf. Perhaps I missed it in the latter. btw. I was poking under the hood of std.xml and though, wow, instances of Element class look humongous, and so I'm interested to how exactly how humongous. Thanks for all help. Justin There's no way to get it at compile-time in D1. The best you can do is Class.classinfo.init.length. What nonsense, of course there is! http://gist.github.com/140531 Note: this is VERY old code, but I have no reason to think it won't still work. I may need a little dusting off...
Re: Sizeof class instance
Daniel Keep wrote: ... Note: this is VERY old code, but I have no reason to think it won't still work. I may need a little dusting off... *It* may need a little dusting off. Argh.
Re: What if gc.disable at all
Sam Hu wrote: Ah yes,I once translated most of Tango's tango.util.container.* into D2 excluding one or two modules which heavily depends on Tango other modules.It get compiled.However,the test program crashed with below error message: Error 42:Symbol Undefined _D5tango4core6Memory2GC6addrOfFpvZPv ---errorlevel 1 I have no clue what this means and where to restart. Regards, Sam How about by reading the error message? Error 42:Symbol Undefined _D5tango4core6Memory2GC6addrOfFpvZPv -- Error 42:Symbol Undefined void* tango.core.Memory.GC.addrOf(void*) Ergo, you didn't link in tango.core.Memory, which it wants.
Re: Linking in an .so on linux with rebuild?
Jarrett Billingsley wrote: On Wed, Sep 23, 2009 at 1:11 AM, Daniel Keep daniel.keep.li...@gmail.com wrote: Now I just have to figure out how to fix THIS: ../build/dsss_objs/D/sandbox.minid_repl.o: In function `_Dmain': sandbox/minid_repl.d:(.text._Dmain+0x6f): undefined reference to `_D5minid11commandline45__T3CLITS5minid11commandline14MDConsoleInputZ3CLI11interactiveMFPS5minid5types8MDThreadZv' I *hate* linker errors. :( Oh boy, looks like templates are at it again. I'm not sure what the problem is there. Maybe minid.commandline isn't actually being compiled somehow, only imported? Yeah, I got around it by manually adding minid/commandline.d to the compile line.
Re: Linking in an .so on linux with rebuild?
Nick Sabalausky wrote: I can't seem to get that to work. Tried all sorts of stuff. Off the top of my head: -llthelibname -llthelibname.so -L-l thelibname -L-l thelibname.so -L-l -Lthelibname -L-l -Lthelibname.so None of them were able to find the file (and, yes, the name+path are right), and I'm not using any links. I've had exactly the same problem in trying to compile MiniD on Ubuntu last night. MiniD wants libhistory, but -llhistory doesn't work. What's worrying me is that even if I call ld directly and pass -lhistory, IT says it can't find it, either. It's in /lib, so I have no idea what's going on. Passing the .so directly on the command line, like on Windows, doesn't appear to work as either rebuild or DMD is chucking a wobbly at the .so file, complaining it doesn't know what that extension is for.
Re: Linking in an .so on linux with rebuild?
Jarrett Billingsley wrote: On Wed, Sep 23, 2009 at 12:41 AM, Daniel Keep daniel.keep.li...@gmail.com wrote: I found a solution. See http://stackoverflow.com/questions/335928/linux-gcc-linking-ld-cannot-find-a-library-that-exists For me, I needed readline and history, so I did this: $ cd /lib $ sudo ln -s libreadline.so.5 libreadline.so $ sudo ln -s libhistory.so.5 libhistory.so After that, ld didn't complain. Oh yay. I was going to suggest that but I had never had that kind of problem on Ubuntu when building MiniD before. Maybe we're using different versions or something. Now I just have to figure out how to fix THIS: ../build/dsss_objs/D/sandbox.minid_repl.o: In function `_Dmain': sandbox/minid_repl.d:(.text._Dmain+0x6f): undefined reference to `_D5minid11commandline45__T3CLITS5minid11commandline14MDConsoleInputZ3CLI11interactiveMFPS5minid5types8MDThreadZv' I *hate* linker errors. :(
Re: delegate reference
Saaa wrote: abstract class C { int method(); } class C2:C { int method() return 2; } class C3:C { int method() return 3; } int delegate() deleg; void main() { C c; C2 c2 = new C2; C3 c3 = new C3; c=c2; deleg = c.method; writefln(deleg()); // 2 c=c3; writefln(deleg()); // 2 // I expected this to write 3, why is this not so? Because you didn't reassign deleg.
Re: delegate reference
Saaa wrote: Daniel Keep daniel.keep.li...@gmail.com wrote in message news:h88cck$1or...@digitalmars.com... Saaa wrote: abstract class C { int method(); } class C2:C { int method() return 2; } class C3:C { int method() return 3; } int delegate() deleg; void main() { C c; C2 c2 = new C2; C3 c3 = new C3; c=c2; deleg = c.method; writefln(deleg()); // 2 c=c3; writefln(deleg()); // 2 // I expected this to write 3, why is this not so? Because you didn't reassign deleg. but isn't deleg pointing to c's method? Yes... just because you change what c points to doesn't magically rewrite all other references. You might want to read http://digitalmars.com/d/1.0/type.html#delegates
Re: delegate reference
Saaa wrote: Ok, disregard my last comment :D How should I do this then? class Foo { C* c; this(ref C c) { this.c = c; } int invoke() { return (*c).method(); } } void main() { // ... deleg = (new Foo(c)).invoke; } Or something similar. This is dangerous. Do not allow either the Foo instance or the delegate to survive past the end of c's scope. It is simpler and safer to just update the delegate.
Re: Structs by ref in D2
bearophile wrote: Daniel Keep: In my own code, I usually record my intent by using inout for variables I intend to modify and ref for ones which I don't. Always seemed reasonable to me. for the compiler they mean the same thing, but inout is being deprecated. Bye, bearophile I realise this. My point is that the two keywords pretty nicely sum up a difference in intent.
Re: Structs by ref in D2
Steven Schveighoffer wrote: ... The issue is possibly with ref. There are two reasons to use ref, 1 is to be able to change the data referenced, 2 is for passing speed. 1 is bad for rvalues. 2 should be ok for rvalues. If there was a way to signify you only want to use ref for reason 2, there would be a good solution. Most of the time, that's const ref, but what you really want is head-const ref, which isn't currently possible. If a struct has references to other values, they might be lvalues, and you may want to be able to change them. I'm uncertain as to how often you would want to pass an rvalue as a ref that had lvalue reference in it, but at the very least, ref const should be valid. -Steve In my own code, I usually record my intent by using inout for variables I intend to modify and ref for ones which I don't. Always seemed reasonable to me.
Re: Semi Automated Object wrapping
Bill Baxter wrote: On Thu, Aug 13, 2009 at 12:43 AM, Rory McGuirerjmcgu...@gmail.com wrote: On Wed, 12 Aug 2009 17:03:17 -0700, Bill Baxter wrote: On Wed, Aug 12, 2009 at 4:52 PM, Rory McGuirerjmcgu...@gmail.com wrote: Here is some code I wrote which enables wrapping a proxy around an object. I am using it for my serialization library. It works in D1(1.046) and D2 (2.031) Posting it here for reference by all before I add to much of the stuff specific to my use, should make it easier to follow. usage: new ProxyClass!(A, cast(string)getInt setInt getString); would implement the methods getInt setInt and getString from A in the new class. the code below will fail to compile but not before printing the generated code to stdout. Shin Fujishiro has made some new templates for D2 which will make it so I can get rid of the setInt getInt getString part which would make the usage for D2: new ProxyClass!A; which would be great! -Rory // author: Rory McGuire, rjmcgu...@gmail.com import std.stdio; import std.typetuple; import std.traits; import std.metastrings; //import serializer; // this CTF from somewhere on news.digitalmars.com string[] splitFuncs(string str) { string[] res; while (str.length 0) { while (str.length 0 (' ' == str[0] || ',' == str[0])) { str = str[1..$]; } int to = 0; for (; to str.length str[to] != ' ' str[to] != ','; ++to) {} if (to 0) { res ~= str[0..to]; str = str[to..$]; } } return res; } string MethodTypeTuple_mixin(alias a)(string[] methods) { string ret = TypeTuple!(~ typeof(C.init.~methods[0]~); foreach (method; methods[1..$]) { ret ~= ,typeof(C.init.~method~); } ret ~= ); return ret; } // test case class A { int a; this(int a) { this.a = a; } int getInt(string intname) { return a; } void setInt(int i) { a = i; } string getString(string s) { return s ~1234; } } string ProxyMethods_mixin(alias C, string methodstr)() { string ret; foreach(i, t; mixin(MethodTypeTuple_mixin!(C)(splitFuncs (methodstr { // output function header ret ~= \t~ReturnType!(t).stringof ~ ~ splitFuncs (methodstr)[i]~(; // output first arg ret ~= ParameterTypeTuple!(t)[0].stringof~ arg; // output remainder of args foreach (j, t1; ParameterTypeTuple!(t)[1...$]) { ret ~= ,~t1.stringof~ arg~std.metastrings.ToString!(j); } // output body ret ~= ) {\n; // output serialization code // send method name ret ~= \t\twritefln(\serialize docall id\); // the method call byte id\n; ret ~= \t\tbuffer ~= serialize!(string)(\~splitFuncs (methodstr)[i]~\, s_state); /+ the method name +/\n; // send args ret ~= \t\tbuffer ~= serialize!(~ ParameterTypeTuple!(t) [0].stringof~)(arg, s_state); /+ the first argument +/\n; foreach (j, t1; ParameterTypeTuple!(t)[1...$]) { ret ~= \t\tbuffer ~= serialize!(~ t1.stringof ~)(arg~ToString!(j)~, s_state); /+ argument ~ToString!(j)~ +/\n; } // receive return type static if (!is(ReturnType!(t) == void)) { ret ~= \t\treturn deserialize!(~ ReturnType! (t).stringof ~)(buffer, des_state);\n; } ret ~= \t}\n; } return ret; } class ProxyClass(alias C, string methodstr) { ubyte[] buffer; mixin(ProxyMethods_mixin!(C,methodstr)()); pragma(msg, class ProxyClass!(~C.stringof~, \~ methodstr ~\) {\n\tubyte[] buffer;\n SerializerState s_state;\n DeserializerState des_state;\n this() {s_state = new SerializerState(); des_state = new DeserializerState(); }\n\n~ ProxyMethods_mixin! (C,methodstr)() ~\n}\n); } void main() { auto pc = new ProxyClass!(A, cast(string)getInt setInt getString); writefln(ProxyClass: ~ pc.getString(asdf)); } That code is screaming for some macros. Or variable interpolation at least. --bb Where would you propose that one would use 'macro'? It doesn't exist yet, so there's not much you can do about it. Unfortunately code that generates code in D pretty much has to look like what you wrote there. I'm just saying it's not a lot of fun to read such code. Compare with Lisp macros that are almost as readable as regular Lisp functions.
Re: calling function templates
Jos van Uden wrote: I noticed that I don't always have to use the bang notation for function templates. I played around with that a little, but got an error when I used a static array. I think it's because of a casting problem or wrong type inference... I don't imagine it's a bug. Just not possible. ... int[20] arr4; putNumbers(arr4, 0, 3); // ERROR, stat array, regular notation } test.d(8): Error: cast(int[])r is not an lvalue test.d(25): Error: template instance test.putNumbers!(int[20u],int) error instantiating You're instantiating the template as putNumbers!(int[20u],int) because arr4 is of type int[20u]. This means Range is int[20u]. Here's the code for put: void put(T, E)(ref T[] a, E e) { assert(a.length); a[0] = e; a = a[1 .. $]; } r.put(i) is rewritten by the compiler as put(r, i)... except that put wants an int[], not an int[20u]. So it implicitly casts it to the correct type, giving put(cast(int[])r, i). But put ALSO expects its first argument to be passed by reference, and you cannot pass the result of a cast by-reference. (There are a LOT of things you can't pass by reference; it's a constant thorn in my side, and many others' sides.) The problem here is that put is fundamentally incompatible with fixed-size arrays. The solution is to change line 25 to read: auto arr4_temp = arr4[]; putNumbers(arr4_temp, 0, 3);
Re: how does range.put work
Jos van Uden wrote: Oliver wrote: The source code for the standard library comes with the compiler. If you look in std\array.d, you find this around line 279 (reflowed for readability): void put(T, E)(ref T[] a, E e) { assert(a.length); a[0] = e; a = a[1 .. $]; } Would anybody care to explain what this is used for? I find the example in array.d rather unhelpful. Example: void main() { int[] a = [ 1, 2, 3 ]; int[] b = a; a.put(5); assert(a == [ 2, 3 ]); assert(b == [ 5, 2, 3 ]); } You're putting an element in a, but then the first element is moved out of a and the new one shows up in b? Weird. I guess I don't understand what a range is. Jos No; read the code. Before the put, a and b are pointing to the same span of memory. a.put(5) puts the value 5 into the front (first element) of the array, then advances the array. However, put can't see b, so it doesn't get updated along with a. The end result is that b = [5,2,3] and a = b[1..3] = [2,3]. Why do it like this? Here's an example: void putNumbers(Range)(Range r) { int i = 0; while( !r.empty ) { r.put(i); ++i; } } void main() { int[10] ten_numbers; putNumbers(ten_numbers); assert( ten_numbers = [0,1,2,3,4,5,6,7,8,9] ); } Note that putNumbers will work with any type that supports the range API, not just arrays.
Re: how does range.put work
O.K. wrote: Hello, could someone plz clearify what the exact semantics of put are ? Put works with an appender, but gives me a runtime exception when using an array. Best regards, Oliver The source code for the standard library comes with the compiler. If you look in std\array.d, you find this around line 279 (reflowed for readability): void put(T, E)(ref T[] a, E e) { assert(a.length); a[0] = e; a = a[1 .. $]; }
Re: byte to char safe?
Harry wrote: Again hello, char[6] t = ragain ~ cast(char)7 ~ rhello; use only own write functions is ok? thank you! I think a more significant problem is that again\x07hello can't possibly fit in six characters, unless you're using some crazy numbering system I'm not familiar with.
Re: How to search for an element in the array. D2 phobos.
bearophile wrote: Eldar Insafutdinov: I think I completely misunderstood how to use it. Yes, it's too much complex. It tries to do many different things in the most efficient way possible, the result is a high complexity in usage. That's one of the faults of Andrei's code, it's not tested by letting average coders use it. A solution for this problem is to offer simple functions (like you can find in Tango. In my dlibs the situation is intermediate, I think) with a simple API for the most common purposes. Bye, bearophile It should work. Taken from the algorithm docs: Example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, 4) == [ 4, 2, 3 ]); That said, find is too complex for his purposes. Amazingly, Phobos still appears to lack a basic indexOf function. Phobos2: can build a working sentient AI that can feel love up from individual atoms, but can't find the index of an array element. :P
Re: Array slice length confusion
Tim Matthews wrote: Kagamin wrote: Tim Matthews Wrote: I thought a slice would behave slighty different due to some sort of meta data that is a separate area of memory so it doesn't effect D's abi. Current plan is to introduce new type - array - into the language. Do you know the ng posts or where ever that was posted? Best bet would be to search for T[new].
Re: How to release memory? (D2.0.30)
BCS wrote: ... The good news is that with virtual memory, all of that has almost zero cost. What matters is how much ram you are actively using. You've obviously never used a netbook with no swap file. :)
Re: why __traits not in trait module and not name it trait
Sam Hu wrote: Yes,__traits did not stole my girl friend,but isn't better to name it trait? And I have thought I can find it in trait moudle but I was wrong. It's not in a module because it's a keyword. You don't find function defined in any library. As for being called __traits instead of traits, I suspect that's for at least one of two reasons: 1. so it won't invalidate existing code that uses the identifier traits, and/or 2. because it's not something regular programmers should have to use; it should be used to build a higher-level API using templates.
Re: D compiler for .NET
Jason House wrote: Earlier today, I tried to use the D compiler for .NET from http://dnet.codeplex.com/ Beyond compilation of the compiler, I found zero instructions on what to do next. How do I integrate the compiler into the .NET framework/visual studio? I'd like to be able to add D files to existing solutions (with C# code). If I can do that, I'll probably push for some small adoption of D at work. (I'm hoping mixins and templates will inspire the initial use of D) Any tips or documentation on how to get started would be appreciated. The back-end code is not of production quality, it is intended for research and educational purposes. The D Programming Language is a fairly complex language, and non-trivial features such as TLS and closures make it an interesting case study for generating IL code. Why do people never read the big red label saying Warning: not ready for use!? As for VS integration, so far as I know, there isn't any. I'm also fairly certain that you can't combine different languages in a single project period.
Re: legal identifier check
Saaa wrote: ... I know use this (in the ddata thread above): foreach(char c; identifier) { if( !inPattern( c, `_a-zA-Z0-9`) ) { return false; } } That's not correct. http://digitalmars.com/d/1.0/lex.html#identifier
Re: Encoding problems...
Robert Fraser wrote: BCS wrote: Reply to Robert, Hmm... I'd say x.⊆(y) is preferable x.isSubsetOf(y), but it's not a huge deal. Only until you have to type it. I think universal alpha includes only the union of things that can be easily typed on standard keyboards. I don't think any keyboard (ok maybe an APL keyboard) has the subset symbol on it. I have 10 configurable keys on my keyboard, none of which are in use. I could also remap my numpad (cause, seriously, who uses this?) Also, many editors can be configured so that a sequence of characters converts to a single one. Which would possibly make D the first language to *require* a specialised keyboard and/or editor since APL. Not a good precedent. Oh, and don't try to argue it isn't mandatory. If you can overload those operators, people WILL use them and WILL complain that it's too hard. There appears to be no reason that mathematical symbols aren't allowed in identifiers... Think of how awesome it would be to write assert(x⊇y→∀a∈x∃b∈y(a⊇b)) ... Okay, that would require overloading of those operators (and instantiating variables in a new way), but still! I think that example you gave is an excellent reason not to allow them. :D It would be nice, but it's really not feasible without widespread editor and/or keyboard support for extra symbols, which I just don't see happening.
Re: How many people here use stackoverflow.com?
Tim Matthews wrote: On Sat, 23 May 2009 08:36:44 +1200, hasen hasan.alj...@gmail.com wrote: If I have some questions about D, should I ask on stackoverflow instead of here? Are there enough D'ers there? I personally think that asking there would bring more public attention to D, but it all depends on whether there are enough people there who know about D. For instance, I might have a couple of question about gtkD, as I'm trying to play with it right now. So, do you regularly visit http://stackoverflow.com/ or no? http://stackoverflow.com/questions/tagged/d I remeber seeing a post on annoucements a long time ago about when you type d on the tags page here http://stackoverflow.com/tags you dont get the d tag. IIRC that guy sent en email to jeff atwood about it but it is still not working. I use the feed at http://stackoverflow.com/feeds/tag/d to keep an eye on any D questions as they pop up. -- Daniel
Re: DMD Modifications
white_man wrote: Does it possible to modify DMD and publish it in that form. Of course with full information about authors. Does it legal? It depends. If you ONLY modify the front-end (front-end files are identified as being licensed under GPL [1]), then you can distribute the modified front-end. However, if you modify the back end, you cannot redistribute those files. You also cannot distribute a compiled version. To be safe, it's probably best to just distribute any changes you make as a patch. -- Daniel [1] There's another license involved, but I forget what it's called.
Re: D1/D2 co-install?
BCS wrote: Does anyone have a good solution to installing both D1 and D2 on the same system? I have... (goes to check) 10 different compilers on my system. There's \dmd\bin\dmd-default which is the only one on the PATH (and is basically a stable version of Tango and DMD). If I want to use the others, I use the full path to them. OR, you can use rebuild and configure it with extra compiler profiles, then use (for example): rebuild -dc=dmd-1.035 stuff -- Daniel
Re: 3 variant questions
Saaa wrote: ... var_arg!(T) will convert _argptr into the type you specify and it will also advance _argptr to the next argument. What would happen if you'd cast it incorrectly if it wasn't a simple pointer ? :D Same as would happen if you incorrectly cast anything. i.e. anything. Segfault if you're lucky. If you're unlucky, random crashes. -- Daniel
Re: Resource availability: fonts
Tyro[a.c.edwards] wrote: One cannot necessarily rely on particular font being available on a system, and for security reasons asminsistrators restrict instalation of fonts (among other things) onto systems in a network. I would like to know if it is possible to embed a font into my code so that I know that it will always be there, or can I provide it with the exe but not have to rely on it being installed (i.e. use it from the same folder in which the exe resides)? Thanks, Andrew That depends. What are you using the font for? If you're using a library that requires a family name, then probably not. If you're using a library that can accept a file name, then probably yes. Remember that the system doesn't care if you append crap to the end of an executable. One trick you can use is to just append whatever files you want to the end of the executable, and then have a little 1K block at the end that tells you where the files are and how big they are; you can then extract the files at run time and delete them when you terminate. -- Daniel
Re: how to initialize an array of typedef-ed type?
Jarrett Billingsley wrote: On Sat, May 2, 2009 at 12:21 AM, Daniel Keep daniel.keep.li...@gmail.com wrote: import std.conf; b = to!(long[])(a); That should work, in theory. In reality, it's std.conv ;) Those letters are like RIGHT NEXT to each otter! Don't judfe ne! (or tango.util.Convert, with identical syntax) Never heard of it. :) -- Daniel
Re: How to get the base type of a typedef
bearophile wrote: MLT: Is there a way to get the base type of location? See the BaseTypedef() template in the templates module of my dlibs (they are for Phobos): http://www.fantascienza.net/leonardo/so/libs_d.zip Bye, bearophile It's probably something along the lines of: template BaseTypedef(T) { static if( is( T U == typedef ) ) alias U BaseTypedef; else alias T BaseTypedef; } -- Daniel
Re: how to initialize an array of typedef-ed type?
Jarrett Billingsley wrote: On Fri, May 1, 2009 at 11:34 AM, MLT n...@anone.com wrote: Is there an easy way to convert arrays from one type to another? int[] a=[1,2,3,4] ; long[] b ; Not really. The best you can do is: b.length = a.length; foreach(i, ref v; b) v = a[i]; import std.conf; b = to!(long[])(a); That should work, in theory. -- Daniel
Re: enum in template
Sam Hu wrote: Hello everybody! Convert integral value to string literal: template myToString(ulong n, string suffix=nuint.max?UL:U { static if (n10) enum myToString=cast(char)(n+'0')-suffix; //q1 else enum myToString=.myToString!(n/10,)- .myToString!(n%10,)-suffix;//q2 Here is my questions,sir: No need to be so formal. Also keep in mind that sir only applies to men, and is thus excluding any women in this NG. :P q1.what the key word enum here is doing? not key word char[] or 'string' or something else? enum defines a manifest constant. In other words, it defines a constant that does NOT consume any storage anywhere in the program: it exists only at compile-time. enum blah = 42; // single manifest constant enum { blah = 42 } // again, but in a block, potentially with others enum Stuff { blah = 42 } // again, but in a named enumeration q2. How does this works?Say n=12,then how can the result be 12? Recursion. I assume you have modified the code from its original since '-' would be invalid. It should be '~' which is the concatenation operator in D. Thanks and best regards, Sam -- Daniel
Re: Get the name of a function and the parameters?
Jarrett Billingsley wrote: On Tue, Apr 28, 2009 at 3:07 PM, grauzone n...@example.net wrote: I'd like to pass several functions at once. Is there a way to make this variadic? The obvious approach (writing NameOfFunc(alias f...)) fails with a syntax error. Sure, you'd just make it NameOfFunc(f...) and then recursively instantiate, converting one item at a time to its name until f.length == 0. Alternatively, you can write a compile-time map and use NameOfFunc as the mapping predicate. That requires f to be a type, which loses you the actual names. And you cannot (last time I checked) have aliases in a tuple. -- Daniel
Re: Get the name of a function and the parameters?
Daniel Keep wrote: Jacob Carlborg wrote: Is it possible to get the name of a function and the names of the function parameters? I don't believe so, no. -- Daniel I should perhaps qualify, in light of Jarrett's response, that I thought you meant from inside the function ala __FUNCTION__ or somesuch. -- Daniel
Re: i need a serialization framework for d
BCS wrote: http://stackoverflow.com/questions/783482/i-need-a-serialization-framework-for-d Put my AU$0.02 in. OT: would anyone be interested in a one way stackoverflow-NNTP hookup kinda like is used with the bugzilla? I think that'd be pretty cool; have it post questions to D.learn so they get better exposure. -- Daniel
Documentation on DMD source
Is there any guide to, or documentation for the DMD compiler source? I'm currently trying to make TypeInfo_Function not completely useless, but I'm not sure my code is actually being run. -- Daniel
Re: Documentation on DMD source
Daniel Keep wrote: Is there any guide to, or documentation for the DMD compiler source? I'm currently trying to make TypeInfo_Function not completely useless, but I'm not sure my code is actually being run. -- Daniel Found this page: http://www.prowiki.org/wiki4d/wiki.cgi?DMDSourceGuide although it's fairly bare-bones. -- Daniel
Re: Widening a type
Doctor J wrote: OK, here's one for you that sounds like it ought to be easy, but I don't immediately see how to do it in a pretty way. Given a type parameter T of a template: If T is an integral type, I want to declare a variable 'widest' of type ulong; If T is a floating-point type, I want to declare a variable 'widest' of type double. And it has to be prettier than my solution. :) static if (is (T: ulong)) ulong widest = 0; else if (is (T: double)) double widest = 0.0; else static assert (false, Unimplemented type ~ T.stringof) ; Now, I thought this sounds like a great job for a mixin: template Widen (T, alias varname) { static if (is (T: ulong)) ulong varname = 0; else if (is (T: double)) double varname = 0.0; else static assert (false, Unimplemented type ~ T.stringof) ; } mixin Widen!(T, widest); but alas, Declaration expected, not 'if'. Help? The error tells you everything you need to know if you read it. Actually, you have two problems: you're trying to use if where you should be using static if, and you can't alias a symbol name then use it in a declaration. Here's a fixed, expanded version. template Widen (T, char[] varname) { static if (is (T: ulong)) { mixin(`ulong `~varname~` = 0;`); } else { static if (is (T: double)) { mixin(`double `~varname~` = 0.0`); } else { static assert (false, Unimplmented type ~ T.stringof); } } } You can remove those braces, I just wanted to point out that putting static out the front of an if doesn't magically make the else branch static as well. -- Daniel
Re: static initialization of associative arrays
Tyro[a.c.edwards] wrote: Is it yet possible to statically initialize an associative array? If so, please point me to the documentation. I am using DMD v2.028. Currently I'm able to do this: import std.stdio; string[string] types; static this(){ types = [ void:void, bool:bool ]; } void main(){ writeln(types); } Output = [void:void,bool:bool] which is exactly what I want. However, removing static this() results in an error. string[string] types = [ void:void, bool:bool ]; Result: api.d(77): Error: non-constant expression [void:void,bool:bool] How do I make the initialization constant? Thanks, Andrew I think Walter said something a while back to the effect that making it possible to statically initialise AAs isn't feasible because it requires setting up a complex structure on the heap. The best you could do would be to *pretend* to statically initialise them, and actually really initialise them in a module ctor. Which is exactly what you currently have to do. Could be wrong; that's just what I remember from the last time this came up. -- Daniel
Re: D1 and read-only views?
As others have stated, your surmise is correct. On a related note, I recently wrote a very simple cstring struct that acts like const(char)[] does in D2. I was using unique interned strings, and didn't want any surprises. You can still get a mutable reference to the string by using .toString, but the struct is really only there to prevent accidental modifications. -- Daniel
Re: Wht std.complex is needed?
Steven Schveighoffer wrote: On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote: Sam Hu wrote: Thank you! Anothe silly question then:What's the disadvantage to have the built-in type of i-type? Regards, Sam It's a very nasty type. It supports *, but isn't closed under *. Which is really annoying for generic programming. idouble x = 2i; x *= x; // oops, this isn't imaginary. (BTW this currently compiles :o). This may be a dumb question, but aren't all real numbers also technically imaginary numbers with a 0i term? that is, I would expect the above to evaluate to: -4 + 0i Which I would view as an imaginary number. Am I completely wrong here? You're thinking of complex. -4 is real, 2i is imaginary, -4+2i is complex. Regarding Don's example, imaginary*imaginary always yields a real, real*imaginary always yields an imaginary. It's the only builtin type I know of that changes type under multiplication with itself. -- Daniel
Re: cast a LinkSeq
Qian Xu wrote: Adam Burton wrote: I wouldn't think so, cos LinkSeq!(Apple) does not inherit LinkSeq!(Fruit), they are 2 separate types. However your apples automatically downcast (or up, depending which way you like to draw your diagrams :-) ) so unless you intend to pass the LinkSeq!(Apple) into a function expecting LinkSeq!(Fruit) it shouldn't be a problem. If you are passing about LinqSeq!(Fruit) and want your LinkSeq!(Apple) to fit you might need to write some adapters and make use of the models available to you or something along them lines. That's my understanding anyway. yes. I can cast all Apple-object to Fruit-objects one by one. I hope there is an one-line-solution :-) You can't do it. Imagine you cast your LinkSeq!(Apple) to LinkSeq!(Fruit). You can now add a Banana to your LinkSeq!(Fruit), thus corrupting the original object. You get a similar problem with arrays. The most direct way would probably be to create a LinkSeqView!(T) class which did the cast on the fly and prohibited mutating operations. -- Daniel
Re: Universel toString
Qian Xu wrote: Hi All, I want to write an universel toString() method for debugging propose. However I cannot write in one version. The compiler says error all the time. Could someone tell me, how to write an universel one? What I want, is to convert primtive types (int, int*, bool, bool*, etc.) to string using tango.text.Convert.to() and convert object to string by calling obj.toString. ... Best regards --Qian Xu to!(char[]) should call toString. to!(T) should support all atomic types, strings, structs and classes. -- Daniel
Re: enum to string
Ary Borenszweig wrote: Lionello Lunesu wrote: Brad Roberts bra...@bellevue.puremagic.com wrote in message news:alpine.deb.2.00.0903121755240.4...@bellevue.puremagic.com... That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :) You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research. Can you foreach at compile-time? I thought you could only do that in CTFE (or templates?). Maybe that's why it's not working. How do you do it to pragma msg the members of a struct? I remember someone proposed static foreach some time ago... We have a sort-of static foreach. The trick is that the aggregate HAS to be a tuple. When in doubt, you can always fall back on the following construct: template Tuple(T...) { alias T Tuple; } template Range(int n) { static if( n = 0 ) alias Tuple!() Range; else alias Tuple!(Range!(n-1), n-1) Range; } void blah() { // Note that static foreach ONLY works inside a function foreach( i ; Range!(n) ) { // do stuff with i, which should be a const int } } There have been times when directly accessing some CT construct would make the compiler choke, but going via an index worked fine. -- Daniel
Re: recognizing asciiz, utf ...
newbee wrote: Jarrett Billingsley Wrote: On Fri, Mar 13, 2009 at 3:04 PM, newbee new...@newbee.com wrote: Hi all, How does one check for asciiz, utf ...? I do get a buffer with characters as parameter in a function, but i don�t know if it is asciiz or utf or wchar. Is it possible to find out in dmd1 and dmd2? Any help is appreciated. How are you getting this buffer? What type is it, char[]? D strings are supposed to be Unicode, always. If you read the data in from a file, there's little to no guarantee as to what encoding it is (unless it started with a Unicode BOM). If you have a zero-terminated char* that a C function gives you, you can turn it into a D string with std.string.toString (Phobos) or tango.stdc.stringz.fromStringz (Tango). i get it from a tcp buffer and do not know in advace if it is char[], asciiz or wchar. is it possible to check for that? If you're getting data from a network connection and you have no idea what it is, then the language certainly isn't going to help you with that. Perhaps reading the documentation for the network protocol is in order? :P -- Daniel
Re: lvalue - opIndexAssign - Tango
The Anh Tran wrote: Hi, When porting from c++ to D, i encounter this strange discrimination: 1. Built-in AA: int[int] arr; arr[123] += 12345; arr[321]++; 2. Tango HashMap: auto hm = new HashMap!(int, int)(); hm[123] += 12345; // error not lvalue hm[123]++;// error D document says current opIndexAssign does not work as lvalue. But why can builtin AA can that? How can i copy builtin AA behaviour? You can't. This is a hole in the language at the moment, hopefully solved by the introduction of ref returns (but that's in D 2.0 which you don't want to use at the moment.) Forgive my noob, where is the place to ask question, report bug for Tango? You could try the Tango IRC channel: irc://irc.freenode.org/#d.tango That, or the Tango forums: http://dsource.org/projects/tango/forums You can report problems with Tango via the ticket system: http://dsource.org/projects/tango/report (New Ticket is down the bottom of the page.) 1. I can't compile D code using tango hashmap in debug mode: import tango.util.container.HashMap; void main() { auto hm = new HashMap!(uint, uint)(); } dmd -w -g -debug hello.d // error When posting problems with compiling something, it helps to mention the version of the compiler you're using, your platform, the version of Tango (in this case) and what the error actually is. 2. Compile D code using Tango Regex by GDC emit lots of link errors. 3. Bug in Tango atomicIncrement, atomicDecrement: int task_done = 0; atomicIncrement(task_done); That function is compiled in asm: lock inc byte ptr[task_done]; Which is wrong. It'll wrap to 0 at 255. It should be: lock inc dword ptr[task_done]; 4. There is no atomicAdd(ref original, int newvalue) family. GCC equivalence is __syn_fetch_and_add ... -- Daniel
Re: Newbie question: COM programming and linking to Windows libraries
Patrick Kristiansen wrote: ... Now, this is probably obvious to some people - but not to me. Why doesn't this work? Why does OPTLINK fail and tell me that the format of the .lib file is wrong? Is it because Digital Mars compilers produce .lib files in a different format? Is it because I have the 64 bit SDK installed, and DMD and optlink only produce and consume 32 bit object files and libraries? Please enlighten me ;-) Thanks in advance. -Patrick The DM toolchain produces and consumes OMF object files, while I suspect the SDK uses COFF. Also, the toolchain is 32-bit, not 64-bit. There's a tool called implib which can generate a .lib file that DMD/OPTLINK can use. Documentation is here: http://www.digitalmars.com/ctg/implib.html. You can get it by going to http://www.digitalmars.com/, clicking on Download Digital Mars C compiler, accept the agreement, and then scroll down to Basic Utilities. -- Daniel
Re: array and pointer
takeshi wrote: Hello, I have just started learning D. I cannot compile the code in the documentation on array and pointer either with dmd (D 2.0) and gdmd (D 1.0). Is some compile option or cast required? int* p; int[3] s; p = s; If that's the example, then it's out of date. It should be this: int* p; int[3] s; p = s.ptr; -- Daniel
Re: Reading and writing Unicode files
jicman wrote: Ok, the only reason that I say Unicode is that when I open the file in Notepad and I do a SaveAs, the Encoding says Unicode. So, when i read this file and I write it back to the another file, the Encoding turns to UTF8. I want to keep it as Unicode. There is no such thing as a Unicode file format. There just isn't. I know the option you speak of, and I have no idea what it's supposed to be; probably UCS-2 or UTF-16. I will give the suggestion a try. I did not try it yet. Maybe Phobos should think about taking care of the BOM byte and provide support for these encodings. I am a big fan of Phobos. :-) I have not tried Tango yet, because I would have to uninstall Phobos and I have just spend two years using Phobos and we already have an application based in Phobos and changing back to Tango will slow us down and put us back. Maybe version 2.0. There's std.stream.EndianStream, which looks like it can read and write BOMs. As for converting between UTF encodings, std.utf. -- Daniel
Re: Dynamic Array Garbage collection
wolftousen wrote: I have a function defined as: some_function(int[] array) { ... }; //this function does not ever modify values of array When I call this function (once every program cycle) from an object using an array of type short: //member variable in an object short[] x = new short[4]; //object calls this some_function([ x[0], x[1], x[2], x[3] ]); After a few seconds of the program running, x[0] and x[1] values are set to 0 and a couple values of another array in the object are modified as well. I have found that this bug is corrected by calling delete at the end of some_function of the variable array. This tells me that the garbage collector is acting funny if I do not call delete on the array. (I have watched the memory usage of the program and it doesn't fluctuate or pause or anything to signal the freeing/allocating of memory) Any Idea what is going on? This sounds like something else is going on, although what I'm not sure. Maybe it's because I just woke up, but I can't see how that code could compile anyway, since you can't pass a short[] to a function expecting an int[]. Do you have a minimal, reproducible test case we can look at? -- Daniel
Re: Generic functions to convert to void* and from void*
TSalm wrote: In my case, there's also no possibility to get the wrong type, because it is managed by the type of the ColumnMem. You still have to get the code right. There's a surprising number of corner cases trying to store arbitrary types. And about Object, if I want to store base type like int,double,etc..., if I do something like : Object o; int a = 30 ; o = cast(Object) a ; is this syntax is GC safe ? It's not safe, period. If the compiler lets you do that, I'd be tremendously surprised; even more surprised if it doesn't cause major problems later. This is what I'm worried about; you're doing dangerous things with a type system you don't understand. Don't do this. Here's the problem: void* isn't going to work for everything. It'll work for Object references, other pointers, and that's it. You can't store arrays, and you can't store value types like structs or primitive types. For that, you need to allocate heap storage, copy the value and then store the pointer to that. Oh, and don't forget that fixed-length arrays have value semantics whereas dynamic arrays and slices have reference semantics; although you generally solve that issue by having a special template for your type which rewrites T[n] as T[]. Also, delegates won't fit, but function pointers will. This is why I was pointing you at Variant because I already went through the trouble to solve all this once. :P If you still want to do this with void*, build that code in isolation and test the heck out of it. -- Daniel
Re: Any way to track memory allocations?
wade wrote: Thanks again for all the help. I found what the problem was and it wasn't obvious (at least to me): float[uint] arr; foreach (uint k; arr.keys) { ... } Changing this to: foreach (uint k, float v; arr) { } fixes the leak. I guess the keys array is constructed on the fly? wade Yup. It's a pity that we don't have, oh I don't know, some sort of efficient iterable interface that doesn't cause a heap allocation that the runtime could use instead *cough*hint*cough*andrei*cough*ranges*cough*. -- Daniel
Re: Dynamic Array Garbage collection
Jarrett Billingsley wrote: On Tue, Feb 24, 2009 at 6:45 PM, Daniel Keep daniel.keep.li...@gmail.com wrote: Maybe it's because I just woke up, but I can't see how that code could compile anyway, since you can't pass a short[] to a function expecting an int[]. You missed the array literal. I saw that, but thought that it would be a short[] literal since it's usually the type of the first argument. -- Daniel
Re: Any way to track memory allocations?
Jarrett Billingsley wrote: On Tue, Feb 24, 2009 at 8:23 PM, Daniel Keep daniel.keep.li...@gmail.com wrote: Yup. It's a pity that we don't have, oh I don't know, some sort of efficient iterable interface that doesn't cause a heap allocation that the runtime could use instead *cough*hint*cough*andrei*cough*ranges*cough*. You can use foreach(k; aa) and foreach(_, v; aa). The thing is they're not always substitutes for .keys and .values. For example, if you want to modify the AA during the foreach loop, you have to use something like foreach(k; aa.keys) since you need a snapshot of the keys as they were before you started modifying it. True; although I'm one of those people who stays up at night, plotting the gruesome demise of invisible allocations, so I tend to do manually create and destroy the storage for the keys. In a perfect world, we'd have extension methods, and then we could just do this: RangeType!(T)[] toArray(T)(ref T this) if isRange!(T) { ... } foreach( k ; aa.keys.toArray ) ... My own policy is that if you have to choose between two designs, one where you always allocate and the other where you can optionally allocate, go for the second. -- Daniel
Re: Generic functions to convert to void* and from void*
TSalm wrote: I'm trying to build function which have the hability to convert a type to void* and from void*. First of all, I have to ask: have you looked at std.variant / tango.core.Variant? Yes, but it seems that Variant class uses more memory than void* . The Phobos Variant will use however much space you reserve as the maximum, plus 4 bytes for a function pointer, but it can only store types as big as you allow for. The Tango version will use max(real.sizeof,void[].sizeof) + 4 bytes for the typeid and can store anything you throw at it. For that extra space, both of these will give you runtime type safety, meaning you can't accidentally get the types wrong. They're MUCH safer than void*. [...] I get the distinct impression that you're seriously over-thinking this. Both of these functions could be rewritten as casts. Aside from that, you've given no context for me to have any idea what you're trying to accomplish here. I'm really a newbie concerning the use of void* ( I think you have notice this ;-) ) Thanks for your usefull remarks. void* is just a pointer like any other. It doesn't have any special properties except that you cannot dereference it; that's it. If you're not sure how to use pointers, then don't. For example, you could store objects instead; this takes the same amount of storage in the DBMS, and allows for safe casting back to the original type. Plus, you don't have to stuff about with casting things to void* and back. I'm simply trying to make a little and lightweight DBMS in memory. Simply made by classes like TableMem, RowMem and ColumnMem(T). There's also a private class which aims to store datas, using void*[][]. Unless you really need to store small value types like integers, etc. in that private data, objects might be the best bet for now. -- Daniel
Re: Generic functions to convert to void* and from void*
TSalm wrote: I'm trying to build function which have the hability to convert a type to void* and from void*. First of all, I have to ask: have you looked at std.variant / tango.core.Variant? I must use ref in the toPtr function because of this : http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.D.learnartnum=15600 Do you think that what I done is correct ? /* - CODE - */ /*** * Convert a value to a void* * Params: * val = * Returns: */ void* toPtr(T)(ref T val) { void* p ; static if ( is( T b : Type ) ) What is this test doing? You're checking to see if T can be implicitly cast to Type... but Type isn't defined. And what is 'b' doing there? { p = new T ; p = val ; You never use the freshly-allocated T. You assign it to p and then immediately overwrite it with val. } else { p = val ; } return p ; } So the function is basically doing this: T fromPtr(T)(ref T val) { return val; } /*** * Convert a void* to his value * Params: * ptr = * Returns: */ T fromPtr(T)(void* ptr) { return *(cast(T*)ptr) ; } /* --- END CODE */ I've forget to say that toPtr can't be call with constants. I get the distinct impression that you're seriously over-thinking this. Both of these functions could be rewritten as casts. Aside from that, you've given no context for me to have any idea what you're trying to accomplish here. -- Daniel
Re: Symbol undefined on interface with public getter and package setter
TSalm wrote: I'm not sure but I think package is not virtual. :-( So there's really no way to have a method declared package in an interface ? You also can't have a private function in an interface. This once lost me four days trying to figure out why my program wouldn't link despite the function very obviously being there. Stick to public functions only. -- Daniel
Re: Unicode problems?
Trass3r wrote: Wikipedia states that D still has some Unicode problems: Operations on Unicode strings are unintuitive (compiler accepts Unicode source code, standard library and foreach constructs operate on UTF-8, but string slicing and length property operate on bytes rather than characters). Is this information correct? They're not bugs, if that's what you mean. It's just a side-effect of how Unicode works. http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD Long story short: they operate on bytes because operating on actual code points can't be done efficiently [1]. -- Daniel [1] Given that strings are implemented as arrays with a given, non-changing width and that you're not using UTF-32 which no one does because it's too big and that we don't add some fancy caching stuff to char[] arrays specifically, blah blah blah.
Re: get a struct member pointer
grauzone wrote: bearophile wrote: Daniel Keep: void lookup(T)(T[] s, size_t offset) { char[] text = *cast(char[]*)(cast(void*)(s[0]) + offset); } I am learning still this topic, but can't this create an aliasing problem, as in C? http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html My theory is, that Walter's code generator is too primitive to care about aliasing. But I guess it's possible, that aliasing rules will be added later to the language, when LDC (hopefully) gets big? By the way, wtf is Daniel's code doing at all? Bye, bearophile Unless I cocked it up (which is entirely possible, mind you) I'm trying to get a pointer to the struct, cast to void* because I can never remember if (ptr + int) multiplies the offset by (*ptr).sizeof or not, casting THAT to a pointer to a char[], then dereferencing it to get the value. It is also, in a round-about way, trying to demonstrate that trying to do this is really just not pretty and Jeffry might like to investigate alternate ways of getting those fields. :P -- Daniel
Re: Template conflict?
Mike L. wrote: Derek Parnell Wrote: On Sun, 15 Feb 2009 02:20:50 -0500, Mike L. wrote: Can anybody explain why I get the following error: test.d(28): Error: test.tblahTemplate!(uint).tblah at test.d(13) conflicts with test.tblahTemplate!(int).tblah at test.d(13) tblah(3); It fails because of the literal '3'. The compiler cannot be sure if you want the 'int' or 'uint' function called because '3' matches both of them. You need to make the literal explicit... tblah(3u); -- uint call tblah(cast(int)3); -- int call -- Derek Parnell Melbourne, Australia skype: derek.j.parnell But what confuses me is that it needs it for the template, but not when I create blah() without templates. Why the inconsistency? It's a side-effect of the mixins. AFAIK, the compiler is treating those mixins as coming from different sources. When it encounters multiple symbols from different sources, it's designed to be overly cautious and assume you didn't know. I think you can override this by changing the two mixin lines to this: alias tblahTemplate!(uint) tblah; alias tblahTemplate!(int) tblah; -- Daniel
Re: state of win32 headers?
akcom wrote: What is the state of the win32 headers? Is there any place where I can get win32 headers including winsock2? http://www.dsource.org/projects/bindings/wiki/WindowsApi Haven't checked on them in a while, but they should be usable. -- Daniel
Re: switch off GC?
Weed wrote: It is possible to disable GC? Yes. See std.gc or tango.core.Memory. That it has not been included in result binary for an increasing performance of ref operations and reduction of the size of the binary I don't know what ref operations are, but odds are disabling the GC will not alter their performance. Disabling the GC just prevents collections from occurring. Collections ONLY occur during allocation, so the only thing you'll speed up are allocations. Whilst it's possible to replace the GC in D, it's not exactly straightforward. I'm not sure what the situation with Phobos is, but last I checked, the GC is built as part of Phobos, so you would need to make a custom version. Tango is slightly better in this respect; the GC is compiled separately, and is then linked in. I also believe Tango has a stub GC that doesn't actually do any garbage collection; you just need to link that in instead of the proper GC. -- Daniel
Re: Some performance questions
Lars Kyllingstad wrote: [snip] From a performance perspective, however, it carries with it the overhead of an extra function call, which I'm not sure I want. -Lars You're worried about a second function call which could potentially be inlined, yet you're seemingly not worried about the overhead of virtual calls or heap allocations... Allow me to quote Donald Knuth: We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Unless you're doing something where you *know* you're going to need every last cycle, just go with whichever design works best. Your response to Jarrett implies that you've already got a design in mind, and are just fishing for a magic make it go faster button. Believe me, if Walter had invented such a thing, he wouldn't be wasting his time putting up with us; he'd be too busy smoking $100 bills from the comfort of his SPACE FORTRESS. :D In any case, I'm willing to bet that if there *are* inefficiencies you're not going to know exactly where until you've written the code, anyway. :P If classes work, and make for an elegant design, go for it. -- Daniel
Re: Segmentation error at the end problem (148 line program listing)
grauzone wrote: The garbage collector isn't guaranteed to to free and destroy an unreachable object. That's because the GC is conservative. So if you want to be sure the object's resources are freed, you have to do it explicitly. I think you have two choices: 1. Remove close() from the destructor, and call close() manually when you're done. 2. Use scope or delete to ensure the destructor is always directly called, and never by the GC. Here's how you can use scope: { scope BlockFile f = new BlockFile(...); //... do something with f } //f goes out of scope, and the compiler inserts delete f; If you're going to do that, you really should make the it a scope class to ensure you never accidentally let the GC try to delete it. I (and a few others) petitioned what feels like years ago for a simple argument to dtors to distinguish between deterministic destruction (delete/scope) and automatic destruction (GC). Never gained any ground, sadly. -- Daniel
Re: casting int[] to bool[]
Saaa wrote: This will take some time to understand. Things I have never used before : D Tuple, variadic function, template, mixin ..stringof(can't find this one), static if I'll read up until I understand this. One question I can ask. Why is that foreach loop run at compile time? The compiler checks for a template parameter? [snip] Tuples are like arrays that have a fixed length, where each element can be of absolutely any type at all. What this means is that it potentially takes different code to access each element of a tuple. So when you see foreach( i ; Range!(4) ) foo(i); What is actually being generated is this: foo(0); foo(1); foo(2); foo(3); It's not really doing the foreach at compile time, but it is unrolling it. You might think but why doesn't this happen for arrays? Because you can't do THIS with arrays: foreach( i,x ; Tuple!(0, b, 3.0) ) writefln(Element %s == %s,i,x); Which expands to: writefln(Element %s == %s,0,0); writefln(Element %s == %s,1,b); writefln(Element %s == %s,2,3.0); -- Daniel
Re: Moving from C to D
bob wrote: do IN become in maybe? BLS Wrote: BCS wrote: Reply to bob, sorry i copy wrong line. how do i do this line: int PASCAL FAR mycnt ( IN SOCKET s, IN const struct sockaddr FAR *name, IN int namelen ); bob Wrote: step 1 would be get the output from the preprocessor and take a look at it. I'm guessing that PASCAL, FAR and IN are macros step 0 is try htod: http://www.digitalmars.com/d/1.0/htod.html I think int PASCAL FAR mycnt() becomes : extern (Pascal) int mycnt() The FAR* thingy seems to be a 16 bit relict... Guess the IN is not nessesary in D..., not sure though Bjoern in means pass argument by value, and is the default for arguments. Also, I believe that PASCAL is the same as the Windows cc, so my guess at the conversion would be: For D 1.x: extern(Windows) int mycnt ( SOCKET s, sockaddr* name, int namelen ); For D 2.x: extern(Windows) int mycnt ( SOCKET s, const sockaddr* name, int namelen ); Note that you'd have to supply definitions of SOCKET and sockaddr. -- Daniel
Re: Prevent default-initialised struct
grauzone wrote: Use a class instead. That would defeat the purpose of defining a non_null template in the first place. -- Daniel
Re: Moving from C to D
BLS wrote: Daniel Keep wrote: [snip] Also, I believe that PASCAL is the same as the Windows cc, so my guess at the conversion would be: For D 1.x: extern(Windows) int mycnt ( SOCKET s, sockaddr* name, int namelen ); For D 2.x: extern(Windows) int mycnt ( SOCKET s, const sockaddr* name, int namelen ); Note that you'd have to supply definitions of SOCKET and sockaddr. -- Daniel I am pretty sure that PASCAL means __pascal so the D1 translation is : extern (Pascal) int mycnt ( SOCKET s, sockaddr* name, int namelen ); See :http://www.digitalmars.com/d/1.0/htomodule.html at the bottom Bjoern Aah yes; I didn't realise Pascal was defined; I thought it was limited to C, D, Windows and System for D1, adding C++ for D2. -- Daniel
Re: Is there a way to remove the requirement for parenthesis?
Charles Hixson wrote: Suppose that you have four types, equivalent to, say, float. Call one of them Horiz, one Vertic, one Radians, and one Radius. These are all floats, but when you specify, say, float dist (Horiz x, Vert y) { return sqrt(x * x + y * y); } It's important that the arguments aren't Radius and Radians. Or Horiz and Horiz. [snip] There's no problem with that: make them structs that implement the appropriate operators. See, what I don't get (note: this is how I perceive it) is the desire to have this sort of type protection, but require the compiler to somehow be psychic in order to know when and where you don't care and throw it away. You either have distinct types that aren't automatically compatible, or you don't. -- Daniel
OT: Alan Turing [Was: Re: halting problem :)]
Alan Turing wrote: Maybe I can help... At first glance, this might look like someone being silly and not at all helpful... but in truth, Mr. Turing has probably already fixed your source code with his incredible powers. If you notice your firewall has melted into a pile of slag, and your PC seems to be running a lot faster, that'd be him. Most people seem to think he's dead; this is only partially true. Whilst his physical body died, his mind lives on in the Internet, ever vigilant to ensure the safe delivery of our daily LOLCATs. Some other random Alan Turing facts: * The only reason Alan Turing hadn't solved the halting problem is that it was too busy running from him in fear. * Alan Turing could tell what a RAM chip contains simply by smelling it. * Alan Turing programmed computers in raw machine code, using a magnetised pin. * Alan Turing didn't bother programming; he just stared at a computer until it submits to his will. * Alan Turing only designed the bombe because he just stared at ciphertexts for 10 seconds and wrote down the plaintext wouldn't make for an interesting documentary 70 years later. * Steve Ballmer lives in perpetual fear of the day Alan Turing will return to unmake Microsoft. * When Alan Turing crashes a machine, all the other machines on the same subnet dump core out of fear. * Alan Turing can break RSA encryption up to 4096 bits; he doesn't bother because it's not challenging enough. * Alan Turing knows what you were browsing last summer. -- Daniel insomnia is a terrible thing... Keep
Prevent default-initialised struct
Hi all, is there any way to prevent a struct from being created directly? Basically, I want to prevent this: { non_null!(T) a; } I want people to have to use provided functions to create a structure: { auto a = non_null!(T)(new T); } -- Daniel
Re: Class and Interface Fun
[snip] B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't. I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit. No, I don't: class B : private A, public I { } Other example: interface IOStream : InputStream, OutputStream { } class A : InputStream { // implement InputStream } class B : A, IOStream { // implement OutputStream interface *only* } You can't define B like this: class B : A, OutputStream { ... } because this way it won't be castable to IOStream. I believe the rationale behind this is so that you can't implement an interface by accident. For example, you might be implementing an interface, miss one method, and not know because the base class implements it. Alternately, you might be relying on such inheritance. Then, the base class changes, and you're left with compile errors and wondering why it doesn't work. Forcing you to specify each method removes this ambiguity from the code. That said, I could have SWORN that aliasing a method from the superclass worked. If this isn't a bug, it should be. Personally, yes it is a bit tedious, but this is why we have templates and mixins... -- Daniel
Re: C++ operator new
This might also be of interest, as it has an example of overriding allocation/deallocation to use malloc: http://digitalmars.com/d/1.0/memory.html#newdelete
Re: How to get the implementer of an interface?
Qian Xu wrote: Hello All, how to get the implementer of an interface? Here is an example: - interface intf_1 {} class c_1 : intf_1 {} class c_2 : c_1 {} c_1 aaa = new c_1; c_2 bbb = new c_2; auto list = [cast(intf_1)(bbb), cast(intf_1)(aaa)]; foreach (intf_1 i; list) { print_intf_implementor(i); // bbb should return c_2 // aaa should return c_1 } - --Qian I don't think you can. i.classinfo returns intf_1's ClassInfo. Also, the only two bits of hidden information on an object are the monitor object and the vtable, so I don't know that you could use those, either. Of course, I could be wrong. -- Daniel
Re: how to use dll
reimi gibbons wrote: Hi all, 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. *im trying to link my software with ICU lib, since mango seems outdated. Thanks, Reimi. You need two things to link to a DLL: 1. You need the interface of the DLL. In C/C++, this is provided by .h files; in D, this is simply provided by a D module. 2. Loader code. You can either roll your own, or generate the above two. You can use htod (it's somewhere on the official D pages) which tries to convert a C header file into a D import module. As for the loader code, you can either write a dynamic loader, or just use implib on the DLL to generate one (I think; it's been a while since I've had to roll one.) If I can remember more specific details, I'll post again, but that's the basic gist of it. -- Daniel
Re: loop through specific class members
Trass3r wrote: Is there any way to loop through specific members of a class, e.g. all public functions? I've already seen a function getMembers in druntime's ClassInfo class but I can't find anything related to the attributes there. Assuming you're using D2, http://digitalmars.com/d/2.0/traits.html might prove to be of interest. -- Daniel
Re: time measurement under linux?
Trass3r wrote: I wrote a module to ease time measurement in my projects. Does anyone know how to get elapsed milli- or nanoseconds under linux? Want to make it portable :) [snip] Check std.perf; it's documented, but sadly doesn't show up in the docs. -- Daniel
Re: loop through specific class members
BCS wrote: Reply to Daniel, It depends on what exactly you're trying to do. Some time ago, I wrote a library that created XML loaders for structs, and it needed to know the names of fields. Pre-traits, this is what I used: struct Stuff { int foo; char[] bar; alias Tuple!(foo, bar) _fields; } Then I just looped over _fields. -- Daniel you can get the names even in D1.0. Not exactly clean but... http://codepad.org/Eu16XqFu I remember trying that, but abandoning it for some reason. This code is getting old now; over two years now, so that might not have worked back then. -- Daniel
Re: array questions
yes wrote: [snip] also, can this be done? int size; size = 10; //runtime void function( int[size][] array){} No, static arrays are static, i.e. compile time. I meant it to be an dynamic array argument, but that the function wouldn't need to check the size of all the elements itself. Dynamic arrays do not have a fixed size, thus code needs to check the number of elements when it uses them. Static arrays have a fixed size, but that size MUST be fixed at compile time. You can convert static arrays into dynamic arrays, but not the other way around (at least, not without copying the contents). When you compile with the -release flag, it disables range checking. You can also avoid it by going via pointers, but that's just asking for trouble. -- Daniel
Re: Foreach problem
Tim M wrote: Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecated Yes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel