Re: Passing a generic struct as parameter
Well, the problem is that I must do the cast always, see : // alias Matrix!(real,4) Mat4r; // alias Vector!(float, 3) Vec3f; // alias Vector!(real, 4) Vec4r; // In Mat4r, VCol it's aliased to Vector!(real, 4) auto tcol = Mat4r.IDENTITY; auto v = cast(tcol.VCol) Vec3f(1, 2 ,3 ); auto v2 = Vec4r(-1, -2 ,-3 ,-4); tcol[1] = v2; // Do a compiler error tcol[2] = v; I get this error : Error: function zmath.matrix.Matrix!(real,4).Matrix.opIndexAssign (real c, ulong row, ulong cl) is not callable using argument types (Vector! (real,4),int) Error: cannot implicitly convert expression (v2) of type Vector!(real,4) to Vector!(real,dim) If I do cast(tcol.Vcol) to v2, this works. Plus if I do a typeid(v1), typeid(v2) to see his types, I get this : zmath.vector.Vector!(real,4).Vector zmath.vector.Vector!(real,dim).Vector On Fri, 01 Jul 2011 02:29:58 +0200, Simen Kjaeraas wrote: > On Fri, 01 Jul 2011 01:39:53 +0200, Zardoz > wrote: > >> I have a parametrized struct (Vector!(T, dim)) that takes two >> parameters (Type and a number). And made some Alias with defaults >> parameters. >> >> In other struct (Matrix!(T, dim)), that uses these struct to represent >> a matrix in column-major order. I have a internall alias for Vector >> using internally (alias Vector!(T,dim_) VCol;) . The problem that I >> have it's when I try to use opIndexAssign to assign to a column a >> Vector. I try this : >> >> void opIndexAssign(Vector v, size_t j) { >> if ( code that see if VCol if same type that v ) { >> col[j] = v; >> } else { >> col[j] = cast (VCol) v; >> } >> } >> >> But not compile... I get this error : Error: struct >> zmath.vector.Vector(T,ulong dim_) if (__traits (isFloating,T)) is used >> as a type >> Error: template instance zmath.matrix.Matrix!(float,2) error >> instantiating >> >> So finally I try this : >> /** >> * Assigns a new column vector >> */ >> void opIndexAssign(VCol v, size_t j) { >> col[j] = v; >> } >> >> But now I must do cast outside, even knowing that are same type. Plus >> now I must keep VCol alias public. >> >> How should fix this, or What is the correct way of doing this ? > > Private symbols in D are visible outside the defining module (and > private symbols are accessible inside the same module), so having the > alias private is no problem. > > In other words, the latter solution is good, and should not require any > casting or public alias. > > Or have I perhaps misunderstood? Is there some other reason you need to > cast? > > > Also, the error message you get (Vector(...) is used as a type) is > indicative of your referring to the Vector template rather than an > instantiation. Struct templates in D behave as if defined thusly: > > template Foo( T ) { > struct Foo { > } > } > > for a struct Foo( T ). > > >> Note : I have a opCast for Vector that cast between Vectors with >> different parameters and it's checked that works. >> >> Second Question : I'm thinking publish this small Vector/Quaternion/ >> Matrix lib that I made learning D2.. where I should put and how ? (and >> I use Git) > > GitHub, then? Or dsource.org. -- Yep, I'm afraid that I have a blog : zardoz.es
Creating a thread-local duplicate of a globally shared array
I have two functions running concurrently and they share data via a globally shared array. Generally one thread modifies an array and potentially changes its length, the other thread reads from it. I have to avoid too many locks and message passing wouldn't really work since I need fast access to the array. I can't use the array directly in the reading thread because the array could possibly be reallocated by the writing thread (e.g. if it changes the .length property), while at the same time the reading thread could just have sent the .ptr value of that array to some API function. I've had this problem occur and the app would crash due to a reallocation while the API was reading the array. Here's the gist of it: __gshared int[] values; void foo() { // modify, write to the array, and possibly change the length } void bar() { // send the .ptr field of 'values' and its length to an API function which reads // 'values' in sequence and does some visual output. } Is it possible to lock 'values', but only once in the bar function while creating a thread-local copy? I mean something like this: void bar() { static int[] localValues; localValues = LOCK(values[]); // temporarily lock values and copy its contents to a thread-local array // values is now unlocked and foo() can modify/write to it again APIFun(localValues.ptr, localValues.length); // safe to pass this array to the API }
Re: Why does std.string use public imports?
Andrej Mitrovic Wrote: > I'm referring to these two in std.string: > public import std.algorithm : startsWith, endsWith, cmp, count; > public import std.array : join, split; I'm not sure why they are public, but selective/named imports have been publicly imported for some time. Bugzilla 3?? I think.
Re: Generic invert function?
Woops, bug, right side not inclusive. Fixed: auto arr = array(retro(iota(0, 128)));
Re: Generic invert function?
Stupid brain, LOL. auto arr = array(retro(iota(0, 127))); Problem solved.
Re: Generic invert function?
On 2011-06-30 18:27, Andrej Mitrovic wrote: > So I thought this would be in Phobos, basically I want to reverse the > "polarity" of a value in a range. > > What I mean is if I have a possible range of 0 .. 127, then the values > of the left would equal the inverted values on the right: > > 0 -> 127 > 10 -> 117 > 20 -> 107 > 50 -> 77 > 77 -> 50 > > and so on.. Quite easy to do, is it common enough to be in Phobos though? std.range.retro? - Jonathan M Davis
Generic invert function?
So I thought this would be in Phobos, basically I want to reverse the "polarity" of a value in a range. What I mean is if I have a possible range of 0 .. 127, then the values of the left would equal the inverted values on the right: 0 -> 127 10 -> 117 20 -> 107 50 -> 77 77 -> 50 and so on.. Quite easy to do, is it common enough to be in Phobos though?
Re: Passing a generic struct as parameter
On Fri, 01 Jul 2011 01:39:53 +0200, Zardoz wrote: I have a parametrized struct (Vector!(T, dim)) that takes two parameters (Type and a number). And made some Alias with defaults parameters. In other struct (Matrix!(T, dim)), that uses these struct to represent a matrix in column-major order. I have a internall alias for Vector using internally (alias Vector!(T,dim_) VCol;) . The problem that I have it's when I try to use opIndexAssign to assign to a column a Vector. I try this : void opIndexAssign(Vector v, size_t j) { if ( code that see if VCol if same type that v ) { col[j] = v; } else { col[j] = cast (VCol) v; } } But not compile... I get this error : Error: struct zmath.vector.Vector(T,ulong dim_) if (__traits (isFloating,T)) is used as a type Error: template instance zmath.matrix.Matrix!(float,2) error instantiating So finally I try this : /** * Assigns a new column vector */ void opIndexAssign(VCol v, size_t j) { col[j] = v; } But now I must do cast outside, even knowing that are same type. Plus now I must keep VCol alias public. How should fix this, or What is the correct way of doing this ? Private symbols in D are visible outside the defining module (and private symbols are accessible inside the same module), so having the alias private is no problem. In other words, the latter solution is good, and should not require any casting or public alias. Or have I perhaps misunderstood? Is there some other reason you need to cast? Also, the error message you get (Vector(...) is used as a type) is indicative of your referring to the Vector template rather than an instantiation. Struct templates in D behave as if defined thusly: template Foo( T ) { struct Foo { } } for a struct Foo( T ). Note : I have a opCast for Vector that cast between Vectors with different parameters and it's checked that works. Second Question : I'm thinking publish this small Vector/Quaternion/ Matrix lib that I made learning D2.. where I should put and how ? (and I use Git) GitHub, then? Or dsource.org. -- Simen
Re: Why does std.string use public imports?
On 2011-06-30 16:14, Andrej Mitrovic wrote: > I'm referring to these two in std.string: > public import std.algorithm : startsWith, endsWith, cmp, count; > public import std.array : join, split; > > Because whenever I try to use .count in my code: > > import std.stdio; > import std.string; > import std.utf; > > void main() > { > writeln("foo".count); > } > > std.utf.count conflicts with std.string's publicly imported > std.algorithm.count > > Can we avoid public imports in modules? The rise of conflicts in > Phobos is getting slightly annoying. I believe that they're there because the functions in question used to be in std.string but were generalized and moved to other modules. So, rather than immediately break code, they were publicly imported in std.string. They're scheduled for deprecation and will be removed once the deprecation process has completed. However, they shouldn't be causing conflicts. It's probably due to a bug related to explicit imports being seen as new functions in the module that they're imported into (I forget the bug number). Maybe using static imports with aliases would fix the problem. - Jonathan M Davis
Re: Passing a generic struct as parameter
On 2011-06-30 16:39, Zardoz wrote: > I have a parametrized struct (Vector!(T, dim)) that takes two parameters > (Type and a number). And made some Alias with defaults parameters. > > In other struct (Matrix!(T, dim)), that uses these struct to represent a > matrix in column-major order. I have a internall alias for Vector using > internally (alias Vector!(T,dim_) VCol;) . The problem that I have it's > when I try to use opIndexAssign to assign to a column a Vector. I try > this : > > void opIndexAssign(Vector v, size_t j) { > if ( code that see if VCol if same type that v ) { > col[j] = v; > } else { > col[j] = cast (VCol) v; > } > } > > But not compile... I get this error : > Error: struct zmath.vector.Vector(T,ulong dim_) if (__traits > (isFloating,T)) is used as a type > Error: template instance zmath.matrix.Matrix!(float,2) error instantiating > > So finally I try this : > /** > * Assigns a new column vector > */ > void opIndexAssign(VCol v, size_t j) { > col[j] = v; > } > > But now I must do cast outside, even knowing that are same type. Plus now > I must keep VCol alias public. > > How should fix this, or What is the correct way of doing this ? > > > Note : I have a opCast for Vector that cast between Vectors with > different parameters and it's checked that works. > > Second Question : I'm thinking publish this small Vector/Quaternion/ > Matrix lib that I made learning D2.. where I should put and how ? (and I > use Git) The first thing that you need to understand is that Vector is not a type. It does not exist. Vector!(int, 4) is a type. Vector!(float, 3) is a type. Vector is not. Vector is a template for a type. When you use a template, you instantiate it for a particular set of arguments, and that creates a new type. An instantiation of a templated type such as Vector is a type, and every instantiation is its own, separate type which has no connection with any other instantion of that template. So, it makes no sense for a function to take a Vector (though within the Vector template that works, because Vector stands for that particular instantiation inside of the Vector template). If you want a function to take multiple instantiations of a template, then you need to templatize the function. If you want it to take a particular instantiation of a template, then you give its parameter that exact template instantiation. Now, if you want two separate instantions (such as Vector!(int, 3) and Vector! (float, 3)) to interact, you're going to need to either write opCasts to cast between them or have templated functions which are templated on both of their types (e.g. func(V1, V2)(V1 vector1, V2 vector2) {...}). They are two completed different types, just like if you created IntVector and FloatVector, so you have to write code which allows them to interact. They aren't going to just work together because they came from the same template. - Jonathan M Davis
Passing a generic struct as parameter
I have a parametrized struct (Vector!(T, dim)) that takes two parameters (Type and a number). And made some Alias with defaults parameters. In other struct (Matrix!(T, dim)), that uses these struct to represent a matrix in column-major order. I have a internall alias for Vector using internally (alias Vector!(T,dim_) VCol;) . The problem that I have it's when I try to use opIndexAssign to assign to a column a Vector. I try this : void opIndexAssign(Vector v, size_t j) { if ( code that see if VCol if same type that v ) { col[j] = v; } else { col[j] = cast (VCol) v; } } But not compile... I get this error : Error: struct zmath.vector.Vector(T,ulong dim_) if (__traits (isFloating,T)) is used as a type Error: template instance zmath.matrix.Matrix!(float,2) error instantiating So finally I try this : /** * Assigns a new column vector */ void opIndexAssign(VCol v, size_t j) { col[j] = v; } But now I must do cast outside, even knowing that are same type. Plus now I must keep VCol alias public. How should fix this, or What is the correct way of doing this ? Note : I have a opCast for Vector that cast between Vectors with different parameters and it's checked that works. Second Question : I'm thinking publish this small Vector/Quaternion/ Matrix lib that I made learning D2.. where I should put and how ? (and I use Git) -- Yep, I'm afraid that I have a blog : zardoz.es
Re: Why does std.string use public imports?
That makes sense, I understand. But I hate these conflicts. I've got `alias std.bla.foo foo` scattered in most of my code due to constant conflicts. :/
Re: Why does std.string use public imports?
On 01.07.2011 01:14, Andrej Mitrovic wrote: I'm referring to these two in std.string: public import std.algorithm : startsWith, endsWith, cmp, count; public import std.array : join, split; Because whenever I try to use .count in my code: import std.stdio; import std.string; import std.utf; void main() { writeln("foo".count); } std.utf.count conflicts with std.string's publicly imported std.algorithm.count Can we avoid public imports in modules? The rise of conflicts in Phobos is getting slightly annoying. I cannot comment on the count issue, but if I was to import only std.string and I was missing basic functionality like the ones imported here, it would have annoyed me :) So it's good if it makes sense I think.
Why does std.string use public imports?
I'm referring to these two in std.string: public import std.algorithm : startsWith, endsWith, cmp, count; public import std.array : join, split; Because whenever I try to use .count in my code: import std.stdio; import std.string; import std.utf; void main() { writeln("foo".count); } std.utf.count conflicts with std.string's publicly imported std.algorithm.count Can we avoid public imports in modules? The rise of conflicts in Phobos is getting slightly annoying.
Re: C callback receives bad pointer argument
> Now that typedef is deprecated what solution do you suggest instead? Something like this, I think: struct ccharPtr { const char* ptr; alias ptr this; } ccharPtr toStringz2(string s) { return ccharPtr(toStringz(s)); } Bye, bearophile
Re: C callback receives bad pointer argument
Try this: int process (jack_nframes_t nframes, void *arg) -> extern(C) int process (jack_nframes_t nframes, void *arg)
Re: C callback receives bad pointer argument
Marco Cosentino: > Translated correctly the C callback style into D delegates types with alias. D has function pointers too. > Managed some segment faluts happened when not using toStringz() with > some "strings" For this kind of bugs I suggest to use the D type system in a smarter way. With extern you allowed to give what type you want to the C char* arguments, so you are free to use another type. An example: import std.stdio: writeln; import std.string: toStringz; typedef const char* ccharPtr; // example of C function, with smarter string type extern(C) size_t strlen(ccharPtr str); ccharPtr toStringz2(string s) { return cast(ccharPtr)toStringz(s); } void main() { string s1 = "this is "; string s2 = s1 ~ "just a string"; writeln(s2.length); auto cs = toStringz2(s2); writeln(strlen(cs)); } Now that typedef is deprecated what solution do you suggest instead? Bye, bearophile
C callback receives bad pointer argument
Hi, I'm approaching to D2 with writing a wrapper for the popular JACK2 client library. I managed the following troubles: Translated correctly the C callback style into D delegates types with alias. Managed some segment faluts happened when not using toStringz() with some "strings" Managed the multithreaded model of jack using __gsharde for global variables needed in a callback Now I'm in trouble again but this time I can't find a solution without some help. Have a look at this code: // jack.di alias int function(jack_nframes_t nframes, void *arg) JackProcessCallback; int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, void *arg); //simple_client.d int process (jack_nframes_t nframes, void *arg) { stderr.writeln("process() - data:", arg); [...] } int main() { [...] paTestData * data_ptr = &data; stderr.writeln("main() - data:",data_ptr); jack_set_process_callback (client, &process, data_ptr); [...] } Execution gives: main() - data:6B6AE0 process() - data:80 of course when trying to access the real data casting to its original type I get a segmentation fault. I think that part of the problem is that the process() callback runs into a separate thread. What should I try? Thanks, Marco.
Re: r/w binary
On Fri, 01 Jul 2011 05:28:56 +1200, Joel Christensen wrote: > Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some > thing? [0..1] follows the regular slicing syntax there: those are element indexes. Since &i is an int*, [0..1] slices the first int. It would be different if it were ubyte* or void*. Ali
Re: r/w binary
Yes, portability, I hadn't thought of that. Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some thing? - Joel On 30-Jun-11 7:53 PM, Ali Çehreli wrote: On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote: I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's). I would still use a portable text format myself. For binary, you should consider rawWrite() and rawRead(). Here is just a start: import std.stdio; void main() { int i = 42; auto file = File("deleteme.bin", "w"); file.rawWrite((&i)[0..1]); } (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's not necessary.) The parameter to rawWrite() above is a nice feature of D: slicing a raw pointer produces a safe slice: http://digitalmars.com/d/2.0/arrays.html Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays: int* p; int[] b = p[0..8]; For strings (actually arrays), you would need .length and .ptr properties. I've never used it but you might want to consider the serialization library Orange as well: http://www.dsource.org/projects/orange Ali
Re: Forcing compile time evaluation of pure functions
On Thu, 30 Jun 2011 07:11:44 +0200, scarrow wrote: Hey all, I'd like to embed hashed strings into my code. The C++ version of this engine ran an external tool to preprocess the files. In D my strongly pure function is only evaluated if I assign it to something like an enum or invoke it from a template. So the following generate compile time hashes: enum blort = Hash("foo"); f(CHash!("foo")); Annoyingly, however, I can't do the following at compile time: f(Hash("foo")); I'm not sure what the point is in distinguishing between these two cases. If it is a properly pure function there should be no harm in doing a compile time evaluation. Actually, there might. Pure functions are allowed to depend upon the immutable global variables, whose values may be calculated at startup (see static this) -- Simen
Re: Forcing compile time evaluation of pure functions
scarrow: > Annoyingly, however, I can't do the following at compile time: > > f(Hash("foo")); > > I'm not sure what the point is in distinguishing between these two cases. Walter has decided that he doesn't like the D compiler to arbitrary run at compile time arbitrary long to run code. This is named partial compilation and it has some traps. In theory I agree with you that I'd like the compiler to be smarter, but in practice Walter prefers control here, so DMD runs compile-time functions only if you explicitly ask their result to be known at compile-time. Note that in D you are able to run at compile time functions that are pure just in the execution path that's used at compile-time, even if on the whole they are not pure. This works: int x; int foo(bool b, int y) { if (b) return x; else return y; } enum result = foo(false, 10); > I want to be able to write: > > string s = "bar"; > f(Hash("foo"));// invoke the compile time version and pass a constant > to f > f(Hash(s));// invoke the runtime version and pass the result to f Is this good enough? /** To execute a function at compile time. */ template StaticEval(A...) { enum typeof(A[0]) StaticEval = A[0]; } void f(size_t) {} size_t Hash(string s) { return 0U; } void main() { f(Hash("foo")); f(StaticEval!(Hash("foo"))); } The second Hash runs at compile-time, there is only one call to _D4test4HashFAyaZk (compiled with -O -release, without -inline): __Dmain comdat L0: pushEAX pushdword ptr FLAT:_DATA[0Ch] pushdword ptr FLAT:_DATA[08h] callnear ptr _D4test4HashFAyaZk callnear ptr _D4test1fFkZv xor EAX,EAX callnear ptr _D4test1fFkZv xor EAX,EAX pop ECX ret Bye, bearophile
Re: r/w binary
On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote: > I'm thinking more about handling binary files. With the C version I > would write a int for how many letters in the string, then put in the > the string along side ([0005][house]). That way I can have any character > at all (though I just thinking of char's). I would still use a portable text format myself. For binary, you should consider rawWrite() and rawRead(). Here is just a start: import std.stdio; void main() { int i = 42; auto file = File("deleteme.bin", "w"); file.rawWrite((&i)[0..1]); } (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's not necessary.) The parameter to rawWrite() above is a nice feature of D: slicing a raw pointer produces a safe slice: http://digitalmars.com/d/2.0/arrays.html Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays: int* p; int[] b = p[0..8]; For strings (actually arrays), you would need .length and .ptr properties. I've never used it but you might want to consider the serialization library Orange as well: http://www.dsource.org/projects/orange Ali