Re: object splitting in multiple threads
Jarrett Billingsley wrote: > On Sat, Jan 10, 2009 at 12:30 AM, Jarrett Billingsley > wrote: >> On Sat, Jan 10, 2009 at 12:18 AM, yes wrote: >>> Does Phobos also do threadpools? >> From what I understand, not without modification. At least, not >> efficiently. Downs has implemented such a thing in scrapple.tools, >> but it requires a patch to Phobos to make it run at a reasonable >> speed. > > Ffff.. ignore this, I was thinking about fiber pools. I don't > think there's any technical reason why a ThreadPool couldn't be > written for Phobos, but there isn't one provided by default. Scrapple.Tools has a Threadpool too :)
Re: Access Vialotation
BCS wrote: > Reply to Jarrett, > >> On Fri, Feb 27, 2009 at 9:01 AM, Qian Xu >> wrote: >> >>> Hi All, >>> >>> Is there any way to keep program alive, when an AV takes place? >>> >> It's possible on Windows in D, but that's because Windows reports >> segfaults with the same mechanism that D uses for exceptions. Since >> Linux (and many other Posix systems) uses signals, it's probably very >> tricky to implement in a cross-platform manner. >> > > you can have a posix signal handler throw an exception (I have done it > and had it work) but I have no idea if it is supported. > > In my experience, that works exactly once.
Re: Reading and writing Unicode files
jicman wrote: > Greetings. > > Sorry guys, please be patient with me. I am having a hard time understanding > this Unicode, ANSI, UTF* ideas. I know how to get an UTF8 File and turn it > into ANSI. and I know how to take a ANSI file and turn it into an UTF file. > But, now I have a Unicode file and I need to change the content and create a > new Unicode file with the changes in the content. I have read all kind of > places, and I found mtext, from Chris Miller's site, by reading, > > http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD > > Anyway, what I need is to read an Unicode file, search the strings inside, > make changes to the file and write the changes back to an Unicode file. > > Any help would be greatly appreciate. > > thanks, > > josé Wow, you're in luck! D is all unicode. Just do import std.file; auto text = cast(string) filename.read(); do your changes; filename.write(cast(void[]) text); and you're done.
Re: Reading and writing Unicode files
downs wrote: > jicman wrote: >> Greetings. >> >> Sorry guys, please be patient with me. I am having a hard time >> understanding this Unicode, ANSI, UTF* ideas. I know how to get an UTF8 >> File and turn it into ANSI. and I know how to take a ANSI file and turn it >> into an UTF file. But, now I have a Unicode file and I need to change the >> content and create a new Unicode file with the changes in the content. I >> have read all kind of places, and I found mtext, from Chris Miller's site, >> by reading, >> >> http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD >> >> Anyway, what I need is to read an Unicode file, search the strings inside, >> make changes to the file and write the changes back to an Unicode file. >> >> Any help would be greatly appreciate. >> >> thanks, >> >> josé > > Wow, you're in luck! > > D is all unicode. > > Just do import std.file; auto text = cast(string) filename.read(); do your > changes; filename.write(cast(void[]) text); > > and you're done. PS: You may need to do detection for UTF-16. In that case, just cast to a wstring instead, then (optionally) use std.utf.toUTF8.
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? > Take a look at tools.behave_as (for phobos). It only works properly with built-in types though. http://dsource.org/projects/scrapple/browser/trunk/tools/tools/behave_as.d It should let you implement a HashMap that supports += and similar, at least for built-ins.
Re: -profile and threaded code
BCS wrote: > Hello BCS, > >> I have a program that runs an "easily" parallelizable loop. When I run >> it as a single thread it only takes about 10% longer than 2 threads >> (on a dual-core). I'm trying to track down the lossed time and am >> wondering if turning on -profile is even worth looking at. The concern >> is that it might not be thread safe or might just skew the result so >> much as to be useless. >> > > Well it seems that runing threded code with -profile gives a seg-v. So I > guess that answers that. > > Try GDC. :)
Re: Sockets and D?
Jimi_Hendrix wrote: > Hi, I am new to D but not to programming. I have had some socket experience > before. How would i connect to a server using sockets in D? A link to a D > socket tutorial (if one exists) would also be appreciated. > > by the way, first post to a newsgroup for me As certain Tango users have neglected to tell you, Phobos also has a perfectly servicable socket interface in std.socket. If you know Sockets in C, you should have no problem with it. http://digitalmars.com/d/1.0/phobos/std_socket.html
Re: wchar[] and wchar*
Jarrett Billingsley wrote: > On Tue, Apr 7, 2009 at 3:09 PM, novice2 wrote: >> thank you Sergey >> >> but sometime wchar* is zero-terminated strings (LPWSTR) >> i feel lack of toStringz(wchar[]) and toString(wchar*) functions in phobos > > Yeah, that does suck, doesn't it? > > I wouldn't want to mention the 'T' word for fear of Downs accusing me > of proselytizing. :snort: I do agree in this case. I just don't like it when Tango is proposed as an alternative and the existence of a perfectly valid Phobos solution is ignored.
Open GL extensions, dglut style
AxelS wrote: > Hello evrybody... > > I want to use all the opengl extensions like Shaders in my D2.0 prog... > I already got the opengl32.lib and also the headers... > > I tried it wglGetProc (similar name...)! I could compile it but it hangs up > runtime and creates errors which dont tell me the actual problem... > and yes, I'm sure that these functions which I want to get are existing! > I know the usage of predefined function variables is recommended... > I tried but failed... > > Thanks in advance! This is how we do it in dglut: version(Win32) { extern(System) void* wglGetProcAddress(char* procName); alias wglGetProcAddress getExtProc; } else { extern(C) void* glXGetProcAddressARB(char* procName); alias glXGetProcAddressARB getExtProc; } template SysFunc(C) { extern(System) alias ReturnType!(C) function(ParameterTypeTuple!(C)) SysFunc; } struct ExtFunc(C, string name) { static { SysFunc!(C) load() { static if (is(typeof(&getExtProc))) { return cast(SysFunc!(C)) getExtProc(toStringz("gl"~name)); } else static assert(false, "Platform not supported (yet)"); } SysFunc!(C) fn; ReturnType!(C) opCall(ParameterTypeTuple!(C) params) { if (!fn) fn=cast(typeof(fn)) load(); if (!fn) throw new Exception("Extension function \""~name~"\" not found in lookup table!"); return fn(params); } } } Then later on, they're used like this: alias ExtFunc!(void function(GLenum, GLenum, GLenum, int *), "GetFramebufferAttachmentParameterivEXT") getpar; foreach (where, obj; attachedObjects) { int res, res2; getpar(GL_FRAMEBUFFER_EXT, where, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, &res); getpar(GL_FRAMEBUFFER_EXT, where, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &res2);
Re: SQLite with D
reimi gibbons wrote: > im failry new to D, is there any D library project with support for SQLite, > if not is there any guide so i can integrate sqlite amalgamated c source > (sqlite3.c, sqlite3.h) into my D code. tools.sqlite3 might work for you. Ask me if you have any questions about it. http://dsource.org/projects/scrapple/browser/trunk/tools/tools/sqlite3.d (Check the very end for an example)
Re: SQLite with D
reimi gibbons wrote: > downs Wrote: > >> reimi gibbons wrote: >>> im failry new to D, is there any D library project with support for SQLite, >>> if not is there any guide so i can integrate sqlite amalgamated c source >>> (sqlite3.c, sqlite3.h) into my D code. >> tools.sqlite3 might work for you. Ask me if you have any questions about it. >> >> http://dsource.org/projects/scrapple/browser/trunk/tools/tools/sqlite3.d >> >> (Check the very end for an example) > > sorry about earlier reply, mistaken your lib to another lib. btw, how do i > use this file. with precompiled library (dll/so) or .h/.c ? > thanks > Oh, I don't know about that. Sqlite3 is a static library on my Linux. Try to compile the sqlite3.c to .o and just link that in.
Re: convert *void to void[]
gabrielsylar wrote: > can anybody please tell me how to properly convert from void* to void[] > as the code below? > > void[] get_bytes(int n) { return sqlite3_column_blob(stmt, n); } In unrelated matters: if you're writing a sqlite3 binding, take a look at tools.sqlite3. :) http://dsource.org/projects/scrapple/browser/trunk/tools/tools/sqlite3.d
Re: legal identifier check
Saaa wrote: > Is there a function to check whether some string is a legal identifier? > > Sure. static if(is(typeof({ /* code to be checked for validity goes here */ }))) ...
Re: Should be easy
Saaa wrote: > I can't figure out how to create the IndexArray function, > it should work on arrays of any depth > > int[][][] array; //any depth > array.length=10; > array[1].length=3; > array[1][2].length=4; > array[1][2][1]=99; > > writefln(array); > //[[],[[],[],[0,99,0,0]],[],[],[],[],[],[],[],[]] > > int[3] index; //same length as depth > index[0]=1; > index[1]=2; > index[2]=3; > > IndexArray( array, index) = -1; > //equal to : > //array[ index[0] ][ index[1] ][ index[2] ] = -1; > > writefln(array); > //[[],[[],[],[0,99,0,-1]],[],[],[],[],[],[],[],[]] > > All suggestions are greatly appreciated ! > > > Here's one. module test144; import std.stdio, std.metastrings; struct PointerAssign(T) { T* ptr; T opAssign(T t) { *ptr = t; return t; } static PointerAssign opCall(T* p) { PointerAssign res; res.ptr = p; return res; } } template isArray(T: T[]) { const bool isArray = true; } template isArray(T) { const bool isArray = false; } template Init(T) { const T Init; } template ElemType(T) { alias typeof(Init!(T)[0]) ElemType; } template BaseType(T) { static if (isArray!(T)) alias BaseType!(ElemType!(T)) BaseType; else alias T BaseType; } template Depth(T) { static if (isArray!(T)) const int Depth = 1 + Depth!(ElemType!(T)); else const int Depth = 0; } string ctToString(int i) { if (!i) return "0"; string res; while (i) { res = "0123456789"[i%10] ~ res; i /= 10; } return res; } string index(int len) { string res; for (int i = 0; i < len; ++i) res ~= "[indices["~ctToString(i)~"]] "; return res; } PointerAssign!(BaseType!(T)) IndexArray(T)(T array, int[] indices...) { return PointerAssign!(BaseType!(T)) (mixin("&array"~index(Depth!(T; } void main() { int[][][] array; array.length = 10; array[1].length = 3; array[1][2].length = 4; array[1][2][1] = 99; writefln(array); IndexArray(array, 1, 2, 3) = -1; writefln(array); }
Re: Should be easy
Saaa wrote: > Thanks! > I thought about the idea of just creating the code and mix it in, but now I > can see why I failed at that: Your code is kind of read-only to me, for now, > because I need to change it a bit to accept an array instead of seperat > indices. > > Wouldn't it be nice if it worked like this: > int[] index = (1,2,3); > array(index) = -1; > >> Here's one. >> >> module test144; >> >> import std.stdio, std.metastrings; >> >> struct PointerAssign(T) { >> T* ptr; >> T opAssign(T t) { *ptr = t; return t; } >> static PointerAssign opCall(T* p) { PointerAssign res; res.ptr = p; >> return res; } >> } >> >> template isArray(T: T[]) { const bool isArray = true; } >> template isArray(T) { const bool isArray = false; } >> >> template Init(T) { const T Init; } >> template ElemType(T) { alias typeof(Init!(T)[0]) ElemType; } >> >> template BaseType(T) { >> static if (isArray!(T)) alias BaseType!(ElemType!(T)) BaseType; >> else alias T BaseType; >> } >> >> template Depth(T) { >> static if (isArray!(T)) const int Depth = 1 + Depth!(ElemType!(T)); >> else const int Depth = 0; >> } >> >> string ctToString(int i) { >> if (!i) return "0"; >> string res; >> while (i) { >>res = "0123456789"[i%10] ~ res; >>i /= 10; >> } >> return res; >> } >> >> string index(int len) { >> string res; >> for (int i = 0; i < len; ++i) >>res ~= "[indices["~ctToString(i)~"]] "; >> return res; >> } >> >> PointerAssign!(BaseType!(T)) IndexArray(T)(T array, int[] indices...) { >> return PointerAssign!(BaseType!(T)) (mixin("&array"~index(Depth!(T; >> } >> >> void main() { >> int[][][] array; >> array.length = 10; >> array[1].length = 3; >> array[1][2].length = 4; >> array[1][2][1] = 99; >> writefln(array); >> IndexArray(array, 1, 2, 3) = -1; >> writefln(array); >> } > > IndexArray should take an array of integers as well. The int[] foo... syntax is implicit "convert to array" anyway. Also, please bottom-post. It's the convention. :)
Re: A public apology.
Jarrett Billingsley wrote: > On Mon, Jun 15, 2009 at 10:15 PM, Derek Parnell wrote: >> On Mon, 15 Jun 2009 21:47:53 -0400, Jarrett Billingsley wrote: >> I've actually given up trying to influence D ... the patricians have made >> it too hard to contribute and I've haven't got *that* much free time. > > So have I. But we can at least still shout. Shout! Shout! Let it all out!
Re: bitfields
novice2 wrote: > does anyone know: is D2 std.bitmanip compatible with C bitfields? > can i use it, if i need translate .h file with something like this: > > typedef struct { > unsigned int can_compress : 1; > unsigned int can_uncompress : 1; > unsigned int can_get_info : 1; > unsigned int : 7; > unsigned int : 16; > unsigned int : 16; > unsigned int : 16; > unsigned int : 16; > unsigned int : 16; > } capabilities; > > Thanks. Here's a way to do it. Enjoy! :) Usage example: struct Test { ushort bits; mixin GroupPackedAccess!(bits, ubyte, "stuff", 3, bool, "otherstuff" ); } module packed; template PackedAccessTools(string NAME, int from, int to) { const max = 1 << (to-from); static if (to >= 32) static assert(false, "Too large"); else static if (to >= 16) alias uint type; else static if (to >= 8) alias ushort type; else alias ubyte type; // 0 .. 4 -> ((1 << 4):16 - 1):15 & ~0 -> 7 == // 4 .. 8 -> ((1 << 8):256 - 1):255 & ~((1 << 4): 16 - 1):15 -> const type mask = ((1 << to) - 1) - ((1 << from) - 1); const ID = NAME~"_"~from.stringof~"_"~to.stringof; } template PackedAccess(alias VAR, T, string NAME, int from, int to) { mixin(ctReplace(` T NAME() { static if (is(T == bool)) return (VAR & (°.mask)) != 0; else return cast(T) ((VAR & (°.mask)) >> from); } T NAME(T nv) { Assert(nv < °.max, "Value too big"); VAR &= (~°.mask); VAR |= (nv << from); return nv; } `, "NAME", NAME, "°", "PackedAccessTools!(NAME, from, to)", "·", PackedAccessTools!(NAME, from, to).ID )); } template NaturalTypeSize(T) { static if (is(T==bool)) const NaturalTypeSize = 1; else static assert(false, "No known default size for "~T.stringof~"!"); } template GroupPackedAccess(alias VAR, T...) { static if (T.length > 2) { static if (is(typeof(T[0])==void)) { static if (is(typeof(T[4]): int) && !is(T[4]: int)) { mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+T[4]); mixin GroupPackedAccess!(VAR, void, T[1]+T[4], T[5 ..$]); } else { mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+NaturalTypeSize!(T[2])); mixin GroupPackedAccess!(VAR, void, T[1]+NaturalTypeSize!(T[2]), T[4 ..$]); } } else { mixin GroupPackedAccess!(VAR, void, 0, T); } } }
Re: bitfields
novice2 wrote: > downs Wrote: >> Here's a way to do it. >> >> Enjoy! :) >> >> Usage example: >> >> struct Test { >> ... skipped... > > Thank you, downs, for your job! > > but, heh, i can't use something, that i can't understand :( > i hate template and mixin (imho it lead to full unreadable code). > so with my dumbness, i need deveral weeks to understand this :) PackedAccessTools contains a few useful definitions given a bitfield variable name and a from..to bits-used range. PackedAccess uses ctReplace (compile-time search&replace, from scrapple.tools.base), to generate accessors that cut out (or set) a bit of a variable. This is the meat of PackedAccess. NaturalTypeSize is just the "default" size for a type. And GroupPackedAccess is just a wrapper template for PackedAccess. All it does is split its parameter tuple into groups that are used to instantiate PackedAccess. Feel free to ask if you have more specific questions.
Re: Specify the type but not number of function arguments in an interface?
Doctor J wrote: > I want to write an interface that expresses the following idea: "classes > implementing this interface must have a void function named update, with a > fixed but indeterminate number of parameters of the same (template parameter) > type." Use a typesafe variadic function, i.e. void test(int[] integers...);
Re: How to release memory? (D2.0.30)
BCS wrote: > Hello AxelS, > >> BCS Wrote: >> >>> You can't. The D runtime (and most other runtimes) don't ever reduce >>> the amount of memory they keep in the heap. If you where to allocate >>> another 25MB right after that function you would see no change in the >>> memory usage. 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. >>> >> I want to load and send a file via network...when I load the entire >> file into memory it's very stupid that I can't release that memory >> again... >> >> OK I'll try it with the C API but thanks for your help! >> > > C's runtime (malloc/free) doesn't return memory to the OS either. Um .. yes it does. :) #include #include int main() { void *p = calloc(1024*1024*256, 1); system("sleep 10"); free(p); system("sleep 10"); return 0; } Run that, wait 10s, and watch the memory usage go down.
Re: Specify the type but not number of function arguments in an interface?
Jarrett Billingsley wrote: > On Sun, Jul 5, 2009 at 5:44 AM, downs wrote: >> Doctor J wrote: >>> I want to write an interface that expresses the following idea: "classes >>> implementing this interface must have a void function named update, with a >>> fixed but indeterminate number of parameters of the same (template >>> parameter) type." >> Use a typesafe variadic function, i.e. >> >> void test(int[] integers...); >> > > Read the rest of his post, downs. Particularly option 2. Oops.
Re: Specify the type but not number of function arguments in an interface?
downs wrote: > Jarrett Billingsley wrote: >> On Sun, Jul 5, 2009 at 5:44 AM, downs wrote: >>> Doctor J wrote: >>>> I want to write an interface that expresses the following idea: "classes >>>> implementing this interface must have a void function named update, with a >>>> fixed but indeterminate number of parameters of the same (template >>>> parameter) type." >>> Use a typesafe variadic function, i.e. >>> >>> void test(int[] integers...); >>> >> Read the rest of his post, downs. Particularly option 2. > > Oops. But then isn't what he asks for kinda impossible by design? I mean, interfaces are bound at runtime. That's what they _do_.
Re: Specify the type but not number of function arguments in an interface?
Jarrett Billingsley wrote: > On Tue, Jul 7, 2009 at 8:29 AM, downs wrote: >> But then isn't what he asks for kinda impossible by design? I mean, >> interfaces are bound at runtime. That's what they _do_. >> > > Now read *my* post, downs. ;) :blushes:
Re: Precision, new prices
Saaa wrote: > I thought my previous precision question was so retarded it didn't need any > explanation; anybody here could easily tell me my fault in reasoning. > > Here is my question again but this time with examples. > > Is there some formatting which lets me print out a floating point in full > precision? > > Observation: 6 digits is not full precision: > > float f=3.4028234; // 0x7f7f > writefln("%.8g",f); // prints 3.4028234 > writefln(f.dig); // prints 6 > writefln(3.4028234f.dig); // prints 6 > > Shouldn't f.dig print out 8? > .dig = number of decimal digits of precision > > I still think I don't get something, somewhere. > > Here's an incredibly simple hack. import std.stdio, std.string; string ftoaFull(float f) { if (f < 0) return "-" ~ ftoaFull(-f); auto start = f; auto res = toString(cast(int) f) ~ "."; while (true) { f -= cast(int) f; f *= 10; res ~= "0123456789"[cast(int) f]; // The critical step if (res.atof() == start) return res; if (res.length > 32) { writefln("Cannot find string representation for ", start, ", parses as ", res.atof(), ", delta ", res.atof() - start); return res; } } } void main() { writefln(ftoaFull(0f)); writefln(ftoaFull(-5.234)); writefln(ftoaFull(1f / 3f)); // problematic } Output: 0.0 -5.2340002059936523437 Cannot find string representation for 0.33, parses as 0.33, delta 5.96046e-09 0.3334922790527343750 And there you have it.
Re: Precision, new prices
Saaa wrote: > I thought my previous precision question was so retarded it didn't need any > explanation; anybody here could easily tell me my fault in reasoning. > > Here is my question again but this time with examples. > > Is there some formatting which lets me print out a floating point in full > precision? > Here's an incredibly simple hack. import std.stdio, std.string; string ftoaFull(float f) { if (f < 0) return "-" ~ ftoaFull(-f); auto start = f; auto res = toString(cast(int) f) ~ "."; while (true) { f -= cast(int) f; f *= 10; res ~= "0123456789"[cast(int) f]; // The critical step if (cast(float) res.atof() == start) return res; } } void main() { writefln(ftoaFull(0f)); writefln(ftoaFull(-5.234)); writefln(ftoaFull(1f / 3f)); // problematic } Output: 0.0 -5.234 0.3334 And there you have it.
Re: CRTP in D?
bearophile wrote: > I don't know much C++. Can CRTP be used in D1 too, to improve the performance > of some D1 code? > > http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern > > Bye, > bearophile We have this, except we call it "template mixin" :)
Re: D1: std.md5: corrections for the given example
notna wrote: > Stewart Gordon schrieb: >> The .ptr is necessary, but the cast(uint) isn't. Even if a change of >> type were necessary, just 1U would do. (U is a suffix meaning >> unsigned. There's also L meaning long.) >> >> Stewart. > > Thank Stewart. > > As the std.md5-example is not working with "unicode" file names > (fopen...) I rewrote the "MDFile" function and use "file.readBlock" > instead now. Maybe the std.md5 example should be changed to use a > "file.read" or "file.readBlock". > > Here is my code (I've checkedthe file exists and is readable before): > > string MD5File(string fileName) { > > File file = new File; scope file = new File(fileName, FileMode.In); > MD5_CTX context; > int len; // int len; > ubyte[4 * 1024] buffer; > ubyte digest[16]; > > file.open(fileName, FileMode.In); // file.open(fileName, FileMode.In); > context.start(); > while ((len = file.readBlock(buffer.ptr, buffer.sizeof)) != 0) while (auto len = file.readBlock(buffer.ptr, buffer.sizeof)) > context.update(buffer[0 .. len]); > context.finish(digest); > file.close(); > // What's up with this? > string MD5Sum = (digestToString(digest)); > return MD5Sum; // return digestToString(digest); > > } > > Regards > notna
Re: D1: std.md5: corrections for the given example
Stewart Gordon wrote: > downs wrote: > >> while (auto len = file.readBlock(buffer.ptr, buffer.sizeof)) > > > md5_example_2.d(7): expression expected, not 'auto' > md5_example_2.d(7): found 'len' when expecting ')' > md5_example_2.d(7): found '=' instead of statement > > (this is line 7 after I removed comments and blank lines from your edit) > > Stewart. God I'm stupid. Sorry. I guess I wish that worked.
Re: Getting started - D meta-program question
Justin Johansson wrote: > Daniel Keep Wrote: > >> 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.D&article_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 > > Thanks for your answer, Daniel. I thought the original post was a bit of a > red herring but > thought I'd ask about it anyway. Good thing I did as you motivated me to > delve into the > subject just after reading your reply. > > Just now I've written a bit of CS101 play around code (shown below) for > constructing a > singly-linked list of numbers (Conslist idiom). As the code seems to work, > it looks like > I've cut my first teeth on "D meta programming". > > I'm sure there's lots to learn though .. especially looking though some of > that std.functional > stuff. > > If you have any comments / suggestions for improvement about this code, I'd > graciously accept the same. > It's just a tutorial exercise for learning the D way of doing things. > > > class List > { >List next; >int data; > >this( int data) { > this.next = null; > this.data = data; >} > >static List opCall() { > return cast(List) null; >} > >static List opCall( int data) { > return new List( data); >} > >static List cons( int data, List list) { > auto newList = List( data); > newList.next = list; > return newList; >} > >int opApply( int delegate( ref int data) dg) { > auto result = 0; > auto list = this; > > while ( list !is null) { > if ((result = dg( list.data)) != 0) > break; > > list = list.next; > } > > return result; >} > > } > > > void printdata( int data) { >writef( " %d", data); > } > > > void print( List list) { >writef( "("); > >if (list !is null) { > foreach ( x; list) { > printdata( x); > } >} > >writef( ")"); > } > > > void println( List list) { >print( list); >writefln(); > } > > > List list(A...)( A args) { >static if (A.length == 0) { > return List(); >} > >else { > return List.cons( args[0], list( args[1..$])); >} > } > > > void main() { >auto l0 = list(); >println( l0); > >auto l1 = list( 10); >println( l1); > >auto l2 = list( 10, 20); >println( l2); > >auto l3 = list( 10, 20, 30); >println( l3); > > } > > > Outputs: > > () > ( 10) > ( 10 20) > ( 10 20 30) > > Thanks again, Justin > I really recommend using a struct. There's rarely need to subclass List nodes dynamically, and structs would allow you to define allocators externally, for instance, for implementing freelists. Also, I generally think of a list node as a value, not an object :) In that sense .. module test; import std.string; struct List(T) { List* next; T data; static List* opCall(T data, List* next) { auto res = new List; res.next = next; res.data = data; return res; } static List* opCall(T[] data...) { if (!data.length) return null; else if (data.length == 1) return opCall(data[0], null); else return opCall(data[0], opCall(data[1..$])); } List* cons(T data) { return List(data, this); } int opApply( int delegate( ref int data) dg) { auto current = this; do { if (auto res = dg(current.data)) return res; current = current.next; } while (current); return 0; } string toString() { string res = "("; bool first = true; foreach (value; *this) { if (first) first = false; else res ~= ", "; res ~= format(value); } return res ~ ")"; } } void print(T)(T what) { if (!what) writefln("(nil)"); else writefln(what.toString()); } import std.stdio; void main() { auto l0 = List!(int)(); print(l0); auto l1 = List!(int)(10); print(l1); auto l2 = List!(int)(10, 20); print(l2); auto l3 = List!(int)(10
Re: Member functions C to D
Craig Kuhnert wrote: > Hi > I am trying to convert some code I wrote in C++ to D to give it a try and I > have come across some code that I dont know how to convert. > I have simplified the code to illustrate the problem I have. > How do I do this in D? > > class IFieldSetter > { > public: > virtual void SetValue(void * object, const void * value) = 0; > }; > > template > class FieldSetter : public IFieldSetter > { > private: > typedef T (C::* MemberField); >MemberField field; > > public: > FieldSetter(MemberField afield) > : field(afield) > {} > > void SetTypedValue(C * object, const T& value) > { > object->*field = value; > } > > void SetValue(void * object, const void * value) > { > SetTypedValue((C*) object, (const T&) value); > } > }; > > class MySampleClass > { > public: > int Status; > std::string Name; > }; > > void main(void) > { > IFieldSetter * StatusSetter = new > FieldSetter(&MySampleClass::Status); > IFieldSetter * NameSetter = new > FieldSetter(&MySampleClass::Name); > > MySampleClass * a = new MySampleClass(); > MySampleClass * b = new MySampleClass(); > > StatusSetter->SetValue(a, (void*)20); > StatusSetter->SetValue(b, (void*)40); > > NameSetter->SetValue(a, "2002"); > NameSetter->SetValue(b, "2002"); > } > > Thanks > Craig If I'm getting this correctly, here's one way to do it .. module test; import std.stdio, tools.ctfe: ctReplace; // easy to write your own ctReplace function template Init(T) { T Init; } interface IFieldSetter { void setValue(Object obj, void* value); } class FieldSetter(T: Object, string Name) : IFieldSetter { override void setValue(Object obj, void* value) { auto tee = cast(T) obj; mixin("tee.%NAME = *cast(typeof(tee.%NAME)*) value; ".ctReplace("%NAME", Name)); } void setValue(T obj, typeof(mixin("Init!(T)."~Name)) value) { mixin("obj.%NAME = value; ".ctReplace("%NAME", Name)); } } class Sample { int status; string name; } void main() { auto statSetter = new FieldSetter!(Sample, "status"); auto nameSetter = new FieldSetter!(Sample, "name"); auto sample = new Sample; int i = 20; statSetter.setValue(sample, &i); statSetter.setValue(sample, 40); nameSetter.setValue(sample, "Fooblr"); }
Re: Getting started - D meta-program question
Justin Johansson wrote: > Your code as below, using auto to declare a temporary var in an if statement, > ahh, nice, > didn't know that. > > if (auto res = dg(current.data)) > return res; > > What other statement types can you generalized use of auto like this to? > Sadly, it's an if-specific syntax. > Thank you for taking the time downs, > > -- Justin Anytime.
Re: Associative array trouble
Bill Baxter wrote: > You query presence of a key in an AA using 'in' > > if (id in symtab) { > Symbol sym = symtab[id]; > ... > } else { > .. > } > > Or this avoids a double lookup if the symbol is present: > > Symbol* pSym = id in symtab; > if (pSym !is null) { > Symbol sym = *pSym; > ... > } else { > ... > } > > --bb > Slightly shorter form: if (auto pSym = id in symtab) { ... }
Re: Different class template args to generate same template instance?
Nick Sabalausky wrote: > "BCS" wrote in message > news:a6268ffc3898cc29d1f554d...@news.digitalmars.com... >> Hello Nick, >> >> >>> So...is there any trickery I >>> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would >>> resolve to the same subclass of Foo? >> Make a SubFoo!(char[] s) that does your logic and if it passesa alises to >> SubFoo!(s,"") >> >> > > I'm not sure I understand...? > > I think what he's trying to say is template SubFoo!(char[] name, char[] type) { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!("sam", "human") SubFoo; /* etc */ }
Re: something "weird" about polymorphism
funog wrote: > The following code : > > -- > import std.stdio; > class A { > void foo(A a) { > writefln("A"); > } > } > > class B : A { > void foo(B b) { > writefln("B"); > } > } > > void main() { > B b = new B; > A a = b; > assert(a is b); > b.foo(b); > a.foo(b); > } > -- > outputs: > B > A > > > This is understandable as B.foo doesn't actually overrides A.foo. But > somehow it's weird to get different outputs while "a" and "b" are > basically the same object. Has anyone else encountered this problem in > real life? Will C+++, java act the same way? > The behavior here is entirely correct and, in fact, could not happen any other way. The only improvement would be disallowing declaring methods that shadow but don't override methods in the super class. The inheritance contract that B enters when it inherits from A states that its foo will take any object of type A. Remember: parameters generalize, results specialize. B's foo _cannot_ override A's foo because that would mean you could not use a B in all situations you could use an A, which breaks polymorphism completely.
Re: Are named variadic arguments possible?
Alex wrote: > Is it possible, using templates, tuples, or some other mechanism, to > implement named variadic arguments in D? > > For example, I'd like to be able to do something like... > foo( 2, &bar, age : 10, status : "down"); > > and so forth. Yes, with a small hack. typedef int age_type; age_type age(int i) { return cast(age_type) i; } void foo(T...)(int i, Bar*, T t) { // Test T for age_type here. }
Re: Unexpected behaviour on socket
On 10.02.2010 14:41, daoryn wrote: >> >> The buffer you are passing to receive is 0 bytes long. The >> std.socket.Socket.receive function is a wrapper over the normal socket >> function, and includes a test for an empty buffer. >> >> Daniel > > Ohh, I see. Thank you! > > I thought that the function would resize the buffer accordingly. Thank you > for the clarification, i feel like an idiot *giggle* http://d.puremagic.com/issues/show_bug.cgi?id=3794 Filed a bug.
Re: use variant as associative array
On 10.02.2010 22:28, GG wrote: > I try to use variant as associative array with dmd2.039, > > Variant[char[]][int] aa; > aa[0]["Month"] = "Jan"; > aa[0]["Profit"] = 500; > aa[1]["Month"] = "Feb"; > aa[1]["Profit"] = 800; > > I got core.exception.rangeer...@main(28): Range violation > I'm doing something wrong ? Or it's same problem as : > http://digitalmars.com/d/archives/digitalmars/D/Variant_string_associative_array_..._fail_87248.html > Same problem with dmd2.040 > > Thanks ! > GG I don't have a D2 compiler, but try this. Variant[char[]] v; aa[0] = v; aa[0]["Month"] = "Jan"; If that also fails, file a bug.