Re: Load D shared library on windows x64
On Saturday, 18 August 2018 at 21:10:55 UTC, Tofu Ninja wrote: On Saturday, 18 August 2018 at 11:27:29 UTC, Mike Wey wrote: On 18-08-18 02:31, Tofu Ninja wrote: On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote: Its this part that fails... always returns null HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName); if (h is null) { writeln("error loading"); return; } I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful. You can probably use: core.sys.windows.winbase.GetLastError That was helpful, error is: ERROR_DLL_INIT_FAILED 1114 (0x45A) A dynamic link library (DLL) initialization routine failed. Thank you this helped lead me to the real error. The problem was here writeln("DLL_PROCESS_ATTACH"); Runtime.initialize(); Cant use writeln before Runtime.initialize
Re: Load D shared library on windows x64
On Saturday, 18 August 2018 at 11:27:29 UTC, Mike Wey wrote: On 18-08-18 02:31, Tofu Ninja wrote: On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote: Its this part that fails... always returns null HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName); if (h is null) { writeln("error loading"); return; } I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful. You can probably use: core.sys.windows.winbase.GetLastError That was helpful, error is: ERROR_DLL_INIT_FAILED 1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
Re: Load D shared library on windows x64
On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote: Its this part that fails... always returns null HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName); if (h is null) { writeln("error loading"); return; } I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
Re: Load D shared library on windows x64
Its this part that fails... always returns null HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName); if (h is null) { writeln("error loading"); return; }
Load D shared library on windows x64
Do shared libraries work? I am trying to load a D library into a D program but Runtime.loadLibrary just returns null for me and I am not sure what I am doing wrong. import std.stdio; import std.file : exists, getcwd, rename; import core.thread; import std.conv : to; version(tofu_dynamic){ import core.sys.windows.windows; import core.runtime; pragma(msg, "Dynamic Link Library"); HINSTANCE g_hInst; export extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) { switch (ulReason) { case DLL_PROCESS_ATTACH: writeln("DLL_PROCESS_ATTACH"); Runtime.initialize(); break; case DLL_PROCESS_DETACH: writeln("DLL_PROCESS_DETACH"); Runtime.terminate(); break; case DLL_THREAD_ATTACH: writeln("DLL_THREAD_ATTACH"); return false; case DLL_THREAD_DETACH: writeln("DLL_THREAD_DETACH"); return false; default: } g_hInst = hInstance; return true; } pragma(mangle, "rti_start") export void rti_start(){ writeln("rti start :)"); } } else { void main(string[] args) { uint id = 0; while(true) { if(exists("graph.dll")){ auto name = "rti." ~ id.to!string ~ ".dll"; rename("graph.dll", name); id++; loadLib(name); } Thread.sleep(dur!("seconds")(1)); } } static void loadLib(string dllName) { import core.sys.windows.windows; import core.runtime; Thread.sleep(dur!("seconds")(1)); writeln("Start Dynamic Link to ", dllName, "..."); HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName); if (h is null) { writeln("error loading"); return; } scope(exit){ if (!Runtime.unloadLibrary(h)) writeln("error freeing dll"); } FARPROC fp = GetProcAddress(h, "rti_start"); if (fp is null) { writeln("error loading symbol rti_start"); return; } auto fun = cast(void function()) fp; fun(); writeln("End..."); } }
isFuture
What is __traits(isFuture)? The language documents says it tests for @future which doesn't really help as @future is undocumented.
Re: TypeInfo_Class.interfaces has TypeInfo_Class and not TypeInfo_Interface?
On Friday, 15 December 2017 at 05:19:04 UTC, Tofu Ninja wrote: TypeInfo_Class.interfaces has TypeInfo_Class and not TypeInfo_Interface? Is this correct? Or is it a bug? Doesn't make much sense to me. Also the following code prints false so there are some consequences to this. import std.stdio; void main(string[] args) { writeln(typeid(c).interfaces[0].classinfo == typeid(i)); } interface i {} class c : i {}
TypeInfo_Class.interfaces has TypeInfo_Class and not TypeInfo_Interface?
TypeInfo_Class.interfaces has TypeInfo_Class and not TypeInfo_Interface? Is this correct? Or is it a bug? Doesn't make much sense to me.
Re: Open Scene Graph For D?
On Thursday, 7 December 2017 at 19:30:13 UTC, Tofu ninja wrote: Is there a binding for it? Just a question, trying to convince people at work to use D and that is something they asked about. Guess not
Open Scene Graph For D?
Is there a binding for it? Just a question, trying to convince people at work to use D and that is something they asked about.
Re: Debugging shared libs on windows
On Wednesday, 6 December 2017 at 22:59:17 UTC, user1234 wrote: On Wednesday, 6 December 2017 at 21:17:55 UTC, Tofu ninja wrote: On Wednesday, 6 December 2017 at 21:12:20 UTC, Tofu ninja wrote: I am compiling with -m64 -shared -debug -g and a .pdb is generated but visual studio says the dll was not compiled with debug information, am I missing something or is this not supported? DMD32 D Compiler v2.076.0 Actually never mind, -gf worked what is -gf ? it's not documented here https://dlang.org/dmd-windows.html#switches dmd has this in the help -gf emit debug info for all referenced types I dont know why that made it work, I feel like -g should have still made it at least recognizable for a debugger but it didn't think it was compiled with debug info. My suspicion is it compiled debug info for the import .lib but not for the DLL itself and -gf forced it to do the dll too. But I haven't confirmed that.
Re: Debugging shared libs on windows
On Wednesday, 6 December 2017 at 21:12:20 UTC, Tofu ninja wrote: I am compiling with -m64 -shared -debug -g and a .pdb is generated but visual studio says the dll was not compiled with debug information, am I missing something or is this not supported? DMD32 D Compiler v2.076.0 Actually never mind, -gf worked
Debugging shared libs on windows
I am compiling with -m64 -shared -debug -g and a .pdb is generated but visual studio says the dll was not compiled with debug information, am I missing something or is this not supported? DMD32 D Compiler v2.076.0
Re: Windows X64 Calling conventions
On Thursday, 20 April 2017 at 08:36:32 UTC, kinke wrote: On Thursday, 20 April 2017 at 01:16:11 UTC, Tofu Ninja wrote: My question is, why is it passed twice, both in xmm0 and rcx? The MSDN docs say floating point are passed in xmm registers, why is it also copied in into rcx? Is it necessary for anything? That is only required for variadics, quoting MSDN [https://msdn.microsoft.com/en-us/library/dd2wa36c.aspx]: For floating-point values only, both the integer and the floating-point register will contain the float value in case the callee expects the value in the integer registers. Oh thanks, that answers my question, but it seem odd that dmd does it no matter what even when variadics are not used.
Windows X64 Calling conventions
I am trying to learn the calling conventions in DMD, I am sure I will have more than one question about them so as I come across them I will ask them in this thread. I am mainly reading the MSDN docs on the x64 calls and looking at disassemblies to confirm what I learn. While I was looking at a call of the form void foo(float), I get the following disassembly: movss xmm0,dword ptr [_TMP0] sub rsp,20h movdrcx,xmm0 callvoid main.foo(float) add rsp,20h My question is, why is it passed twice, both in xmm0 and rcx? The MSDN docs say floating point are passed in xmm registers, why is it also copied in into rcx? Is it necessary for anything? If it was skipped would anything break? Thanks
Get method address from alias?
I only have an alias to the method without a this pointer, is there any way to get the address? Something like struct T{ void foo(){} } alias A = Alias!(__traits(getMemeber, T, "foo")); void* A_addres = ? // Somehow get the address from A
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 19:01:41 UTC, Tofu Ninja wrote: Actually.. if I do dub describe on the root package it lists both the exe and the lib as targets but the build settings for the lib has "targetType": 6 which according to dub/source/dub/compilers/buildsettings.d is staticLibrary... is this a bug or what? omfg I should have read the build output more closely...right at the top "Dynamic libraries are not yet supported as dependencies - building as static library."... welp guess I give up then, 4 days waisted.
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:26:27 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this... This [https://github.com/dlang/dub/issues/665] seems to be somewhat related to what I am trying to do, not sure if this got addressed at all though. Actually.. if I do dub describe on the root package it lists both the exe and the lib as targets but the build settings for the lib has "targetType": 6 which according to dub/source/dub/compilers/buildsettings.d is staticLibrary... is this a bug or what?
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:10:12 UTC, Tofu Ninja wrote: On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this... This [https://github.com/dlang/dub/issues/665] seems to be somewhat related to what I am trying to do, not sure if this got addressed at all though.
Re: dub subpackage output to shared lib not working
On Thursday, 26 January 2017 at 18:00:57 UTC, Tofu Ninja wrote: Is this not doable? I guess an alternative question, is there any way to have multiple binaries(an executable and a bunch of shared libs) built from a single dub package? Or should I just give up on trying to use dub for this...
Re: dub subpackage output to shared lib not working
On Sunday, 22 January 2017 at 08:16:49 UTC, Tofu Ninja wrote: Trying to get a dub sub package to output as a shared lib but for some reason I can only get it to output as a static lib. dub.json --- { "name": "tofueng", "targetType": "executable", "targetPath" : "game", "sourcePaths": ["eng"], "importPaths": ["eng"], "dependencies": { "tofueng:test": "*", }, "subPackages": [ { "name": "test", "targetType": "dynamicLibrary", "targetPath" : "game/libs", "sourcePaths": ["com/test"], "importPaths": ["com/test"] } ] } --- Get tofueng_test.lib instead of tofueng_test.dll. If I try to build the sub package directly it builds the dll. What am I doing wrong? Is this not doable?
dub subpackage output to shared lib not working
Trying to get a dub sub package to output as a shared lib but for some reason I can only get it to output as a static lib. dub.json --- { "name": "tofueng", "targetType": "executable", "targetPath" : "game", "sourcePaths": ["eng"], "importPaths": ["eng"], "dependencies": { "tofueng:test": "*", }, "subPackages": [ { "name": "test", "targetType": "dynamicLibrary", "targetPath" : "game/libs", "sourcePaths": ["com/test"], "importPaths": ["com/test"] } ] } --- Get tofueng_test.lib instead of tofueng_test.dll. If I try to build the sub package directly it builds the dll. What am I doing wrong?
Re: Proper generic way to get the hash of something?
Well for now I am going to revert back to 2.071.2, 2.072 seems broke as fuck.
Re: Proper generic way to get the hash of something?
Actually better question, why was this breaking change allowed? The semantics of hashOf have completely changed, why was this done??
Proper generic way to get the hash of something?
What is the proper generic way to get the hash of something? It seems that hashOf has been changed to no longer call toHash on anything Just blindly casts to void[]. It actually seems now toHash doesn't call any of the specializations of core.internal.hash.hashOf except the one for void[]. The change seems pretty dumb and broke my code, not sure why it was done, the breakage is not in the change log :/. So what is the proper way to get the hash of something now?
Re: Given two AliasSeq (A and B) and template T, how to make AliasSeq!(T!(A[0], B[0]) ... T!(A[n], B[n])) ?
On Sunday, 27 November 2016 at 07:38:53 UTC, Nicholas Wilson wrote: Whoops it would help if I read your question. You want to use Iota in conjunction with staticMap. alias pairs(int N, alias a, alias b) = AliasSeq(a[N],b[N]); alias C = staticMap!(T,staticMap(pairs,Iota!N)); That didn't actually work, but I got it working with: alias pairs(size_t n) = T!(A[n], B[n]); alias C = staticMap!(pairs, Iota!(A.length));
Given two AliasSeq (A and B) and template T, how to make AliasSeq!(T!(A[0], B[0]) ... T!(A[n], B[n])) ?
Basically the title says it all. alias A = AliasSeq!(...); alias B = AliasSeq!(...); static assert(A.length == B.length); template T(An, Bn){ ... } alias C = AliasSeq!(T!(A[0], B[0]) ... T!(A[n], B[n])); // how to make this :/ How do I actually make the sequence C?
Re: How to declare function with the same call signature as another?
On Thursday, 24 November 2016 at 02:11:21 UTC, ketmar wrote: On Thursday, 24 November 2016 at 00:51:01 UTC, Tofu Ninja wrote: Even with std.traits, you can't know which arguments are variadic. sure, you can. see http://dpldocs.info/experimental-docs/std.traits.variadicFunctionStyle.html that will return variadic style. and the only argument that can be variadic is last. it is enough to reconstruct the signature. Oh well that is my bad, for some reason I was under the impression that there could be more than one typesafe variadic. Still I think the way all of this currently works is very misleading, certainly there is lots of code out there trying to replicate call signatures but are doing it wrong. Having Parameters!(fun) capture things like ref is only going to mislead people(like me!) into thinking it is enough.
Re: How to declare function with the same call signature as another?
On Thursday, 24 November 2016 at 00:36:54 UTC, ketmar wrote: On Thursday, 24 November 2016 at 00:19:04 UTC, Tofu Ninja wrote: You still can't replicate a function with this. you can, by using std.traits and string mixins. Even with std.traits, you can't know which arguments are variadic. The only way to actually replicate a function is with string mixins and parsing the stringof of the function you want to replicate. This (ref int) thing does not help one bit and will only trick people into thinking they are properly replicating the call signature when they are not.
Re: How to declare function with the same call signature as another?
On Thursday, 24 November 2016 at 00:15:07 UTC, ketmar wrote: On Thursday, 24 November 2016 at 00:04:51 UTC, Tofu Ninja wrote: On Wednesday, 23 November 2016 at 23:21:53 UTC, ketmar wrote: On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote: Being able to get an alias to (ref int) seems like a bug. you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-) Unless I can write "alias refint = ref int;", this should not be a feature at all... how did anyone think this is a good idea. Seriously I used to love D but now it's just a mess of hacks... either this, or you won't be able to replicate function with it's exact args; you won't be able to even check if some arg is ref. but not having `ref int` as a valid type declaration has it's reasons. You still can't replicate a function with this. No way to replicate or even know if a parameter is variadic. No way to replicate the ref on the return. No way to replicate the linkage or attributes of the function. This is a hack that solves nothing.
Re: How to declare function with the same call signature as another?
On Wednesday, 23 November 2016 at 23:21:53 UTC, ketmar wrote: On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote: Being able to get an alias to (ref int) seems like a bug. you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-) Unless I can write "alias refint = ref int;", this should not be a feature at all... how did anyone think this is a good idea. Seriously I used to love D but now it's just a mess of hacks...
Re: How to declare function with the same call signature as another?
On Wednesday, 23 November 2016 at 22:48:17 UTC, ketmar wrote: On Wednesday, 23 November 2016 at 22:28:57 UTC, Tofu Ninja wrote: On Wednesday, 23 November 2016 at 22:19:28 UTC, ketmar wrote: On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote: What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type? it is "type with modifier", like "const int" or "immutable int". Since when has ref been a type qualifier? It has always been a parameter/function attribute. which is technically type qualifier. it just forbidden (in grammar) to use it anywhere except arg declaration. Maybe the compiler sees it as a type qualifier, but it is not listed as a type qualifier and does not behave like a type qualifier in any sense. For example typeof will never return "ref int" but will return "const int", auto will never infer ref but can infer const, you can pass const(int) into a template but can never pass ref(int) into a template(even with that hack I posted before, the ref gets striped). Being able to get an alias to (ref int) seems like a bug.
Re: How to declare function with the same call signature as another?
On Wednesday, 23 November 2016 at 22:19:28 UTC, ketmar wrote: On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote: What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type? it is "type with modifier", like "const int" or "immutable int". Since when has ref been a type qualifier? It has always been a parameter/function attribute.
Re: How to declare function with the same call signature as another?
On Sunday, 20 November 2016 at 12:06:15 UTC, Tofu Ninja wrote: On Sunday, 20 November 2016 at 11:52:01 UTC, Tofu Ninja wrote: ... Also does not include function linkage :/ Because of the lack of response, I am going to guess there is no way to do this cleanly. Guess I am going to have to break out the trusty old mixin to get this working. Also wtf is this... how does this even make sense? template make_ref(T){ static if(is(void delegate(ref T) ftype == delegate) && is(ftype P == function)) alias make_ref = P; else static assert(false); } void main(){ import std.stdio; writeln(make_ref!int.stringof); // (ref int) } What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?
Re: How to declare function with the same call signature as another?
On Sunday, 20 November 2016 at 11:52:01 UTC, Tofu Ninja wrote: ... Also does not include function linkage :/
Re: How to declare function with the same call signature as another?
On Sunday, 20 November 2016 at 11:23:37 UTC, Nicholas Wilson wrote: On Sunday, 20 November 2016 at 11:19:24 UTC, Tofu Ninja wrote: I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :) import std.traits; ReturnType!Sig func(Parameters!Sig args) { //... } This does not seem to account for return type attributes or function attributes. Eg: alias Sig = ref int function() @nogc; ReturnType!Sig func(Parameters!Sig args) { // func is missing ref on return type and is not @nogc static int g; return g; } How should I account for these things?
How to declare function with the same call signature as another?
I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :)
Re: VisualD core.exception.RangeError@pipedmd(286): Range violation
On Thursday, 8 September 2016 at 19:56:45 UTC, Rainer Schuetze wrote: I think I fixed both issues in this build: https://ci.appveyor.com/project/rainers/visuald/build/1.0.76/job/kq0a5bqpy7anou46/artifacts Well that was fast :) It does appear to be fixed on my machine, thanks a lot for the help.
Re: VisualD core.exception.RangeError@pipedmd(286): Range violation
On Thursday, 8 September 2016 at 07:45:56 UTC, Rainer Schuetze wrote: Fixed it again. You can find a prebuilt binary of pipedmd.exe here: https://ci.appveyor.com/project/rainers/visuald/build/1.0.75/job/n9tf67jxcir6kpmg/artifacts Thanks for the response, I think there is more going on than that bug. The pipedmd that you linked did the same thing that mine did when I got rid of the rangeerror@pipedmd(285). Pipedmd just locks up and never finishes the build. Here is the project that gives me the problem, don't have something smaller that demonstrates it. https://www.dropbox.com/s/awtweclzl9kdm53/DGraphics.7z?dl=0 dub 1.0.0 dmd v2.071.0 visuald v0.3.44 beta 1 Generate the visuald project with "dub generate visuald -ax86_64", the project itself only builds in x64. Also fun fact, I get a different error if the folder that project is in has spaces in the path... so yeah...
VisualD core.exception.RangeError@pipedmd(286): Range violation
I get "core.exception.RangeError@pipedmd(286): Range violation" whenever I try to build from visual D. Is there any workaround for this? It was reported[1] almost 9 months ago, does not seem like it's going to be fixed anytime soon. Visual D is completely broken for me right now because of it. Only reason I use Visual D is because it's the only useable debugger on windows, now I can't even do that... Lost a day of work trying to fix this, starting to get really annoyed... [1] https://issues.dlang.org/show_bug.cgi?id=15606
Re: dub generate visuald
On Monday, 5 September 2016 at 19:03:00 UTC, Tofu Ninja wrote: On Monday, 5 September 2016 at 17:25:45 UTC, Tofu Ninja wrote: I am not sure what changed but I can no longer build using visuald after generating from dub. When I try to build from visual studio I get the following error LINK : warning LNK4001: no object files specified; libraries used LINK : warning LNK4068: /MACHINE not specified; defaulting to X86 LINK : fatal error LNK1561: entry point must be defined I did update visuald recently so I suppose that's what caused it. Updated dub to 1.0 trying to fix this. Anyone else get this, any solution. I can build directly from dub with no problem, but building from VS gives that error. I moved my project to a folder that has no spaces in the path, which has changed the error. Now I get: core.exception.RangeError@pipedmd(286): Range violation https://issues.dlang.org/show_bug.cgi?id=15606 U it seems that bug has been in visuald for months now... and people wonder why D isn't popular... shit ain't useable.
Re: dub generate visuald
On Monday, 5 September 2016 at 17:25:45 UTC, Tofu Ninja wrote: I am not sure what changed but I can no longer build using visuald after generating from dub. When I try to build from visual studio I get the following error LINK : warning LNK4001: no object files specified; libraries used LINK : warning LNK4068: /MACHINE not specified; defaulting to X86 LINK : fatal error LNK1561: entry point must be defined I did update visuald recently so I suppose that's what caused it. Updated dub to 1.0 trying to fix this. Anyone else get this, any solution. I can build directly from dub with no problem, but building from VS gives that error. I moved my project to a folder that has no spaces in the path, which has changed the error. Now I get: core.exception.RangeError@pipedmd(286): Range violation
Re: dub generate visuald
On Monday, 5 September 2016 at 18:22:02 UTC, Guillaume Piolat wrote: On Monday, 5 September 2016 at 17:25:45 UTC, Tofu Ninja wrote: I can build directly from dub with no problem, but building from VS gives that error. Building with dub uses the dmd settings in sc.ini Building with VisualD can override those settings. There is an option to disable that in the visuald settings, but that does not seem to change anything.
Re: Unicode function name? ∩
On Sunday, 28 August 2016 at 05:28:17 UTC, rikki cattermole wrote: On 28/08/2016 5:21 PM, Tofu Ninja wrote: ... Try Ÿ. Yeah Ÿ and π both work but ∩ does not. I think I found my answer though... http://dlang.org/spec/lex.html#IdentifierChar Identifiers start with a letter, _, or universal alpha, and are followed by any number of letters, _, digits, or universal alphas. Universal alphas are as defined in ISO/IEC 9899:1999(E) Appendix D. (This is the C99 Standard.) Identifiers can be arbitrarily long, and are case sensitive. Identifiers starting with __ (two underscores) are reserved.
Re: Unicode function name? ∩
On Sunday, 28 August 2016 at 05:21:03 UTC, Tofu Ninja wrote: ... Also visual D seems to recognize its not a valid character and highlights the error which makes me think its known behavior.
Re: Unicode function name? ∩
On Sunday, 28 August 2016 at 05:21:03 UTC, Tofu Ninja wrote: Are unicode function names not supported in dmd? bool ∩(A, B)(A a, B b){ return intersect(a, b); } Error: character 0x2229 is not a valid token I won't be terribly disappointed if I can't do this, I really just tried it on a whim, but I thought dmd supported unicode. Oddly enough bool π(A, B)(A a, B b) { ... } works just fine.
Unicode function name? ∩
Are unicode function names not supported in dmd? bool ∩(A, B)(A a, B b){ return intersect(a, b); } Error: character 0x2229 is not a valid token I won't be terribly disappointed if I can't do this, I really just tried it on a whim, but I thought dmd supported unicode.
Using shared libraries for external scripts, looking for advice (windows)
So this is kind of an open ended question, just looking for advice on doing it in general, if it's possible, and doing it specifically in D on windows. I am not super familiar with how shared libraries work so I had some questions. I would like to attempt to use D to write scripts for a game engine I am working on. The goal is to have the ability to externalize the code that is specific to an individual game or level instead of just compiling it all into the engine it self. I want to be able to treat them as resources similar to other asset files such as images or models. A secondary goal is to be able to reload them at runtime for iteration. So with that in mind, my general plan was to compile them into dll's and load them at runtime. My understanding is that to make it work, each dll will need to have an entry point that registers its data with the rest of the engine but I am unclear of some of the details or even if it is possible. I am unsure of how to give the library access to the rest of the engine. For instance, I have some global data in the engine. How do I go about making sure the dlls have access to that data, is there a way to make sure the dll will share the memory space as the rest of the program, or will I need to explicitly pass that data into the dll to give it access. Also I am unsure of how to go about keeping the engine code out of the dll. I would like to keep the dll as small as possible. If the dll accesses anything from the engine, how do I keep the engine code out of the dll? Idealy I would also like to keep phobos out of the dll as well. If the dlls get too big then it will probably not be useable. Is this even possible currently? Is this a terrible idea or am I severely misunderstanding things? I think I heard that remedy games did something similar, anyone know the specifics of how they did it?
Re: Why is ElementType!(char[]) == dchar?
On Saturday, 9 July 2016 at 11:35:24 UTC, Tofu Ninja wrote: On Saturday, 9 July 2016 at 11:29:18 UTC, ketmar wrote: On Saturday, 9 July 2016 at 11:24:01 UTC, Tofu Ninja wrote: Seems pretty silly to me... due to universally beloved autodecoding. Hmmm... I dont really know the history of autodecoding, why was that supposed to be a good idea? Hmm, well I fixed my problem that originally prompted me to ask this by using ubyte instead of char. Still kinda curious on the whole autodecoding thing and why it's even a thing.
Re: Why is ElementType!(char[]) == dchar?
On Saturday, 9 July 2016 at 11:29:18 UTC, ketmar wrote: On Saturday, 9 July 2016 at 11:24:01 UTC, Tofu Ninja wrote: Seems pretty silly to me... due to universally beloved autodecoding. Hmmm... I dont really know the history of autodecoding, why was that supposed to be a good idea?
Why is ElementType!(char[]) == dchar?
Seems pretty silly to me...
Re: Real implicitly converts to float?
On Friday, 24 June 2016 at 20:10:16 UTC, Tofu Ninja wrote: I am glad I was not the only one who thought that sounded a little crazy... I thought D was supposed to be type safe. I think I will make a bug report and see where that goes. https://issues.dlang.org/show_bug.cgi?id=16202
Re: Real implicitly converts to float?
On Friday, 24 June 2016 at 08:52:48 UTC, Ola Fosheim Grøstad wrote: This is so wrong. _especially_ when you have parameter overloading/templates. It means that you accidentally can trash a computation by getting the wrong function. That is not type-safe in my book. Jonathan's max-value example is a good one. The distinction between infinity and a large actual value is an important one. I am glad I was not the only one who thought that sounded a little crazy... I thought D was supposed to be type safe. I think I will make a bug report and see where that goes.
Re: Real implicitly converts to float?
On Thursday, 23 June 2016 at 15:25:49 UTC, Steven Schveighoffer wrote: I disagree. I've used languages where converting floating point types is not implicit, and it's painful. Most of the time, the loss in precision isn't important. -Steve Which is why a flag would be nice, for some applications the precision matters, for some it doesn't.
Re: Real implicitly converts to float?
On Thursday, 23 June 2016 at 13:57:57 UTC, Steven Schveighoffer wrote: Whenever you work with floating point, the loss of precision must be expected -- a finite type cannot represent an infinite precision number. The loss in precision should still be a warning. If I am using reals then I obviously needed a certain level of precision, I don't want to accidentally lose that precision somewhere because the compiler decided it was not important enough to warn me about it.
Re: Real implicitly converts to float?
On Wednesday, 22 June 2016 at 14:17:42 UTC, Jonathan M Davis wrote: Well, that particular value should probably work thanks to VRP (value range propagation), since 10 can fit into float with no loss of precision. However, what's far more disconcerting is that real x = real.max; float y = x; compiles. real to float is a narrowing conversion, which should be an error barring the compiler detecting that the value will fit in the target type even if it's a narrowing conversion (which only happens with VRP). That's not the sort of thing that I would have expected to be broken such that it begs the question as to whether it's intentional, but given that narrowing conversions without a cast are illegal everywhere else, this definitely seems broken. - Jonathan M Davis Should I make a bug report? I am not sure it's a bug, seems intentional. Maybe a dip for a compiler flag to warn on implicit down conversions, but it would be a pretty small dip.
Re: Real implicitly converts to float?
On Wednesday, 22 June 2016 at 08:57:38 UTC, Guillaume Piolat wrote: On Wednesday, 22 June 2016 at 05:04:42 UTC, Tofu Ninja wrote: Is this intended behavior? I can't seem to find it documented anywhere, I would think the loss in precision would atleast be a warning. real x = 10; float y = x; // No error or warning real to double and double to float also work. Intended behaviour (in TDPL and all), and same behaviour than C. I'm not sure of the reason. That's a little disconcerting, would be nice if there was a compiler flag to give a warning on the precision loss.
Real implicitly converts to float?
Is this intended behavior? I can't seem to find it documented anywhere, I would think the loss in precision would atleast be a warning. real x = 10; float y = x; // No error or warning real to double and double to float also work.
Re: Dub generate visuald, multiple configurations?
On Friday, 17 June 2016 at 08:49:47 UTC, Tofu Ninja wrote: Is there a way to generate a single visuald project file for all dub configurations, selecting the configuration from the visual studio configuration manager? Or do I have to generate a separate project for each configuration? I am guessing no?
Dub generate visuald, multiple configurations?
Is there a way to generate a single visuald project file for all dub configurations, selecting the configuration from the visual studio configuration manager? Or do I have to generate a separate project for each configuration?
Re: Are __gshared globals gc scanned?
On Tuesday, 14 June 2016 at 13:53:10 UTC, ketmar wrote: __gshared globals are gc scanned. Ah cool, thanks I had to login to my work computer just to read your answer lol
Are __gshared globals gc scanned?
Title says it all...
Re: Shallow copy object when type is know
On Wednesday, 20 April 2016 at 18:48:58 UTC, Alex Parrill wrote: On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote: Is there a way to shallow copy an object when the type is known? I cant seem to figure out if there is a standard way. I can't just implement a copy function for the class, I need a generic solution. A generic class copy function would require accessing private fields, so a clean per-attribute class copy is impossible. Doing a bitwise copy might work except for the synchronization mutex pointer. Can you elaborate on why you need this? To implement a copy/paste/duplicate functionality in a game editor. I have an entity-component system, to duplicate an entity, all it's components need to be duplicated. I have many many components, I don't want to rely on manually writing copy methods for each, it is too error prone. There are only a very few that need special copies, almost all can get by with a simple shallow copy. I would like a generic way to do that shallow copy. How does D not have shallow copy? Seems like a very basic functionality...
Shallow copy object when type is know
Is there a way to shallow copy an object when the type is known? I cant seem to figure out if there is a standard way. I can't just implement a copy function for the class, I need a generic solution.
Re: Anonymous structure
On Tuesday, 19 April 2016 at 16:16:39 UTC, ZombineDev wrote: On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: 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); There's another way: http://forum.dlang.org/post/n3q9vn$1l8g$1...@digitalmars.com How is that supposed to work here?
Re: Anonymous structure
On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: 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); Yeah thats basicly what I meant, just sort of tedious to have to write it like that, makes more complex layouts a real pain to write.
Re: Anonymous structure
On Monday, 18 April 2016 at 03:33:53 UTC, Adam D. Ruppe wrote: The struct inside union is the main pure-language use case I know of though. Actually curiously I found another potential use, applying attributes/UDAs to multiple members at once. enum testUDA; struct T{ @testUDA immutable struct{ int x; int y; int z; } } x,y,and z seem to all be immutable and all have the UDA testUDA. But even odder, it seems that "struct" in there is doing absolutely nothing. The same thing can be done with enum testUDA; struct T{ @testUDA immutable{ int x; int y; int z; } } So it still seems to be useless other than in the case of unions...
Re: Anonymous structure
On Monday, 18 April 2016 at 03:33:53 UTC, Adam D. Ruppe wrote: The struct inside union is the main pure-language use case I know of though. I understand the reason for allowing it in a union, I just don't see the reason it was extended to all aggregates as it seems to do nothing.
Re: Anonymous structure
On Monday, 18 April 2016 at 02:42:15 UTC, Nicholas Wilson wrote: On Monday, 18 April 2016 at 02:12:24 UTC, Tofu Ninja wrote: Just out of curiosity, what is the point of the following? struct a{ struct{ int x; int y; int z; } } As far as I can tell, the anonymous structure does nothing. How is it different from struct a{ int x; int y; int z; } IIRC D doesn't allow anonymous structures. It does, it compiles... Accessing x,y,z on the first one with the anonymous struct is the same as accessing it on the second without the anonymous struct... Seems to make no difference that it is there, which is why I am asking. 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; } Try adding static: struct a { static struct b { } } Does not seem to be what I mean, a static nested struct is just a nested struct without access to the enclosing structure's members. What I meant was a struct to just add a namespace of sorts to the struct so that the substructure members would have to be accessed with a longer more qualified name. Something like struct a{ int x; sub_struct b{ int y; } } a v; v.x = 3; v.b.y = 7; // v.y = 7; // does not work
Anonymous structure
Just out of curiosity, what is the point of the following? struct a{ struct{ int x; int y; int z; } } As far as I can tell, the anonymous structure does nothing. How is it different from struct a{ int x; int y; int z; } 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; }
Implicit conversion from string to custom type?
So I wrote a simple ref counted string type because using the built in strings without the GC is extremely painful. It there any way I can get strings to implicitly convert to my custom string type? Some way to make this work... struct rstring {...} void fun(rstring s) {...} ... fun("hello world"); // Currently an error Would be super nice if it would just call the opAssign when trying to call fun but I suppose that has some non-obvious problems for why it does not work that way.
How is the TypeInfo assigned?
Is the TypeInfo given by typeid() guaranteed to be the same for a type regardless of where I call it? I guess my question is, is the TypeInfo a valid way to dynamically check types? I am implementing a message passing system for an entity-component system, I was planning to use structs as messages and use the TypeInfo to determine where they are supposed to go. Will this cause any problems? Also will typeid() allocate? Or is the TypeInfo statically allocated at compile time? Also how does shared libs affect this? Will a TypeInfo passed across different libs still match up? Thanks
Re: Octree implementation?
On Thursday, 4 February 2016 at 17:56:06 UTC, Marco Leise wrote: Am Mon, 01 Feb 2016 02:56:06 + schrieb Tofu Ninja: Just out of curiosity, does anyone have an octree implementation for D laying around? Just looking to save some time. I have one written in Delphi that you could prune till it fits. I ended up writing my own, Benjamin's was a little hard to fit to my own code but I got some good ideas from it, particularly I didn't really know about loose octrees but they are definitely a good idea.
Re: foreach seems to work with opIndex()
On Saturday, 6 February 2016 at 15:02:16 UTC, H. S. Teoh wrote: Not really sure, but opIndex() with no arguments is supposed to be the current way of implement the [] slicing operator for user-defined types. I'm not sure when foreach started supporting that, but it's certainly a nice thing! T It feels a little weird because none of the range functions like map support calling opIndex so you can omit the [] in foreach but not with map. Just feels inconsistent.
Re: foreach seems to work with opIndex()
On Saturday, 6 February 2016 at 14:43:52 UTC, Tofu Ninja wrote: Foreach seems to work if there is an opIndex() with no arguments that returns a range interface, is this documented? I can't seem to find anything that say this is supposed to happen. I am not really complaining, its nice, but I just didnt really expect it because I feel like I remember this being an error some time ago. To clerify, I was doing something like struct someStruct{ ... dchar[] opIndex(){ if(data==null) return null; else return data.some_array; } } ... someStruct s; foreach(c;s) {} I expected to need to write foreach(c;s[]) {}
foreach seems to work with opIndex()
Foreach seems to work if there is an opIndex() with no arguments that returns a range interface, is this documented? I can't seem to find anything that say this is supposed to happen. I am not really complaining, its nice, but I just didnt really expect it because I feel like I remember this being an error some time ago.
Octree implementation?
Just out of curiosity, does anyone have an octree implementation for D laying around? Just looking to save some time.
Re: Compiling dmd -m64 on windows?
On Friday, 29 January 2016 at 18:26:15 UTC, Tofu Ninja wrote: For some reason it complains that link.exe is missing. Anyone know what's up? dmd test.d dmd test.d -m64 Can't run '\bin\link.exe', check PATH link.exe is definitely on PATH... where link.exe C:\D\dmd2\windows\bin\link.exe
Compiling dmd -m64 on windows?
For some reason it complains that link.exe is missing. Anyone know what's up? dmd test.d dmd test.d -m64 Can't run '\bin\link.exe', check PATH
Output range for file?
I tried looking for this in phobos but cant seem to find it which is really annoying. For my uses this works: struct fileOutRange { File f; void put(ubyte[] a) { f.rawWrite(a); } } But was just wondering if there was a real output range for files somewhere in phobos that I just cant seem to find.
Re: Output range for file?
On Sunday, 24 January 2016 at 15:08:33 UTC, H. S. Teoh wrote: On Sun, Jan 24, 2016 at 12:38:22PM +, Tofu Ninja via Digitalmars-d-learn wrote: I tried looking for this in phobos but cant seem to find it which is really annoying. For my uses this works: What kind of data do you need to write to file? If it's textual data, use File.lockingTextWriter, which is an output range. If it's binary data, you'll probably have to roll your own; there's a Phobos PR right now that implements File.lockingBinaryWriter, but it's not quite ready for merging yet. T I am writing out binary data, so I guess I will just keep using what I am using.
Re: Reset all Members of a Aggregate Instance
On Thursday, 3 December 2015 at 21:04:00 UTC, Nordlöw wrote: ... I think reflection will be a bad choice for this because of private members and what not. I think the correct way is: void reset(C)(ref C c) { static if(is(C == class)) { auto init = typeid(c).init(); auto objmem = ((cast(void*)c)[0 .. init.length]); if(init.ptr == null) (cast(byte[])objmem)[] = 0; else objmem[] = init[]; if(c.classinfo.defaultConstructor != null) c.classinfo.defaultConstructor(c); } else c = C.init; } Seems to work for structs, classes, and basic types. It even calls the default constructor for classes, even if there is inheritance and the object passed in is not actually C but a sub class of C.
Re: Reset all Members of a Aggregate Instance
On Friday, 4 December 2015 at 04:08:33 UTC, Tofu Ninja wrote: On Thursday, 3 December 2015 at 21:04:00 UTC, Nordlöw wrote: ... I think reflection will be a bad choice for this because of private members and what not. I think the correct way is: void reset(C)(ref C c) { static if(is(C == class)) { auto init = typeid(c).init(); auto objmem = ((cast(void*)c)[0 .. init.length]); if(init.ptr == null) (cast(byte[])objmem)[] = 0; else objmem[] = init[]; if(c.classinfo.defaultConstructor != null) c.classinfo.defaultConstructor(c); } else c = C.init; } Seems to work for structs, classes, and basic types. It even calls the default constructor for classes, even if there is inheritance and the object passed in is not actually C but a sub class of C. Oh after reading chris's post, probably should change to... void reset(C)(ref C c) { static if(is(C == class)) { auto type_info = typeid(c); auto class_info = c.classinfo; destroy(c); auto init = type_info.init(); auto objmem = ((cast(void*)c)[0 .. init.length]); if(init.ptr == null) (cast(byte[])objmem)[] = 0; else objmem[] = init[]; if(class_info.defaultConstructor != null) class_info.defaultConstructor(c); else throw new Exception("No default constructor"); } else c = C.init; }
Re: isAllocator
On Tuesday, 1 December 2015 at 08:58:56 UTC, BBaz wrote: I think that `is(CAllocatorImpl!Alloc)` should work too then. According to the 'is' version, int is an allocator. No idea why it thinks this works... enum isAllocator(Alloc) = is(CAllocatorImpl!Alloc); static assert(isAllocator!int); This seems to work well though... enum isAllocator(Alloc) = __traits(compiles, {IAllocator alloc = new CAllocatorImpl!Alloc;}); static assert(isAllocator!Mallocator); static assert(isAllocator!GCAllocator); static assert(!isAllocator!int);
Re: isAllocator
On Monday, 30 November 2015 at 14:21:49 UTC, Tofu Ninja wrote: Is there something like isInputRange for allocators, I tried looking for something but couldn't find anything? If not, why not? Aka, some way to check that type T is an allocator.
isAllocator
Is there something like isInputRange for allocators, I tried looking for something but couldn't find anything? If not, why not?
Re: Compile time strings auto concatenation!?
On Friday, 20 November 2015 at 20:39:58 UTC, Ilya wrote: Can DMD frontend optimize string concatenation ``` enum Double(S) = S ~ S; assert(condition, "Text " ~ Double!"+" ~ ___FUNCTION__); ``` to ``` assert(condition, "Text ++_function_name_"); ``` ? If you really want to make sure it is concatenated at compile time, just do this: ... enum CT(alias S) = S; assert(condition, CT!("Text " ~ Double!"+" ~ ___FUNCTION__)); // Must be evaluated at CT no matter what
Re: Manually allocate delegate?
On Saturday, 21 November 2015 at 00:30:45 UTC, userABCabc123 wrote: Yes: class Foo { void bar(){writeln(__PRETTY_FUNCTION__);} } auto uncollectedDelegate(T, string name)(ref T t) { import std.experimental.allocator.mallocator; struct Dg{void* ptr, funcptr;} void* funcptr = &__traits(getMember, T, name); void* ptr = cast(void*)t; Dg* dg = cast(Dg*) Mallocator.instance.allocate(Dg.sizeof); dg.ptr = ptr; dg.funcptr = funcptr; return dg; } void main(string[] args) { Foo foo = new Foo; auto dg = uncollectedDelegate!(Foo, "bar")(foo); auto tdg = cast(void delegate()*) dg; (*tdg)(); } with just a type __traits(getMember,...) on a delegate will only return the function address in the process image. so without the context ptr, just like a static or a global function. Later you set the context by hand, using a pointer to an instance. I think you are misunderstanding a bit what my original question was. The delegate it self is not gc allocated. The delegate it self is just 2 pointers(a function pointer and a context pointer), they are simply stack allocated. I am not woried about allocating that bit. What I am worried about allocating is the context, and primarily the context for nested functions(often called a closure). For delegates to member functions, the context pointer is always just a pointer to the object that you pulled the delegate off of. To avoid gc allocating the context there, all you need to do is just don't gc allocate the object. Simple. In your example the context is still gc allocated with new Foo;. You actually added in another allocation on top of that with the mallocator. You now allocate the delegate it self, which normally can just be stack allocated. The problem that I was concerned about was the case of nested function delegates. For delegates to nested functions that need to generate a closure, the allocation of the closure is implicitly done and done with the gc. As far as I can tell, there is no way to know anything about that closure, not its size, layout, contents, no way to manually allocate it. Example: auto foo(int x) { int bar(){ return x; } return // <-- implicitly allocates a closure with the gc }
Re: std.experimental.allocator optlink error
On Tuesday, 10 November 2015 at 11:39:56 UTC, Rikki Cattermole wrote: One already exists. I've confirmed it in the build scripts. It only effects Windows. Any fix for this right now?
Re: std.experimental.allocator optlink error
On Friday, 20 November 2015 at 12:49:02 UTC, Rikki Cattermole wrote: Dunno if its been fixed in ~master (doubt it), but all you need to do in your code, is copy it in. Cool, that worked. I've personally marked (well voted anyway) for this bug to be critical. It seems I'm the only one who thinks this is worth its own point release *shrugs*. Yeah this is a pretty big oversight and seems like it should be fixed asap.
Re: BidirectionalRange switching direction
On Wednesday, 23 September 2015 at 03:26:29 UTC, John Colvin wrote: On Wednesday, 23 September 2015 at 02:10:22 UTC, Tofu Ninja wrote: Trying to implement a bi directional range and it is slightly unclear what the semantics are supposed to be and just wanted some clarification. Are bidirectional ranges supposed to be able to support switching direction mid iteration? Like if I do popFront popFront popBack should that be equal to just a single popFront? Or once you start on a direction should switching be considered an error? Or is popFront and popBack supposed to consume from both ends of the range and the range is empty when they meet? -tofu The last one. E.g. for arrays (except narrow strings... ugh) auto popFront(T)(ref T[] a) { a = a[1 .. $]; } auto popBack(T)(ref T[] a) { a = a[0 .. $-1]; } Ok cool, that's what I ended up doing.
BidirectionalRange switching direction
Trying to implement a bi directional range and it is slightly unclear what the semantics are supposed to be and just wanted some clarification. Are bidirectional ranges supposed to be able to support switching direction mid iteration? Like if I do popFront popFront popBack should that be equal to just a single popFront? Or once you start on a direction should switching be considered an error? Or is popFront and popBack supposed to consume from both ends of the range and the range is empty when they meet? -tofu
Re: Theoretical Best Practices
On Friday, 14 August 2015 at 22:25:15 UTC, DarthCthulhu wrote: Ahh, that is a much cleaner way to do it rather than using a singleton. By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct? Is the compiler smart enough to compile out all the symbols associated with the logger if it is never instantiated? If you want to make 100% sure that the Logger code does not end up in the release version, you can just put the Logger class definition in that debug block as well. Also, am I the only one who is imagining that you are really the dog in your avatar. I am just imagining that there is a dog somewhere trying to learn D.
Yieldable function?
Is there any way to have a yieldable function that can be resumed at a later time in D? Some thing like: void test() { writeln(A); yeild(); writeln(B); } ... auto x = yieldable!test(); x.resume(); // prints A x.resume(); // prints B x.resume(); // throws an error or something, i dont know.. Also how portable is the built in asm support, was thinking about implementing this if it's not already available. Also is there a way to define naked functions in D? I think not but they might make implementing this a little more simple.
Re: Yieldable function?
On Thursday, 13 August 2015 at 22:29:17 UTC, MrSmith wrote: http://dlang.org/phobos/core_thread.html#.Fiber Man I feel like I saw that before but when I went looking for it I couldn't find it. Didn't think to check in core. :/ Welp that solves my question, thanks :D
Re: Find on sorted range slower?
On Friday, 7 August 2015 at 08:18:04 UTC, Nordlöw wrote: On Friday, 7 August 2015 at 05:21:32 UTC, Tofu Ninja wrote: HAHAH wow, this is hilarious, I just checked, nothing in std.algo takes advantage of sorted ranges, sort doesn't even take advantage of it! You pass a sorted range into sort and it will just resort it! Wow Who fixes this? I can look into it... is there an issue for this? I have no idea, but it is pretty silly. Sort/isSorted on a sorted range should be a nop. Find and friends, should do doing some kind of binary search. Max and min should be O(1). Some of the functions that return a sub range or a mutated range could probably be returning sorted ranges as well if its input is a sorted range, remove, strip and split at least could.
Re: Find on sorted range slower?
On Friday, 7 August 2015 at 10:01:39 UTC, Timon Gehr wrote: On 08/07/2015 11:03 AM, Tofu Ninja wrote: On Friday, 7 August 2015 at 08:18:04 UTC, Nordlöw wrote: On Friday, 7 August 2015 at 05:21:32 UTC, Tofu Ninja wrote: HAHAH wow, this is hilarious, I just checked, nothing in std.algo takes advantage of sorted ranges, sort doesn't even take advantage of it! You pass a sorted range into sort and it will just resort it! Wow Who fixes this? I can look into it... is there an issue for this? I have no idea, but it is pretty silly. Sort/isSorted on a sorted range should be a nop. Find and friends, should do doing some kind of binary search. Max and min should be O(1). Some of the functions that return a sub range or a mutated range could probably be returning sorted ranges as well if its input is a sorted range, remove, strip and split at least could. Binary search is not always faster than linear search. It will be for the majority of sorted ranges. Though if other searches are needed, find and friends could take an extra arg SearchPolicy for sorted ranges that defaults to binary search.
Re: Template-Parameterized Variadic isInstaceOf
On Friday, 7 August 2015 at 14:45:44 UTC, Nordlöw wrote: On Friday, 7 August 2015 at 14:30:55 UTC, Nordlöw wrote: Any suggestions on adding support for `binaryFun!pred` aswell? I cracked it. template isSortedRange(T, alias pred = a b) { import std.traits : TemplateArgsOf; static if (TemplateArgsOf!T.length == 2) { import std.functional : binaryFun; alias predArg = TemplateArgsOf!T[1]; static if (isSomeString!(typeof(pred))) { alias predFun = binaryFun!pred; } else { alias predFun = pred; } static if (isSomeString!(typeof(predArg))) { alias predArgFun = binaryFun!predArg; } else { alias predArgFun = predArg; } enum isSortedRange = (is(T == SortedRange!Args, Args...) is(typeof(predFun) == typeof(predArgFun))); } else { enum isSortedRange = false; } } /// unittest { import std.functional : binaryFun; alias R = int[]; enum pred = a b; alias SR = SortedRange!(R, pred); static assert(isSortedRange!(SR, pred)); static assert(isSortedRange!(SR, binaryFun!pred)); alias SR2 = SortedRange!(R, binaryFun!pred); static assert(isSortedRange!(SR2, pred)); static assert(isSortedRange!(SR2, binaryFun!pred)); } Comments, please. I think you could have omitted the need for a predicate with just using isInstanceOf. enum isSortedRange(T) = isInstanceOf!(SortedRange, T); But I think yours works better for what you are trying to do, the pred of whatever function you are trying to specialize needs to match the pred of the sorted range itself, else the specialization is wrong.
Re: Find on sorted range slower?
On Friday, 7 August 2015 at 04:23:21 UTC, Ali Çehreli wrote: Do you want to see SortedRange 1700 times faster? ;) On 08/06/2015 05:35 PM, Tofu Ninja wrote: void main() auto temp = assumeSorted(a).find(f); SortedRange does not have a find() member. What happens is, it goes to find() algorithm. Replace that line with auto temp = assumeSorted(a).equalRange(f); writefln(found: %s, temp.front); New result: found: 10240 found: 10240 Sorted 83235 Regular 141392157 Ratio 0.000588682 Ali Hmm I feel like I have read on the forums like a million times that certain parts of std.algorithm was specialized for sorted ranges, I guess that was just talk... Still does not really explain why find is slower on the assumeSorted version.
Re: Find on sorted range slower?
On Friday, 7 August 2015 at 05:01:41 UTC, Tofu Ninja wrote: On Friday, 7 August 2015 at 04:23:21 UTC, Ali Çehreli wrote: Do you want to see SortedRange 1700 times faster? ;) On 08/06/2015 05:35 PM, Tofu Ninja wrote: void main() auto temp = assumeSorted(a).find(f); SortedRange does not have a find() member. What happens is, it goes to find() algorithm. Replace that line with auto temp = assumeSorted(a).equalRange(f); writefln(found: %s, temp.front); New result: found: 10240 found: 10240 Sorted 83235 Regular 141392157 Ratio 0.000588682 Ali Hmm I feel like I have read on the forums like a million times that certain parts of std.algorithm was specialized for sorted ranges, I guess that was just talk... Still does not really explain why find is slower on the assumeSorted version. HAHAH wow, this is hilarious, I just checked, nothing in std.algo takes advantage of sorted ranges, sort doesn't even take advantage of it! You pass a sorted range into sort and it will just resort it! Wow