Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 22:18:59 UTC, tsbockman wrote: Why do you think you need a `void[]` slice? I think `void*` pointers are sufficient. This handles all normal data types, as long as they are allocated on the GC heap: I wanted to have the registry own the structs' memory, though using new makes more sense on second thought. Your example templated implementation makes so much sense, though it doesn't work in this case. Thanks for the idea though. Aye, I'm using hashes. The idea is to support either D interfaces or structs with arbitrary content. You can use TypeInfo references as the keys for the struct types, too. It's better than hashes because the TypeInfo is already being generated anyway, and is guaranteed to be unique, unlike your hashes which could theoretically collide. Makes sense. Using TypeInfo never occurred to me. I assume they are generated for COM classes as well? `I` is *not* the type of an interface instance, it is the type of a reference to an instance of the interface. So `I i` is a reference to the instance, which itself holds a reference to the implementation, like a reference to a delegate (pointer to (ctx, fn))? No. What you are calling "the implementation" is the same thing as "the instance". `I i` is a reference into the interior of the implementing class instance, offset such that it points at the virtual function table pointer for that interface. The lowering is something like this: interface I { ... } class C : I { ... } struct C_Instance { void* __vtblForC; // ... other junk void* __vtblForI; // ... explicit and inherited class fields, if any. } C c = new C; // Works like `C_Instance* c = new C_Instance;` I i = c; // Works like `void** i = (C_Instance.__vtblForI.offsetof + cast(void*) c);` Makes sense, I always thought of them as existing in separate places. So much head-bashing, and it's over. Thanks, tsbockman, Imperatorn.
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 18:14:12 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:57:06 UTC, David Zhang wrote: On Friday, 12 March 2021 at 17:46:22 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:37:43 UTC, David Zhang wrote: [...] Have you tried using Variant or jsvar (https://code.dlang.org/packages/arsd-official%3Ajsvar)? 🤔 It doesn't appear to support interfaces, see opAssign at line 682. It occurs to me that I.sizeof == 8 which is just enough for the vtbl, but not enough for an implementation ptr. Maybe it's a pointer to a {self, vtbl} pair? SomeClass.sizeof == 16, which is enough storage for both... Did you try Variant? Seems to work for me It seems a bit overkill for this. I also want to be able to track memory usage here, and Variant doesn't appear able to store arbitrary-sized structs without untrackable allocations. The idea has merit, but doesn't give me the control I desire :)
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 18:50:26 UTC, tsbockman wrote: The idea is to implement a service locator s.t. code like this is possible: // struct (I didn't mention this in the top post, my mistake) auto log = Logger() api_registry.register!Logger(log); // class/interface auto input = new InputReplay(recorded_input); api_registry.register!InputStream(input); // // somewhere else // // interface auto input = api_registry.get!InputStream(); // do something with input. // struct* api_registry.get!Logger().info(...); // // and additionally // auto input = new KeyboardInput(...); api_registry.replace!InputStream(input); /* Fully qualified names can be *very* long because of templates, so it can be wasteful to store and compare them at runtime. Let's use `TypeInfo` instead: */ Aye, I'm using hashes. The idea is to support either D interfaces or structs with arbitrary content. `I` is *not* the type of an interface instance, it is the type of a reference to an instance of the interface. So `I i` is a reference to the instance, which itself holds a reference to the implementation, like a reference to a delegate (pointer to (ctx, fn))? Thus cast(void*) produces something like *(ctx, fn). I don't mind that. I just want to store that reference as void[], be able to replace with with some other reference to another implementation as void[], then retrieve that as a reference intact. I don't really need to copy or move the class instances here, just be able to read, assign, and replace references to them in the same place that I read, assign, and replace void[]'s of structs.
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 17:46:22 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:37:43 UTC, David Zhang wrote: I want to store interfaces as untyped void[], then cast them back to the interface at a later time. However, it appears to produce garbage values on get(). Is this even possible, and if so, what is happening here? The alternative would be a struct { CheckedPtr self; api_fns } e.g. void register(I)(I i) { auto mem = new void[](I.sizeof); memcpy(mem.ptr, cast(void*) i, I.sizeof); // CheckedPtr includes a hash of fullyQualifiedName map[i.get_name()] = CheckedPtr!I(mem.ptr); } I get(I)() { // basically cast(I) p return map[I.get_name()].as!I(); } Have you tried using Variant or jsvar (https://code.dlang.org/packages/arsd-official%3Ajsvar)? 🤔 It doesn't appear to support interfaces, see opAssign at line 682. It occurs to me that I.sizeof == 8 which is just enough for the vtbl, but not enough for an implementation ptr. Maybe it's a pointer to a {self, vtbl} pair? SomeClass.sizeof == 16, which is enough storage for both...
Storing interfaces as void[]
I want to store interfaces as untyped void[], then cast them back to the interface at a later time. However, it appears to produce garbage values on get(). Is this even possible, and if so, what is happening here? The alternative would be a struct { CheckedPtr self; api_fns } e.g. void register(I)(I i) { auto mem = new void[](I.sizeof); memcpy(mem.ptr, cast(void*) i, I.sizeof); // CheckedPtr includes a hash of fullyQualifiedName map[i.get_name()] = CheckedPtr!I(mem.ptr); } I get(I)() { // basically cast(I) p return map[I.get_name()].as!I(); }
Re: How to create an overwriteable struct that is always const?
Ah, fair enough.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 13:00:50 UTC, ag0aep6g wrote: How is setting/replacing different from modifying? e.g.: S s; this() { s = ...; } update(S s) { this.s = s; } mod(int i) { s.i = i; } // illegal Kinda like how strings can be copied and assigned to, but not modified.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 16:30:12 UTC, Jonathan M Davis wrote: If any member variable of a struct is const, then you can't modify that member ever, and assignment isn't possible unless you override opAssign so that it overwrites only the mutable members. It's very rare that it makes sense to make any member variables of a struct const or immutable, because then you basically can't use assignment anymore. You could make all of the member variables private and provide no functions that set any of them, then the only way to change any of their values would be to construct a new value of that type and assign it to the variable. - Jonathan M Davis Ideally, I'd like for member functions to be checked against modifying s also, not just externally.
How to create an overwriteable struct that is always const?
Say I have a struct `S`: struct S { /*const*/ char* pointer; ... other members ... this(/*const*/ char* p, ... others ...) { pointer = p; ... } } What I want, is to be able to use `S` in other data structures with the following properties checked by the compiler: - The variable can be set - The variable can be read - The variable cannot be modified, only replaced Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. Thanks
Re: Getting a reference to an immutable string
On Saturday, 10 February 2018 at 22:59:18 UTC, ag0aep6g wrote: But there is a recent regression on Windows that might be related. Do you also have a static constructor (`static this`) that uses `wndclassName`? If so, you might be hitting issue 18412. https://issues.dlang.org/show_bug.cgi?id=18412 If you don't have a static constructor, it might be a different bug. In that case, please provide complete code so that we can get to the bottom of it. I have a static constructor that uses wndclassName to register the window class... at the top of the file. I think that's the bug.
Re: Getting a reference to an immutable string
Building with Visual Studio seems to be fine. This isn't an OptLink issue, is it?
Re: Getting a reference to an immutable string
On Saturday, 10 February 2018 at 22:36:41 UTC, ag0aep6g wrote: On 02/10/2018 11:26 PM, David Zhang wrote: I've got an immutable string declared in module scope, and I attempted to get a pointer to its characters through both &str[0] and str.ptr. However, it appears to me that the string is behaving like a manifest constant, in that the pointer is null. The language reference indicates that it has a location in memory and thus has a pointer. So, my question is thus: Is this a bug in DMD, or is this just something I missed? The pointer should not be null, even when `str` is a manifest constant. But without code it's impossible to say if you're hitting a compiler bug or if you're doing something wrong. Ah, yeah. It appears to occur only when compiled in x86 mode. This is what I'm talking about: void createWindow( ... ) { assert( wndclassName.ptr ); //This fails HWND hwnd = CreateWindowW( wndclassName.ptr, //This too null, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, null, null, null, null ); } wstring wndclassName = "wndclass_name"w;
Getting a reference to an immutable string
Hi, I've got an immutable string declared in module scope, and I attempted to get a pointer to its characters through both &str[0] and str.ptr. However, it appears to me that the string is behaving like a manifest constant, in that the pointer is null. The language reference indicates that it has a location in memory and thus has a pointer. So, my question is thus: Is this a bug in DMD, or is this just something I missed? Thanks David
Re: String copying fails when output from assert
On Tuesday, 21 November 2017 at 19:05:21 UTC, Jonathan M Davis wrote: Well, the assertion is going to throw an AssertError, which takes a string for its message. It doesn't copy the contents of the string. It's just taking a slice just like whenever you pass a string to any other function. So, it refers to the same memory as what's passed in. So, if what it's passed is a string that refers to memory on the stack, then when it goes to print the message, it's going to be garbage, because the stack was unwound, and the static array is gone. Honestly, I'd argue that it's a bug that it allows you provide a message as a char[] instead of immutable(char)[]. It seems that the compiler is implicitly converting char[] to immutable(char)[] in this case, which is very bad. It would matter less if you were giving the assertion a char[] that referred to memory on the heap, but it still shouldn't be allowed. You really should be giving assertions a value that is an actual string that lives on the heap when providing a message, not a char[], and definitely not a char[] that's a slice of a static array. - Jonathan M Davis Right. So a literal would work, because it's in the .data segment, or inlined. Basically, only strings from the heap, or that are compiled into the code are valid for assert messages. What kind of behavior would an assert from stdc have (id, betterC)?
Re: String copying fails when output from assert
On Tuesday, 21 November 2017 at 18:56:03 UTC, Adam D. Ruppe wrote: On Tuesday, 21 November 2017 at 18:49:40 UTC, David Zhang wrote: assert(false, chars[0..str.length]); } What am I missing here? You're escaping a reference to a local variable there. chars[] is a pointer to the stack, which is promptly smashed when the assert error starts working up the call chain, so by the time it actually prints, you have undefined behavior. So I'd have to allocate the buffer on the heap then... Is there any way to do this without allocating to the stack?
String copying fails when output from assert
Hi, I've been trying to copy a string, then output it from an `assert(false)` statement, but the copy seems to be corrupted somehow. void main() { string str = "some string"; //initializing `chars` with any value doesn't do anything char[64] chars; //char[64] chars = '!'; //memcpy doesn't work either, though the output's different //import core.stdc.string; //memcpy(&chars[0], &str[0], str.length); chars[0..str.length] = str; assert(false, chars[0..str.length]); } What am I missing here?
Re: @nogc deduction for templated functions
Huh, I think I did something weird. It compiles now, and I don't know why. Thanks for your answers.
@nogc deduction for templated functions
Hi, Is there a way for a templated function to deduce or apply the @safe/@nogc attributes automaticaly? I feel like I remember dmd doing so at one point, but it doesn't appear to work anymore. In particular, I need to call a function belonging to a templated type, but do not know what attributes are applied. eg. void func(T)(T t) { //Don't know if safe or nogc t.someFunc(); } Thanks.
Re: Getting the size of a type tuple
On Thursday, 21 September 2017 at 19:49:14 UTC, ag0aep6g wrote: I don't have a one-liner, but here are some other solutions that might be interesting. None of them is particularly pretty, though. 1) Recursive template: 2) Using the std library: 3) Declaring a packed struct in a function literal that gets immediately called: I think the recursive one looks best, but I agree. None of them look particularly good.
Getting the size of a type tuple
Given the function F, where: F(Args...)(Args args) { ... } How can I statically determine the size of the argument list in bytes? Preferably, I would like a one-liner. However, std.algorithm doesn't seem to support tuples, or `Args.each!(T => T.sizeof).sum` would work. For the moment, I've settled on using a helper function: size_t size(Args...)() { size_t size; foreach(Arg; Args) size += Arg.sizeof; return size; } But it's a bit clunky. Is there a more idiomatic way to do this? Thanks
Re: Propagating constness through function results
Nevermind! I rediscovered the `inout`attribute. Though if I may say so, I have no idea how `inout` is supposed to indicate "whatever the constness of a".
Re: Propagating constness through function results
On Sunday, 17 September 2017 at 21:18:08 UTC, David Zhang wrote: Hi, I have a class `Image`, and I have a function called `getSubImage(Rect bounds)`. What I can't figure out is how to get the result of `getSubImage()` to take on the constness of the backing image. ie. //The Image class is really just a view over a buffer that's managed elsewhere const(Image).getSubImage(...) -> const(Image) Image.getSubImage(...) -> Image I tried to do this with `inout`, but that requires that a parameter in the function be `inout`. I don't suppose I could somehow declare `this` to be inout? Thanks I am aware that you can duplicate the method, but it seems a bit unwieldy and excessive.
Propagating constness through function results
Hi, I have a class `Image`, and I have a function called `getSubImage(Rect bounds)`. What I can't figure out is how to get the result of `getSubImage()` to take on the constness of the backing image. ie. //The Image class is really just a view over a buffer that's managed elsewhere const(Image).getSubImage(...) -> const(Image) Image.getSubImage(...) -> Image I tried to do this with `inout`, but that requires that a parameter in the function be `inout`. I don't suppose I could somehow declare `this` to be inout? Thanks
Re: DLL loading behaviors and pragma(lib)
On Friday, 11 August 2017 at 04:50:48 UTC, rikki cattermole wrote: On 11/08/2017 12:18 AM, David Zhang wrote: I've been working on getting OpenGL to load on windows without a library, and encountered something curious; Context creation fails when I try to use the function pointer retrieved through GetProcAddress, but works just fine with the statically linked version provided through core.sys.windows.wingdi.d. This may be a stupid question, but why is this? Thanks. Odd. Just to confirm your wglGetProcAddress, is extern(Windows/System)? And it is non-null after being loaded? Yes.
DLL loading behaviors and pragma(lib)
I've been working on getting OpenGL to load on windows without a library, and encountered something curious; Context creation fails when I try to use the function pointer retrieved through GetProcAddress, but works just fine with the statically linked version provided through core.sys.windows.wingdi.d. This may be a stupid question, but why is this? Thanks.
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 10:03:58 UTC, Nicholas Wilson wrote: As in the function signature of the function you call `ok` or `error` in. Result!(int, SomeEnum) myfunc(bool foo) { if(!foo) return ok(42); else return error(SomeEnum.fooHappened); } should work. This is what I've got right now. --- [module 1] struct Result(OkType, ErrType) { this(OkType ok) pure nothrow { isOk = true; okPayload = ok; } this(ErrType error) pure nothrow { isOk = false; errorPayload = error; } bool isOk; union { OkType okPayload; ErrType errorPayload; } } auto ok(T, E)(T payload) { return Result!(T, E)(payload); } auto error(T, E)(T payload) { return Result!(T, E)(payload); } --- [module 2] Result!(string, int) fn(bool shouldErr) { if (!shouldErr) return ok("No problem"); return error(0); } --- But it can't infer the second parameter. "template result.ok cannot deduce function from argument types !()(string)"
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 09:37:46 UTC, Nicholas Wilson wrote: On Sunday, 21 May 2017 at 09:29:40 UTC, David Zhang wrote: Well then it becomes Result!(T, E) ok(T,E) (T t) { return Result(t); } Result!(T, E) error(T,E)(E e) { return Result(e); } and then provided it can be inferred (e.g. from the function signature) it will still work. But how would it be inferred? Like the `ok` function, `T` could be inferred, but E? I'm not sure I understand. If you have to specify the types every time, it kinda defeats the purpose. With the function signature as it is, you'd have to specify the type of the other type (e.g. you'd need to specify E for `ok()`).
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 09:15:56 UTC, Nicholas Wilson wrote: have free functions Result!(T, ErrorEnum) ok(T)(T t) { return Result(t); } Result!(T, ErrorEnum) error(T)(ErrorEnum e) { return Result(e); } then go if (!foo) return ok(42); else return error(Error.fooHappened); Ah, I think you misread. ErrorEnum is a template type, like `T`. There's no ErrorEnum enum specified.
Implicit conversion from 'Ok' to 'Result' type when returning functions
Hi, I was reading a bit about this in Rust, and their enum type. I was wondering if this is replicate-able in D. What I've got right now is rather clunky, and involves using `typeof(return).ok` and `typeof(return).error)`. While that's not too bad, it does involve a lot more typing, and thus more area for human error. If you're not familiar with the Result and Option types, it allows you to do something like this: --- Result!(string, ErrorEnum) someFunction(...) { return Ok("Hello!"); } Result!(string, ErrorEnum) someFunction2(...) { return Error(ErrorEnum.dummyError); } --- I'm not entirely sure it's possible... but I figured I might give it a try.
Re: Converting a string[] to char**
On Tuesday, 9 May 2017 at 07:59:19 UTC, Stanislav Blinov wrote: On Tuesday, 9 May 2017 at 07:50:33 UTC, David Zhang wrote: If indeed there is no way to avoid allocation, do the allocations have to remain 'alive' for the duration of the instance? Or can I deallocate immediately afterwards? I can't seem to find it in the Vulkan spec. 2.3.1. Object Lifetime: Application-owned memory is immediately consumed by any Vulkan command it is passed into. The application can alter or free this memory as soon as the commands that consume it have returned. I see, thanks.
Re: Converting a string[] to char**
On Tuesday, 9 May 2017 at 05:52:28 UTC, Mike Parker wrote: On Tuesday, 9 May 2017 at 05:38:24 UTC, ag0aep6g wrote: You have to create a new array of pointers. As rikki cattermole has pointed out, you also have to null-terminate the individual strings, and pass the amount of pointers in a separate parameter. import std.algorithm.iteration: map; import std.array: array; import std.conv: to; import std.string: toStringz; string[] strs = ["foo", "bar", "baz"]; /* convert string[] to char*[]: */ immutable(char)*[] chptrs = strs.map!toStringz.array; immutable(char)** ppEnabledLayerNames = chptrs.ptr; uint enabledLayerCount = chptrs.length.to!uint; Although, if it's known that the array was populated with literals, toStringz isn't needed. String literals are automatically nul terminated. Thanks for all your answers. The strings are all predefined statically for the moment, with a '\0' character at the end. I take from this that there's no way to avoid allocating then? I had hoped... :( If indeed there is no way to avoid allocation, do the allocations have to remain 'alive' for the duration of the instance? Or can I deallocate immediately afterwards? I can't seem to find it in the Vulkan spec.
Converting a string[] to char**
Hi, I'm playing around with Vulkan, and part of its initialization code calls for an array of strings as char**. I've tried casting directly (cast(char**)) and breaking it down into an array of char*s (char*[]) before getting the pointer to its first element (&a[0]). It provides the correct type, but Vulkan rejects it. Is there a standard way of doing this? I'm trying to set the ppEnabledExtensionNames member of VkInstanceCreateInfo. Regards, David
Implementing casting outside of the target struct
Hi, I have two structs and want to cast between them. The cast is generalizable, so I want to keep it outside of the structs themselves (I'll be adding more later). How can I do this? I've tried the following so far: struct Event { EventID id; ubyte[32 - EventID.sizeof] payload; } struct WindowCreateEvent { enum id = EventID.windowCreate; version (Windows) { import core.sys.windows.windows; HWND windowHandle; } } T opCast(T, K)(auto ref K e) { import core.stdc.string: memcpy; auto result = Event(e.id); memcpy(result.payload.ptr, cast(void*) & e, K.sizeof); return result; } The compiler seems to want to convert the two structs bit-by-bit. How can I make it use the module-scoped override? Thanks.
Re: Declaring interfaces with a constructor
On Tuesday, 14 March 2017 at 02:14:53 UTC, evilrat wrote: like this? -- [snip] - there is also way to do this using templates and duck typing, I think it will be more idiomatic way since ranges and stuff heavily use it to provide such generalism, though just like you say, I would prefer to have strict interface for such use case... Yeah, that's the idea. Though I just thought of a possibility using an isPublicInterface template. Is that what you meant by templates and duck typing?
Re: Declaring interfaces with a constructor
On Monday, 13 March 2017 at 17:52:09 UTC, XavierAP wrote: On Monday, 13 March 2017 at 02:15:21 UTC, David Zhang wrote: What it says on the tin. Is there a way to create interfaces with a constructor or must I use an abstract class. What do you want to do in your constructor? I can't think of anything that wouldn't change some state, either of the class (but interfaces aren't allowed to have fields either, precisely because they may not have state), or the global state (worse...). Just curious. Additionally, is there a way to force the linker to link a function in a class without an implementation with another that does have an implementation? I'm not sure if you mean the same as generating "interface files"? [1] https://dlang.org/dmd-windows.html#interface-files Basically, I want to define a common interface for a group of platform-specific classes, except that they should ideally also share constructor parameters. What I want to do is then alias them to a common name, selecting the implementation for the target platform at compile time.
Declaring interfaces with a constructor
What it says on the tin. Is there a way to create interfaces with a constructor or must I use an abstract class. Additionally, is there a way to force the linker to link a function in a class without an implementation with another that does have an implementation? i.e. --- //module a; class Foo { void fun(); } import b: Foo; //module b; class Foo { void fun() { import std.stdio; writeln("!"); } } --- Or something like this? Thanks.
Re: Declaring constant references in struct members
On Thursday, 16 February 2017 at 00:49:45 UTC, Adam D. Ruppe wrote: On Thursday, 16 February 2017 at 00:43:30 UTC, David Zhang wrote: struct S { O object; } import std.typecons; Rebindable!O object; http://dpldocs.info/experimental-docs/std.typecons.Rebindable.html Is there a similar mechanism for one struct holding another? Otherwise, you get a cannot modify X with immutable members error. eg: struct A { B b; } struct B { const size_t something; } A a = A(B(16)); //attempt to replace a.b with new B a.b = B(32); //error: cannot modify struct a.b B with immutable members
Declaring constant references in struct members
Hi, Say I have a struct S that holds a reference to an object O. Is there a way to express that I want to be able to change the reference, but not what the reference points to? Thanks. struct S { O object; } class O { size_t things. }
Re: Creating an array of immutable objects
Thanks for your answers. Out of curiosity though, how could something like this be done with classes instead?
Creating an array of immutable objects
Hi, I have a struct with two immutable members, and I want to make an array of them. How do I to this? I'm using allocators for this. string[] paths; struct FileDesc { immutable string path; immutable uint index; } _fileDesc = /*something*/; You can't use alloc.makeArray because it requires a range with which to initialize the array, and while I can produce an array of paths, I don't know how to merge both a range of paths and indices. Lockstep doesn't work. I also tried using emplace and an allocated byte array, but it gave me random values and was (I think) unnecessarily complicated. What am I missing?
How does cast(SomeObj) (cast(void*) ptrFromC) work?
I was trying to figure out why calling an object's function from a wndProc that modified the object's state didn't actually change anything. Wrapping the GetWindowLongPtr in a cast(void*) seems to make it work. What am I missing about this? I though that object references were really just pointers with special restrictions/behaviors? Old: window = cast(Win32Window) GetWindowLongPtr(hwnd, GWLP_USERDATA); New: window = cast(Win32Window) (cast(void*) GetWindowLongPtr(hwnd, GWLP_USERDATA));
Object function cannot change member when called from callback?
So I have a window (Windows), and my wndProc is basically the same as the one on the windows guides. However, even though WM_CLOSE gets passed (and I can use if(msg == WM_CLOSE)), I can't seem to set my shouldClose flag. I've confirmed that I still get the event within my processMessage method. SO my question is this: what is going on, and how can I make it work? extern (Windows) LRESULT wndProc(HWND hwnd, uint msg, WPARAM wp, LPARAM lp) nothrow { import std.stdio; import std.exception; Win32Window* window; if (msg == WM_NCCREATE) window = setWindowPtr(hwnd, lp); else window = getWindowPtr(hwnd); if (window !is null) return window.processMessage(msg, wp, lp); else return DefWindowProc(hwnd, msg, wp, lp); } Window { //--- other stuff ---// LRESULT processMessage(uint msg, WPARAM wp, LPARAM lp) nothrow { switch (msg) { case WM_CLOSE: _shouldClose = true; //tests as true here, but has no effect after method exits assumeWontThrow(writeln("close request received")); //this works return 0; default: return DefWindowProc(_hwnd, msg, wp, lp); } } } Sidenote, I can't build this with ldc2 for some reason: "cannot open input file 'kernel32.lib'". dmd seems to work just fine.
Re: Accessing a function within an object's superclass from the outside
On Saturday, 14 January 2017 at 22:17:23 UTC, ketmar wrote: class ClassB: ClassA { alias fun = super.fun; override void fun(uint a) {} } I tried that, but it seems to think I mean to override super.fun(uint) instead of super.fun(uint, float). Looking at my code again, one of them is templated with a range interface. I think that might be the problem, though I can't figure out how to fix it. Wrapping the alias in a template block doesn't seem to do it.
Accessing a function within an object's superclass from the outside
Hello, Say I have a class, and it overrides a function from its superclass. However, the superclass has two overloaded versions of the same function. My intent is to override only one of the functions, but the second is rendered inaccessible from outside of the class. How can I make the overloaded function visible? ie: class ClassA { void fun(uint a) {} void fun(uint a, float b) {} } class ClassB: ClassA { void fun(uint a) {} } ca.fun(a); //ok ca.fun(a, b);//ok cb.fun(a); //ok cb.fun(a, b);//function fun not callable with uint and float I seem to remember something about using aliases to fix this, but I can't find anything about it either way.
Re: Unittest hangs on completion
On Saturday, 31 December 2016 at 02:36:01 UTC, rikki cattermole wrote: No, my understand is thus: next = current.next; theAllocator.dispose(current); When current is deallocated, current is pointing to free'd memory. After that point it should be segfaulting when you try to access it *I think*. Huh, alright. I see what you mean. I'll keep this in mind.
Re: Unittest hangs on completion
On Saturday, 31 December 2016 at 02:03:07 UTC, rikki cattermole wrote: As it should, current is never reassigned. You only need one var, next. Of course I didn't read the entire thread chain so, I'm probably missing something. import std.experimental.allocator; void main() { struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next; next = _foo; while(next !is null) { auto nextT = next.next; theAllocator.dispose(next); next = nextT; } } Thanks for your response. So next is never null, and thus there is an infinite loop, correct? If so, why does dub indicate that all tests are complete?
Re: Unittest hangs on completion
Extracting everything into a main() also causes the application to hang. ie: struct S { S* next; } S* _foo; foreach (e; 0 .. 10) _foo = theAllocator.make!S(_foo); S* next, current; next = current = _foo; while (next) { next = current.next; theAllocator.dispose(current); }
Re: Unittest hangs on completion
On Friday, 30 December 2016 at 22:42:07 UTC, Steven Schveighoffer wrote: What is actually happening is that the D main function returns. Then the D runtime tears down everything, including joining all threads, running all module static dtors, terminating the GC, etc. Then it returns to the OS the exit code. So it's likely somewhere in there that it's hanging. -Steve I've tried manually reducing the code to find the problem. This is what I've got. I'm not sure how to reduce it further. class Foo { ~this() { S* next, current; next = current = _foo; while (next) { next = current.next; theAllocator.dispose(current); } } void insert(Range)(Range range) { foreach (e; range) _foo = theAllocator.make!S(_foo); } S* _foo; struct S { S* next; } } unittest { auto list = new Foo(); list.insert([1, 2, 3, 4]); }
Re: Unittest hangs on completion
On Friday, 30 December 2016 at 20:59:30 UTC, Seb wrote: On Friday, 30 December 2016 at 18:03:44 UTC, David Zhang wrote: On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote: [snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -Steve So, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not. Dustmite (https://github.com/CyberShadow/DustMite) is your friend! Specifically with a timeout command (e.g. https://github.com/CyberShadow/DustMite/wiki/Running-commands-with-a-timeout) and checking whether your reduced code is still timing out (exit code of timeout is 124). If you set it to sth. reasonable (e.g. 10s) and use multiple threads (e.g. -j32) it shouldn't take that long to have a reduced code example. There wouldn't happen to be an alternative on windows without installing cygwin would there? I don't have access to a linux machine at the moment. @Steven, the process hangs after the "All unit tests have been successfully", after which the process is supposed to exit immediately. -- Running .\bin\__test__library__.exe All unit tests have been run successfully. ^C --
Re: Unittest hangs on completion
On Friday, 30 December 2016 at 14:12:35 UTC, Steven Schveighoffer wrote: [snip] It depends on what is actually hanging the process. If it's something in your code base only, then nobody else would be seeing it. -Steve So, what should I do with it? I'd submit a bug report, but I don't know how to isolate the bug, and thus where to submit it. Really, I'd just be happy knowing if it's my code or not.
Re: Unittest hangs on completion
On Friday, 30 December 2016 at 01:25:50 UTC, Steven Schveighoffer wrote: Looks like that comes from here: https://github.com/dlang/dub/blob/master/source/dub/dub.d#L577 I have serious doubts that this is the correct way to run tests, as share ctors are supposed to have run BEFORE unit tests are allowed to. It's quite possible (and likely) that unit tests are running before critical other shared ctors have completed, which is why something isn't working. In any case, it looks like the unit tests have run, and run successfully, and then main has run, and then it's the teardown of the runtime that's hanging. I'm not 100% certain, because I don't know exactly how this code comes into play -- it's a string in this file. -Steve Huh, shouldn't this problem have manifested itself earlier then? Why only now? I don't remember this happening previously. At the very least I'm pretty sure I first encountered it last week. Unless something in DMD was patched? But then there'd be no way I'm the only one encountering this problem, and there don't appear to be any issues on github's tracker.
Re: Unittest hangs on completion
On Friday, 30 December 2016 at 00:44:50 UTC, Steven Schveighoffer wrote: Where does the "All unit tests have been completed successfully." message come from? That's not standard D, which prints nothing. -Steve I should have mentioned that I use dub then, shouldn't I? Anyway, this is what I get: C:\Users\David\Projects\weave>dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86. weave ~master: building configuration "__test__library__"... Linking... Running .\bin\__test__library__.exe All unit tests have been run successfully.
Re: Unittest hangs on completion
On Thursday, 29 December 2016 at 20:50:54 UTC, David Zhang wrote: On Thursday, 29 December 2016 at 20:33:33 UTC, Stefan Koch wrote: It would be very helpful if you could provide example code that triggers that behavior. I'd love to, but I'm not actually sure just what it is that breaks it. I can provide the git repo for one of them though though: https://gitlab.com/Straivers/Weave https://gitlab.com/Straivers/Weave.git Ok, so after further fiddling, it seems to originate from here: [from the list class] @safe unittest { class A { int foo; } auto list = new List!A(); list ~= [new A, new A, new A]; assert(list.findElement(null).result == null); } However, commenting it out, and replacing it with another block (the test immediately below it, causes it to hang too, or error out and crash without any error message.
Re: Unittest hangs on completion
On Thursday, 29 December 2016 at 20:33:33 UTC, Stefan Koch wrote: It would be very helpful if you could provide example code that triggers that behavior. I'd love to, but I'm not actually sure just what it is that breaks it. I can provide the git repo for one of them though though: https://gitlab.com/Straivers/Weave https://gitlab.com/Straivers/Weave.git
Unittest hangs on completion
Hi, I've noticed recently, that whenever I unittest, it program hangs either at the very end, or right before they start. When using vanilla unit tests, the program appears to hang after the "All unit tests have been completed successfully." message, and I have to force to program to exit. However, when I use unit-threaded for my unit testing, it gets to the "Running unit tests in dirs ["."]" and then refuses to do anything more. Strangely enough, sometimes commenting out one or two tests seems to fix the issue with unit-threaded, only to resurface when I write a new test. Just what is going on?
Re: Allocating a class within another class during object init w/o passing in an allocator
I haven't considered alignment here. I'm not sure if you have to. I though all classes were aligned to sizeof(size_t) boundaries? Wouldn't it then just be align(sizeof(size_t)) byte[__traits(classInstanceSize, SomeClass)] scStorage;
Re: Allocating a class within another class during object init w/o passing in an allocator
On Thursday, 15 December 2016 at 21:08:51 UTC, ag0aep6g wrote: On 12/15/2016 09:51 PM, David Zhang wrote: However, it leaves me with another question, how much (if any) space would the static array require from the class? Depends on SomeClass. The array's size is just the value of __traits(classInstanceSize, SomeClass). There's no overhead. You can print such stuff at compile time with pragma(msg, ...): pragma(msg, __traits(classInstanceSize, SomeClass)); pragma(msg, Foo.scStorage.sizeof); /* same */ So the size of Foo would be the size of SomeClass plus members? ie. Is the size of the array stored too?
Re: Allocating a class within another class during object init w/o passing in an allocator
Thank you for your responses. Visitor, I don't want any reference to an allocator within the class if I can avoid it. ag0aep6g, thanks! That's what I was looking for. However, it leaves me with another question, how much (if any) space would the static array require from the class? It's not a strict necessity for me, but I'm curious.
Allocating a class within another class during object init w/o passing in an allocator
Hello, It is my understanding that a class can have a struct as one of its members, and it will be allocated in-line with the rest of the class' members. My question is this; how might I be able to do this with another class? I want to be able to allocate Foo using std.experimental.allocator without having to pass in a reference to the actual allocator. Thanks. eg: class SomeClass {} class Foo { this(IAllocator alloc) { sc = alloc.make!SomeClass; this.alloc = alloc } ~this() { alloc.dispose(sc); } size_t something; SomeClass sc; IAllocator alloc } auto foo = alloc.make!Foo(alloc); vs. struct SomeStruct {} class Foo { this() { ss = SomeStruct (...); } size_t something; SomeStruct ss; } auto foo = alloc.make!Foo;