Re: GTKD resources
On 2017-08-11 13:00, Mr. Pib wrote: How can one include external files such as glade, icons, images that are static in nature in to the binary but not require extraction on program run to be used? gtk's builder doesn't seem to take an in memory representation of glade files and building a pixbuf seems quite over the top to do such simple things? including the glade UI/XML defs to the executable is simple, compile with -J. switch and: immutable string UIdefs = import("myuidefs.glade"); ... main(){ ... builder.addFromString( UIdefs ); ...
Re: core.stdc.stdlib.malloc & alignment
On 2016-06-29 14:39, Hiemlick Hiemlicker wrote: Yes, the C standard requires malloc to be aligned to the platform size(4 for 32bit, 8 for 64-bit). just what i was hopping for. thanks!
core.stdc.stdlib.malloc & alignment
is there an alignment guarantee for core.stdc.stdlib.malloc? more specifically, using DMD and compiling for 32bit on windows, can i assume proper alignment for int or uint variables? background: i like to re-use a (ubyte) buffer, sometimes it will store only bytes, sometimes it shall store uints. thanks
Re: Using .lib and .dll in D applications
On 2016-06-20 06:33, moe wrote: I see where I went wrong. I thought that it's possible to only use the .lib file without the source code of dbar. Having access to the source makes what I am trying somewhat pointless. Is it otherwise possible to provide some functionality without having to give away your source? I would like to put together a library that I can reuse, without having to rely on the source each time. Maybe a dll instead? for this purpose there are .di interface files that can be generated automatically: https://dlang.org/dmd-windows.html#interface-files
Re: GTKD - overrideBackgroundColor of Button doesn't work
string cssPath = "test.css"; CssProvider provider = new CssProvider(); provider.loadFromPath(cssPath); unfortunately i don't know anything about yr specific problem. but i just wanted to mention (in case you are not aware of it) that the CSS can be embedded into the D source. this is what i did to fix GTKs terrible design mistake for the background of Notebook: ``` enum myCSS = q{ GtkNotebook { background-color: #e9e9e9; } GtkNotebook tab { background-color: #d6d6d6; } }; ... int main(string[] args){ ... import gtk.CssProvider; auto styleProvider = new CssProvider; styleProvider.loadFromData(myCSS); import gdk.Screen; import gtk.StyleContext; StyleContext.addProviderForScreen( Screen.getDefault(), styleProvider, 800); ```
Re: How to share an appender!string?
On 2016-05-20 07:49, Era Scarecrow wrote: Experimented and quickly got what looks like good clean results. Took your code, ripped out what I didn't want and added in what I did. Simple! https://dpaste.dzfl.pl/6952fdf463b66 i am most curious about your solution. why does printAll() has a synchronized block? in case you would call it before thread_joinAll() i.e. before all threads are terminated? then again, why is there a synchronized block necessary in printAll() at all? it is only reading out data, not writing. (i am still learning the subtleties of multithreading.) /det
Re: Anonymous structure
On 2016-04-18 14:12, Tofu Ninja wrote: Also is there a way to have a named substructure, not a nested structure but something to just add an additional name, maybe something like struct a{ struct{ int x; int y; int z; } b; } not sure what you mean by "named substructure, not a nested structure" but this works: struct Outer{ struct Inner{ int x; int y; int z; } Inner inner; int a; } Outer outer; outer.a = 7; outer.inner.y = 42; // outer.x = 13; //fails writeln(outer);
Re: static void arrays under garbage control?
On 2015-02-26 10:07, Steven Schveighoffer wrote: Static data I believe is always scanned conservatively because no type information is stored for it ever, even on allocation (i.e. program startup). ouh, the confusion goes on... are you saying that { // will be all scanned by GC for // potential pointers into GC managed memory: void[16] buffer0 = void; ubyte[16] buffer1; uint[4] buffer3; // will not be scanned by GC for pointers: void[] buffer4 = cast(void[])(new ubyte[16]); uint[] buffer5 = cast(uint[])(new ubyte[16]); }
Re: static void arrays under garbage control?
On 2015-02-26 12:07, Steven Schveighoffer wrote: On 2/26/15 11:57 AM, captaindet wrote: On 2015-02-26 10:07, Steven Schveighoffer wrote: Static data I believe is always scanned conservatively because no type information is stored for it ever, even on allocation (i.e. program startup). ouh, the confusion goes on... are you saying that { // will be all scanned by GC for // potential pointers into GC managed memory: void[16] buffer0 = void; ubyte[16] buffer1; uint[4] buffer3; Yes, all 3 are stack based. This is not static data, which would be like uint[4] at module level. Those are also treated as scannable, as the entire stack of every thread is scanned. // will not be scanned by GC for pointers: void[] buffer4 = cast(void[])(new ubyte[16]); uint[] buffer5 = cast(uint[])(new ubyte[16]); Correct, since they are allocated as ubyte[]. uint[] also would not be scanned. -Steve got it, finally! thanks to everyone for their help. /det
Re: static void arrays under garbage control?
On 2015-02-25 20:45, H. S. Teoh via Digitalmars-d-learn wrote: On Wed, Feb 25, 2015 at 08:20:37PM -0600, captaindet via Digitalmars-d-learn wrote: [...] struct Stuff2Do{ static ubyte[1024*1024] buffer4speed = void; // even if untyped at this point // more } [...] Tangential note: be careful with putting a large static array inside a struct. Structs are passed by value, which means that if you didn't allocate that struct on the heap and you pass it around to various functions, you will overflow your stack very quickly -- every function call that passes the struct will consume 1MB of stack space. Many OSes do not allocate that much space for the runtime stack. T this is why i tried to get away with a 'static' static array, which only exists once for all Stuff2Do structs. but as it seems, i'll rather need on the order of 512MB buffer, so i will probably go with c.stdlib.malloc /det
Re: static void arrays under garbage control?
On 2015-02-25 19:24, Adam D. Ruppe wrote: does this warning only apply to dynamic void[] arrays but not to static void[CTconstant] arrays? Both of those will be scanned for pointers. thanks, adam, so i should always use struct Stuff2Do{ static ubyte[1024*1024] buffer4speed = void; // even if untyped at this point // more } to avoid that the GC is scanning my buffer for pointers?
static void arrays under garbage control?
if i understand correctly, static arrays are exempt from GC scanning for memory pointers http://dlang.org/garbage.html : Pointers in D can be broadly divided into two categories: Those that point to garbage collected memory, and those that do not. Examples of the latter are pointers created by calls to C's malloc(), pointers received from C library routines, pointers to static data. but there is also a warning for void arrays http://dlang.org/arrays.html : The garbage collector will scan void[] arrays for pointers, since such an array may have been implicitly converted from an array of pointers or an array of elements that contain pointers. does this warning only apply to dynamic void[] arrays but not to static void[CTconstant] arrays? (because sometimes the docs also mean static arrays even if just type[] is written.) thanks! ps: this is for 32bit apps
one of the weirdest bugs ever - request for testing
hi, i just run into a (wrong code gen?) bug that manifests itself only under certain conditions. before i file it, i'd like to know if it is still around in the latest DMD version and/or if other platforms and 64bit code is affected as well. bug description: std.algorithm.countUntil fails to find the needle my system: DMD 2.0642 compiling into 32bit code on Win7 64bit required conditions: compile with -release -inline -noboundscheck (an additional -O will also cause the bug) AND the module imports std.file /det import std.stdio; import std.algorithm; import std.file;// not needed, but if imported, causing trouble, see below void main() { auto names = [one,FOO,two,three]; // wrong code gen(*) with -release -O -inline -noboundscheck or // with -release -inline -noboundscheck but only if std.file is imported: auto x = countUntil( names, FOO ); write(x); if( 0 = x ) writeln( found a FOO); // (*) not found! }
Re: one of the weirdest bugs ever - request for testing
On 2014-06-12 14:20, captaindet wrote: before i file it, i'd like to know if it is still around in the latest DMD version and/or if other platforms and 64bit code is affected as well. thanks andrew, philippe, i had the suspicion that it is a windows only problem anyway because the only thing that an unused std.file would do is pulling a lot of windows specific stuff (on my system). if now someone could test this with the current DMD on windows, 64 and 32 bit executables... /det
Re: one of the weirdest bugs ever - request for testing
On 2014-06-12 17:27, Rene Zwanenburg wrote: On Thursday, 12 June 2014 at 22:14:23 UTC, captaindet wrote: On 2014-06-12 14:20, captaindet wrote: before i file it, i'd like to know if it is still around in the latest DMD version and/or if other platforms and 64bit code is affected as well. thanks andrew, philippe, i had the suspicion that it is a windows only problem anyway because the only thing that an unused std.file would do is pulling a lot of windows specific stuff (on my system). if now someone could test this with the current DMD on windows, 64 and 32 bit executables... /det No problems with 2.065 on win, both 32 and 64 bit. great, thanks, so no need to file a bug report. some other bugfix seemed to have taken care of the issue alongside. (in the meantime i had the bug confirmed on another win7/64 machine, however, using DMD2.0642 again.) hopefully it is still fixed in 2.066 which will be my next upgrade step once it is out. /det
delegate issue
hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}
Re: delegate issue
On 2014-06-02 08:08, Marc Schütz schue...@gmx.net wrote: On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote: hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){} This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. so the real explanation is that a module as such has no context. much of the module design has the look and feel as if it were some sort of object, so this is a bit of a surprise to me. well, i learned something. thanks, det
Re: delegate issue
On 2014-06-02 08:03, MrSmith wrote: On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote: hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){} You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; } i knew about the static constructor, mentioned it in my OP ;) tried it in my project proper and got run-time cycle detected between modules ctors/dtors :( something new to figure out now. thanks, det
Re: delegate issue
On 2014-06-02 08:08, Marc Schütz schue...@gmx.net wrote: On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote: hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){} This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. The workaround is either, as Mr Smith suggests, to use a static constructor, or you can use std.functional.toDelegate() (probably, didn't test). i knew about the static constructor workaround (mentioned it in my OP). works in a simple case, but when i tried it in my project proper i hit a run-time error: cycle detected between modules ctors/dtors :( could be an unrelated, so far undetected bug, will look into it tonight. will try std.functional.toDelegate() as well, maybe it will do the trick. thanks, det
Re: delegate issue
On 2014-06-02 08:08, Marc Schütz schue...@gmx.net wrote: On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote: hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){} This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. The workaround is either, as Mr Smith suggests, to use a static constructor, or you can use std.functional.toDelegate() (probably, didn't test). FWIW, tried toDelegate() and it does not work either: module demo2; import std.functional : toDelegate; int function(int) fn = function int(int){ return 42; }; // ok int dg_def(int){ return 666; } int delegate(int) dg = toDelegate(dg_def); // c:\D\DMD2\windows\bin\..\..\src\phobos\std\functional.d(758): Error: Cannot convert int delegate(int a0) @system to void* at compile time // demo2.d(8):called from here: toDelegate( dg_def) void main(){}
Re: delegate issue
On 2014-06-02 09:57, Steven Schveighoffer wrote: On Mon, 02 Jun 2014 10:37:07 -0400, captaindet 2k...@gmx.net wrote: On 2014-06-02 08:03, MrSmith wrote: On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote: hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a feature that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){} You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; } i knew about the static constructor, mentioned it in my OP ;) tried it in my project proper and got run-time cycle detected between modules ctors/dtors :( something new to figure out now. FYI, the module ctor/dtor cycles thing is an interesting problem. When D decides to call module ctors or dtors, it wants to initialize them in an order where two initializations don't depend on one another. For instance: module a; import b; int x; static this() { x = b.x;} module b; import a; int x; static this() { x = a.x;} But of course, D does not know what exactly is done in module a, and module b. It could be: module a; import b; int x; static this() { x = b.x; } module b; import a; int x; static this() { x = 15;} Which could be perfectly legal, as long as module b is initialized before module a. But D doesn't have the information to sort this out. So at the moment, it has to assume the first situation, and reject the code. And it can only detect this at runtime, since we have no way to tell the linker to refuse to link this code. The typical solution is to put your static ctors into another module, which nothing will import (and therefore cannot be part of a cycle). A module with no static ctors/dtors will not be flagged as causing a problem. -Steve thanks a lot, steve! turned out - not surprisingly - that i would run into the ctor/dtor cycle issue whenever the user code module had a static constructor (even if not due to the delegate workaround mixin). i was able to refactor my package and after 'outsourcing' of the static constructor there, i can now use the mixed in static constructors in the user module to initialize the delegate with a default. not pretty, but it works! /det
Re: templates, enums, CT reflection: compiler bug or not?
no one any ideas? well, i filed two bug reports for now: https://d.puremagic.com/issues/show_bug.cgi?id=12532 https://d.puremagic.com/issues/show_bug.cgi?id=12533
templates, enums, CT reflection: compiler bug or not?
i stumbled upon something strange while wondering around meta/codegen-lands. it took me almost a week to reduce it to the following test case. i have no clue what is going on, whether i have entered bug territory or just encountered my own limitations mind you, i have 2 issues with the code: (1) that my template, which uses __traits(compiles, ...), under certain circumstances (aka 'if things are getting complicated') fails to see symbols that one could argue are valid in this scope. (annoying maybe, but not my main problem) (2) the strange compiler error i get when using the template on itself, but only if it is not the first time that the instantiation is used. this is my real issue cause i don't know how to work around this. during my attempts to reduce this, starting from much more complicated code, i encountered all sorts of errors, including ICE and __error stuff. so am i being stupid or is it a compiler bug? cheers, det ===CODE=== module demo; template valid(string mem){ pragma(msg, instantiation of valid with: ~mem); static if( !__traits( compiles, mixin(mem) ) ){ enum valid = false; }else{ enum valid = true; } } enum ok = valid!foo; pragma(msg, ok ); // - true // fine, recognizes 'foo' in module scope enum works = valid!fails; pragma(msg, works );// - false // problematic, fails to see 'fails' in module scope enum dummy = valid!fails; pragma(msg, dummy );// - false // same behavior, as long as you are not testing yourself enum fails = valid!fails; // Error: variable demo.fails had semantic errors when compiling // NOTE: if you comment out the first two usages of valid!fails, it will work here, // although it will result in false // pragma(msg, fails ); enum foo = 42; void main(){}
Re: shouldn't this work? / how to make it work?
On 2014-03-22 19:37, anonymous wrote: On Saturday, 22 March 2014 at 22:54:15 UTC, captaindet wrote: pls see example code below. the two 'test' templates work fine by themselves. if, however, in the same module, the eponymous template does not work anymore. instead the compiler seems to try instantiating the variadic template. a) why? for how i understand it, this should not happen as o they have very different signatures, i.e. completely incompatible argument lists ( zero vs 1 arguments) o the string parameter is more specialized than the take-all tuple b) how can i make it work? cheers, det CODE: = import std.stdio; // cannot be used with function arguments template test(string str ){ enum test = template 'test' used with ~str; } // cannot be called with less than 2 function arguments string test (T ...)( T strs ) if( 1strs.length ) { return templated function 'test' called with ~strs[0]~ and ~strs[1]; } // enum epo = test!one; // use eponymous template // if commented in: // Error: tuple T is used as a type // in line 9 = string test (T ...)( T strs ) enum vari = test(two, three); // use templated/variadic function void main(string[] args) { // writeln( epo ); writeln( vari ); } Looks like a bug to me. i thought so too By the way, the variadic template is eponymous, too: The template declares a function with the same name. right filed a bug report: https://d.puremagic.com/issues/show_bug.cgi?id=12447
shouldn't this work? / how to make it work?
pls see example code below. the two 'test' templates work fine by themselves. if, however, in the same module, the eponymous template does not work anymore. instead the compiler seems to try instantiating the variadic template. a) why? for how i understand it, this should not happen as o they have very different signatures, i.e. completely incompatible argument lists ( zero vs 1 arguments) o the string parameter is more specialized than the take-all tuple b) how can i make it work? cheers, det CODE: = import std.stdio; // cannot be used with function arguments template test(string str ){ enum test = template 'test' used with ~str; } // cannot be called with less than 2 function arguments string test (T ...)( T strs ) if( 1strs.length ) { return templated function 'test' called with ~strs[0]~ and ~strs[1]; } // enum epo = test!one; // use eponymous template // if commented in: // Error: tuple T is used as a type // in line 9 = string test (T ...)( T strs ) enum vari = test(two, three); // use templated/variadic function void main(string[] args) { // writeln( epo ); writeln( vari ); }
std.algorithm.find and array of needles?
std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det
Re: std.algorithm.find and array of needles?
On 2014-03-03 14:58, John Colvin wrote: On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2)); thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det
Re: std.algorithm.find and array of needles?
On 2014-03-03 16:19, John Colvin wrote: On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote: On 2014-03-03 14:58, John Colvin wrote: On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote: std.algorithm.find has an overload that works with several needles: // phobos doc example: int[] a = [ 1, 4, 2, 3 ]; assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); the function i want to write has to deal with variadic arguments serving as needles. unfortunately, i failed trying to make find work with the needles provided in an array: int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ]; auto res = find( a, ns ); //Error: template std.algorithm.find does not match any function template declaration. Candidates are: any ideas how this can be achieved? thanks /det You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2)); thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det Luckily, you don't have to. foreach over tuples is awesome: import std.typecons; import std.algorithm; auto makeProperNeedle(T)(T needle) { //do something to needle return needle; } auto foo(A, T ...)(A[] a, T preNeedles) { Tuple!T needles; foreach(i, preNeedle; preNeedles) { needles[i] = makeProperNeedle(preNeedle); } //use find as follows. For example: return a.find(needles.expand); } unittest { assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3)); } awesome indeed - works like a charm! many thanks /det
Re: objects as AA keys
On 2013-10-15 08:32, Daniel Davidson wrote: On Tuesday, 15 October 2013 at 05:44:25 UTC, captaindet wrote: hi, i am a bit confused. the official language ref ( http://dlang.org/hash-map.html ) states: Classes can be used as the KeyType. For this to work, the class definition must override the following member functions of class Object: hash_t toHash() bool opEquals(Object) int opCmp(Object) ... but now i stumbled on http://forum.dlang.org/post/mailman.2445.1354457588.5162.digitalmars-d-le...@puremagic.com int[typeof(O)] rc; rc[O] = 42; auto O2 = O; // [...] if (auto r = O2 in rc) return *r; else return rc[O2] = compute(O2); IOW explicitly taking the address may not be necessary when doing that kind of things. and i did a quick test and indeed, it seems to work out of the box - without overriding any member functions. in my use case, i wouldn't be able to modify the class anyway. so my questions: why is it working, is it just syntactic sugar for using cast(void*)Obj as key? what is the danger of using objects as keys? when would it fail? as it seems to be working against language specs, will this 'feature' eventually be removed? (then maybe i should use cast(void*)Obj right away...) thanks, det Do you have an example where it is really working? The problem of not overriding those functions is that maybe you are not getting what you think. For example, the code below will print: [aaa.S:42] [aaa.S:42, aaa.S:43] This is probably not what you want. If you don't override the functions how is the implementation to know what are equivalent keys? Below you would probably expect two S's that are default constructed to hit the same key spot in the AA. But this does not happen since the implementation does not know you want new S to equal new S because there is no opEquals. Thanks, Dan in my use case i don't have multiple objects with the same state, so keying them per obj_ptr (if this is what is happening) seems to be sufficient for me. (the object classes are 3rd party so i cannot overwrite member functions anyway.) /det
objects as AA keys
hi, i am a bit confused. the official language ref ( http://dlang.org/hash-map.html ) states: Classes can be used as the KeyType. For this to work, the class definition must override the following member functions of class Object: hash_t toHash() bool opEquals(Object) int opCmp(Object) ... but now i stumbled on http://forum.dlang.org/post/mailman.2445.1354457588.5162.digitalmars-d-le...@puremagic.com int[typeof(O)] rc; rc[O] = 42; auto O2 = O; // [...] if (auto r = O2 in rc) return *r; else return rc[O2] = compute(O2); IOW explicitly taking the address may not be necessary when doing that kind of things. and i did a quick test and indeed, it seems to work out of the box - without overriding any member functions. in my use case, i wouldn't be able to modify the class anyway. so my questions: why is it working, is it just syntactic sugar for using cast(void*)Obj as key? what is the danger of using objects as keys? when would it fail? as it seems to be working against language specs, will this 'feature' eventually be removed? (then maybe i should use cast(void*)Obj right away...) thanks, det
Re: more enum and pragma troubles
On 2013-08-19 00:31, JS wrote: module main; import std.stdio, std.conv; template foo(alias T) { string foo(string s) { string x = to!string(T) ~ s ~ ; //pragma(msg, x); // pragma see's x as a run time variable(or rather pragma is executed before x is truly defined) return x; } well, i think i understand what is going on in your example. here x is a runtime value because 's' is passed as a function argument (always runtime within this very function). template instantiation (this is when pragmas(msg) is already called) comes first and at this time 's' is unknown, as the instantiated function could be later called with whatever 's' - the compiler cannot know what 's' at this point. tricks i found around this: a) if current structure of example program is required (i.s. definition of foo), add a wrapper template for compile time printing: template _dbg_foo(alias T, string s){ enum x = foo!(T)(s); pragma(msg, x); enum _dbg_foo = x; } b) if foo does not need to have 's' as an argument, make it a template parameter, too. you also have to use an enum instead of a string for temporary storage: string foo2(alias T, string s)(){ enum x = to!string(T) ~ s ~ ; pragma(msg, x); return x; } the problems i currently face during CTFE are more like: a) in some cases manifest enums are broken in that they don't contain working compile time copypaste values. this is currently the case for TypeTuples. i think this will be fixed in the next DMD release. b) pragma(msg) has not the same behavior as write() when it comes to formating the output of non-string values, it sometimes needs help, e.g. with a to!string() call.
Re: more enum and pragma troubles
On 2013-08-17 21:54, JS wrote: On Sunday, 18 August 2013 at 00:17:22 UTC, captaindet wrote: On 2013-08-17 14:36, Jesse Phillips wrote: Third you've declared a variable, bar, which will store your enumerated value, 4. Variables are not compile time, even if the value stored came from a compile time known value. yep, it completely escaped me that these are 'normal' variables. and i have realized now that i can make them known at compile time the same way as is done for other 'normal' variables, by declaring them const ;) But if they are const then what good does that do you? Just use an alias or enum in the first place? to be honest, i have not found a use case ;) highest priority was that i understood what was going on here... how did i get there? i was looking for an easy way to get pragma(msg,...) to print the given name for an enumerated value. in this example test2 or test4 instead of 2 and 4 - just like write is doing it at runtime. so i was playing around with the different variants of enum to see if i could get it working somehow.. and got sidetracked in the end i stuck to manifest constant enums storing the enumerated values and found that pragma( msg, to!string(foo) ); is doing the trick. /det
Re: more enum and pragma troubles
[enum foo = Test.test2;] On 2013-08-17 01:03, JS wrote: pragma( msg, foo ); // why does it print: cast(Test)2 // it should be: test2 // or at least simply: 2 It is 2! Notice the 2 at the end? The cast is just mumbo jumbo due to the the compiler deals with the stuff. You can remove the casts manually if you don't like them. i saw the 2, but foo semantically contains a Test Test.test2 (this is the idea) or technically an int 2. don't understand why pragma displays an explicit cast here. maybe some internals that are leaking through the pragma(msg,...) implementation. // pragma( msg, bar ); // Error: variable bar cannot be read at compile time Because bar is not a compile time constant. It is an runtime object. pragma can't display certain things that it doesn't know about due to the way the compiler works. It's unfortunate in some cases that it simply doesn't work correctly, in others, such as this, it works as expected. You could argue that the compiler should know that bar is known at compile time up to the pragma, and I would agree... but the compiler simply isn't that smart. but this is my very point! my understanding was that enums are all compile time entities that are just copied around. at compile time. a named enum type should make no difference. where is it documented that named enums become runtime objects? but you are right that this seems to be the case here and that pragma(msg,...) is off the hook this time: enum Test{ test2 = 2, test4 = 4 } enum foo = Test.test2; Test bar = Test.test4; // enum wtf = bar; // Error: variable bar cannot be read at compile time /det
Re: more enum and pragma troubles
On 2013-08-17 01:51, captaindet wrote: named enums become runtime objects - named enums become runtime *only* objects
Re: more enum and pragma troubles
On 2013-08-17 01:51, captaindet wrote: my understanding was that enums are all compile time entities that are just copied around. at compile time. a named enum type should make no difference. oh i see now, naming them is just creating a disguise for the base type. then they can become compile-time-known when declared const (see below). only anonymous enum (manifest constant) are true compile time objects. reminds me of my (type)tuple confusion. two completely different animals/concepts, with similar/confusing syntax and blurry docs. module demo; import std.stdio; enum Test{ test2 = 2, test4 = 4 } enum foo = Test.test2; const Test bar = Test.test4;// does the trick enum wtf = bar; pragma( msg, foo ); // prints: cast(Test)2 pragma( msg, bar ); // pritns: cast(Test)4 void main(){ writeln( typeof(foo).stringof, = , foo ); // prints: Test = test2 writeln( typeof(bar).stringof, = , bar ); // prints: const(Test) = test4 }
Re: more enum and pragma troubles
On 2013-08-17 14:36, Jesse Phillips wrote: Third you've declared a variable, bar, which will store your enumerated value, 4. Variables are not compile time, even if the value stored came from a compile time known value. yep, it completely escaped me that these are 'normal' variables. and i have realized now that i can make them known at compile time the same way as is done for other 'normal' variables, by declaring them const ;) pragma( msg, foo ); // why does it print: cast(Test)2 You are referring to a manifest constant, this is a simple textual replacement. Enumerations are typed, 2 is not a Test, so the compiler will write out a cast so the type system is happy. Similarly Test.test2 is not the value of foo, foo is a signal to the compiler to insert cast(Test)2. Hope that makes sense. things are becoming clearer now. thanks for your explanation, jesse! /det
more enum and pragma troubles
are these bugs or expected behavior? (2 issues, see code below) i thought enums are just compile time copypaste magic so i cannot think of a reason why it should not be available at compile time... if buggy, what is broken, enum (really bad) or pragma(msg,...) (worse enough)? and are they in bugzilla already? (looked but nothing caught my eye) if expected behavior, can someone pls explain. cheers /det import std.stdio; enum Test{ test2 = 2, test4 = 4 } enum foo = Test.test2; Test bar = Test.test4; pragma( msg, foo ); // why does it print: cast(Test)2 // it should be: test2 // or at least simply: 2 // pragma( msg, bar ); // Error: variable bar cannot be read at compile time void main(){ writeln( typeof(foo).stringof, = , foo ); // prints as expected: Test = test2 writeln( typeof(bar).stringof, = , bar ); // prints as expected: Test = test4 }
Re: enum and tuples
I'm pretty sure that this is just a bad error message. void main(){ writeln(ok: , ok, ok[0]: , ok[0]); // ok: Tuple!(string, string, string)(one, two, three) ok[0]: one writeln(er: , er, er[0]: , er[0]); // er: onetwothree er[0]: one } What I expect is happening is that TypeTuples don't convert to string, so the pragma fails, hmm, but it is a TypeTuple of strings and aren't they supposed to automatically expand? and pragma(msg, ...) takes various arguments, e.g. pragma(msg, this, and, that); so is it just a bad error message or a bug in pragma(msg, ...)? (..,i know, pragmas are difficult to blame for anything as they are not part of the language proper. but in lieu of a compile time print this is all we got for debugging our meta stuff.) then there is the thing of assigning value type TypeTuples to variables/enums. is this allowed or not? see my observations regarding enums which are for 2.063.2. according to anonymous in the git head for 2.064 the enum example for string value TypeTuples now fails...i don't think any of this behavior is documented anywhere. what i think is missing is a clearly defined boundary/set of rules for what we can do with the internal tuples (aka TypeTuples) and how, and what not. /det
enum and tuples
hi, i am still struggling getting to grips with tuples, especially typetuples. i got into this when trying module introspection and the surprise discovery that __traits(allMembers, .) seems to return a typetuple of strings. (the tuple article on dlang and philippe's template tutorial do help a bit, but only so much.) typetuples seem to live in a shadow world and quite obscurely should be referred to/passed around via aliases. even though we have alias a = b now i regard this as an irregularity/oddity of the language, i.e. that they are not treated the same way as variables/aggregates. anyhow, i started playing a bit putting them in enums anyway. surprisingly, storing tuples and typetuples in enums is accepted by the compiler. however, while enum tuples seem to behave normal/useful at compile time and run time, enum'ed typetuples don't like compile time, but seem to behave at runtime. (i rather would have expected the other way around). examples further below. so i guess my questions are a) if we are not allowed to put typetuples in enums, why is it not an error? b) if enums are supposed to handle typetuples, why is it not working at compile time? /det module demo; import std.stdio, std.typetuple, std.typecons; enum ok = tuple(one, two, three); pragma(msg, ok, , , ok[0]); // Tuple(one, two, three), one enum er = TypeTuple!(one, two, three); // pragma(msg, er); // Error: variable _er_field_0,1,2 cannot be read at compile time void main(){ writeln(ok: , ok, ok[0]: , ok[0]); // ok: Tuple!(string, string, string)(one, two, three) ok[0]: one writeln(er: , er, er[0]: , er[0]); // er: onetwothree er[0]: one }
Re: enum and tuples
On 2013-08-09 11:36, Ali Çehreli wrote: as I am in the process of revising and translating a Tuples chapter. thanks for the reply, Ali. as a matter of fact, i am checking your website regularly, eagerly awaiting the translations of the tuples chapter. and the __traits and the template chapter too ;) your examples make things a bit clearer in general, but not in the specific case of enums. i investigated my enum cases a bit more and it seems that enums of string value typetuples are good-natured expression by far and large, only pragma(msg, X) fails terribly. enum X = TypeTuple!(only, strings, here); // fine everywhere but pragma(msg hovever, enums of integer or float value typetuples throw a phobos error when appearing outside of main(), but work alright within main() enum er = TypeTuple!(1,2,3);// ...\utf.d(1147): Error: cannot cast int to (int, int, int) void main(){ enum er = TypeTuple!(1,2,3);// fine } quite mysterious. /det
Re: Reading a structured binary file?
On 2013-08-02 17:13, Jonathan M Davis wrote: On Friday, August 02, 2013 19:49:54 Gary Willoughby wrote: What library commands do i use to read from a structured binary file? I want to read the byte stream 1, 2 maybe 4 bytes at a time and cast these to bytes, shorts and ints respectively. I can't seem to find anything like readByte(). I'd probably use std.mmfile and std.bitmanip to do it. MmFile will allow you to efficiently operate on the file as a ubyte[] in memory thanks to mmap, and std.bitmanip's peek and read functions make it easy to convert multiple bytes into integral values. - Jonathan M Davis FWIW i have to deal with big data files that can be a few GB. for some data analysis software i wrote in C a while back i did some testing with caching and such. turns out that for Win7-64 the automatic caching done by the OS is really good and any attempt to speed things up actually slowed it down. no kidding, i have seen more than 2GB of data being automatically cached. of course the system RAM must be larger than the file size (if i remember my tests correctly by a factor of ~2, but this is maybe not a linear relationship, i did not actually change the RAM just the size of the data file) and it will hold it in the cache only as long as there are no concurrent applications requiring RAM or caching. i guess my point is, if your target is Win7 and your files are 5x smaller than the installed RAM i would not bother at all trying to optimize file access. i suppose -nix machine will do a similar good job these days. /det
Re: reading a structure (eg header info) from file
thanks everyone for your help! i should have mentioned that i did play with std.stdio.File.readf and rawRead but was too thick to figure out a working solution. o i could not figure out how to make readf work with my self defined struct o same with rawRead. but here i understand my mistake now: i have to pass an array of my struct, even if i only want to read it once. endianness and padding are certainly issues. i have spent some time figuring out how to adjust struct packing in D. my definitions are now full of align(2) declarations... as for the endianness, as i can oversee it now all potential users will sit on little-endian machines. the group of users is small, just our workgroup. the datafiles in question are produced by some 3rd party 16bit windows software, so i have to accept the way the data is stored in the file. also, they can be as big as 2GB so reading in the whole file is not an option. thanks again, det
reading a structure (eg header info) from file
hi, whilst converting some of my C code into D i got stuck. in C: typedef struct { /* info */ } INFO; INFO info; size_t checkio; // read INFO from data file: pf_datafile = fopen(datafile,rb); checkio = fread((char *) info, sizeof(info), 1, pf_datafile); how do i do this in D? i'd like to avoid falling back to calling C functions, but i cannot figure out how do this with phobos functions. mind you, eventually the INFO struct might be anywhere in the file, not only at the beginning. cheers, det
Re: Why there is too many uneccessary casts?
On 2013-06-11 19:48, captaindet wrote: On 2013-06-11 07:35, Adam D. Ruppe wrote: On Tuesday, 11 June 2013 at 10:12:27 UTC, Temtaime wrote: ubyte k = 10; ubyte c = k + 1; This code fails to compile because of: Error: cannot implicitly convert expression (cast(int)k + 1) of type int to ubyte The reason is arithmetic operations transform the operands into ints, that's why the error says cast(int)k. Then it thinks int is too big for ubyte. It really isn't about overflow, it is about truncation. That's why uint + 1 is fine. The result there is still 32 bits so assigning it to a 32 bit number is no problem, even if it does overflow. But k + 1 is promoted to int first, so it is a 32 bit number and now the compiler complains that you are trying to shove it into an 8 bit variable. Unless it can prove the result still fits in 8 bits, it complains, and it doesn't look outside the immediate line of code to try to prove it. So it thinks k can be 255, and 255 + 1 = 256, which doesn't fit in 8 bits. The promotion to int is something D inherited from C and probably isn't going anywhere. i think part of the problem is that '1' is an int. so the calculation must be promoted to integer. if we had byte and ubyte integer literals (suffix b/B and ub/UB?), then if all RHS arguments are (unsigned) bytes the compiler could infer that we are serious with sticking to bytes... ubyte k = 10; // or optional 10ub ubyte c = k + 1ub; clarification: i was only half serious. i understand that indicating a byte literal is not enough and that the promotion rules would have to be altered too. however, i think it would be backwards compatible. then the question is if enough ppl want this feature badly enough to push the issue. i don't think this is the case meaning we will have to accept this little quirk.
Re: Why there is too many uneccessary casts?
On 2013-06-11 07:35, Adam D. Ruppe wrote: On Tuesday, 11 June 2013 at 10:12:27 UTC, Temtaime wrote: ubyte k = 10; ubyte c = k + 1; This code fails to compile because of: Error: cannot implicitly convert expression (cast(int)k + 1) of type int to ubyte The reason is arithmetic operations transform the operands into ints, that's why the error says cast(int)k. Then it thinks int is too big for ubyte. It really isn't about overflow, it is about truncation. That's why uint + 1 is fine. The result there is still 32 bits so assigning it to a 32 bit number is no problem, even if it does overflow. But k + 1 is promoted to int first, so it is a 32 bit number and now the compiler complains that you are trying to shove it into an 8 bit variable. Unless it can prove the result still fits in 8 bits, it complains, and it doesn't look outside the immediate line of code to try to prove it. So it thinks k can be 255, and 255 + 1 = 256, which doesn't fit in 8 bits. The promotion to int is something D inherited from C and probably isn't going anywhere. i think part of the problem is that '1' is an int. so the calculation must be promoted to integer. if we had byte and ubyte integer literals (suffix b/B and ub/UB?), then if all RHS arguments are (unsigned) bytes the compiler could infer that we are serious with sticking to bytes... ubyte k = 10; // or optional 10ub ubyte c = k + 1ub;
Re: modulename
On 2012-09-04 15:36, Andrej Mitrovic wrote: 9/4/12, Ellery Newcomerellery-newco...@utulsa.edu wrote: On 09/04/2012 12:41 PM, Andrej Mitrovic wrote: __FILE__? It doesn't necessarily have the exact package hierarchy. We could really use __MODULE__ then. I think it's been asked before but I didn't see any enhancement request in buzilla. +1 would love this too so far tried to get away with __FILE__ but this has issues, as noted before. on a slightly different note, __FILE__ and __LINE__ are not quite doing what they are supposed to do either: http://dlang.org/template.html Template Value Parameters The __FILE__ and __LINE__ expand to the source file name and line number at the point of instantiation. unfortunately, they only do this for functions (sort of¹), not for other templates. dunno why, i think it is just not implemented. in fear of code bloat? i don't get this argument though. if you use __FILE__ and such extensively it would be only in debugging scenarios. other than that, you shouldn't have many of those. at least this is the case in my code. and the danger of code bloat with templates is omnipresent, no reason to single out __FILE__ usage. ¹using funtempl(Ps)(As){...}: + always works in argument list (As), also in non-templated functions + as template parameter (P), works only when called short: funtempl() - as template parameter(P), this does not work: funtempl!()()
Re: modulename
On 2012-09-05 13:05, Jose Armando Garcia wrote: On Sep 5, 2012, at 10:56, captaindet 2k...@gmx.net wrote: On 2012-09-04 15:36, Andrej Mitrovic wrote: 9/4/12, Ellery Newcomerellery-newco...@utulsa.edu wrote: On 09/04/2012 12:41 PM, Andrej Mitrovic wrote: __FILE__? It doesn't necessarily have the exact package hierarchy. We could really use __MODULE__ then. I think it's been asked before but I didn't see any enhancement request in buzilla. +1 would love this too so far tried to get away with __FILE__ but this has issues, as noted before. on a slightly different note, __FILE__ and __LINE__ are not quite doing what they are supposed to do either: http://dlang.org/template.html Template Value Parameters The __FILE__ and __LINE__ expand to the source file name and line number at the point of instantiation. unfortunately, they only do this for functions (sort of¹), not for other templates. It should work for templates too; std.log uses this extensively. Or at least it used to work. Can you post the code sample where it doesn't work? i had a quick look at std.log and it seems to use __LINE__ and __FILE__ only as function argument defaults or parameter defaults for templated functions. these are the only cases where it actually works (with the one syntax catch though). however, it does not work for bare/mixin tamplates, templated structs or templated classes. (so i ended up writing factory functions for my code) here a test program: /** __LINE__ testing for F := function S := struct C := class T := template MT := mixin template as A := function value argumentP := template value parameter using dmd2.060 /windows prints: Instantiating Code starts line: 63 F(A) OK : captured line = 67 T(P) FAIL : captured line = 43 MT(P) FAIL : captured line = 46 TF()(A) OK : captured line = 78 TF(P)(): short call syntax: TF_P() OK : captured line = 82 TF(P)(): longer call syntax: TF_P!()() FAIL : captured line = 52 TS(P) FAIL : captured line = 55 TC(P) FAIL : captured line = 58 **/ module testline; import std.stdio; size_t F_A( size_t l = __LINE__ ){ return l; } template T_P( size_t l = __LINE__ ){ enum size_t t_p = l; } mixin template MT_P( size_t l = __LINE__ ){ enum size_t mt_p = l; } size_t TF_A()( size_t l = __LINE__ ){ return l; } size_t TF_P( size_t l = __LINE__ )(){ enum size_t _l = l; return _l; } struct TS_P( size_t l = __LINE__ ){ size_t _l = l; } class TC_P( size_t l = __LINE__ ){ size_t _l = l; } void main(){ size_t L = __LINE__;// if things work: __LINE__ L writeln(\nInstantiating Code starts line: , L); writeln(\nF(A)); auto l_f_a = F_A(); writeln((l_f_aL)?OK:FAIL, : captured line = , l_f_a); writeln(\nT(P)); writeln((T_P!().t_pL)?OK:FAIL, : captured line = , T_P!().t_p); writeln(\nMT(P)); mixin MT_P!(); writeln((mt_pL)?OK:FAIL, : captured line = , mt_p); writeln(\nTF()(A)); auto l_tf_a = TF_A!()(); writeln((l_tf_aL)?OK:FAIL, : captured line = , l_tf_a); writeln(\nTF(P)(): short call syntax: TF_P()); auto l_tf_p = TF_P(); writeln((l_tf_pL)?OK:FAIL, : captured line = , l_tf_p); writeln(\nTF(P)(): longer call syntax: TF_P!()()); auto l_tf_p2 = TF_P!()(); writeln((l_tf_p2L)?OK:FAIL, : captured line = , l_tf_p2); writeln(\nTS(P)); TS_P!() ts_p; writeln((ts_p._lL)?OK:FAIL, : captured line = , ts_p._l); writeln(\nTC(P)); auto tc_p = new TC_P!(); writeln((tc_p._lL)?OK:FAIL, : captured line = , tc_p._l); }
caller trouble
i need a discreet handle on the calling/instantiating source file (module). using __FILE__, it is surprisingly easy for functions (via argument) and templated functions (via template parameter) but i cannot get it working for templated classes. how can i make them aware of the calling module? thx, det module other; string fun(string infile = __FILE__){ return infile; } string tfun(string infile = __FILE__)(){ return infile; } class tclass(string infile = __FILE__){ string from = infile; } //...// module main; import other; void main(){ auto _fun = fun(); //_fun == main.d auto _tfun = tfun();//_tfun == main.d auto _tclass = new tclass!(); //_tclass.from == other.d !!! //this works but i do not want to provide __FILE__ explicitly: auto _tclassx = new tclass!(__FILE__)();//_tclass.from == main.d //and why do i get 2 different results for the last 2 cases? }
Re: caller trouble
On 2012-07-14 02:12, Jonathan M Davis wrote: [..] I believe that __FILE__ and __LINE__ are treated specially with functions in order for them to be filled in at the call site rather than the declaration site. If it's not working with classes, then that probably means that whatever special logic was done to make them work with functions was only done for functions. IIRC, __FILE__ is a template itself. so it must be about the very moment it is resolved. apparently, for function (templates) default parameters are treated as if given on the caller side. maybe even for __FILE__ and __LINE__ as main usage case? in any case, there would be a consistent rule resolve all templates in argument lists on caller side, including default parameters if it were not broken for class templates. moreover, i am puzzled why the small variation in usage rusults in an inconsistent outcome: auto _tclass = new tclass!(); //_tclass.from == other.d !!! auto _tclassx = new tclass!(__FILE__)(); //_tclass.from == main.d However, I would point out that that would mean that every single module which uses tclass would end up with a different and incompatible instantiations of tclass yes, but not an issue in my case. there would be only one object, created from the main module. background: i want to do some compile time magic including parsing information from a file that always has the same name as the module containing main(){...}. However, if you _really_ want something like this, you can always just wrap the creation of the object in a function: good idea, i will try this next. thanks for your help! /det
Re: caller trouble
auto _fun = fun(); //_fun == main.d auto _tfun = tfun(); //_tfun == main.d auto _tclass = new tclass!(); //_tclass.from == other.d !!! //this works but i do not want to provide __FILE__ explicitly: auto _tclassx = new tclass!(__FILE__)(); //_tclass.from == main.d //and why do i get 2 different results for the last 2 cases? } This is a bug. dlang.org agrees: http://dlang.org/template.html#TemplateValueParameter right, i missed this in the specs. there seem to be several bug reports on this and related issues, eg: http://d.puremagic.com/issues/show_bug.cgi?id=4018 http://d.puremagic.com/issues/show_bug.cgi?id=5686 apparently and old issue that was never addressed...too bad
starting independent processes
i am just in the middle of my first little d project. i came to the point where i have to start new processes command line style incl arguments. they need to run independent of the main program, i.e., several such processes need to be started and must run parallel while the main program continues and maybe even finishes. in c/c++ (M$ VS2005, e.g.) this can be achieved using one of the spawnXXX functions with mode=P_DISPATCH (value 4). phobos has a similar function std.process.spawnvp, however, P_DISPATCH doesn't seem to be supported (not defined and when using '4L' anyway resulting in a crash). so the main question is: what do i do instead? (win32 system) also i noticed that std.process.spawnvp with mode=P_NOWAIT seems to be broken. it behaves as if mode=P_WAIT: the parent thread is halted until child thread has finished. if this at least would be multithreaded i might be able to live with it (and let the parent process silently wait in the background even though it is done). thx, det