Re: Where is there documentation on how to write inline asm?
Well, for anyone who is tangling with similar mysteries, I finally got something to work the way I wanted it to. Thank you for the help, Adam and kinke! The first "x" argument was stored in R8. The second "y" argument was stored in RDX. The invisible return value pointer was stored in RCX. Here's what I was hoping to accomplish. The multiply function returns the low bits of the product in the `low` attribute of the struct and the high bits in the `high` attribute of the struct. The divide function returns the quotient in `low` and the remainder in `high`. struct Result { ulong low; ulong high; } Result unsignedMultiply(ulong x, ulong y) { version(D_InlineAsm_X86_64) asm { naked; mov RAX, R8; mul RDX; mov qword ptr [RCX], RAX; mov qword ptr [RCX + 8], RDX; ret; } } Result unsignedDivide(ulong x, ulong y) { version(D_InlineAsm_X86_64) asm { naked; mov RAX, R8; mov R9, RDX; mov RDX, 0; div R9; mov qword ptr [RCX], RAX; mov qword ptr [RCX + 8], RDX; ret; } }
Re: Where is there documentation on how to write inline asm?
Ah, I've got something working! It's not exactly what I wanted, but it's good enough for now. Instead of using an invisible output pointer, the output pointer is passed in explicitly. struct Result { ulong low; ulong high; } void retTest(Result* result) { version(D_InlineAsm_X86_64) asm { naked; mov [RAX + 0], 0x80; mov [RAX + 8], 0xff; ret; } }
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:48:46 UTC, kinke wrote: The MS docs are complete IIRC. The pointer to the pre-allocated result of your 16-bytes struct is passed in RCX. If unsure, just reverse-engineer what you need: type it down in normal D and analyze the generated assembly. You can even do so online via run.dlang.io (https://run.dlang.io/is/rhsDBF); just select LDC and add `-mtriple=x86_64-pc-windows-msvc` to generate Win64 assembly. Note that run.dlang.io displays AT asm, not the Intel one. You can use LDC offline via `-output-s -x86-asm-syntax=intel` to generate a .s file with Intel syntax. When I tested by writing to the pointer given by RCX, the program didn't crash but I did get different values every time and never the ones I wanted.
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:12:39 UTC, Adam D. Ruppe wrote: On Thursday, 15 November 2018 at 21:07:51 UTC, pineapple wrote: Is there a way to access this pointer? It is passed as.. I think the final argument to the function. (unless it is the first, do a quick test to find out). Also, the calling convention documentation there doesn't mention anything about 64-bit targets, are 64-bit registers just not used? It uses the C rules there, so look up the 64 bit C abi. I think this is accurate https://msdn.microsoft.com/en-us/library/ms235286.aspx On the positive side: I see now how to return a 64-bit value from a function in Windows x64! And I understand how the arguments are coming in. This is very helpful. On the less positive side: I still have no clue how to return my 16-byte struct. The Microsoft x64 ABI documentation I've seen so far explains how return values of 8 bytes and fewer work, but haven't explained how larger return values work. The obvious answer of "RAX or EAX contains a pointer" is either not working or my asm is wrong. (The latter is certainly a possibility.) // Returns 128 (0x80) ulong retTest() { version(D_InlineAsm_X86_64) asm { naked; mov RAX, 0x80; ret; } } // Crashes struct Result { ulong low; ulong high; } Result retTest() { version(D_InlineAsm_X86_64) asm { naked; mov [RAX + 0], 0x80; mov [RAX + 8], 0x80; ret; } } // Also crashes struct Result { ulong low; ulong high; } Result retTest() { version(D_InlineAsm_X86_64) asm { naked; mov [R9 + 0], 0x80; mov [R9 + 8], 0x80; ret; } }
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:00:10 UTC, Adam D. Ruppe wrote: It would be part of the abi: https://dlang.org/spec/abi.html#function_calling_conventions though it references C so you might need to look that up too. That's helpful, thank you! For other sized structs and static arrays, the return value is stored through a hidden pointer passed as an argument to the function. Is there a way to access this pointer? Also, the calling convention documentation there doesn't mention anything about 64-bit targets, are 64-bit registers just not used?
Where is there documentation on how to write inline asm?
I've managed to get a few functions working before mostly by copying whatever Phobos was doing for a similar purpose, but now that I'm trying to do something different I am really hitting a wall. My issue is that I can't figure out how to access a function's arguments from within inline asm or how to ensure that the correct value is returned. I haven't found a single piece of documentation about this so far! I am mainly concerned about doing this for naked asm functions, but any documentation on the subject would be helpful.
Re: Running tests for a large library on Windows
Speaking of which, is there any AppVeyor config or script laying around somewhere for how to install 64-bit DMD? Since I would ideally like to automate testing with both 32-bit and 64-bit DMD
Running tests for a large library on Windows
I do mach.d - https://github.com/pineapplemachine/mach.d I've been setting up CI tests and OSX and Linux tests are good to go thanks to Travis. I'm having a little more difficulty with testing on Windows via AppVeyor, since DMD is too memory-hungry to `dub test` without a fatal error when DMD was compiled for a 32-bit target as opposed to 64-bit, as is the case for all Windows releases. How can I compile and run unit tests for only a part of the library at a time, so that 32-bit Windows can run tests too? (Which is actually important, since there are different x86 and x86-64 implementations of some library functions.) Or is there another solution? It's my understanding that phobos would have a similar problem if it didn't do something deliberate with how tests are run.
Stack traces with DMD on OSX
When I run code on OSX and it produces a stack trace, the output uses mangled symbols and is missing line numbers, like so - how can I change these stack traces to be more readable? 0 objectpool 0x000104e9a3bc _D4core7runtime18runModuleUnitTestsUZ19unittestSegvHandlerUNbNiiPS4core3sys5posix6signal9siginfo_tPvZv + 56 1 libsystem_platform.dylib0x7fff8bd5b5aa _sigtramp + 26 2 ??? 0x0002 0x0 + 2 3 objectpool 0x000104ea994b D2gc4impl12conservative2gc14ConservativeGC200__T9runLockedS79_D2gc4impl12conservative2gc14ConservativeGC12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS40_D2gc4impl12conservative2gc10mallocTimelS40_D2gc4impl12conservative2gc10numMallocslTmTkTmTxC8TypeInfoZ9runLockedMFNbKmKkKmKxC8TypeInfoZPv + 147 4 objectpool 0x000104ea3463 D2gc4impl12conservative2gc14ConservativeGC6qallocMFNbmkxC8TypeInfoZS4core6memory8BlkInfo_ + 115 5 objectpool 0x000104ea26a3 gc_qalloc + 51 6 objectpool 0x000104eaf5a8 D2rt8lifetime12__arrayAllocFNaNbmxC8TypeInfoxC8TypeInfoZS4core6memory8BlkInfo_ + 236 7 objectpool 0x000104eb3d9a _d_arrayliteralTX + 102 8 objectpool 0x000104cf7c2c D4mach3sys6memory19__unittestL120_1062FZv + 240 9 objectpool 0x0001049f8496 _D4mach3sys6memory9__modtestFZv + 14 10 objectpool 0x000104e9a409 D4core7runtime18runModuleUnitTestsUZ14__foreachbody2MFPS6object10ModuleInfoZi + 45 11 objectpool 0x000104e9067f D6object10ModuleInfo7opApplyFMDFPS6object10ModuleInfoZiZ9__lambda2MFyPS6object10ModuleInfoZi + 35 12 objectpool 0x000104eb5c56 D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZ14__foreachbody2MFKS2rt19sections_osx_x86_6412SectionGroupZi + 86 13 objectpool 0x000104eb5be1 D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZi + 33 14 objectpool 0x000104e90656 D6object10ModuleInfo7opApplyFMDFPS6object10ModuleInfoZiZi + 34 15 objectpool 0x000104e9a2f3 runModuleUnitTests + 127 16 objectpool 0x000104eaddc3 D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 23 17 objectpool 0x000104eadd5c D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32 18 objectpool 0x000104eadcc7 _d_run_main + 459 19 objectpool 0x0001049f8caa main + 34 20 libdyld.dylib 0x7fff854835fd start + 1
Re: Best syntax for a diagonal and vertical slice
On Saturday, 22 July 2017 at 20:55:06 UTC, kerdemdemir wrote: And what if I want to go diagonal like 1,5,9 or 3,5,7 in the example above. Is there a good solution in std without using for loops? I suggest using an actual matrix type for tasks like this. I don't know about diagonal slicing, but the implementation here at least provides accessors for both rows and columns. https://github.com/pineapplemachine/mach.d/blob/master/mach/math/matrix.d
Re: map on char[] converts to dchar?
It is worth noting too that mach's map function will not behave this way; UTF encoding and decoding is instructed explicitly and is not done implicitly like in phobos. https://github.com/pineapplemachine/mach.d import mach.range : map, asarray; import mach.text.ascii : toupper; void main(){ char[] x = ['h', 'e', 'l', 'l', 'o']; char[] y = x.map!toupper.asarray(); assert(y == "HELLO"); }
Re: Lookahead in unittest
On Friday, 12 May 2017 at 21:23:23 UTC, Steven Schveighoffer wrote: Note, you can achieve what you want with version(unittest): Please prefer `private version(unittest){...}` if the module might be imported by someone else's code, as to not pollute it with unneeded symbols
Re: Split Real / Float into Mantissa, Exponent, and Base
On Friday, 3 March 2017 at 18:09:02 UTC, Jonathan M. Wilbur wrote: I have tried to come up with a good way to get the mantissa, exponent, and base from a real number, and I just can't come up with a good cross-platform way of doing it. I know about std.math.frexp(), but that function only gives you another real as the mantissa. I need an integral mantissa, exponent, and base. Is there either (1) a crafty, cross-platform way of doing this or (2) a function in a standard library that does this that I somehow missed? If there is no such function, what are your thoughts on me implementing such a thing and submitting it to Phobos, probably similar to how frexp is implemented (elseifs for each FP format)? The various functions in std.math mostly extract these values on their own, using the floatTraits template to help. The mach library has the module mach.math.floats.extract: https://github.com/pineapplemachine/mach.d/tree/master/mach/math/floats
Re: Array start index
One reason for zero-based indexes that isn't "it's what we're all used to" is that if you used one-based indexes, you would be able to represent one fewer index than zero-based, since one of the representable values - zero - could no longer be used to represent any index. Also, it's what we're all used to, and it makes perfect sense to a lot of us, and the only times in recent memory I've ever made off-by-one errors were when I was trying to use Lua and its one-based indexing.
Re: Yield from function?
On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis wrote: I need to yield from a complex recursive function too allow visualizing what it is doing. e.g., if it is a tree searching algorithm, I'd like to yield for each node so that the current state can be shown visually. I realize that there are several ways to do this but D a yield version without additional threads would be optimal. I don't need concurrency or speed, just simple. You may be able to use Generator in std.concurrency for this: https://dlang.org/phobos/std_concurrency.html#.Generator You could also rephrase your algorithm as a range, which would not involve concurrency but may be unintuitive to implement. In this case you would likely have to use a stack or queue rather than a recursive function. Is it an option to just accumulate the information regarding your algorithm in a separate data structure and then analyze it after the algorithm is complete, or has recorded some number of entries?
Re: Learning resources
On Tuesday, 24 January 2017 at 20:15:38 UTC, Dlearner wrote: Hey all! I'm learning programming through D and having a really good time (much better than with C++ or Python). I'm aiming to make little games with it as a hobby so I've learned some OpenGL stuff. But, I feel like I'm learning more library code rather than D concepts and idioms, especially where efficiency and performance are concerned. (I also have a light interest in functional programming for when it would make sense to employ those principles.) Are there any tutorials that show off the power of D with worked examples that explain the importance of certain features? I highly recommend going through this to start with: https://p0nce.github.io/d-idioms/ I've been working on this library (which includes some gamedev and functional programming stuff). It's moderately-well documented and I am more than happy to help and provide examples if it interests you https://github.com/pineapplemachine/mach.d/tree/master/mach/sdl
Re: Multiple return type or callback function
On Monday, 23 January 2017 at 15:15:35 UTC, aberba wrote: I'm creating a function to authenticate user login. I want to determine login failure (Boolean) and error message (will be sent to frontend) but D does have multiple return type (IMO could use struct but will make code dirty with too much custom types). struct Result { bool success = false string message; } Result authen(){} auto r = authen() if (r.success) writeln(r.message); I use structs like this quite frequently, myself. It works well and I don't think it's particularly ugly. And if you don't want to pollute the namespace with one-off structs, you can also place them inside the function that's returning them (making them voledmort types).
Re: Profiling calls to small functions
On Saturday, 21 January 2017 at 12:33:57 UTC, albert-j wrote: Now I dmd -profile it and look at the performance of funcA with d-profile-viewer. Inside funcA, only 20% of time is spend in funcB, but the rest 80% is self-time of funcA. How is it possible, when funcB has three times the calculations of funcA? It appears that the call to funcB itself is very expensive. I'm not sure if it's what happening in this case but, in code as simple as this, function calls can sometimes be the bottleneck. You should see how compiling with/without -O affects performance, and adding `pragma(inline)` to funcB.
Re: Assigning in constructor.
On Wednesday, 18 January 2017 at 23:08:07 UTC, Adam D. Ruppe wrote: On Wednesday, 18 January 2017 at 22:57:22 UTC, NotSpooky wrote: Is it undefined behavior to assign to a pointer in the constructor of a struct? Yes: http://dlang.org/spec/struct.html "A struct is defined to not have an identity; that is, the implementation is free to make bit copies of the struct as convenient." That means it might copy and/or move it without giving you a chance to update the pointer. Updating in postblit can help sometimes but still the compiler and library are allowed to move structs without notice. Practically speaking I've found that if the struct was allocated on the heap, then acquires that pointer and seems not to break anything, e.g. how it's used in the uncopyable struct here https://github.com/pineapplemachine/mach.d/blob/master/mach/collect/linkedlist.d#L165
Re: Where is floating point next{Up,Down}?
On Tuesday, 17 January 2017 at 23:41:27 UTC, Nordlöw wrote: On Tuesday, 17 January 2017 at 23:38:46 UTC, Ali Çehreli wrote: Found'em! :) https://dlang.org/phobos/std_math.html#.nextUp Thanks! (Shouts into the soundless void) https://github.com/pineapplemachine/mach.d/blob/master/mach/math/floats/neighbors.d
Re: Printing a floats in maximum precision
On Wednesday, 18 January 2017 at 00:09:42 UTC, Nordlöw wrote: What's the easiest way to print a double in maximum precision? https://github.com/pineapplemachine/mach.d/blob/master/mach/text/numeric/floats.d#L60 You can also try the formatting directive "%.20f" but unlike the former I can't offer any guarantees of its accuracy (it's probably accurate)
Re: Initializing floating point types with explicit mantisa and exponent
On Tuesday, 17 January 2017 at 00:08:24 UTC, Nordlöw wrote: How do I best initialize a D double to an exact mantissa and exponent representation? I'm specifically interested in 2^^i for all i in [min_exp, max_exp] This mach module can do the job: https://github.com/pineapplemachine/mach.d/blob/master/mach/math/floats/inject.d
Re: Quine using strings?
On Monday, 16 January 2017 at 09:33:23 UTC, Nestor wrote: PS. Isn't this approach considered "cheating" in quines? ;) I'm afraid so - while the empty program has been technically accepted as being a quine (e.g. http://www.ioccc.org/1994/smr.hint) programs which use file io to read their own source have not.
Re: Quine using strings?
On Sunday, 15 January 2017 at 21:37:53 UTC, Nestor wrote: Any ideas for a shorter version (preferably without using pointers)? When compiling with the -main flag, this D program is a quine:
Re: Parsing a UTF-16LE file line by line, BUG?
On Friday, 6 January 2017 at 06:24:12 UTC, rumbu wrote: I'm not sure if this works quite as intended, but I was at least able to produce a UTF-16 decode error rather than a UTF-8 decode error by setting the file orientation before reading it. import std.stdio; import core.stdc.wchar_ : fwide; void main(){ auto file = File("UTF-16LE encoded file.txt"); fwide(file.getFP(), 1); foreach(line; file.byLine){ writeln(file.readln); } } fwide is not implemented in Windows: https://msdn.microsoft.com/en-us/library/aa985619.aspx That's odd. It was on Windows 7 64-bit that I put together and tested that example, and calling fwide definitely had an effect on program behavior.
Re: Parsing a UTF-16LE file line by line, BUG?
On Wednesday, 4 January 2017 at 19:20:31 UTC, Nestor wrote: On Wednesday, 4 January 2017 at 18:48:59 UTC, Daniel Kozák wrote: Ok, I've done some testing and you are right byLine is broken, so please fill a bug A bug? I was under the impression that this function was *intended* to work only with UTF-8 encoded files. I'm not sure if this works quite as intended, but I was at least able to produce a UTF-16 decode error rather than a UTF-8 decode error by setting the file orientation before reading it. import std.stdio; import core.stdc.wchar_ : fwide; void main(){ auto file = File("UTF-16LE encoded file.txt"); fwide(file.getFP(), 1); foreach(line; file.byLine){ writeln(file.readln); } }
Re: Working with Modules
On Wednesday, 28 December 2016 at 02:08:44 UTC, Guy Asking a Question wrote: import test; <---dmd choking here. You will need to use the -I option of dmd/rdmd to inform the compiler of where your `HopefullySomeDLibrary` directory is located, as well as any other places you will want to import modules from. If you're using another compiler, it should have a similar option. (Though I can't speak from experience.)
Re: sort, .array and folding on immutable data (finding most common character in column of matrix)
On Monday, 19 December 2016 at 09:24:38 UTC, Ali wrote: Ok so laziness stops as soon as sort is required on a range then? Ahh, because in place algorithms? Are there any plans in D to make is to that you can output copies to collections so that you could do something like filter.transpose.sort and just have it output a modified copy? This is a shortcoming of Phobos - here is a package of sorting algorithms including some that do not require their inputs to be mutable, random access, and/or finite: https://github.com/pineapplemachine/mach.d/tree/master/mach/range/sort The library is permissively licensed; feel free to take out whatever you need. It's worth noting that giving up eagerness, random access, etc. often comes with a speed penalty. It may be more efficient just to copy the lazy things into memory first and then sort in-place, as you have been doing.
Re: problem with isnan
On Thursday, 10 November 2016 at 16:47:30 UTC, Adam D. Ruppe wrote: On Thursday, 10 November 2016 at 16:41:56 UTC, Charles Hixson wrote: It's *supposed* to be nan, and the assert message reports that it is, but it should pass the assert test, not throw an assertion. What am I doing wrong? How did you set it? There are like billions of different NaNs. I'm not sure if isnan checks for all of them. (I'm also not sure that it doesn't, the docs don't specify.) you might try using std.math.isNaN instead and see what it does. Incidentally, I just recently submitted a PR to fix this. What probably happened is that you're referring to a limited `isnan` method defined as a unittest utility method in object.d that should have been private but wasn't. You want to use `isNan` instead.
Re: Best way to get ceil(log2(x)) of a BigInt?
On Wednesday, 2 November 2016 at 14:24:42 UTC, Andrea Fontana wrote: On Wednesday, 2 November 2016 at 14:05:50 UTC, pineapple wrote: I'm trying to do some math stuff with std.bigint and realized there's no obvious way to calculate the ceil of log2 of a bigint. Help? How big are your bigints? I think they'll generally stay between 0 and 2^200 I came up with this, I guess it'll work? auto clog2(BigInt number) in{ assert(number > 0); }body{ uint log; auto n = number - 1; while(n > 0){ log++; n >>= 1; } return log; }
Best way to get ceil(log2(x)) of a BigInt?
I'm trying to do some math stuff with std.bigint and realized there's no obvious way to calculate the ceil of log2 of a bigint. Help?
Re: A question of function design?
On Thursday, 27 October 2016 at 22:17:35 UTC, WhatMeWorry wrote: I'm using Derelict GLFW3 and I found the following GLFW3 code snippet in a demo. In a small demo, crap like this usually isn't a big deal. It's not common practice, though, and for good reason. You should definitely avoid imitating it.
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 07:55:36 UTC, orip wrote: I get "Error: mismatched function return type inference" errors with choosing the return type for functions that work on ranges using, e.g, std.algorithm or std.range functions, but have different behavior based on runtime values. The return type is always a range with the same underlying type. Here's an example: auto foo(int[] ints) { import std.range; if (ints.length > 10) { return chain(ints[0..5], ints[8..$]); } else { //return ints; // Error: mismatched function return type inference of int[] and Result return chain(ints[0..0], ints[0..$]); // This workaround compiles } } Is there a compatible return type that can be used, or some other workaround? I couldn't find one when searching for the error or looking at the phobos source code. Thanks! orip Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`.
Re: Why can't static arrays be sorted?
On Thursday, 6 October 2016 at 09:17:08 UTC, pineapple wrote: On Wednesday, 5 October 2016 at 19:30:01 UTC, Jonathan M Davis wrote: Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem. It doesn't even make conceptual sense for a static array to be a range, because you can't remove elements from it. - Jonathan M Davis Just because the static array itself isn't a range doesn't mean that it should be necessary to do unintuitive gymnastics with it just to pass it to functions like `sort`. I mean, people post here how often asking why static or dynamic arrays aren't being accepted by Phobos' range functions in their code? Maybe Phobos really ought to consider another approach. Accepting things that are _valid_ as ranges and not only things that are ranges themselves has proven to be an effective strategy in mach.
Re: Why can't static arrays be sorted?
On Wednesday, 5 October 2016 at 19:30:01 UTC, Jonathan M Davis wrote: Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem. It doesn't even make conceptual sense for a static array to be a range, because you can't remove elements from it. - Jonathan M Davis Just because the static array itself isn't a range doesn't mean that it should be necessary to do unintuitive gymnastics with it just to pass it to functions like `sort`.
Re: Why can't static arrays be sorted?
On Wednesday, 5 October 2016 at 18:19:27 UTC, TheGag96 wrote: On Wednesday, 5 October 2016 at 02:19:13 UTC, Jonathan M Davis wrote: The problem is that static arrays aren't ranges (calling popFront on them can't work, because their length isn't mutable). However, you can slice a static array to get a dynamic array which _is_ a range. e.g. thing[].sort(); Just make sure that such a dynamic array does not outlive the static array, or it will refer to invalid memory (which would not be a problem in this case). - Jonathan M Davis Ah thanks guys. I think I just got used to thinking arrays would always be found to be ranges by the compiler. Good to know! Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem.
Re: How to make rsplit (like in Python) in D
On Monday, 3 October 2016 at 19:25:59 UTC, Uranuz wrote: When I pass empty string to splitter in most of languages I expect to get list with 1 item (empty string) as a result, but I get error instead. And I see inconsistency in that .front behaves normally, but .back is not. Usually I access front of range directly without any check when I expect it to have exactly 1 item. But in this case it not working and is very strange. Hm, if front works but not back that is probably a bug. I think checking whether the range is empty before accessing the member should be a viable workaround.
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 17:55:08 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:32:59 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:23:16 UTC, Uranuz wrote: [...] But these example fails. Oops. Looks like a bug( import std.stdio; import std.algorithm; import std.range; import std.string; [...] I created bug report on this: https://issues.dlang.org/show_bug.cgi?id=16569 This isn't a bug. It's illegal to access the front or back of an empty range. (If anything is a bug, it's the nondescriptiveness of the error.) You should write this instead: void main() { string str = ""; auto split = str.splitter('.'); if(!split.empty) writeln(split.back); }
Re: Get date at compile time
On Saturday, 1 October 2016 at 14:43:31 UTC, Adam D. Ruppe wrote: On Saturday, 1 October 2016 at 14:41:22 UTC, Andrew wrote: Is there any way to get the system date at compile time. Not exactly, but the special symbol __TIMESTAMP__ gets a string out of the compiler at build time. http://dlang.org/spec/lex.html#specialtokens Has there been consideration for adding separate integral tokens for day, month, year, etc? The documentation there doesn't seem to specify but I assume currently the timestamps are for local time? Though I don't currently have any need for this feature I'd imagine that if I did I'd want the time in UTC, not locally, or if it was local that I'd at least want to be able to similarly retrieve the timezone info.
Is there any way to have [] overloads use compile-time indexes as is currently done for Tuples?
I'd really like to define my own types that accept indexes for opIndex and opSlice as template arguments. Is there any way to do this? If not, this seems like an obvious thing to add to the language - what's been holding it back?
Re: how to access struct member using [] operator?
On Sunday, 25 September 2016 at 16:07:59 UTC, Basile B. wrote: WooW I have to say that I'm mesmerized ! How can this works ? "member" is run time variable so the return type shouldn't be inferable. The int fields are promoted to and returned as floats.
Re: how to access struct member using [] operator?
On Sunday, 25 September 2016 at 04:54:31 UTC, grampus wrote: Dear all For example, I have a struct struct point{int x;int y} point a; Is there an easy way to access x and y by using a["x"] and a["y"] I guess I need to overload [], but can't figure out how. Someone can help? Thank you very much If they all share the same type, you can use a switch like @Namespace suggested. If the "x" and "y" strings are available at compile-time, you can use a mixin. auto getattr(string attr)(point a){ mixin(`return a.` ~ attr ~ `;); } auto x = a.attr!"x"; Otherwise, no. D types aren't dynamic in the same way that Python's types are.
Re: Is it possible to override the behavior of a type when used in a conditional expression?
On Saturday, 10 September 2016 at 14:24:23 UTC, ag0aep6g wrote: On 09/10/2016 04:10 PM, pineapple wrote: I've got a struct and it would be very convenient if I could specify what happens when I write `if(value)` - is this possible? `if (value)` implies a cast to bool. Define opCast!bool and it gets called: struct S { bool opCast(T : bool)() { return true; } } void main() { S value; import std.stdio: writeln; if (value) writeln("yup"); } Huh, I could've sworn that some time ago I tried that and it didn't work. Was this a recent addition to the language?
Is it possible to override the behavior of a type when used in a conditional expression?
I've got a struct and it would be very convenient if I could specify what happens when I write `if(value)` - is this possible?
Re: Fully-qualified symbol disambiguation is deprecated???
On Friday, 9 September 2016 at 11:54:42 UTC, Steven Schveighoffer wrote: Can you demonstrate the issue? I have never heard of this. imports should work when done inside a function. -Steve Tried and failed to reproduce with a simple example, but any time I've tried doing it in the code I'm working on I get Symbol Undefined errors which I had to fix by moving imports out of struct/class methods.
Re: Using local import path
On Friday, 9 September 2016 at 09:43:15 UTC, O-N-S wrote: On Friday, 9 September 2016 at 09:31:54 UTC, pineapple wrote: On Friday, 9 September 2016 at 08:25:40 UTC, rikki cattermole wrote: TLDR: no you cannot do what you were thinking. Seems like something one ought to be able to do, though. DIP time? Where can I find DIP? Here? https://forum.dlang.org/group/issues Here: https://github.com/dlang/DIPs
Re: Fully-qualified symbol disambiguation is deprecated???
On Thursday, 8 September 2016 at 22:13:26 UTC, Steven Schveighoffer wrote: I posted an article on this: http://www.schveiguy.com/blog/2016/03/import-changes-in-d-2-071/ -Steve Regarding that article: Another import-related bug fix is to prevent unintentional hijacking of symbols inside a scoped import. Such imports are not at module level, and import inside a function or other scope. I've actually never been able to get imports to work if I place them inside a function. They'll work fine compiling that single module which has the import-in-a-function, but as soon as I import that module from somewhere else I'll hit compile errors. Is this a known bug or am I just uniquely screwed?
Re: Using local import path
On Friday, 9 September 2016 at 08:25:40 UTC, rikki cattermole wrote: TLDR: no you cannot do what you were thinking. Seems like something one ought to be able to do, though. DIP time?
Re: Templates problem
On Wednesday, 7 September 2016 at 20:29:42 UTC, jmh530 wrote: Thanks for the reply. It looks like an interesting idea. You might consider adding this (or a modified version) to a read me in the range subfolder. Fuck it, I took an hour to document the most significant modules. https://github.com/pineapplemachine/mach.d/tree/master/mach/range
Re: Templates problem
On Wednesday, 7 September 2016 at 18:22:39 UTC, jmh530 wrote: On Wednesday, 7 September 2016 at 18:10:45 UTC, pineapple wrote: You might want to check out the ranges package of the library I'm working on. https://github.com/pineapplemachine/mach.d/tree/master/mach/range There's a lot of stuff there. Do you mind giving a TL;DR version of what your range library does differently than phobos? So the first difference you're likely to notice is that it's not as well documented. (Sorry. I'm a busy woman. I'll get around to it.) I try to make up for it with copious unit tests, which should provide a good example for how to use any given module. In terms of functionality, the single-biggest difference is that unlike phobos I don't treat arrays or any other collection directly as ranges; instead types may provide an `asrange` property returning a range that enumerates their contents. This architecture allows you to express HOFs as shown in that prior post, not having to worry about whether it's safe to treat the array itself as a range or whether you have to slice it. Other significant differences include not requiring bidirectional, slicing, random-access ranges to also be saving ("forward") ranges; (for the most part) supporting immutable elements in ranges; and a more clearly defined interface for what insertion and removal operations you may perform upon a range and how they are expected to behave. There are a few things phobos provides that I don't yet, but there's also a handful of things implemented in mach.range that aren't in phobos. (My personal favorite example of such is its small suite of PRNG implementations.) Also: I just pushed the fix.
Re: Templates problem
On Tuesday, 6 September 2016 at 14:38:54 UTC, Russel Winder wrote: and I have no idea just now why it is complaining, nor what to do to fix it. You might want to check out the ranges package of the library I'm working on. https://github.com/pineapplemachine/mach.d/tree/master/mach/range This topic motivated me to see if my map function worked with static arrays. Turns out that somehow I'd neglected to include a unit test, and it in fact failed. Once I've had a chance to commit the couple-line fix, probably in a couple hours, this will be a valid program: import mach.range : map; import std.stdio : writeln; void main(){ const(const(int)[3]) array = [1, 2, 3]; auto mapped = array.map!(e => e + 1); mapped.front.writeln; // 2 mapped[0].writeln; // 2 // etc. }
Re: Inexplicable invalid memory operation when program terminates
On Monday, 5 September 2016 at 17:33:17 UTC, pineapple wrote: Am I missing something or is this an obnoxious bug with the GC? Oh, I've been trying to figure this out on and off for days and of course five minutes after I post I fix the problem. I'm not really sure why, but it did fix it. In the example the window class destructor was being called. I found that if I did `delete win;` at the end there it worked fine, but otherwise the GC was tripping up? I removed a console output statement and rewrote a thing using a foreach loop instead of a filter range and it stopped complaining. I'm realizing now, too, that the reason I was getting the same error in commits long before I added that particular thing the GC disliked was an entirely different one. That was not fun to debug. On Monday, 5 September 2016 at 17:42:18 UTC, Lodovico Giaretta wrote: InvalidMemoryOperationError is raised when you try to allocate memory inside a destructor called by the GC. I see from your repository that the destructor of Window uses a function called log defined by yourself. That function uses writeln internally. writeln is not @nogc, so it may be that that call to log in the destructor is actually allocating memory. That was in fact part of the problem
Re: Getting the superclass of a type?
On Monday, 5 September 2016 at 15:43:52 UTC, Lodovico Giaretta wrote: On Monday, 5 September 2016 at 15:20:10 UTC, pineapple wrote: I'd like to be able to write something like this, but I haven't been able to find anything in the docs class Base{} class Sub: Base{} static assert(is(SuperClassOf!Sub == Base)); https://dlang.org/phobos/std_traits.html#.BaseClassesTuple Aha, thank you!
Getting the superclass of a type?
I'd like to be able to write something like this, but I haven't been able to find anything in the docs class Base{} class Sub: Base{} static assert(is(SuperClassOf!Sub == Base));
What is this behavior and how do I disable or get around it?
This program does not compile. Error: cannot implicitly convert expression (cast(int)x - cast(int)x) of type int to ubyte void main(){ ubyte x; x = x - x; } I don't even know what to say. Who thought this behavior was a good idea?
Re: Prevent copy of range in foreach
On Wednesday, 31 August 2016 at 14:03:20 UTC, Yuxuan Shui wrote: I want to make a hash table that uses std.experiment.allocator. The bucket is allocated from an allocator, and freed in ~this(). I don't want to copy the whole bucket in this(this). Maybe I should use a reference counter or something? A reference counter should solve the problem, but there's also the option of just making it a class instead of a struct
Re: Checking all elements are unique.
On Wednesday, 31 August 2016 at 07:40:39 UTC, Dorian Haglund wrote: Hello, I have an array of objects of class C which contain a id member. I want to figure out if all the id members are unique using functional primitives. For example, if I have: class C { int id; } and an array of C 'Cs'; My idea was to do: auto ids = Cs.map!(c => c.id); assert(equal(ids.sort().uniq(), ids.sort())); But it doesn't compile because I can't can call sort on ids. Any idea why ? and how to solve my initial problem, which is to check all ids are unique. Regards, Dorian Your post inspired me to write this addition to my D library, I'll commit it later today but you can use it straightaway by just adding this file. It will be far more efficient than any of the other solutions posted here. The file - http://pastebin.com/RN2nagEn The library - https://github.com/pineapplemachine/mach.d Example usage: import std.stdio; import mach.range.unique; class C{ this(int id){this.id = id;} int id; } auto c0 = [new C(0), new C(1), new C(2), new C(3)]; auto c1 = [new C(0), new C(1), new C(2), new C(3), new C(0)]; c0.unique!(c => c.id).writeln; // true c1.unique!(c => c.id).writeln; // false
Re: Does D have any construct like Python's with keyword?
I would just love if I could express this as something more like context(auto file = File("some_file.txt")){ file.write(); }
Re: Does D have any construct like Python's with keyword?
On Friday, 26 August 2016 at 23:30:15 UTC, Cauterite wrote: On Friday, 26 August 2016 at 23:28:27 UTC, pineapple wrote: I've grown to very much appreciate how context initialization and teardown can be very conveniently handled using `with` in Python. Is there any clean way to imitate this syntax in D? Yep, scope guards. auto p = OpenProcess(...); scope(exit) {CloseHandle(p);}; What I had in mind was something more like this, but not quite so messy-looking. Though after having actually written it out I'm wondering if it's not better to just keep it looking like this, or similar, rather than make it part of the language. It's not _too_ hideous. import std.stdio; void context(Context, Dg)(Context context, Dg content){ scope(exit) context.conclude; content(context); } struct File{ this(string path){ writeln("open a file"); } void write(){ writeln("write some data"); } void conclude(){ writeln("close the file"); } } void main(){ context(File("some_file.txt"), (File file){ file.write(); }); }
Does D have any construct like Python's with keyword?
I've grown to very much appreciate how context initialization and teardown can be very conveniently handled using `with` in Python. Is there any clean way to imitate this syntax in D?
Re: compile error while use `extern(C++, class)`
On Thursday, 18 August 2016 at 11:43:03 UTC, Lodovico Giaretta wrote: On Thursday, 18 August 2016 at 11:11:10 UTC, mogu wrote: On Thursday, 18 August 2016 at 10:45:14 UTC, Lodovico Giaretta wrote: Which kind of error? An error message by the compiler? One by the linker? The compiler crashes? Compiler Error exactly. The minimal code is(dmd or ldc2 in ubuntu 16.04 lts): ``` extern (C++, struct) class A {} ``` Error: identifier expected for C++ namespace found 'struct' when expecting ')' declaration expected, not ')' Which compiler version are you using? On DMD 2.071.0 this does not work. On nightly build it compiles without errors. So probably it is a feature that is present, but didn't ship yet. I suggest you download the latest beta or a nightly build from the site. Wouldn't this be more syntactically consistent if it were "Cpp" instead of "C++"?
Re: minor question of the difference between " and '
On Wednesday, 10 August 2016 at 23:32:54 UTC, WhatMeWorry wrote: Afterall, isn't that the definition of a string? So what's up with the two groupings of single quotes? http://www.howtogeek.com/howto/29980/whats-the-difference-between-single-and-double-quotes-in-the-bash-shell/
Re: Why Does Dscanner Warn About a Missing toHash if opEquals is Defined?
On Sunday, 31 July 2016 at 18:57:50 UTC, Jack Stouffer wrote: Next question: what's the fastest hashing implementation that will provide the least collisions? Is there a hash implementation that's perfered for AAs? There's no hashing function that would be specifically better for associative arrays, it's a hashing function either way. The primary things that should affect what your hashing function looks like should be what your inputs - keys for an AA - look like. djb2 is my go-to for string hashing because it's conceptually simple, efficient, and effective for most use cases. http://www.cse.yorku.ca/~oz/hash.html Every hashing function will produce collisions. As long as you handle them, and as long as they aren't inordinately frequent, you'll be fine.
Re: FunctionTypeOf behaves unexpectedly for function pointers?
On Saturday, 30 July 2016 at 12:54:32 UTC, Basile B. wrote: func is a pointer to a function but FunctionTypeOf extracts the target type. So the correct assertion is static assert(is(FunctionTypeOf!func* == typeof(func))); I can't believe that it worked for delegates because the same happens. It extracts the target type, i.e it discards the information saying that it's a member function: import std.traits; void function() fun; void delegate() dlg; static assert(is(FunctionTypeOf!fun* == typeof(fun))); static assert(is(FunctionTypeOf!dlg* == typeof(fun))); Ah, that makes sense. Thank you!
FunctionTypeOf behaves unexpectedly for function pointers?
This failure seems curious and I haven't been able to understand why it occurs, or whether it might be intentional. For all other callable types, including functions and delegates and types implementing opCall, the assertion passes. import std.traits : FunctionTypeOf; void function() func; // Error: static assert (is(void() == void function())) is false static assert(is(FunctionTypeOf!func == typeof(func)));
Re: string mixin and alias
On Friday, 29 July 2016 at 12:22:54 UTC, Andre Pany wrote: It is more or less syntax sugar. In the main function instead of writing "mixin(generateCode(s));" I want to write "foo(s);". So, the mixin statement is hidden while the functionality of mixin stays. Kind regards André As far as I know, there's no way to hide away the `mixin` statement in a template or alias. You could do something like this, if you really wanted to, but really the only difference is that it uses fewer parentheses. string generateCode(string s){return "";} enum foo(string s) = generateCode(s); void main(){ enum s = "int a = 2 + 3; int b = 4 + a;"; mixin foo!s; }
Re: string mixin and alias
On Friday, 29 July 2016 at 06:38:17 UTC, Andre Pany wrote: Hi, is there a way to alias a string mixin? Neither foo nor foo2 compiles. import std.meta : Alias; alias foo = (s) => Alias!(mixin(generateCode(s))); alias foo2(string s) = Alias!(mixin(generateCode(s))); string generateCode(string s){return "";} void main() { enum s = "a = 2 + 3; b = 4 + a;"; foo(s); foo2(s); } Kind regards André It's not clear what you're trying to accomplish. What would you expect this code to do?
Re: Verifying the arguments of a function with ref parameters?
On Thursday, 28 July 2016 at 21:49:00 UTC, pineapple wrote: On Thursday, 28 July 2016 at 20:28:39 UTC, jdfgjdf wrote: "Parameters!dgref.init" does not yield a reference. The real error is not displayed. In a normal context it would be "stuff is not callable with" What would be a better way to check whether some callable can be called using a parameters tuple? Oh, I answered my own question enum bool dgrefcallable = is(typeof((){auto params = Parameters!dgref.init; dgref(params);}));
Re: Verifying the arguments of a function with ref parameters?
On Thursday, 28 July 2016 at 20:28:39 UTC, jdfgjdf wrote: "Parameters!dgref.init" does not yield a reference. The real error is not displayed. In a normal context it would be "stuff is not callable with" What would be a better way to check whether some callable can be called using a parameters tuple?
Verifying the arguments of a function with ref parameters?
Why doesn't this code do what I'd expect it to, and how can I fix it? unittest{ import std.traits : Parameters; // Works as expected alias dg = int delegate(int value); enum bool dgcallable = is(typeof((){dg(Parameters!dg.init);})); pragma(msg, dgcallable); // Prints true // Doesn't work as expected alias dgref = int delegate(ref int value); enum bool dgrefcallable = is(typeof((){dgref(Parameters!dgref.init);})); pragma(msg, dgrefcallable); // Prints false } Thanks!
Re: shuffle a character array
On Wednesday, 20 July 2016 at 18:32:15 UTC, Jesse Phillips wrote: I think you mean that your range library treats them as arrays of code units, meaning your library will break (some) unicode strings. Right - I disagree with the assessment that all (or even most) char[] types are intended to represent unicode strings, rather than arrays containing chars. If you want your array to be interpreted as a unicode string, then you should use std.utc's byGrapheme or similar functions.
Re: shuffle a character array
On Wednesday, 20 July 2016 at 16:04:50 UTC, pineapple wrote: On Wednesday, 20 July 2016 at 16:03:27 UTC, pineapple wrote: On Wednesday, 20 July 2016 at 13:33:34 UTC, Mike Parker wrote: There is no auto-decoding going on here, as char[] and wchar[] are rejected outright since they are not considered random access ranges. They are considered random access ranges by my ranges library, because they are treated as arrays of characters and not as unicode strings. On second thought that's not even relevant - the linked-to module performs an out-of-place shuffle and so does not even require the input range to have random access. Pardon my being scatterbrained (and there not being an "edit post" function) - you're referring to phobos not considering char[] and wchar[] to have random access? The reason they are not considered to have random access is because they are auto-decoded by other functions that handle them, and the auto-decoding makes random access inefficient. Not because shuffleRandom itself auto-decodes them.
Re: shuffle a character array
On Wednesday, 20 July 2016 at 16:03:27 UTC, pineapple wrote: On Wednesday, 20 July 2016 at 13:33:34 UTC, Mike Parker wrote: There is no auto-decoding going on here, as char[] and wchar[] are rejected outright since they are not considered random access ranges. They are considered random access ranges by my ranges library, because they are treated as arrays of characters and not as unicode strings. On second thought that's not even relevant - the linked-to module performs an out-of-place shuffle and so does not even require the input range to have random access.
Re: shuffle a character array
On Wednesday, 20 July 2016 at 13:33:34 UTC, Mike Parker wrote: There is no auto-decoding going on here, as char[] and wchar[] are rejected outright since they are not considered random access ranges. They are considered random access ranges by my ranges library, because they are treated as arrays of characters and not as unicode strings.
Re: shuffle a character array
On Wednesday, 20 July 2016 at 08:02:07 UTC, Mike Parker wrote: You can then go to the documentation for std.range.primitives.isRandomAccessRange [2], where you'll find the following: "Although char[] and wchar[] (as well as their qualified versions including string and wstring) are arrays, isRandomAccessRange yields false for them because they use variable-length encodings (UTF-8 and UTF-16 respectively). These types are bidirectional ranges only." There's also the shuffle module in mach.range which doesn't do any auto-decoding: https://github.com/pineapplemachine/mach.d/blob/master/mach/range/random/shuffle.d
Re: to auto or not to auto ( in foreach )
On Sunday, 17 July 2016 at 01:57:21 UTC, pineapple wrote: On Saturday, 16 July 2016 at 22:05:49 UTC, ketmar wrote: actually, `foreach (v; rng)` looks like `foreach` is *reusing* *existing* *variable*. most of the time you can put `immutable` or something like that there to note that it is not reusing (purely cosmetical thing), but sometimes you cannot, and then `auto` is perfect candidate... but it is not allowed. (sigh) Chipping in my agreement. foreach(x; y) makes as much syntactic sense as for(x = 0; x < y; x++) where x was not previously defined. One does not expect something that does not look like every other variable definition in the language to be defining a new variable. Furthermore, if foreach(int x; y) is legal then why isn't foreach(auto x; y)?
Re: to auto or not to auto ( in foreach )
On Saturday, 16 July 2016 at 22:05:49 UTC, ketmar wrote: actually, `foreach (v; rng)` looks like `foreach` is *reusing* *existing* *variable*. most of the time you can put `immutable` or something like that there to note that it is not reusing (purely cosmetical thing), but sometimes you cannot, and then `auto` is perfect candidate... but it is not allowed. (sigh) Chipping in my agreement. foreach(x; y) makes as much syntactic sense as for(x = 0; x < y; x++) where x was not previously defined. One does not expect something that does not look like every other variable definition in the language to be defining a new variable.
Interface final methods are erased by the overloads of a subclass
I was surprised when this didn't work. What's the rationale? Is there any better workaround than renaming methods? interface A{ void foo(); final void foo(int x){} } class B: A{ void foo(){} } void main(){ auto b = new B(); b.foo(); b.foo(10); // not callable using argument types (int) }
Re: Defining and overriding methods of an abstract base class which must accept a template parameter
On Sunday, 10 July 2016 at 21:20:34 UTC, Basile B. wrote: The problem you encounter here is that templatized functions cannot be virtual. If you remove "abstract" and put an empty body than it works, but you lose the whole OOP thing, i.e you cannot call the most derived override from the base. Yeah, that was the first thing I tried, and it took me a while and some measure of annoyance to realize the base method was being called instead of the derived one. Surely there's some reasonable workaround?
Defining and overriding methods of an abstract base class which must accept a template parameter
This is essentially what I'm trying to accomplish. The intuitive solution, of course, does not work. In theory I could write a separate method for every anticipated return type, but that would be horrible and in that case I'd probably just write the damn thing in a dynamically-typed language instead. import std.conv; abstract class BaseClass{ abstract X convertSomePropertyTo(X)(); } class SubClass(T): BaseClass{ T property; X convertSomePropertyTo(X)(){ return property.to!X; } } void main(){ BaseClass obj = new SubClass!int; auto x = obj.convertSomePropertyTo!real; // Error: function test.BaseClass.convertSomePropertyTo!real.convertSomePropertyTo non-virtual functions cannot be abstract }
Re: Typesafe variadic functions requiring at least one argument
On Thursday, 7 July 2016 at 03:52:40 UTC, Jonathan M Davis wrote: However, it looks like you can combine those two types of variadic functions to get more or less what you want (albeit more verbosely). e.g. template isInt(T) { enum isInt = is(std.traits.Unqual!T == int); } void test(Args...)(Args args) if(args.length > 0 && std.meta.allSatisfy!(isInt, Args)) { test2(args); } Exactly what I was looking for. Thanks!
Typesafe variadic functions requiring at least one argument
I'd like to do something like this but it doesn't seem to be legal - void test(int[] ints...) if(ints.length){ // stuff } Not being able to specify this interferes with how I'd like to define my method overloads. What's the best way to achieve what I'm looking for?
Shorthand for defining numeric literals as size_t and ptrdiff_t
There are suffixes for numbers like 0L, 0u, 0f, 0d, etc. What about suffixes representing size_t and ptrdiff_t? Do they exist? If not, why?
Passing anonymous templated functions as template parameters
Here's a simple code example to illustrate what I expected to work and didn't - is this a mistake in my syntax or a limitation of the language? template SomeTemplate(alias func){ auto templatefunc(T)(int x){ return func!T(x); } } // Valid auto somefunc(T)(int x){ return cast(T) x; } alias fn1 = SomeTemplate!somefunc; // Not valid alias fn2 = SomeTemplate!( (T)(int x){return cast(T) x;} );
Re: How to call one static method from another?
On Tuesday, 14 June 2016 at 07:35:36 UTC, Andrea Fontana wrote: Simply: method2(); Also, typeof(this).method2();
Re: how to get rid of "cannot deduce function from argument types" elegantly
On Monday, 13 June 2016 at 22:54:13 UTC, Ali Çehreli wrote: Tree!T tree(TL, T, TR)(TL left, T node, TR right) { return new Tree!T(left, node, right); } There's also this: Tree!T tree(TL, T, TR)(TL left, T node, TR right) if( (is(TL == Tree!T) || is(TL == typeof(null))) && (is(TR == Tree!T) || is(TR == typeof(null))) ){ return new Tree!T(left, node, right); }
Re: Is it possible to use a template to choose between foreach and foreach_reverse?
On Saturday, 4 June 2016 at 15:43:01 UTC, Mihail K wrote: As far as I recall, foreach_reverse is deprecated in favour of range operations. ie. import std.algorithm, std.range; static if(forward) { items.each!(item => doStuff()); } else { items.retro.each!(item => doStuff()); } As for your question, I suggest writing a range function that calls retro conditionally. Something like, items.direction!(forward).each!(item => doStuff()); Won't this pattern fail if items is a type implementing opApply and/or opApplyReverse?
Is it possible to use a template to choose between foreach and foreach_reverse?
It would be fantastic if I could write this - static if(forward){ foreach(item; items) dostuff(); }else{ foreach_reverse(item; items) dostuff(); } as something like this - foreach!forward(item; items) dostuff(); Is there any way to accomplish this?
Unittests run without error when done individually, but when unittesting the package some fail
How this could possibly be happening is confounding me and I have no idea if it's something I missed or some contrived compiler bug. This is the package.d that previously I've compiled with unittest every so often as a way of doing regression testing - https://github.com/pineapplemachine/mach.d/blob/master/mach/range/package.d Currently, when compiled as is, tests in `indexof` and `contains` (a depending module) fail. If those two are commented out, everything else passes. If either of those modules is unittested individually, rather than with the others as part of the package, everything passes. What's going on here?
Re: Getting the parameters and other attributes belonging to the function overload with the greatest number of arguments
On Tuesday, 31 May 2016 at 20:46:37 UTC, Basile B. wrote: Yes this can be done, you must use the getOverload trait: https://dlang.org/spec/traits.html#getOverloads The result of this trait is the function itself so it's not hard to use, e.g the result can be passed directly to 'Parameters', 'ReturnType' and such library traits. Awesome, thank you!
Getting the parameters and other attributes belonging to the function overload with the greatest number of arguments
I'd like to find the overload of some function with the most parameters and (in this specific case) to get their identifiers using e.g. ParameterIdentifierTuple. There have also been cases where I'd have liked to iterate over the result of Parameters!func for each overload of that function. Can this be done, and if so how?
Re: Operator overloading through UFCS doesn't work
Here's one more vote for extending UFCS to operator overloading. Elie wrote that it's "a restriction that seems pointless and arbitrary"... which summarizes my own thoughts rather well, too. There are certainly concerning scenarios that can arise from making this change, but the correct way to approach this problem is not to tell the programmer "I won't let you use that tool, because if you mishandle it then you might find yourself in a nasty mess." That's what Java does - it treats the programmer like an idiot - and that's why it's so universally despised. It has consistently been my impression that this is very much not the sort of philosophy D follows. Anyway, D already provides the programmer with a wealth of tools which, if mishandled, can place them in a nasty mess. So I think this is a poor rationale for withholding from the programmer one more.
Re: Why aren't overloaded nested functions allowed?
On Monday, 30 May 2016 at 16:22:26 UTC, Max Samukha wrote: From the spec (https://dlang.org/spec/function.html#nested): "Nested functions cannot be overloaded." Anybody knows what's the rationale? I'm guessing it's related to - Unlike module level declarations, declarations within function scope are processed in order. And I'd suspect that the cleanest solution would be similar to the one given for interdependent functions: Declare the nested functions in a static nested struct instead.
Re: Keeping a mutable reference to a struct with immutable members
On Sunday, 29 May 2016 at 19:52:37 UTC, Basile B. wrote: Do yo have a simple, concise runnable example to show ? This is the example I was using to test solutions, it's similar to where I encountered the problem in the first place import core.stdc.stdlib : malloc, free; import std.stdio; import std.range; import std.traits; struct RepeatRange(Range) if(isForwardRange!Range){ Range* source; Range original; this(Range original){ this.original = original; this.repeat(original.save); } @property auto ref front(){ return this.source.front; } void popFront(){ this.source.popFront(); if(this.source.empty) this.repeat(this.original.save); } @nogc void repeat(Range from){ if(this.source) free(this.source); ubyte* newptr = cast(ubyte*) malloc(Range.sizeof); assert(newptr !is null, "Failed to allocate memory."); ubyte* fromptr = cast(ubyte*) for(size_t i; i < Range.sizeof; i++) newptr[i] = fromptr[i]; this.source = cast(Range*) newptr; } this(this){ auto source = *this.source; this.source = null; this.repeat(source); } ~this(){ if(this.source) free(this.source); } enum bool empty = false; } struct SomeForwardRange{ int value = 0; const int other = 1; // Immutable member enum bool empty = false; @property auto ref save(){ return SomeForwardRange(this.value); } @property auto ref front(){ return this.value; } void popFront(){ this.value++; } } void main(){ auto range = RepeatRange!SomeForwardRange(SomeForwardRange(0)); foreach(item; range.take(10)){ writeln(item); } }
Re: Keeping a mutable reference to a struct with immutable members
On Sunday, 29 May 2016 at 18:52:36 UTC, pineapple wrote: What's the best way to handle something like this? Well I did get something to work but it's ugly and I refuse to believe there isn't a better way to handle this. Where `Range` is an alias to a struct with an immutable member, and `this.source` is the attribute that I need to be able to re-assign to a locally scoped return value: import core.stdc.stdlib : malloc, free; if(this.source) free(source); ubyte* newptr = cast(ubyte*) malloc(Range.sizeof); assert(newptr !is null, "Failed to allocate memory."); Range saved = this.original.save; ubyte* savedptr = cast(ubyte*) for(size_t i; i < Range.sizeof; i++){ newptr[i] = savedptr[i]; } this.source = cast(Range*) newptr;
Keeping a mutable reference to a struct with immutable members
I found another post on this subject and the advice there was "don't put const members in your structs" - http://forum.dlang.org/thread/m87ln2$idv$1...@digitalmars.com This doesn't work out so well when the templated struct is referring to what happens to be a const array. I thought I could get it done with pointers, but then I realized my data was going out-of-scope. I tried using `Unqual!T thing_i_need_to_reassign_sometimes` where T was immutable but that didn't solve anything, either. What's the best way to handle something like this?
Re: I wrote a function that accepts input ranges, and I get compile errors when passing an array
On Saturday, 28 May 2016 at 16:25:02 UTC, Seb wrote: If you are interested how it works under the hood - it's pretty simple & elegant: I checked up on the phobos implementation and found that arrays are mutated when iterated over as ranges, which didn't rest well with me. Nor did the idea of importing some module having such a significant side-effect as whether some type can act as a range or not. So I ended up making a sort of factory that turns arbitrary objects into ranges, including arrays. Seems to work pretty well.
I wrote a function that accepts input ranges, and I get compile errors when passing an array
I'm writing my own map function modeled after the one in phobos. (because I feel like it, that's why. good learning experience.) I've encountered one remarkable difference: The phobos function accepts arrays and mine does not. I understand why - I'm calling methods that arrays don't have - but what I don't understand is why the phobos function _does_ work. I haven't been able to find what in the phobos code accounts for iterables that aren't ranges. What am I missing? enum canMap(T) = isInputRange!(Unqual!T); auto map(alias func, Range)(Range range) if(canMap!Range){ return Mapping!(func, Range)(range); } struct Mapping(alias func, Range) if(canMap!Range){ alias URange = Unqual!Range; Range input; this(URange input){ this.input = input; } void popFront(){ this.input.popFront(); } @property auto ref front(){ return func(this.input.front); } static if(isBidirectionalRange!URange){ @property auto ref back(){ return func(this.input.back); } void popBack(){ this.input.popBack(); } } static if(isInfinite!URange){ enum bool empty = false; }else{ @property bool empty(){ return this.input.empty; } } static if(isRandomAccessRange!URange){ static if(is(typeof(URange.opIndex) == function)){ alias Index = Parameters!(URange.opIndex)[0]; }else{ alias Index = size_t; } auto ref opIndex(Index index){ return func(this.input[index]); } } static if(is(typeof(URange.opDollar))){ alias opDollar = URange.opDollar; } static if(hasLength!URange){ @property auto length(){ return this.input.length; } } static if(hasSlicing!URange){ static if(is(typeof(URange.opIndex) == function)){ alias SliceIndex = Parameters!(URange.opIndex)[0]; }else{ alias SliceIndex = size_t; } auto opSlice(SliceIndex low, SliceIndex high){ return typeof(this)(this.input[low .. high]); } } static if(isForwardRange!URange){ @property auto save(){ return typeof(this)(this.input.save); } } } version(unittest) import mach.error.unit; unittest{ import std.stdio; //import std.algorithm : map; // Works with this // no property 'popFront', etc for type 'int[]' writeln( [1, 2, 3].map!((item) => (item * item)) ); } Tangentially related question - Why does phobos use isInputRange!(Unqual!T) instead of just isInputRange!T? What's the functional difference here?
Re: What's wrong with my usage of std.algorithm.map in this code example?
On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote: Slice assignment from range to array is not supported. In your example, I'm curious why the efforts to specify the type? I think it would work with just saying auto itemstrings = ... -Steve I still get an error if I use auto instead.
What's wrong with my usage of std.algorithm.map in this code example?
I would've expected this to work, but instead I get a compile error. Is my syntax wrong? Is this just not a case that map can handle, and I should be doing something else? import std.algorithm : map; import std.conv : to; import std.stdio : writeln; import std.string : join; string test(Args...)(in Args items){ immutable string[items.length] itemstrings = map!(to!string)(items); return join(itemstrings, ", "); } unittest{ writeln(test(1, 2, 3, 4)); }