Re: How to loop through characters of a string in D language?
On Thursday, 23 December 2021 at 07:14:35 UTC, Salih Dincer wrote: It seems faster than algorithms in Phobos. We would love to see this in our new Phobos. Replace: 436 msecs Malloc : 259 msecs */ It seems because MallocReplace is cheating a lot: - it is not called through another function like replace is called; - accesses directly the constant str; - assumes that it has a single character to replace; - assumes that the character will be deleted not replaced with something; - assumes that the character is always ';' - assumes that the replacing string is not bigger than the replaced one, so it knows exactly how much space to allocate; - does not have any parameter, at least on x86 this means that there is no arg pushes when it's called. - does not return a string, just compares its result with another constant; Since we already know all this stuff, we can go further :) ```d string superFast() { enum r = str.replace(";", ""); return r; } ``` Replace: 436 msecs Malloc : 259 msecs SuperFast: 0 msecs
Re: what the closest thing we have to racket's check_expect()?
On Wednesday, 22 December 2021 at 20:14:01 UTC, Dr Machine Code wrote: it differ from assert because it contains the expression, file and line information. See this https://stackoverflow.com/questions/14420857/check-expect-example-in-racket what's the closest thing we have in D? can we make it without compiler builtin? Every error or exception in D has line and file information, stack trace and more, therefore you can catch AssertError and print the details if the default message printed on console is not enough. For unit testing you have https://code.dlang.org/packages/dunit
Re: How to insert code in place with templates/mixins?
On Monday, 20 December 2021 at 10:49:20 UTC, rempas wrote: On Monday, 20 December 2021 at 09:30:30 UTC, rumbu wrote: Thanks a lot for the info. When I try to use this code, I'm getting the following error: ``` Error: expression expected, not `%` Error: expression expected, not `%` ``` My fault, I forgot to put some char delimiters. You can find tested code here: https://run.dlang.io/is/KfdED0 So I suppose there is a problem with string concatenation. I couldn't use it anyway because it is inefficient and because I'm using betterC. Do you know any other way that I can concatenate strings that does not depend an the Garbage Collector or the standard library? Enums (that's why the string is declarated as enum) are evaluated at compile time, the concatenation op will not end in your code as instruction, so you can do anything outside betterC rules as long you do it at compile time. You are just building some code to use later, the compiler does not generate any instruction for it. In the example above you can press the AST button to see exactly how your code is generated. Wnen you have doubts about a generated string you can always test it with ```pragma msg```. In this case, if you write: ``` pragma(msg, add_char!'%'); ``` you will have in the output exactly what the compiler will generate for your mixin.
Re: How to insert code in place with templates/mixins?
On Monday, 20 December 2021 at 08:45:50 UTC, rempas wrote: Here I am having a problem with templates again. No matter how much I read, I can't seem to understand how templates/mixins work. So any ideas why this doesn't work? because you cannot have statements directly in a template (the fact that is a mixin template is irelevant), only declarations. If you want to just insert some random code, use strings. You can create a templated enum to store your parametrized string. Please note how your parameter (c) becomes part of the resulting string through concatenation (~): ``` enum add_char(char c) = `if (stdout_index < STDOUT_BUF_LEN) { stdout_buffer[stdout_index++] =` ~ c ~ `; continue; } else { sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index); stdout_index = 0; stdout_buffer[stdout_index++] =` ~ c ~ `; continue; }`; ``` and when you want the code inserted: ``` mixin(add_char!'%'); ``` If you want to be sure that your string is syntactically correct, use token strings (https://dlang.org/spec/lex.html#token_strings)
Re: Immutability and arrays
On Tuesday, 14 December 2021 at 16:21:03 UTC, Steven Schveighoffer wrote: On 12/14/21 11:19 AM, Steven Schveighoffer wrote: Er... scratch that, this isn't construction, it should use opAssign. Again, probably because memcpy+postblit is used by the runtime. If not reported, it should be. Simple proof that it is a bug: ```d immutable (ComplexStruct)[] arr; ComplexStruct[] arr2; arr2[0] = arr[0]; // ok arr2[] = arr[]; // error ``` If you can copy one element, you should be able to copy all the elements. -Steve Thank you everybody, especially to Steve for the detailed explanation. It seems that every post I put in the learn forum, results in a bug report :) https://issues.dlang.org/show_bug.cgi?id=22601 https://issues.dlang.org/show_bug.cgi?id=22600
Re: Immutability and arrays
On Tuesday, 14 December 2021 at 12:13:23 UTC, Stanislav Blinov wrote: Because is(typeof(immutable(ComplexStruct).x) == immutable(int[])). Can't bind an array of immutable to array of mutable. This would require a deep copy, i.e. copy constructor. This means that the only way to write a generic function which copies an array of immutable elements to another array is this: ```d void copy10(T)(T[] dst, immutable(T)[] src) { static if (is(immutable(T): T)) dst[0..10] = src[0..10]; else dst[0..10] = cast(T[])src[0..10]; // or better a deep copy } ``` Btw, tried to give ComplexStruct a some copy constructors (casting away immutable is just for the example, I know it's not the way to do it). ```d struct ComplexStruct { int[] x; this(ref return scope ComplexStruct another) { this.x = another.x; } this(ref return scope immutable(ComplexStruct) another) { this.x = cast(int[])(another.x); } } ``` Still slice assignment does not work. I think I will drop immutability, it's too complicated to work with.
Immutability and arrays
I am trying to understand why in this two different cases (Simple and Complex), the compiler behaviour is different. ```d struct SimpleStruct { int x;} struct ComplexStruct { int[] x; } void main() { SimpleStruct[] buf1; immutable(SimpleStruct)[] ibuf1; buf1[0 .. 10] = ibuf1[0 .. 10]; //this works ComplexStruct[] buf2; immutable(ComplexStruct)[] ibuf2; buf2[0 .. 10] = ibuf2[0 .. 10]; //error cannot implicitly convert expression `ibuf2[0..10]` of type `immutable(ComplexStruct)[]` to `ComplexStruct[]` } ```
Re: How to loop through characters of a string in D language?
On Saturday, 11 December 2021 at 14:42:53 UTC, russhy wrote: Here is mine - 0 allocations - configurable - let's you use it how you wish - fast You know that this is already in phobos? ``` "abc;def;ghi".splitter(';').joiner ```
Re: How to loop through characters of a string in D language?
On Friday, 10 December 2021 at 18:47:53 UTC, Stanislav Blinov wrote: Be interesting to see if this thread does evolve into a SIMD http://lemire.me/blog/2017/01/20/how-quickly-can-you-remove-spaces-from-a-string/
Re: How to loop through characters of a string in D language?
On Friday, 10 December 2021 at 11:06:21 UTC, IGotD- wrote: On Friday, 10 December 2021 at 06:24:27 UTC, Rumbu wrote: Since it seems there is a contest here: ```d "abc;def;ghi".split(';').join(); ``` :) Would that become two for loops or not? I thought it's a beauty contest. ```d string stripsemicolons(string s) { string result; // prevent reallocations result.length = s.length; result.length = 0; //append to string only when needed size_t i = 0; while (i < s.length) { size_t j = i; while (i < s.length && s[i] != ';') ++i; result ~= s[j..i]; } } ```
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The character I want to skip: `;` Expected result: ``` abcdefab ``` Since it seems there is a contest here: ```d "abc;def;ghi".split(';').join(); ``` :)
Re: Mixin template overloads not working
On Friday, 3 December 2021 at 10:57:34 UTC, Stanislav Blinov wrote: On Friday, 3 December 2021 at 10:42:37 UTC, Rumbu wrote: Bug or feature? Is there any workaround? The error message explains what to do :) Error: class `mixinover.AnotherVisitor` use of `mixinover.Visitor.visit(S s)` is hidden by `AnotherVisitor`; use `alias visit = Visitor.visit;` to introduce base class overload set Yes, I know, but in fact the compiler wrongly assumes that visit(A) is hiding visit(S). visit(A) is just an overload, it has a different signature than visit(S), theoretically the compiler must mangle it using a different name. Finally I solved it by "finalizing" visit(S), so it's not taken into overrides set. ```d class Visitor { final void visit(S s) {} //... }
Mixin template overloads not working
```d class S {} class A:S {} class B:S {} mixin template vmix(T) { void visit(T t) {} } class Visitor { void visit(S s) {} mixin vmix!A; mixin vmix!B; } class AnotherVisitor: Visitor { override void visit(A a) {} } ``` This will result in error when I try to override mixin generated visit(A) in AnotherVisitor. If A doesn't inherit S, the override in AnotherVisitor works like a charm. Bug or feature? Is there any workaround?
Re: Attributes (lexical)
On Thursday, 25 November 2021 at 11:25:49 UTC, Ola Fosheim Grøstad wrote: On Thursday, 25 November 2021 at 10:41:05 UTC, Rumbu wrote: I am not asking this questions out of thin air, I am trying to write a conforming lexer and this is one of the ambiguities. I think it is easier to just look at the lexer in the dmd source. The D language does not really have a proper spec, it is more like an effort to document the implementation. I try to base my reasoning on specification, dmd is not always a good source of information, the lexer is polluted by old features or right now by the ImportC feature, trying to lex D an C in the same time. DMD skips the new line if the file was not specified, that's why the "filename" is unexpected on a new line: https://github.com/dlang/dmd/blob/d374003a572fe0c64da4aa4dcc55d894c648514b/src/dmd/lexer.d#L2838 libdparse completely ignores the contents after #line skipping everything until EOL, even a EOF/NUL marker which should end the lexing: https://github.com/dlang-community/libdparse/blob/7112880dae3f25553d96dae53a445c16261de7f9/src/dparse/lexer.d#L1100
Re: Attributes (lexical)
On Thursday, 25 November 2021 at 10:10:25 UTC, Dennis wrote: On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote: Also, this works also for #line, even if the specification tells us that all tokens must be on the same line Where does it say that? Well: ``` #line IntegerLiteral Filespec? EndOfLine ``` Having EndOfLine at the end means for me that there are no other EOLs between, otherwise this syntax should pass but it's not (DMD last): ```d #line 12 "source.d" ``` I am not asking this questions out of thin air, I am trying to write a conforming lexer and this is one of the ambiguities.
Attributes (lexical)
Just playing around with attributes. This is valid D code: ```d @ nogc: //yes, this is @nogc in fact, even some lines are between @ /* i can put some comments */ /** even some documentation */ // single line comments also (12) // yes, comments and newlines are allowed between attribute and declaration int x; //@(12) is attached to declaration ``` Is that ok or it's a lexer bug? Also, this works also for #line, even if the specification tells us that all tokens must be on the same line ```d # //this works line /* this too */ 12 //this is #line 12 ```
Re: Using YMM registers causes an undefined label error
On Saturday, 6 March 2021 at 12:15:43 UTC, Mike Parker wrote: On Saturday, 6 March 2021 at 11:57:13 UTC, Imperatorn wrote: What... Is this really how it's supposed to be? Makes no sense to not use any of the existing conventions. extern(C) and extern(D) are both documented to be the same as the platform's C calling convention everywhere except x86 windows: https://dlang.org/spec/abi.html#function_calling_conventions There have been times when differences were noted (I recall a particularly bad one related to passing structs by value on 64-bit linux) and there may be more. When they are, they should be reported in Bugzilla. Where exactly is documented the extern(D) x86-64 calling convention? Because currently seems like a mess according to the dissasembly. First X parameters on stack from left to right, last 4 in registers. But wait, if you have less than 4 parameters, they are passed in register. Again, WTF?
Re: Using YMM registers causes an undefined label error
On Friday, 5 March 2021 at 21:47:49 UTC, z wrote: On Friday, 5 March 2021 at 16:10:02 UTC, Rumbu wrote: First of all, in 64 bit ABI, parameters are not passed on stack, therefore a[RBP] is a nonsense. void complement32(simdbytes* a, simdbytes* b) a is in RCX, b is in RDX on Windows a is in RDI, b is in RSI on Linux I'm confused, with your help i've been able to find the function calling convention but on LDC-generated code, sometimes i see the layout being reversed(The function i was looking at is a 7 argument function, all are pointers. The first argument is on the stack, the seventh and last is in RCX) and the offsets don't seem to make sense either(first arguemnt as ss:[rsp+38], second at ss:[rsp+30], and third at ss:[rsp+28]) Secondly, there is no such thing as movaps YMMX, [RAX], but vmovaps YMM3, [RAX] Same for vxorps, but there are 3 operands, not 2. You're absolutely right, but apparently it only accepts the two-operand version from SSE. Other AVX/AVX2/AVX512 instructions that have «v» prefixed aren't recognized either("Error: unknown opcode vmovaps"), is AVX(2) with YMM registers supported for «asm{}» statements? I just made some tests, it seems that D has invented his own calling convention. And it's not documented. If you decorate your function with extern(C) it should respect the x86-64 ABI conventions. This is what I got for a 7 parameters function. The two compilers seems to do the same thing: param no., extern(C), extern(D) 1 RCX RSP + 56 2 RDX RSP + 48 3 R8RSP + 40 4 R9R9 5 RSP + 40 R8 6 RSP + 48 RDX 7 RSP + 56 RCX I would stick to extern(C), the extern(D) convention seems completely illogical, they push the first 3 parameters on the stack from left to right, but if there are less than 4, they use register transfer. WTF. Note: tested on Windows, probably on Linux both conventions will use Linux ABI conventional registers and will not reserve 32 bytes on stack. Now, on the other side, it seems that LDC is one step behind DMD because - you are right - it doesn't support AVX-2 instructions operating on ymm registers.
Re: Using YMM registers causes an undefined label error
On Friday, 5 March 2021 at 12:57:43 UTC, z wrote: XMM registers work, but as soon as they are changed into YMM DMD outputs "bad type/size of operands %s" and LDC outputs an "label YMM0 is undefined" error. Are they not supported? To illutrate : https://run.dlang.io/is/IqDHlK By the way, how can i use instructions that are not listed in [1]?(vfmaddxxxps for example) And how are function parameters accessed if they are not on the stack?(looking up my own code in a debugger, i see that the majority of pointer parameters are already in registers rather than being on the stack.) I need those so that i can write a better answer for [2]. Big thanks [1] https://dlang.org/spec/iasm.html#supported_opcodes [2] https://forum.dlang.org/thread/qyybpvwvbfkhlvulv...@forum.dlang.org First of all, in 64 bit ABI, parameters are not passed on stack, therefore a[RBP] is a nonsense. void complement32(simdbytes* a, simdbytes* b) a is in RCX, b is in RDX on Windows a is in RDI, b is in RSI on Linux Secondly, there is no such thing as movaps YMMX, [RAX], but vmovaps YMM3, [RAX] Same for vxorps, but there are 3 operands, not 2.
Re: How can I make this work?
On Sunday, 28 February 2021 at 09:04:49 UTC, Rumbu wrote: On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote: I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l; LPARAM is not long on 32 bits, it's int. Use LPARAM instead of long. And you are passing only the address of the first element this way, loosing the array/slice length. This should work, but keep in mind that you have no warranty that the array stays in memory and it is not garbage collected. int[] arr = [1, 2, 3]; LPARAM l = cast(LPARAM)cast(void*) int[] a = *cast(int[]*)(cast(void*)l);
Re: How can I make this work?
On Sunday, 28 February 2021 at 07:05:27 UTC, Jack wrote: I'm using a windows callback function where the user-defined value is passed thought a LPARAM argument type. I'd like to pass my D array then access it from that callback function. How is the casting from LPARAM to my type array done in that case? for example, I need something like this to work: int[] arr = [1, 2, 3]; long l = cast(long) cast(void*) arr.ptr; int[] a = cast(int[]) cast(void*) l; LPARAM is not long on 32 bits, it's int. Use LPARAM instead of long.
Re: fold on empty range
On Wednesday, 17 February 2021 at 12:58:29 UTC, Mitacha wrote: On Wednesday, 17 February 2021 at 11:38:45 UTC, Rumbu wrote: [...] If you replace `fold` and `splitter` with this, then it doesn't allocate: ``` auto fn() @nogc { return only("k1,k2", "k3,k4") .map!(x => x.splitter(",")) .joiner; } void main() { auto range = fn(); range.writeln; } ``` Wow, thanks a lot.
Re: fold on empty range
On Wednesday, 17 February 2021 at 10:15:10 UTC, Mitacha wrote: it'll use empty string as first element in range. BTW perheps you could use `joinner` instead of this `fold` to join values with ",". Thanks for that. I thought to joiner too, but it doesn't work. I need fold to take a list of strings and concatenate them. Basically I read comma separated keywords from various sources and i want to iterate through all of them. If you know other method without the involved allocation of fold... .map!(a => a.hit.stripLeft("[").strip("]")) //"k1,k2", "k3,k4" ... .fold!((a, b) => a ~ "," ~ b)("") //"k1,k2,k3,k4,..." .splitter(',') //"k1", "k2", "k3", "k4", ..., .map!(a => a.stripLeft("\" '").strip("\" '")) .filter!(a => a.length && !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':')) .array .sort .uniq;
fold on empty range
In the expression below: return matchAll(content, keywordsPattern) .map!(a => a.hit.stripLeft("[").strip("]")) .fold!((a, b) => a ~ "," ~ b) .splitter(',') .map!(a => a.stripLeft("\" ").strip("\" ")) .filter!(a => !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':')) .array .sort .uniq; fold is throwing an exception if the result of the previous map is empty. Is there any way to express something to convince fold to return the empty range received from map? Of course, I know I can test for empty in a separate expression, but I'd like to keep my expression flow as it is.
Re: Is there other way to do that?
On Monday, 15 February 2021 at 07:26:56 UTC, Jack wrote: I need to check if an instance is of a specific type derived from my base class but this class has template parameter and this type isn't available at time I'm checking it. Something like: class B { } class A(T) : B { } class X : B { } class Z : B { } auto c = can be any derived class from B bool isX = cast(A!???) c !is null; assert(isX); an interface would work: interface IA { } class A(T) : B, IA { } bool isX = cast(IA) c !is null; assert(isX); but I would have create one just for that. It feels a bit hacky? also, does an empty interface like that increase the A class memory size at all? Hackier than hack: bool isA(Object o) { return o && (cast(TypeInfo_Class)(typeid(o))).name == "A"; } Of course, this is not recommended, I am sure that there is another way to achieve what you want but with other design. Unfortunately, your examples are too limited to have an idea.
Re: Is this the proper way to do it?
On Saturday, 13 February 2021 at 05:52:34 UTC, Jack wrote: I have a base class A, where I make specific operator depending on the derived class type. Currently I'm using something like this: c is a class derived from A bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || (cast(K)c) !is null ... ; as the number of cast(C) !is null is growing, I'm afraid of this being a inelegant or even poor performance approach. How would you do that? Option 1, reverse the condition, && op will shortcut boolean conditions bool shouldNotDoX = cast(X)c && cast(Y)c && cast(K)c && ... Option 2, reverse the condition by testing the classes that are not supposed to "do" it, if you have less classes in that category. bool shoudldNotDoX = cast(P)c || cast(Q)c
Re: Real simple unresolved external symbols question...
On Tuesday, 9 February 2021 at 19:37:17 UTC, WhatMeWorry wrote: I'm trying to create a super simple dynamic library consisting of two files: file2.d -- extern(D): double addEight(double d) { return (d + 8.0); } fileB.d -- extern(D) { string concatSuffix(string s) { return (s ~ ".ext"); } } dmd -m64 -c file2.d dmd -m64 -c fileB.d creates file2.obj and fileB.obj files link.exe /DLL /NOENTRY file2.obj fileB.obj msvcrt.lib fileB.obj : error LNK2019: unresolved external symbol _D12TypeInfo_Aya6__initZ referenced in function _D5fileB12concatPrefixFAyaZQe fileB.obj : error LNK2019: unresolved external symbol _d_arraycatT referenced in function _D5fileB12concatPrefixFAyaZQe Ok. I find _d_arraycatT in the D website at: https://dlang.org/library/rt/lifetime/_d_arraycat_t.html So I thought, this symbol will be in phobos64.lib. But when I add it to the command, all hell breaks loose: link.exe /DLL /NOENTRY file2.obj fileB.obj msvcrt.lib phobos64.lib phobos64.lib(bits_23fa_21c.obj) : error LNK2001: unresolved external symbol memcpy o o o file2.dll : fatal error LNK1120: 57 unresolved externals So I'm stuck and don't have a clue as to how to continue. I thought Phobos64.lib was self-contained. Do I need to add other libraries? And how do I know which ones? You have 2 obj files, and you link them. Where do you want the "self contained" to be present? The missing symbols in your case are in druntime.lib, not in phobos.
Re: Dimensions in compile time
On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote: On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote: size_t ndim(A)(A arr) { return std.algorithm.count(typeid(A).to!string, '['); } Is there a way to find out the number of dimensions in an array at compile time? yeah. --- template dimensionCount(T) { static if (isArray!T) { static if (isMultiDimensionalArray!T) { alias DT = typeof(T.init[0]); enum dimensionCount = dimensionCount!DT + 1; } else enum dimensionCount = 1; } else enum dimensionCount = 0; } /// unittest { static assert(dimensionCount!char == 0); static assert(dimensionCount!(string[]) == 1); static assert(dimensionCount!(int[]) == 1); static assert(dimensionCount!(int[][]) == 2); static assert(dimensionCount!(int[][][]) == 3); } --- that can be rewritten using some phobos traits too I think, but this piece of code is very old now, more like learner template. dimensionCount!string should be 2. My take without std.traits: template rank(T: U[], U) { enum rank = 1 + rank!U; } template rank(T: U[n], size_t n) { enum rank = 1 + rank!U; } template rank(T) { enum rank = 0; }
Re: Finding position of a value in an array
On Sunday, 29 December 2019 at 08:26:58 UTC, Daren Scot Wilson wrote: Reading documentation... Array, Algorithms, ... maybe I've been up too late... how does one obtain the index of, say, 55 in an array like this int[] a = [77,66,55,44]; I want to do something like: int i = a.find_value_returning_its_index(55); assert(i==2) I'm sure it's obvious but I'm not seeing it right now. Just reactivating this post to tell you that I lost 15 minutes of my life searching for a basic way to obtain the position of an element in an array; Out of frustration, I ended to write my own indexOf function. Any library on Earth has such function and it's not named countUntil, nor giveMeTheDamnPositionOfXInThatArray. It seems that D is specialised in finding needles in haystacks, not finding elements in arrays. https://issues.dlang.org/show_bug.cgi?id=21615
Re: Ugly c++ syntax
On Saturday, 6 February 2021 at 00:35:12 UTC, Ali Çehreli wrote: On 2/5/21 1:10 PM, Rumbu wrote: I gave up after reading a lot, but I didn't manage to understand the meaning "&& ..." I think it's the universal reference. Thank you Ali, but nope, it's "parameter pack folding". This allows starting with C++ 17 to have recursive templates in one liner. Basically, it means "&& template(the rest of arguments)" https://github.com/microsoft/cppwin32/blob/8a6b2507734dd9e9892059b5794f35109688fc20/cppwin32/winmd/impl/winmd_reader/database.h#L490
Ugly c++ syntax
Can some C++ guru translate in D the template below? I gave up after reading a lot, but I didn't manage to understand the meaning "&& ..." template static uint8_t composite_index_size(Tables const&... tables) { return (composite_index_size(tables.size(), impl::bits_needed(sizeof...(tables))) && ...) ? 2 : 4; } Thanks.
Re: books for learning D
On Wednesday, 29 January 2020 at 08:40:48 UTC, p.shkadzko wrote: Has anyone read "d programming language tutorial: A Step By Step Appoach: Learn d programming language Fast"? https://www.goodreads.com/book/show/38328553-d-programming-language-tutorial?from_search=true=G9QIeXioOJ=3 Beware, this is a scam. This guy has hundreds of "books". These books are promoted on various forums for download. Of course, you must enter your CC to "prove your identity".
Re: How to convert this C++ code to Dlang? Please send me Dlang version of this C++ code
On Monday, 27 January 2020 at 11:34:47 UTC, Marcone wrote: #include #include #include #include "resource.h" #include HINSTANCE hInst; BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: { } return TRUE; case WM_CLOSE: { EndDialog(hwndDlg, 0); } return TRUE; case WM_COMMAND: { switch(LOWORD(wParam)) { //case BT_1: //{ //std::cout << "Ola Mundo!\n"; //} } } return TRUE; } return FALSE; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { hInst=hInstance; InitCommonControls(); return DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DlgMain); } Translated (including errors & comments): import core.sys.windows.windows; import core.sys.windows.commctrl; import std.stdio; HINSTANCE hInst; extern(Windows): BOOL DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) nothrow { switch(uMsg) { case WM_INITDIALOG: { } return TRUE; case WM_CLOSE: { EndDialog(hwndDlg, 0); } return TRUE; case WM_COMMAND: { switch(LOWORD(wParam)) { //case BT_1: //{ //writeln("Ola Mundo!"); //} } } return TRUE; } return FALSE; } int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { hInst=hInstance; InitCommonControls(); return DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, ); }
Re: How load icon from resource using LoadImage?
On Sunday, 5 January 2020 at 13:33:35 UTC, Marcone wrote: I am using this code to load icon from local directory, but I want to load icon from resource.res file: wndclass.hIcon = LoadImage( NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE| LR_SHARED | LR_LOADTRANSPARENT); You cannot load icons from res files. If you link your res file to the executable, you can load the icon using: LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(youriconid)); The function LoadImage from above loads an icon from the file named icon.ico, not from a res file.
array of functions/delegates
I am trying to create an array of functions inside a struct. struct S { void f1() {} void f2() {} alias Func = void function(); immutable Func[2] = [, ] } What I got: Error: non-constant expression '' Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`. So, is there any way to have an array of functions without adding them at runtime?
Re: How add "version.txt" Version File by Command Line or by resources.res using dmd.exe
On Sunday, 8 December 2019 at 20:50:05 UTC, Marcone wrote: I want to add version to my program. I have configurated my version file "version.txt", but I dont know how link this file to my program. If Need spec file, please send the exemple code of spec. Or is is possible add version file by dmd command line or resources. Thank you. Your version.txt file is python specific, it will not work in D. You have 2 options: - create a .res file in Visual Studio and edit it by adding a VERSIONINFO resource. - create a .rc file in any text editor adding a VERSIONINFO resource; compile it to .res using rc yourfile.rc Pass the .res file to the dmd compiler in the command line.
Re: why local variables cannot be ref?
On Monday, 25 November 2019 at 08:20:59 UTC, rumbu wrote: On Monday, 25 November 2019 at 08:07:50 UTC, Fanda Vacek wrote: Thanks for answer, I'm coming from C++. But anyway, pointers are not allowed in @safe code, so this is not always solution. Workaround exits even for @safe code, so my question remains the same. What is a rationale for such a language design restriction, if it can be workarounded easily. Enjoy: https://forum.dlang.org/post/blgcfjqdhtusavlrg...@forum.dlang.org sSorry, wrong link above. https://forum.dlang.org/thread/ruwapnhkuvozitefz...@forum.dlang.org?page=1
Re: why local variables cannot be ref?
On Monday, 25 November 2019 at 08:07:50 UTC, Fanda Vacek wrote: Thanks for answer, I'm coming from C++. But anyway, pointers are not allowed in @safe code, so this is not always solution. Workaround exits even for @safe code, so my question remains the same. What is a rationale for such a language design restriction, if it can be workarounded easily. Enjoy: https://forum.dlang.org/post/blgcfjqdhtusavlrg...@forum.dlang.org
Re: why local variables cannot be ref?
On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote: Maybe I'm missing the thing, but I'm not able to declare local ref variable even if simple workaround exists. Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` Fanda Probably you are coming from C#. There are no reference variables in D, but you can use pointers like in: int* b = *b = 2;
Re: Proper desctructor for an class containing dynamic array of objects
On Friday, 14 June 2019 at 07:52:24 UTC, Marco de Wild wrote: On Thursday, 13 June 2019 at 16:08:52 UTC, Mike wrote: Opposed to Java, D's member variables are static initialised. Is there any documentation about this? I find it unexpected.
Re: Proper desctructor for an class containing dynamic array of objects
On Thursday, 13 June 2019 at 16:08:52 UTC, Mike wrote: How would a proper destructor of class Foo look like? Is it enough to set "array" to null? Or do I have to set every element of the array to null and then the array, or nothing of that at all because the garbage collecter collects it, if the reference to Foo is set to null? Nothing at all, GC will take care. As long as your Block class doesn't create any system resources that must be discarded.
Re: Casting to interface not allowed in @safe code?
On Tuesday, 21 May 2019 at 07:16:49 UTC, Jim wrote: On Tuesday, 21 May 2019 at 07:04:27 UTC, rumbu wrote: On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote: That's because foo is of type Base, not implementing FeatureX. Right, Base isn't implementing FeatureX, but foo is really a Foo That's your knowledge, for the compiler foo is really a Base, as written in your own code. The only way to tell the compiler that you safely assume that foo is really a Foo, is to mark code as @trusted, not @safe. interface Base { void setup(); } interface FeatureX { @safe void x(); } class Foo: Base, FeatureX { void setup(){}; @safe void x(){}; } @trusted FeatureX imsureitsfeaturex(Base b) { return cast(FeatureX)b; } @safe void main() { Base foo = new Foo(); // This would be the result of a factory class imsureitsfeaturex(foo).x(); // 1 }
Re: Casting to interface not allowed in @safe code?
On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote: Hi, consider this: interface Base { void setup(); } interface FeatureX { void x(); } class Foo: Base, FeatureX { void setup(){}; void x(){}; } void main() { Base foo = new Foo(); // This would be the result of a factory class (cast(FeatureX)foo).x(); // 1 } 1) error: casting to interface FeatureX is not allowed in @safe code. Question: How to call foo.x in @safe code ? That's because foo is of type Base, not implementing FeatureX.
Re: [windows] Can't delete a closed file?
On Friday, 10 May 2019 at 19:10:05 UTC, Machine Code wrote: Well, I've had similar issue. The error message says "access denied" which I believe refers to the tmp directory; i.e, the user that is running your executable has no permissions to delete that file. Well, this has nothing to do with access rights, the user have full access to his own temp folder even in the most restrictive windows configuration. According to winapi docs, FreeLibrary doesn't guarantee file close op, and that's why you cannot delete it. Internally, windows maps a memory handle directly into the dll file and that pointer remains active until the application exits. Actually, I ran your example with several sequential calls to FreeLibrary, all returning success, even if it's clear that the internal reference count touched zero after the first call. The lock of the file disappears effectively after the application has exited and the dll can be safely deleted afterwards. If you want this dll deploying mechanism (which I consider a bad approach, contributing to the well known dll hell) check at startup if the dll already exists, delete it and redeploy if the existing one doesn't satisfy your version requirements. To avoid dll hell, dlls must be deployed in the system dir, or at least in the application folder through a normal installation process. In our network environment governed by a restrictive GPO, your application will never run.
Re: [windows] Can't delete a closed file?
On Thursday, 9 May 2019 at 10:09:23 UTC, Cym13 wrote: Hi, this is likely not related to D itself but hopefully someone can help me with this since I'm rather new to windows programming, I mainly work on linux. I'm trying to bundle a DLL in a binary, write it in a temp folder, use it and remove the dangling file. So far I have the following file: import std; void main(string[] args) { import core.runtime; static immutable libcurl = import("libcurl.dll"); import std.file: write; auto libpath = tempDir.buildPath("libcurl.dll"); libpath.write(libcurl); auto libcurlMem = rt_loadLibrary(libpath.toStringz); import std.net.curl; "https://dlang.org/".byLine.count.writeln; rt_unloadLibrary(libcurlMem); remove(libpath); } Compiled with: dmd.exe -Jlibdir test.d It almost work, I can write, load and use the library, but when it comes to removing it nothing works. std.file.FileException@std\file.d(1045): C:\users\cym13\Temp\libcurl.dll: Access denied. 0x00402377 in EntryPoint 0x00413BC7 in EntryPoint 0x00413B49 in EntryPoint 0x004139E3 in EntryPoint 0x0040B77F in EntryPoint 0x7B4754C2 in call_process_entry 0x7B477FC6 in ExitProcess 0x7B4754CE in call_process_entry I tried using an explicit File handle to explicitely close the file after writing to it but that doesn't change anything. I'm pretty sure I'm missing something basic about the way windows handles open files but I don't know what, could someone explain why this doesn't work the way I expect it to? Since deploying a dll is a suspect behaviour outside a normal installation process, most probably you have a lock on the file put by windows defender or an antivirus if installed. FreeLibrary doesn't guarantee that the dll file is closed, maybe other windows processes are accessing it (like prefetch). Anyway, you are deploying a dll just to read a file, It's over engineering, use WinAPI UrlDownloadToFile instead or any other winapi functions.
Re: Idiomatic error handling for ranges
On Thursday, 5 April 2018 at 17:36:56 UTC, Seb wrote: On Thursday, 5 April 2018 at 17:06:04 UTC, rumbu wrote: Is there a standard way to handle errors in a chain of range transformations? [...] Are you aware of ifThrown? https://dlang.org/phobos/std_exception.html#ifThrown It's not perfect, but imho a nice start and one of the places where lazy really shines. Thanks, ifThrown is perfect.
Idiomatic error handling for ranges
Is there a standard way to handle errors in a chain of range transformations? Let's say I want to read some comma separated numbers from a file. auto myArray = file.byLine().splitter().map!(to!int).array(); Now, besides fatal errors (like I/O), let's suppose I want to handle some errors in a silent way: - skip unicode decoding errors; - assume blank records with 0; - skip the line entirely if the conversion to int is not possible; I can catch UTFException, ConvException or ConvOverflowException for the entire syntax chain but there are some disadvantages: - I don't know exactly which of the chain members thrown the exception; - I cannot skip/handle the error and continue; The only solution I thought about is to break the nice chain syntax and handle errors on each of the chain members, but I wonder if there is probably another way. Thanks.
Re: Help with specific template function
On Monday, 26 March 2018 at 06:40:34 UTC, Vladimirs Nordholm wrote: However I do not understand how to use that with my arguments. Eg. I would expect to do something like: void foo(X, Y, Args...)(X x, Y y, Args args) if(isNumeric!(x) && isNumeric!(y) && args.length >= 1) { // ... } gives the error template instance isNumeric!(x) does not match template declaration isNumeric(T) How would I resolve this issue? isNumeric applies to a type, not to a variable => IsNumeric!X
Re: Calling Windows Command
On Wednesday, 21 March 2018 at 18:50:38 UTC, Vino wrote: Hi All, Request your help in calling the windows command to delete all file and folders recursively as the D function rmdirRecurse does not delete file in the permission of the file is readonly in windows 2008 R2 import std.process: execute; import std.array: empty; auto RemoveDir () ( auto dFiles = "C:\\Temp\Test1"; auto Step = "run"; if (Step == "run" && !dFiles.empty) { version(Windows) { foreach(d; dFiles) { execute(["rmdir.exe","-command", "/S /Q", `~d~`]); } } } return dFiles; ) void main () { writeln(RemoveDir); } From, Vino.N It is faster if you use SHFileOperationW directly on Windows (and also it will ignore readonly attributes): https://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx //not tested void winrmdir(string path) { import core.sys.windows.shellapi; import std.exception : enforce; import std.file: FileException; import std.utf: toUTF16; auto shpath = (path ~ "\0\0").toUTF16(); SHFILEOPSTRUCTW s; s.wFunc = FO_DELETE; s.pFrom = shpath.ptr; s.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; enforce!FileException(SHFileOperationW() == 0 && !s.fAnyOperationsAborted); }
Template condition evaluation (shortcircuit)
I tried to define a template: enum isFoo(alias T) = T.stringof.length >= 3 && T.stringof[0..3] == "abc"; int i; pragma(msg, isFoo!i); Error: string slice [0 .. 3] is out of bounds Error: template object.__equals cannot deduce function from argument types !()(string, string), candidates are: [...] Is it normal that the condition is not short circuited at first test? Of course, I can throw there a bunch of static ifs in an eponymous template, but I don't see the point of this verbosity.
Re: Slow start up time of runtime (correction: Windows real-time protection)
On Tuesday, 20 March 2018 at 16:56:59 UTC, Dennis wrote: On Tuesday, 20 March 2018 at 12:18:16 UTC, Adam D. Ruppe wrote: On Tuesday, 20 March 2018 at 09:44:41 UTC, Dennis wrote: I suspect you are seeing the Windows antivirus hitting you. D runtime starts up in a tiny fraction of a second, you shouldn't be noticing it. You're totally right, disabling real-time protection makes a massive difference. I always found a second exceptionally long for a runtime to initialize, but I couldn't think of any other differences between a simple dmd-compiled program and a simple dmc-compiled program. On Tuesday, 20 March 2018 at 12:18:16 UTC, Adam D. Ruppe wrote: I betcha you'll see this delay (and a similar one on dmd itself, your compiles could be running at half-speed with this too) Definitely. I've tested how long tools take to simply print their help text: for the first time with virus scan, second time with virus scan and without any real-time protection. D tools seem to get the longest delay. First Second No protection (miliseconds) dmc 84 52 16 dmd 2400120024 dub 2300110025 ldc 4500180 30 gcc 240 100 18 On Tuesday, 20 March 2018 at 12:18:16 UTC, Adam D. Ruppe wrote: I don't know why the antivirus picks on D so much, but on my box it does and it sounds like it is on yours too. BTW that real time check box likes to keep turning itself on... so the slowness will keep coming back. Typical Windows... It keeps turning on the Windows update service too. This now leaves the question what's the best way to mitigate this, because I would gladly get rid of the second of delay any time I invoke dmd, ldc or dub as well as my own applications. I cannot guarantee that this is the cause, but I observed that Bitdefender is very picky with Intel OMF format. I made a lot of complaints about this (it was impossible to debug a intel omf compiled exe with Bitdefender installed and the advice received from Bitdefender was to compile my executables in mscoff format. That's how my problem disappeared. Windows Defender incorporated last year Bitdefender scanning technology, maybe this is an explanation.
Re: Is there a way to pipeline program with random-access ranges in C#?
On Monday, 19 March 2018 at 11:35:46 UTC, Dukc wrote: This topic is technically in wrong place, since the problem is with C#, not D. But because what I'm asking is more idiomatic in D than elsewhere, I think I have the best changes to get understood here. So, I'm looking for some library, or technique, that allows me to chain range-evaluating commands like Phobos, but on C# or JavaScript. Either does, because I'm using Bridge.Net to compile C# to JavaScript, but I would prefer C# because of the type system. LinQ is otherwise just what I described, except that it can work only with input ranges that can be reseted to their initial state. That leads me to do a lot of for loops. In D I virtually never need them. I am wondering, does anybody know an alternative which can forward forwarding/bidirectional/random-access capability of source ranges too? Sorry, but I fail to understand your requirements. Do you have a practical example?
Re: signbit question
On Thursday, 15 March 2018 at 17:18:08 UTC, Miguel L wrote: On Thursday, 15 March 2018 at 16:31:56 UTC, Stefan Koch wrote: On Thursday, 15 March 2018 at 15:28:16 UTC, Miguel L wrote: Why does std.math.signbit only work for floating point types? Is there an analogue function for integer types? what is the best way to compare the sign of a float with the sign of an integer? Thanks in advance integers don't have a sign-bit. since they are not necessarily singed. However if an integer is signed and using 1-complement you can either do sign = var < 0 or sign = (var & (1 << (sizeof(var)*8 - 1)); though I cannot tell which one is faster you have to experiment. Thanks. Just one more question: Is this code correct? I don't care about +0 or -0 as the calculations on f guarantee it cannot be 0 at all. int a; float f; if((a<0)==signbit(f)) {} else {...} If you are comparing with an integer, please avoid signbit. It will return 1 also for -0.0, -inf and -nan. Don't bother also with signbit for integer types. The compiler usually outsmarts the programmer in finding the best way to compare an integer with 0. You can simply write: if (a < 0 && f < 0) {...} This will cover the [-inf..0) but not the NaN case. You can test it in a separate branch if (isNaN(f)) {...}
Are there any working instructions about how to build and test dmd on Windows?
I know that there are contributing guides but I fail to successfully follow any of them: https://wiki.dlang.org/Starting_as_a_Contributor 1. Bash install script will not run under Windows. Using git bash will result in error (Command error: undefined switch '-C') 2. Digger it's not compiling 3. Tried to make my own powershell script to mimic the setup.sh behavior. I'm stuck at compilation part (below) https://wiki.dlang.org/Building_under_Windows 1. After several retries, I managed to compile DMD with make -fwin32.mak. In fact I'm not sure which is the intended makefile (the one in \dmd or the one in \dmd\src?) 2. make -fwin64.mak fails: make -fwin32.mak C=dmd\backend TK=dmd\tk ROOT=dmd\root MAKE="make" HOST_DC="dmd" MODEL=64 CC="vcbuild\msvc-dmc" LIB="vcbuild\msvc-lib" OBJ_MSVC="..\generated\windows\release\64/strtold.obj ..\generated\windows\release\64\longdouble.obj ..\generated\windows\release\64\ldfpu.obj" "OPT=" "DEBUG=-D -g -DUNITTEST" "DDEBUG=-debug -g -unittest" "DOPT=" "LFLAGS=-L/ma/co/la" ..\generated\windows\release\64\dmd.exe vcbuild\msvc-dmc -c -o..\generated\windows\release\64\newdelete.obj -Idmd\root -D -g -DUNITTEST -cpp -DTARGET_WINDOS=1 -DDM_TARGET_CPU_X86=1 dmd\root\newdelete.c "\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\cl.exe" /nologo /Ivcbuild /Idmd\root /FIwarnings.h /c /Fo..\generated\windows\release\64\newdelete.obj /Idmd\root /DDEBUG /Zi -DUNITTEST /TP ^"-DTARGET_WINDOS=1^" ^"-DDM_TARGET_CPU_X86=1^" dmd\root\newdelete.c std.process.ProcessException@std\process.d(753): Failed to spawn new process (The system cannot find the file specified.) 0x004136E8 0x0040D98A 0x00402CDB 0x00412D67 0x00412CE9 0x00412B84 0x0040D5D7 0x758A8654 in BaseThreadInitThunk 0x77B84A77 in RtlGetAppContainerNamedObjectPath 0x77B84A47 in RtlGetAppContainerNamedObjectPath --- errorlevel 1 --- errorlevel 1 --- errorlevel 1 https://wiki.dlang.org/DMD_development 1. Downloaded GNU Make. How do I install it? What binaries are needed? 2. Installed Linux Subsystem (Debian). What next? Why do I need this? 3. All the make commands failed to execute. I suppose because make.exe is expected to be part of the GNU package. Failed to find such file in the GNU Make distribution.
Re: How to simplify nested ifs
On Tuesday, 13 March 2018 at 12:23:06 UTC, Ozan Süel wrote: Hi I have a construction like the following if (source) { if (source.pool) { if (source.pool.repository) { if (source.pool.repository.directory) { if (source.pool.repository.directory.users) { // do something Any chance to simplify this nested ifs? I know some languages has a way like. if (source?pool?repository?directory?users) // do something Similar ways in D? Thanks and Regards, Ozan You need the null conditional operator which is not available in D. A library solution can be found there: https://forum.dlang.org/post/mailman.2562.1403196857.2907.digitalmar...@puremagic.com SafeDeref(source).pool.repository.directory.users
Re: iota to array
On Sunday, 25 February 2018 at 13:33:07 UTC, psychoticRabbit wrote: can someone please design a language that does what I tell it! please!! is that so hard?? print 1.0 does not mean go and print 1 .. it means go and print 1.0 languages are too much like people.. always thinking for themselves. I fed up! fed up I say! That's in fact a data representation problem not a language problem. In C#, if you are using a *decimal* data type, it prints as expected: decimal one = 1m; //internally represented as 10^^0 decimal one2 = 1.0m;//internally represented as 10^^-1 decimal one3 = 1.00m; //internally represented as 100^^-2 //one == one2 == one3, but the output is different: Console.WriteLine(one); //outputs 1 Console.WriteLine(one2); //outputs 1.0 Console.WriteLine(one3); //outputs 1.00 Nor Java and nor D have any built-in decimal type, therefore the internal representation of floating point values is always double (or float, or real). Double has a unique representation for 1, 1.0 or 1.00 and it's always 2^^0. How the writeln/println functions outputs 2^0, it's a design decision. Since D is inheriting C concepts (including printf), it will use the %g format as in C. I'm not a Java fan, therefore I don't know what was behind the decision of the language creators to output floating point values with at least one decimal digit.
Re: iota to array
On Sunday, 25 February 2018 at 08:08:30 UTC, psychoticRabbit wrote: But umm what happended to the principle of least astonishment? writeln(1.1); (prints 1.1) whereas.. writeln(1.0); (prints 1) I don't get it. Cause it's 'nicer'?? Because writeln(someFloat) is equivalent to writefln("%g", someFloat). And according to printf specification, "trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit"
Re: opCast cannot implicitly convert a.opCast of type X to Y
On Monday, 12 February 2018 at 02:05:16 UTC, aliak wrote: From spec: Cast expression: "cast ( Type ) UnaryExpression" converts UnaryExpresssion to Type. And https://dlang.org/spec/operatoroverloading.html#cast makes no mention of the return type of opCast. One could think that the return type of opCast would be the return type. But it seems it must be the same as the template parameter of opCast else you get a compile error that seems like it can be much better. - Ali In my opinion, you should fill a documentation enhancement request on issues.dlang.org.
Re: opUnary with ++ and -- on a struct that has a dynamic array
On Monday, 12 February 2018 at 03:13:43 UTC, aliak wrote: Hi, Is there a way to get post increment and pre increment working properly in this scenario? import std.stdio; struct A { int[] a; this(int a) { this.a = [a]; } auto opUnary(string op)(){ return A(mixin(op ~ "this.a[0]")); } } void main() { auto a = A(0); int b = 0; writeln(a++, ":", b++); // 1, 0 <-- wrong post increment result writeln(++a, ":", ++b); // 2, 2 } writeln(a++) translates to: A copy = a; a.opUnary!"++"; writeln(copy); copy.a[] and a.a[] are the same reference, you increment a.a[0]/copy.a[0] in opUnary to make this work you will need a postblit constructor: struct A { this(this) { a = a.dup; //make a copy a; } } In fact, you'll find exactly the same scenario in docs: https://dlang.org/spec/struct.html#struct-postblit If I switch the order of the mixin expression (i.e. "this.a[0]" ~ op) then the pre increment does not work. Any tips? Cheers - Ali
Re: Fixed size array initialization
On Sunday, 11 February 2018 at 14:06:32 UTC, rjframe wrote: On Sat, 10 Feb 2018 10:55:30 +, rumbu wrote: If you separate initialization to a static this, you'll get a compile error: ``` immutable uint256[78] pow10_256; static this() { // Error: mismatched array lengths, 78 and 2 pow10_256 = [ uint256(1UL), uint256(10UL) ]; } ``` Yes, this was in fact the idea of https://github.com/dlang/phobos/pull/4936 Didn't like it, sorry. Or if you know that no element should be the object's init value, you could do a static foreach to validate that at compile-time. Nice idea too, but this will significantly increase compilation time. You could also generate the elements at compile-time (this could use some improvement, and should be generalized so a single function can generate fillers for your other arrays as well): ``` immutable uint256[78] pow10_256; static this() { // Uncomment this to view the generated code. Helpful for debugging. //pragma(msg, GenPow10_256Initializer); mixin(GenPow10_256Initializer); } static string GenPow10_256Initializer() { import std.range : repeat; import std.conv : text; string code = "pow10_256 = [\n"; foreach(i; 0..78) { code ~= `uint256("1` ~ '0'.repeat(i).text ~ `")` ~ ",\n"; } code = code[0..$-2]; // Remove trailing comma. code ~= "\n];"; return code; } ``` As I said in my previous comments, this was the initial approach for all the arrays there (I'm a very lazy person, believe me) but the compiler complained with a nice "Out of memory" error, that's why I ended writing the array elements by hand.
Re: Fixed size array initialization
On Sunday, 11 February 2018 at 01:26:59 UTC, psychoticRabbit wrote: On Sunday, 11 February 2018 at 01:13:00 UTC, psychoticRabbit wrote: Well, in C.. I can do: int arr[2] = { [0]=10, [1]=20 }; I cannot work out how to do that in D yet (anyone know??) Oh. just worked it out after reading this thread ;-) int[2] arr = [ 0:10, 1:20 ]; This is indeed the most simple and elegant solution. Thanks.
Re: Fixed size array initialization
On Saturday, 10 February 2018 at 14:55:49 UTC, b2.temp wrote: On Saturday, 10 February 2018 at 14:35:52 UTC, rumbu wrote: In this case, it there any way to be sure that I declared all the elements I intended? Obviously, without counting them by hand. At the level of the library use a template. Sorry, but I don't get it. Can you elaborate, please? This is the array in question: https://github.com/rumbu13/decimal/blob/master/src/decimal/integrals.d#L2072 First time, I tried to use mixins to generate the array, in order to avoid writing the same thing again and again. The mixin solution was nice until the compiler served me a nice Out of Memory error, that's why I finally used a hand-written array. At the level of the compiler: no. Not only not all elements are required but they also don't need to be declared in order (static array initialization, like in the example beyond). It would be possible to put a compiler warning but warnings are not in the D philosophy (one consequence is that many people, like me use -de all the time, making a possible warning not compatible with the legit uses of the "partial array initialization"). By the way i said i did change the compiler. Actually i even captured the session to promote my IDE: http://sendvid.com/c00x7nps.
Re: Fixed size array initialization
On Saturday, 10 February 2018 at 12:28:16 UTC, b2.temp wrote: On Saturday, 10 February 2018 at 10:55:30 UTC, rumbu wrote: I know that according to language spec (https://dlang.org/spec/arrays.html#static-init-static) you can skip declaring all your elements in a fixed size array. I'm just recovering from a bug which took me one day to discover because of this. I have a large static initialized array, let's say int[155], and I forgot to declare the last element: int[155] myarray = [ a, b, c, ... //forgot to declare the 155th element ]; I took for granted that the compiler will warn me about the fact that my number of elements doesn't match the array declaration but I was wrong. Does it worth to fill an enhancement on this, or this is intended behavior? I used to agree (https://issues.dlang.org/show_bug.cgi?id=17341) and even patched the compiler to emit a deprecation in this case. Then i discovered that druntime for example relies on this. The classic use case is to init a LUT where only a few elements need a non-default value, for example: ``` bool[char.max] lut = [10:true, 13:true, 9: true]; assert(!lut[46]); assert(lut[9]); ``` which can be useful. In this case, it there any way to be sure that I declared all the elements I intended? Obviously, without counting them by hand.
Fixed size array initialization
I know that according to language spec (https://dlang.org/spec/arrays.html#static-init-static) you can skip declaring all your elements in a fixed size array. I'm just recovering from a bug which took me one day to discover because of this. I have a large static initialized array, let's say int[155], and I forgot to declare the last element: int[155] myarray = [ a, b, c, ... //forgot to declare the 155th element ]; I took for granted that the compiler will warn me about the fact that my number of elements doesn't match the array declaration but I was wrong. Does it worth to fill an enhancement on this, or this is intended behavior?
Re: How to proceed with learning to code Windows desktop applications?
On Monday, 29 January 2018 at 22:55:12 UTC, I Lindström wrote: Hello all! I've been doing console apps for about a year and a half now, but my requirements are reaching the limits of easy to use with ASCII-based UI and typed commands so I'm thinking of moving into GUI-era with my projects. I was wondering if some one could help me into the right direction. I've been Googling a ton these past few days for some kind of a book or a course on how to code desktop applications for Windows, but either there isn't one, or it's very well hidden. I've found bits and pieces but nothing to give me a coherent approach. The other way I've been thinking is to do the thing browser-based, but for some reason that doesn't feel right. On Windows platform, WPF is the way to go right now. Once you accommodate yourself with XAML (descriptive language for designing windows and controls), you can step up from WPF to modern Windows apps (UWP). Unfortunately, none of these technologies are supported in D. WinAPI is for masochistic people, WinForms is obsolete. But we are leaving in the everything-is-an-web-app era, therefore don't dismiss the idea of an web application. I don't like them either.
Re: Cannot initialize associative array
On Friday, 19 January 2018 at 23:27:06 UTC, Adam D. Ruppe wrote: On Friday, 19 January 2018 at 23:16:19 UTC, rumbu wrote: According to this (https://dlang.org/spec/hash-map.html#static_initialization) this is correct static initialization for AA: That only works inside a function, and, ironically, only if the variable is not `static`... I believe this is technically an implementation shortcoming - it is supposed to work in a static context too, but it isn't implemented. But regardless, right now, you need to do it in a function (or a static constructor) right now. You can separate declaration from initialization on module-level like so: immutable RoundingMode[string] ibmRounding; shared static this() { ibmRounding = [ ">" : RoundingMode.towardPositive, "<" : RoundingMode.towardNegative, "0" : RoundingMode.towardZero, "=0": RoundingMode.tiesToEven, "=^": RoundingMode.tiesToAway ]; } Thank you Adam, just figured out myself the same solution, but I didn't expect to have a static constructor in main.d. I thought static constructors are meant to be used in imported modules. Thanks again.
Cannot initialize associative array
According to this (https://dlang.org/spec/hash-map.html#static_initialization) this is correct static initialization for AA: immutable RoundingMode[string] ibmRounding = [ ">" : RoundingMode.towardPositive, "<" : RoundingMode.towardNegative, "0" : RoundingMode.towardZero, "=0": RoundingMode.tiesToEven, "=^": RoundingMode.tiesToAway ]; Error: non-constant expression `[">":cast(RoundingMode)2, "<":cast(RoundingMode)3, "0":cast(RoundingMode)4, "=0":cast(RoundingMode)0, "=^":cast(RoundingMode)1]` RoundingMode is an enum.
Re: New integer promotion rules
On Thursday, 18 January 2018 at 18:00:51 UTC, rumbu wrote: On Thursday, 18 January 2018 at 17:54:59 UTC, rumbu wrote: On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c; That would have been better even before the change, because the operator '-' used on unsigned types is likely to produce unexpected results, if the behaviour is defined at all. I don't think so: ulong c = 128; bool isNegative = true; byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c; Error Deprecation: integral promotion not done for `-cast(ubyte)c`, use '-transition=intpromote' switch or `-cast(int)(cast(ubyte)c)` My bad, it works. Thanks: ulong c = 128; bool isNegative = true; byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c; But this doesn't: ushort c = 128; bool isNegative = true; byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c; Error Deprecation: integral promotion not done for `-c`, use '-transition=intpromote' switch or `-cast(int)(c) This is starting to become truly crazy.
Re: New integer promotion rules
On Thursday, 18 January 2018 at 17:54:59 UTC, rumbu wrote: On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c; That would have been better even before the change, because the operator '-' used on unsigned types is likely to produce unexpected results, if the behaviour is defined at all. I don't think so: ulong c = 128; bool isNegative = true; byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c; Error Deprecation: integral promotion not done for `-cast(ubyte)c`, use '-transition=intpromote' switch or `-cast(int)(cast(ubyte)c)` My bad, it works. Thanks: ulong c = 128; bool isNegative = true; byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c;
Re: New integer promotion rules
On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes Scherkl wrote: On Thursday, 18 January 2018 at 06:05:08 UTC, rumbu wrote: On Thursday, 18 January 2018 at 02:30:17 UTC, Rubn wrote: On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote: code like "m = n < 0 ? -n : n" doesn't worth a wrapper That code is worth a wrapper, it's called "abs"... m = abs(n); Well, since I'm in the learn forum and you seem to have a response to anything, can you help me translate this line under the new integer promotion rules? https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L7804 Thanks. target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c; That would have been better even before the change, because the operator '-' used on unsigned types is likely to produce unexpected results, if the behaviour is defined at all. I don't think so: ulong c = 128; bool isNegative = true; byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c; Error Deprecation: integral promotion not done for `-cast(ubyte)c`, use '-transition=intpromote' switch or `-cast(int)(cast(ubyte)c)`
Re: New integer promotion rules
On Thursday, 18 January 2018 at 02:30:17 UTC, Rubn wrote: On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote: code like "m = n < 0 ? -n : n" doesn't worth a wrapper That code is worth a wrapper, it's called "abs"... m = abs(n); Well, since I'm in the learn forum and you seem to have a response to anything, can you help me translate this line under the new integer promotion rules? https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L7804 Thanks.
Re: New integer promotion rules
On Wednesday, 17 January 2018 at 21:12:07 UTC, Rubn wrote: On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote: And here is why is bothering me: auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max); The generic code above (which worked for all signed integral types T in 2.077) must be rewritten like this in 2.078: static if (T.sizeof >= 4) auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max; else auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : cast(Unsigned!T)T.max; Now I have to translate an 1-liner in a 4-liner all around my project. Or write some wrapper code, which you prob should have done in the first place if you use that all around your project: auto max = myMaxFunc!(isNegative, T); "max" was just an over-templated example to highlight the problem, code like "m = n < 0 ? -n : n" doesn't worth a wrapper, for example. But the original questions remain: 1. Why do I need explicitely to promote my byte to int in order to assign it to an ulong? 2.077: ulong u = -b; 2.088: ulong u = -cast(int)b; 2. Why do I need a cast(int) to assign a byte to an ubyte, since I'm explicitely cast it? 2.077: ubyte c = cast(ubyte)-b; 2.088: ubyte c = cast(ubyte)-cast(int)b
Re: New integer promotion rules
And here is why is bothering me: auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max); The generic code above (which worked for all signed integral types T in 2.077) must be rewritten like this in 2.078: static if (T.sizeof >= 4) auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max; else auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : cast(Unsigned!T)T.max; Now I have to translate an 1-liner in a 4-liner all around my project.
Re: New integer promotion rules
On Wednesday, 17 January 2018 at 19:54:50 UTC, ag0aep6g wrote: On 01/17/2018 08:40 PM, rumbu wrote: This started in the last DMD version (2.078): byte b = -10; ulong u = b < 0 ? -b : b; //Deprecation: integral promotion not done for `-b`, use '-transition=intpromote' switch or `-cast(int)(b) Why do I need a to promote a byte to int to obtain an ulong? Even in the extreme case where b is byte.min, -byte.min as unsigned is exactly what i need: 128; Actually, for b = byte.min, you get u = 18446744073709551488. Wrong, compiled with 2.077 or 2.078 with -transition=intpromote byte b = byte.min; ulong u = -b; writeln(u); outputs correctly 128 2.078 is starting to fix this so that you get 128. But that's a breaking change, so you have to use the compiler switch or the cast for a couple releases. In the changelog: https://dlang.org/changelog/2.078.0.html#fix16997
New integer promotion rules
This started in the last DMD version (2.078): byte b = -10; ulong u = b < 0 ? -b : b; //Deprecation: integral promotion not done for `-b`, use '-transition=intpromote' switch or `-cast(int)(b) Why do I need a to promote a byte to int to obtain an ulong? Even in the extreme case where b is byte.min, -byte.min as unsigned is exactly what i need: 128; This leads to more cases: ubyte u = cast(ubyte)-b; //Deprecation: integral promotion not done for `-b`, use '-transition=intpromote' switch or `-cast(int)(b)` Last time I checked, casting is somehow synonym with "I know what I'm doing", why do I need another cast to prove my sanity: ubyte u = cast(ubyte)-cast(int)b;
Re: Function hijack on selective import
On Tuesday, 16 January 2018 at 20:30:43 UTC, H. S. Teoh wrote: On Tue, Jan 16, 2018 at 07:14:00PM +, rumbu via Even specialized, now I have another problem: std.math: int signbit(X)(X x) { ... } mylibrary: int signbit(D: Decimal!bits, int bits) { ... } = end user: import std.math; import mylibrary; Decimal!32 d; float f; auto y = signbit(f); //ok, call to std.math.signbit auto x = signbit(d); //error, also calls std.math.signbit Arguably, this is a defect in Phobos. Looking at the definition of std.math.signbit, it's obvious that it's only meant to handle built-in floating-point types, yet there are no sig constraints to that effect. Fix: https://github.com/dlang/phobos/pull/6040 T Thank you for the pull request, but the list is longer :) https://issues.dlang.org/show_bug.cgi?id=18244
Re: Function hijack on selective import
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote: On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote: "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them. You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y) Even specialized, now I have another problem: std.math: int signbit(X)(X x) { ... } mylibrary: int signbit(D: Decimal!bits, int bits) { ... } = end user: import std.math; import mylibrary; Decimal!32 d; float f; auto y = signbit(f); //ok, call to std.math.signbit auto x = signbit(d); //error, also calls std.math.signbit
Re: private selective import + overload = breaks accessibility rules
On Tuesday, 16 January 2018 at 18:32:46 UTC, H. S. Teoh wrote: Which version of the compiler is this? I'm pretty sure the std.math.isNaN imported by module a should not be visible in module b. The latest compiler should emit a deprecation warning for this. 2.078, but also 2.077. Deprecation is emitted only if there is no overload; Of course, it's possible that having a public symbol in module a that overloads an imported symbol may have triggered a buggy corner case in the compiler. If so, a bug should be filed. Done: https://issues.dlang.org/show_bug.cgi?id=18243
private selective import + overload = breaks accessibility rules
module a; private import std.math: isNaN; //custom overload public bool isNaN(int i) { return false; } = module b; import a; void foo() { bool b = isNaN(float.nan); //compiles successfully calling std.math.isNaN even it should not be visible. } Is this normal behavior or a bug? OK, let's try another: module b; import a; import std.math; // <== note this void foo() { bool b = isNaN(float.nan); } It ends in a very funny error message: Error: std.math.isNaN!float.isNaN at src\phobos\std\math.d(5335) conflicts with std.math.isNaN!float.isNaN at src\phobos\std\math.d(5335) Real life context: the private import: https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L320 the overload: https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L4201 If the end user wants to use my module like this: import std.math; import decimal; he'll get the nice error message above.
Filling up a FormatSpec
Is there any way to parse a format string into a FormatSpec? FormatSpec has a private function "fillUp" which is not accessible. I need to provide formatting capabilities to a custom data type, I've already written the standard function: void toString(C)(scope void delegate(const(C)[]) sink, FormatSpec!C fs) const but I want to provide another function: string toString(C)(const(C)[] fmt) and forward it to the standard one. The problem is that initializing FormatSpec with fmt does not parse it: auto fs = FormatSpec!C(fmt); //this will just put fmt in fs.trailing I know that I can use format() for this, but I don't want to import 6000 code lines, I would prefer to interpret myself FormatSpec once parsed.
float.max + 1.0 does not overflow
Is that normal? use std.math; float f = float.max; f += 1.0; assert(IeeeFlags.overflow) //failure assert(f == float.inf) //failure, f is in fact float.max On the contrary, float.max + float.max will overflow. The behavior is the same for double and real.
Re: Function hijack on selective import
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote: On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote: "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them. You can specialize on templated structs generically. int foo(T : Bar!(X, Y), X, Y) that kind of thing covers any case of Bar!(X,y) Thank you, Adam.
Re: Function hijack on selective import
On Tuesday, 26 December 2017 at 16:15:55 UTC, Adam D. Ruppe wrote: The mistake you're making is using a constraint when you should try a specialization: int signbit(T:Custom)(T x) { return 0; } That means to use this specialized function when T is Custom. Now, you just need to merge the overload sets: import std.math; alias signbit = std.math.signbit; // this merges local signbit with std.math.signbit and boom it should compile and call your version. "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them. My opinion is that the mistake is in std.math, because std.math.signbit accepts any type instead to be constrained to float types. Actually, calling std.math.signbit with any other type than float will result in compiler error because signbit expects some float traits for the provided type: int signbit(X)(X x) @nogc @trusted pure nothrow { alias F = floatTraits!(X); return ((cast(ubyte *))[F.SIGNPOS_BYTE] & 0x80) != 0; }
Function hijack on selective import
Is there anyway to extend an existing function to accept custom data types? Option 1 - global import of std.math import std.math; struct Custom {} int signbit(T)(T x) if (is(T == Custom)) { return 0; } Custom c; assert(signbit(c) == 0); assert(signbit(-1.0) == 1); Error: template main.signbit cannot deduce function from argument types !()(double), candidates are: main.signbit(T)(T x) if (is(T == Custom)) *** Option 2 - selective import of std.math import std.math : signbit; struct Custom {} int signbit(T)(T x) if (is(T == Custom)) { return 0; } Custom c; assert(signbit(c) == 0); assert(signbit(-1.0) == 1); main.signbit called with argument types (Custom) matches both: \..\src\phobos\std\math.d(5721): std.math.signbit!(Custom).signbit(Custom x) and: main.signbit!(Custom).signbit(Custom x)
Overloading float operators
Is there any way to overload specific floating point operators? https://dlang.org/spec/expression.html#floating-point-comparisons I'm using a decimal data type (a struct) and one of the possible values is NaN, that's why I need these operators. I know also that this also was discussed, but is there any way to separately implement == and !=, so both return true or false in the same time? The reason is the same: NaN == NaN = false and NaN != NaN = false in the same time.
Re: Reflection in D
On Saturday, 28 January 2017 at 07:03:51 UTC, medhi558 wrote: public static NetworkMessage GetInstance(string id) { auto v = (id in ProtocolMessageManager.m_types); if (v !is null) return cast(NetworkMessage)ProtocolMessageManager.m_types[id].create(); else return null; } } As long as your class has a default constructor, you can use directly Object.factory(id): public static NetworkMessage GetInstance(string id) { return cast(NetworkMessage)(Object.factory(id)); }
Re: Reflection in D
On Saturday, 28 January 2017 at 08:18:15 UTC, medhi558 wrote: On Saturday, 28 January 2017 at 07:39:51 UTC, rumbu wrote: On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote: I have a last question, currently i use : if(lc.name.indexOf("protocol.messages") != -1) To know if the class is a NetworkMessage, Would be possible to do this if(lc is NetworkMessage) Sorry for my English, i speak french. if (auto nm = cast(NetworkMessage)lc) { //do something with nm } It doesn't work because lc is TypeInfo_Class In this case: if (lc == typeid(NetworkMessage))
Re: Reflection in D
On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote: I have a last question, currently i use : if(lc.name.indexOf("protocol.messages") != -1) To know if the class is a NetworkMessage, Would be possible to do this if(lc is NetworkMessage) Sorry for my English, i speak french. if (auto nm = cast(NetworkMessage)lc) { //do something with nm }
Re: Parsing a UTF-16LE file line by line, BUG?
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
Re: Issue with dmd, linker, visualD on windows 10
On Wednesday, 14 December 2016 at 11:06:10 UTC, aberba wrote: I am trying to get a fellow to try D but just setting up on windows 10 has been headache. He's currently remote. Here's the problem. (Note I'm a Linux user and haven't used windows 10) 1. He installed dmd 2 but the command "dmd" is not recognized. He confirmed and c:\D\dmd2\windows\bin is in system path. Why? If he runs the command in an already open console window, that's normal. A new console window launch will be enough to know about the recent environment path change. 2. He installed visual studio 2015 and visualD(pointed it to dmd location during installation), restarted visual studio. Without creating a visualD project, "compile and run" does nothing when he clicks. We haven't tried creating a project though, just using a D file with simple "Hello, world!" code. Syntax highlighting work though. Visual Studio doesn't work directly with source files, but with project files. This is not D-specific. I'm sure that if you edit a simple .c file in Visual Studio, it will never launch the C compiler. Create a new project (Console Application) and it will work. 3. He navigated to ...dmd2\windows\bin where "dmd" command works. But "dmd -run file.d" says Oplink error, linker exited with code ... I think this is also a environment variables problem, the linker needs some libs and does not know how to find them. Ask Cortana for "D2 32-bit Command Prompt", this batch file will open a new command prompt with all the environment variables properly set.
Re: How can I concatenate a string, a char array and an int
On Tuesday, 29 November 2016 at 10:21:24 UTC, Anders S wrote: Hi guys, just started to get into Dlang, comming from C and C++ I like to use methods like there if possible. Now I want to catenate something like this, but don't get it to work in standard C i code: char str[80]; sprintf(str, "This is a number = %f", 3.14356); import std.format; string str = format("This is a number = %f", 3.14356); Now in Dlang and import core.stdc.string and code: char [80] str; sprintf(str, "This is a number = %d", 314356); writefln("%s", str); but get error Error: function core.stdc.stdio.sprintf (char* s, const(char*) format, ...) is not callable using argument types (char[80], string, int) Nor does this work char [50] temp = "This is a number"; string greeting5= temp~" "~314356; writefln("%s",greeting5); import std.conv; string temp = "This is a number"; string greeting5 = temp ~ " " ~ to!string(314356); result in error: Error: incompatible types for ((cast(const(char)[])temp ~ " ") ~ (314356)): 'char[]' and 'int' Any ideas or hints? /anders
Re: Is there a way to identfy Windows version?
On Tuesday, 22 November 2016 at 11:00:52 UTC, Bauss wrote: On Monday, 21 November 2016 at 09:11:39 UTC, Jonathan M Davis wrote: On Monday, November 21, 2016 08:57:11 Bauss via Digitalmars-d-learn wrote: [...] Phobos doesn't have anything like that, but you can use the C functions from the Windows API to do it. A quick search turned up GetVersion and GetVersionExA/W: [...] Thank you, I thought I would end up with something like that! :) Obtaining the true Windows version is tricky starting with Windows 8. Be careful when using GetVersionEx, it's deprecated. VerifyVersionInfo is more reliable, but it will not return a version greater than Windows 8 if your application does not embed a specific manifest. The dirty way to obtain the true Windows version without embedding a manifest, it's to check for the availability of specific functions. Another way is to parse HLKM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Product Name. And finally NetServerGetInfo is your best bet, but it's not guaranteed to work in the future version of Windows.
Re: How to muldiv in D?
On Tuesday, 22 November 2016 at 08:54:36 UTC, Kagamin wrote: Yep, I need muldiv for long values on x86-64. Quick and dirty assembler: version(D_InlineAsm_X86_64): long muldiv(long a, long b, long c) { //windows RCX, RDX, R8 //linux RDI, RSI, RDX version(Windows) { asm { naked; mov RAX, RCX; //RAX = a imul RDX; //RDX:RAX = a * b idiv R8;//RAX = a * b / c ret; } } else version(linux) { asm { naked; mov RAX, RDI; //RAX = a; mov R8, RDX;//R8 = b imul RSI; //RDX:RAX = a * b idiv R8;//RAX = a * b / c ret; } } else static assert(0); }
Symbol lookup failed in imported module
module module1; void foo(string s) {} -- module module2; import module1; void foo(int i) { foo("abc"); //error - function foo(int) is not callable using argument types(string) } Ok, this can be easily solved using "alias foo = module1.foo", but according to the documentation "Symbol lookup stops as soon as a symbol is found". I think, in this case, this is too soon, clearly foo(string) does not match foo(int), there is no ambiguity. Is this a bug, or intended behaviour? If it's intended behaviour, it can lead to unintended effects if the overloads are not very different: module module1; void foo(uint x) {} -- module module2; import module1; void foo(ulong x) { foo(cast(uint)x); //the developper thinks that this will call foo(uint) declared in module1 //Instead foo(ulong) will be called recursively until a nice stack overflow will occur. }
Re: Shallow copy object when type is know
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. extern (C) Object _d_newclass(TypeInfo_Class ci); Object dup(Object obj) { if (obj is null) return null; ClassInfo ci = obj.classinfo; size_t start = Object.classinfo.init.length; size_t end = ci.init.length; Object clone = _d_newclass(ci); (cast(void*)clone)[start .. end] = (cast(void*)obj)[start .. end]; return clone; }
Custom type creation guidelines
Let's suppose that I want to implement a custom arithmetic type. Looking through phobos at Complex, BigInt, HalfFloat, Variant, etc, there is no consistent or idiomatic way to implement various operators or functions on custom types. 1) Regarding unary operator overloading, what's the best way to implement them? auto ref opUnary(string op)() if (op == "+") { ... } auto ref opUnary(string op : "+")() if (op == "+") { ... } auto ref opUnary(string op)() { static if (op == "+") { } else ... } 2) Regarding binary operator overloading, question 1 apply also, but there is more: what's the best signature? ref T opBinary(string op, T)(auto const ref T rhs) { ... } inout(T) opBinary(string op, T)(inout(T) rhs) { ... } ref T opBinary(string op, T)(T rhs) { ... } 3) Regarding comparison operators: - is there a way to have the same result for != and == (similar to float nans) - is there a way to return the same result for <, <=, >=, > (similar to float nans) - is there a way to overload float comparison operators? 4) regarding casting: - we have opCast(T) to convert my custom type to type T. Is there any method to overload the casting operation from a built in type, e.g. cast(MyType)(int)? 5) Any other guidelines? Thanks.
Re: Why isn't field-wise constructor automatic for structs and not classes?
On Saturday, 2 January 2016 at 14:57:58 UTC, Shriramana Sharma wrote: John Colvin wrote: Strictly speaking you aren't calling a constructor there, you're writing a struct literal. Why do you say I'm not calling a constructor? A class constructor is written as: auto s = *new* Timespan(1, 2); And that still doesn't answer the question of why can't we have an automatic field-wise constructor for classes... Probably because the inheritance: class C1 { int x, y; } class C2 : C1 { int z; } How the C2 default memberwise constructor would look like? new C2(x, y)? or new C2(x, y, z)? What if x and y are private or reintroduced as public members in C2? I think a default memberwise constructor for classes will break the encapsulation paradigm of OOP programming.
Re: Variable below zero but if statement doesn't grab?
On Sunday, 27 December 2015 at 23:24:55 UTC, TheDGuy wrote: On Sunday, 27 December 2015 at 22:51:27 UTC, Ali Çehreli wrote: On 12/27/2015 07:53 AM, TheDGuy wrote: Any idea what i am doing wrong? https://www.youtube.com/watch?v=j_VCa-5VeP8 YouTube says that the video has been removed by the user. That's exactly the reason why I don't like even dpaste. There is no guarantee that such threads will be useful forever. :) For me, sample code should be right here, and it should be short enough to practically be here. Ali I deleted the video because the problem was solved, it was neither a problem with the single '&' nor with my code it just showed a strange behaviour while debugging but the function returned the right value. Sample code is in my second post. Get used to it :) Unfortunately, DMD is not emitting the best debug information. The program flow is correct, but the line info is not, that's why the execution step will not be triggered in the real location of the source code. The simplest example is this: import std.stdio; void foo(int x) { if (x > 0) //step 1, correct { writeln("bigger"); //step 2, correct } else { writeln("lower"); //step 3, wrong } } int main(string[] argv) { foo(20); //breakpoint with step in return 0; } If you really want to confuse the debugger, write some asserts or contracts here and there and your program will be impossible to debug :)
Re: Graphics/font/platform backends with common interfaces?
On Wednesday, 23 December 2015 at 19:22:01 UTC, Taylor Hillegeist wrote: So I have seen alot of projects that need the same sort of stuff. graphics libraries gui libraries game libraries ploting libaries they would all benefit from a backend solution with a common interface for color fonts drawing pen_style aliasing etc. but each one i look at seems to have a built up solution with various degrees of integration with things like freetype gdi cairo sdl glew opengl. Shouldn't there be like a common (interface/abstract class) that these back-ends can fulfill? maybe I am unaware of how these things are done. And perhaps there are performance reasons that many of these are baked in. perhaps it should be like: standard color implementation. font interface that converts glyphs into drawing strokes. and a standard set of drawing instructions with transforms. //probably a grotesque simplification interface font_do{ glyphstrokes getstrokes(string characterstoget); } interface draw_do{ drawpixel(double x,double y); drawline(double x,double y); drawglyph(glypstrokes g); getpostdrawnsize(glypstroks g) ... other things } It was an initiative, but it looks abandoned now (Aurora Graphics): Thread: http://forum.dlang.org/thread/op.w9w0efr1707...@invictus.hra.local Source Code: https://github.com/auroragraphics/
Re: Most performant way of converting int to string
On Tuesday, 22 December 2015 at 17:15:27 UTC, Andrew Chapman wrote: Sorry if this is a silly question but is the to! method from the conv library the most efficient way of converting an integer value to a string? e.g. string s = to!string(100); I'm seeing a pretty dramatic slow down in my code when I use a conversion like this (when looped over 10 million iterations for benchmarking). Cheers! Converting numbers to string involves the most expensive known two operations : division and modulus by 10.