Re: Selected elements from splitter output
On Tuesday, 4 May 2021 at 22:02:11 UTC, Ali Çehreli wrote: On 5/4/21 1:40 PM, Chris Piker wrote: > I only care about columns 0, 2, 3, 4, 8, 9, 10. That's std.range.stride. > char[][] wanted = string_range.get( [1, 5, 7] ); // pseudo-code element That's std.range.indexed. Hey Thanks! And even more, thanks for the book. It's very well organized. I keep a paper copy of "Programming in D" open on my desk all the time these days. Looking forward to getting a few copies for work once we're back in the office.
Re: Pointer indirections
On 5/4/21 3:06 PM, Imperatorn wrote: >> Is there any limitation as to the number of pointer indirections? No. >> I have a construct: >>a.b.c.d = x; >> where all the variables are pointers to struct (the same struct). >> >> This fails with 'Access Violation', >> but if I change the code to: >> >> temp = a.b.c; >> temp.d = x; >> >> everything seems to work. Sounds like "undefined behavior" somewhere in the program, effects of which can be confusing. Ali
Re: Pointer indirections
On Tuesday, 4 May 2021 at 21:16:10 UTC, DLearner wrote: Hi Is there any limitation as to the number of pointer indirections? I have a construct: a.b.c.d = x; where all the variables are pointers to struct (the same struct). This fails with 'Access Violation', but if I change the code to: temp = a.b.c; temp.d = x; everything seems to work. Best regards Code or it didn't happen 🌞
Re: Selected elements from splitter output
On 5/4/21 3:02 PM, Ali Çehreli wrote: >// Note: The above works only because 'stride' applies >// "design by introspection" (DbI) and is able to work as a >// RandomAccessRanges. Ok, I was too enthusiastic there. The RandomAccessRange'ness of the input range changes how efficient stride() works but we can't say DbI is used there. Ali
Re: Selected elements from splitter output
On 5/4/21 1:40 PM, Chris Piker wrote: > I only care about columns 0, 2, 3, 4, 8, 9, 10. That's std.range.stride. > char[][] wanted = string_range.get( [1, 5, 7] ); // pseudo-code element That's std.range.indexed. import std.range; import std.stdio; void main() { auto r = 10.iota.stride(2); writeln(r); writeln(r.indexed([1, 3])); // Note: The above works only because 'stride' applies // "design by introspection" (DbI) and is able to work as a // RandomAccessRanges. Not every range can do that; so, in a more // general case, you would have to turn your range to a // RandomAccessRange by calling std.array.array first: auto r2 = r.array; // The following can work with any InputRange only after doing that. writeln(r2.indexed([1, 3])); } Ali
Pointer indirections
Hi Is there any limitation as to the number of pointer indirections? I have a construct: a.b.c.d = x; where all the variables are pointers to struct (the same struct). This fails with 'Access Violation', but if I change the code to: temp = a.b.c; temp.d = x; everything seems to work. Best regards
Selected elements from splitter output
Hi D I have a white-space delimited file with quite a few columns, but I only care about columns 0, 2, 3, 4, 8, 9, 10. Since I don't need most of the 60+ columns it seemed like: std.algorithm.iteration.splitter() would be a better function to use then std.array.split(). My problem is that I don't know how to get the elements I care about from the splitter, for example: char[] line; char[][] cols_needed; while(file.readln(line)){ auto a = line.splitter() cols_needed = ??? } On a related note, are there any standard library functions that select specific elements of a range by index without a loop? So the logical equivalent of: auto string_range char[][] wanted = string_range.get( [1, 5, 7] ); // pseudo-code element selection It's not a big deal if there's not something standard. Thanks for the help,
Re: Should this always work?
On Tuesday, 4 May 2021 at 14:18:30 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 4 May 2021 at 13:58:59 UTC, Steven Schveighoffer wrote: Yeah, I wasn't aware of the more general usage, I thought it was always a pointer adjustment. But I also am not steeped in the terminology, just parroting what I've heard. My understanding is that a thunk is the code object that fetches the value for you, in this case there might not be a thunk involved as the interface code can just apply a fixed offset? I guess in D terms it can be best explained as a compiler internal "delegate". Let's take the example of getting the this-pointer: Say, you want to write generic code gen, then you can let that code gen take a "delegate" that computes a this-pointer rather than writing many different code gens for different layouts. Then you trust the optimizer to get rid of it, or keep it if need be. That delegate would be a thunk. It may or may not exist at run-time based on the optimizer/language semantics. You could also do something similar with an offset or switch statement. The point is, the code gen have no idea of how to obtain the this-pointer, the thunk does. It is a separate external code piece that obtains the value of the this-pointer.
Re: Should this always work?
On Tuesday, 4 May 2021 at 13:58:59 UTC, Steven Schveighoffer wrote: Yeah, I wasn't aware of the more general usage, I thought it was always a pointer adjustment. But I also am not steeped in the terminology, just parroting what I've heard. My understanding is that a thunk is the code object that fetches the value for you, in this case there might not be a thunk involved as the interface code can just apply a fixed offset?
Re: Should this always work?
On 5/4/21 6:03 AM, Ola Fosheim Grøstad wrote: On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote: On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote: On Saturday, 1 May 2021 at 04:55:10 UTC, frame wrote: I always thought as long as an object implements an interface, it should be able to cast it from a void* if it really points to a supporting object. No. An interface is like a pointer to a pointer. Can you elaborate on this one? I don't really get it. Is an object handle also like a pointer to a pointer? (I feel like I can learn something here.) Off the top of my head the object layout is something like this: { pointer to vtable0 for the class; monitor mutex stuff; pointer to interface 1 vtable1; pointer to interface 2 vtable2; ... pointer to interface N vtableN; object data 1; object data 2; ... } A pointer to interface 1 is a pointer to the pointer to vtable1 in the object above. Yes, this is exactly how it is. See the ABI document: https://dlang.org/spec/abi.html#classes So a class reference is *also* a pointer to a pointer (to the vtable), and a interface reference is the same. However, the slight difference is, the pointer to the interface doesn't allow useful mechanisms until you apply the offset (necessitating a double indirection), whereas a class pointer (combined with compile-time type knowledge) the compiler can access member fields of the class. -Steve
Re: Should this always work?
On 5/4/21 9:21 AM, Paul Backus wrote: On Tuesday, 4 May 2021 at 10:21:42 UTC, Ola Fosheim Grøstad wrote: On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer wrote: An interface cast involves a thunk (constant pointer adjustment) to get to the interface/object Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ? The article literally gives this exact use-case as an example: https://en.wikipedia.org/wiki/Thunk#Object-oriented_programming Yeah, I wasn't aware of the more general usage, I thought it was always a pointer adjustment. But I also am not steeped in the terminology, just parroting what I've heard. -Steve
Re: Should this always work?
On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote: On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote: No. An interface is like a pointer to a pointer. Can you elaborate on this one? I don't really get it. Is an object handle also like a pointer to a pointer? (I feel like I can learn something here.) So I have no deep knowledge of the implementation details. I only know that a class reference is a pointer under the hood, so it can be cast to `void*` and back, and that an interface reference has an extra level of indirection, so it can go to `void**` and back.
Re: Should this always work?
On Tuesday, 4 May 2021 at 10:21:42 UTC, Ola Fosheim Grøstad wrote: On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer wrote: An interface cast involves a thunk (constant pointer adjustment) to get to the interface/object Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ? The article literally gives this exact use-case as an example: https://en.wikipedia.org/wiki/Thunk#Object-oriented_programming
Re: How to automatically generate function overloads
On Tuesday, 4 May 2021 at 11:21:20 UTC, Zone wrote: ```D template Vectorize_Unary_Function(alias fun) { float[N] Vectorize_Unary_Function(size_t N)(float[N] vec) { float[N] result; static foreach (i; 0 .. N) result[i] = fun(vec[i]); return result; } } alias clamp01 = Vectorize_Unary_Function!clamp01; ``` Not exactly what you were asking for but I hope it works, tricky part is I'm not sure how to generate the function name without string mixins so that's why I used alias instead. Awesome, this does exactly what I wanted. Thanks for the help! :)
Re: How to automatically generate function overloads
On Tuesday, 4 May 2021 at 11:00:42 UTC, Blatnik wrote: I'm porting over my linear algebra library from C++, and I have a bunch of functions that work on both scalars and vectors. The vector versions just apply the scalar function to every element of the vector, for example: ```D float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); } float[N] clamp01(size_t N)(float[N] vec) { float[N] result; static foreach (i; 0 .. N) result[i] = clamp01(vec[i]); return result; } ``` And this is great, I don't have to write the same function for different array lengths. But I still have like 30-ish of these functions and I would like to generate the array overload automatically from the scalar overload. So I would like something like a mixin, that I can use like this: ```D mixin Vectorize_Unary_Function!clamp01; // Generates the code above. mixin Vectorize_Unary_Function!floor; mixin Vectorize_Unary_Function!ceil; ... ``` It doesn't have to be a mixin like this. I don't really care what it is as long as it works :) How could I do this? ```D float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); } template Vectorize_Unary_Function(alias fun) { float[N] Vectorize_Unary_Function(size_t N)(float[N] vec) { float[N] result; static foreach (i; 0 .. N) result[i] = fun(vec[i]); return result; } } alias clamp01 = Vectorize_Unary_Function!clamp01; void main() { float[5] vec = [1,2,3,4,5]; float[5] other = clamp01(vec); writeln(vec); writeln(other); } ``` Not exactly what you were asking for but I hope it works, tricky part is I'm not sure how to generate the function name without string mixins so that's why I used alias instead.
Re: How to automatically generate function overloads
On Tuesday, 4 May 2021 at 11:00:42 UTC, Blatnik wrote: How could I do this? I've already tried this: ```D mixin template Vectorize_Unary_Function(alias Function) { float[N] Function(size_t N)(float[N] vec) { float[N] result; static foreach (i; 0 .. N) result[i] = Function(vec[i]); return result; } } ``` But it didn't work. ```D mixin Vectorize_Unary_Function!clamp01; float[2] vec = [1, 2]; float[2] clamped = clamp01(vec); // Error ``` I think it actually declared a function called "Function" instead of calling it "clamp01" like the alias I passed in.
How to automatically generate function overloads
I'm porting over my linear algebra library from C++, and I have a bunch of functions that work on both scalars and vectors. The vector versions just apply the scalar function to every element of the vector, for example: ```D float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); } float[N] clamp01(size_t N)(float[N] vec) { float[N] result; static foreach (i; 0 .. N) result[i] = clamp01(vec[i]); return result; } ``` And this is great, I don't have to write the same function for different array lengths. But I still have like 30-ish of these functions and I would like to generate the array overload automatically from the scalar overload. So I would like something like a mixin, that I can use like this: ```D mixin Vectorize_Unary_Function!clamp01; // Generates the code above. mixin Vectorize_Unary_Function!floor; mixin Vectorize_Unary_Function!ceil; ... ``` It doesn't have to be a mixin like this. I don't really care what it is as long as it works :) How could I do this?
Re: Should this always work?
On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer wrote: An interface cast involves a thunk (constant pointer adjustment) to get to the interface/object Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ?
Re: Should this always work?
On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote: On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote: On Saturday, 1 May 2021 at 04:55:10 UTC, frame wrote: I always thought as long as an object implements an interface, it should be able to cast it from a void* if it really points to a supporting object. No. An interface is like a pointer to a pointer. Can you elaborate on this one? I don't really get it. Is an object handle also like a pointer to a pointer? (I feel like I can learn something here.) Off the top of my head the object layout is something like this: { pointer to vtable0 for the class; monitor mutex stuff; pointer to interface 1 vtable1; pointer to interface 2 vtable2; ... pointer to interface N vtableN; object data 1; object data 2; ... } A pointer to interface 1 is a pointer to the pointer to vtable1 in the object above.