Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). I did translate the library. Wow! That was a lot. It successfully builds, but does not work for long and crashes if I try to do something: it's either an assertion that fails or out of bounds array access is thrown by D. The only thing that works is pressing a button. Now I need to somehow find and fix these things. Nuclear uses flexible array members in structs and I am a bit puzzled how to handle this without a major code refactor.
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 16:50:51 UTC, Imperatorn wrote: On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). When you're done, will you put it on dub? Yes, I will.
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote: The 1st argument of `getMember` can just be T, like the original macro. The 2nd argument needs to be a compile-time string. Also the `char*` cast needs to apply to `ptr` before subtracting the offset AFAICS. So reordering to keep type inference of `ptr`: ```d auto nk_container_of(T, string member, P)(P ptr) { return cast(T*)(cast(void*)(cast(char*)ptr - __traits(getMember, T, member).offsetof))); } ``` (Untested) I will test it:)
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). When you're done, will you put it on dub?
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote: (Untested) There might be a `need this` error
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote: return cast(T*)(cast(void*)(cast(char*)ptr - __traits(getMember, T, member).offsetof))); There's a trailing `)` that needs removing. Also pretty sure it can be simplified to: return cast(T*)(cast(char*)ptr - __traits(getMember, T, member).offsetof);
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 02:57:07 UTC, Ki Rill wrote: On Thursday, 21 September 2023 at 02:23:32 UTC, Ki Rill wrote: wrote: [...] Translated it to this eventually: ```D auto nk_container_of(P, T)(P ptr, T type, const(char)* member) { return cast(T*)(cast(void*)(cast(char*) (ptr - __traits(getMember, type, member).offsetof))); } ``` The 1st argument of `getMember` can just be T, like the original macro. The 2nd argument needs to be a compile-time string. Also the `char*` cast needs to apply to `ptr` before subtracting the offset AFAICS. So reordering to keep type inference of `ptr`: ```d auto nk_container_of(T, string member, P)(P ptr) { return cast(T*)(cast(void*)(cast(char*)ptr - __traits(getMember, T, member).offsetof))); } ``` (Untested)
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 02:23:32 UTC, Ki Rill wrote: wrote: [...] Translated it to this eventually: ```D auto nk_container_of(P, T)(P ptr, T type, const(char)* member) { return cast(T*)(cast(void*)(cast(char*) (ptr - __traits(getMember, type, member).offsetof))); } ```
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 17:14:41 UTC, Dejan Lekic wrote: [...] NK_CONTAINER_OF should probably be translated to: `cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))` PS. I did not invent this. My original idea was far worse than this. - It was suggested on IRC by a much cleverer D programmer than myself - Herringway@IRC Thanks! I translated it to this originally after looking at the links you've provided: ```D auto nk_container_of(P, T)(P ptr, T type, size_t member_offsetof) { return cast(T*)(cast(void*)(cast(char*)(1 ? (ptr) : ptr - member_offsetof))); } ``` `cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))` Now, how should I wrap it like a macro? Template mixin? I'm not that familiar with D meta programming... I shall skim through the `D templates tutorial` for hints.
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:55:14 UTC, Ki Rill wrote: On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). Here is how `NK_OFFSETOF` is defined: ```c #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m)) ``` NK_OFFSETOF is the same as D's struct `.offsetof` attribute. NK_CONTAINER_OF should probably be translated to: `cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))` PS. I did not invent this. My original idea was far worse than this. - It was suggested on IRC by a much cleverer D programmer than myself - Herringway@IRC
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). My workflow when trying to port weird C code to D is to have a small C file, put an example code, and then run the preprocessor, and try to get how things are expanded Alternatively, latest version of visual studio allows you to see that in real time, you'll still have to write example code tho https://devblogs.microsoft.com/cppblog/visualize-macro-expansion-for-c/
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:55:14 UTC, Ki Rill wrote: On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). Here is how `NK_OFFSETOF` is defined: ```c #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m)) ``` Looks like you are not the only one who has issue with them: https://github.com/Immediate-Mode-UI/Nuklear/issues/94 https://github.com/Immediate-Mode-UI/Nuklear/pull/309
Re: C to D: please help translate this weird macro
On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote: Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation). Here is how `NK_OFFSETOF` is defined: ```c #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m)) ```
C to D: please help translate this weird macro
Here is the macro: ```C #define NK_CONTAINER_OF(ptr,type,member)\ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member))) ``` I'm trying to translate the Nuklear GUI library to D [here](https://github.com/rillki/nuklear-d/tree/nuklear-d-translation).
Re: ELIZA Chatbot Implementation From C to D Lang
On Friday, 17 February 2023 at 17:03:34 UTC, ron77 wrote: Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... ```d /* eliza.c * ys * original code by Weizenbaum, 1966 * this rendition based on Charles Hayden's Java implementation from http://chayden.net/eliza/Eliza.html * * Note: There are certainly far more optimal and elegant ways to code this... we kept this * structure to be faithful to the original. -scaz */ //#include import std.stdio; import std.string; import core.stdc.string; import core.stdc.ctype; //import std.stdlib // #include //#include const NUMKEYWORDS =37; const MAXLINELEN = 120; const NUMSWAPS = 14; const char*[] keywords= [ "CAN YOU","CAN I","YOU ARE","YOURE","I DONT","I FEEL", "WHY DONT YOU","WHY CANT I","ARE YOU","I CANT","I AM","IM ", "YOU ","I WANT","WHAT","HOW","WHO","WHERE", "WHEN","WHY", "NAME","CAUSE","SORRY","DREAM","HELLO","HI ","MAYBE", " NO","YOUR","ALWAYS","THINK","ALIKE","YES","FRIEND", "COMPUTER","CAR","NOKEYFOUND"]; const char*[2][NUMSWAPS] SWAPS = [ ["ARE","AM"], ["WERE", "WAS"], ["YOU","I"], ["YOUR", "MY"], ["IVE", "YOU'VE"], ["IM", "YOU'RE"], ["YOU", "ME"], ["ME", "YOU"], ["AM","ARE"], ["WAS", "WERE"], ["I","YOU"], ["MY", "YOUR"], ["YOUVE", "I'VE"], ["YOURE", "I'M"] ]; int[NUMKEYWORDS] ResponsesPerKeyword= [ 3,2,4,4,4,3, 3,2,3,3,4,4, 3,5,9,9,9,9, 9,9, 2,4,4,4,1,1,5, 5,2,4,3,7,3,6, 7,5,6]; const char *[9][NUMKEYWORDS] responses= [ [ "DON'T YOU BELIEVE THAT I CAN*", "PERHAPS YOU WOULD LIKE TO BE ABLE TO*", "YOU WANT ME TO BE ABLE TO*"], [ "PERHAPS YOU DON'T WANT TO*", "DO YOU WANT TO BE ABLE TO*"], [ "WHAT MAKES YOU THINK I AM*", "DOES IT PLEASE YOU TO BELIEVE I AM*", "PERHAPS YOU WOULD LIKE TO BE*", "DO YOU SOMETIMES WISH YOU WERE*"], [ "WHAT MAKES YOU THINK I AM*", "DOES IT PLEASE YOU TO BELIEVE I AM*", "PERHAPS YOU WOULD LIKE TO BE*", "DO YOU SOMETIMES WISH YOU WERE*"], [ "DON'T YOU REALLY*", "WHY DON'T YOU*", "DO YOU WISH TO BE ABLE TO*", "DOES THAT TROUBLE YOU?"], [ "TELL ME MORE ABOUT SUCH FEELINGS.", "DO YOU OFTEN FEEL*", "DO YOU ENJOY FEELING*"], [ "DO YOU REALLY BELIEVE I DON'T*", "PERHAPS IN GOOD TIME I WILL*", "DO YOU WANT ME TO*"], [ "DO YOU THINK YOU SHOULD BE ABLE TO*", "WHY CAN'T YOU*"], [ "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*", "WOULD YOU PREFER IF I WERE NOT*", "PERHAPS IN YOUR FANTASIES I AM*"], [ "HOW DO YOU KNOW YOU CAN'T*", "HAVE YOU TRIED?", "PERHAPS YOU CAN NOW*"], [ "DID YOU COME TO ME BECAUSE YOU ARE*", "HOW LONG HAVE YOU BEEN*", "DO YOU BELIEVE IT IS NORMAL TO BE*", "DO YOU ENJOY BEING*"], [ "DID YOU COME TO ME BECAUSE YOU ARE*", "HOW LONG HAVE YOU BEEN*", "DO YOU BELIEVE IT IS NORMAL TO BE*", "DO YOU ENJOY BEING*"], [ "WE WERE DISCUSSING YOU-- NOT ME.", "OH, I*", "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?"], [ "WHAT WOULD IT MEAN TO YOU IF YOU GOT*", "WHY DO YOU WANT*", "SUPPOSE YOU SOON GOT*", "WHAT IF YOU NEVER GOT*", "I SOMETIMES ALSO WANT*"], [ "WHY DO YOU ASK?", "DOES THAT QUESTION INTEREST YOU?", "WHAT ANSWER WOULD PLEASE YOU THE MOST?",
Re: ELIZA Chatbot Implementation From C to D Lang
On Friday, 17 February 2023 at 17:03:34 UTC, ron77 wrote: Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... this is nothing compared to chatgpt ;)
Re: ELIZA Chatbot Implementation From C to D Lang
On Friday, 17 February 2023 at 17:03:34 UTC, ron77 wrote: Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... [...] Among the things to do the first is to drop C-style strings, so that you can get rid of `strlen()` and `strcat()` for example. Then maybe try to rewrite your for-loops as UFCS pipes. Have fun.
ELIZA Chatbot Implementation From C to D Lang
Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... ```d /* eliza.c * ys * original code by Weizenbaum, 1966 * this rendition based on Charles Hayden's Java implementation from http://chayden.net/eliza/Eliza.html * * Note: There are certainly far more optimal and elegant ways to code this... we kept this * structure to be faithful to the original. -scaz */ //#include import std.stdio; import std.string; import core.stdc.string; import core.stdc.ctype; //import std.stdlib // #include //#include const NUMKEYWORDS =37; const MAXLINELEN = 120; const NUMSWAPS = 14; const char*[] keywords= [ "CAN YOU","CAN I","YOU ARE","YOURE","I DONT","I FEEL", "WHY DONT YOU","WHY CANT I","ARE YOU","I CANT","I AM","IM ", "YOU ","I WANT","WHAT","HOW","WHO","WHERE", "WHEN","WHY", "NAME","CAUSE","SORRY","DREAM","HELLO","HI ","MAYBE", " NO","YOUR","ALWAYS","THINK","ALIKE","YES","FRIEND", "COMPUTER","CAR","NOKEYFOUND"]; const char*[2][NUMSWAPS] SWAPS = [ ["ARE","AM"], ["WERE", "WAS"], ["YOU","I"], ["YOUR", "MY"], ["IVE", "YOU'VE"], ["IM", "YOU'RE"], ["YOU", "ME"], ["ME", "YOU"], ["AM","ARE"], ["WAS", "WERE"], ["I","YOU"], ["MY", "YOUR"], ["YOUVE", "I'VE"], ["YOURE", "I'M"] ]; int[NUMKEYWORDS] ResponsesPerKeyword= [ 3,2,4,4,4,3, 3,2,3,3,4,4, 3,5,9,9,9,9, 9,9, 2,4,4,4,1,1,5, 5,2,4,3,7,3,6, 7,5,6]; const char *[9][NUMKEYWORDS] responses= [ [ "DON'T YOU BELIEVE THAT I CAN*", "PERHAPS YOU WOULD LIKE TO BE ABLE TO*", "YOU WANT ME TO BE ABLE TO*"], [ "PERHAPS YOU DON'T WANT TO*", "DO YOU WANT TO BE ABLE TO*"], [ "WHAT MAKES YOU THINK I AM*", "DOES IT PLEASE YOU TO BELIEVE I AM*", "PERHAPS YOU WOULD LIKE TO BE*", "DO YOU SOMETIMES WISH YOU WERE*"], [ "WHAT MAKES YOU THINK I AM*", "DOES IT PLEASE YOU TO BELIEVE I AM*", "PERHAPS YOU WOULD LIKE TO BE*", "DO YOU SOMETIMES WISH YOU WERE*"], [ "DON'T YOU REALLY*", "WHY DON'T YOU*", "DO YOU WISH TO BE ABLE TO*", "DOES THAT TROUBLE YOU?"], [ "TELL ME MORE ABOUT SUCH FEELINGS.", "DO YOU OFTEN FEEL*", "DO YOU ENJOY FEELING*"], [ "DO YOU REALLY BELIEVE I DON'T*", "PERHAPS IN GOOD TIME I WILL*", "DO YOU WANT ME TO*"], [ "DO YOU THINK YOU SHOULD BE ABLE TO*", "WHY CAN'T YOU*"], [ "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*", "WOULD YOU PREFER IF I WERE NOT*", "PERHAPS IN YOUR FANTASIES I AM*"], [ "HOW DO YOU KNOW YOU CAN'T*", "HAVE YOU TRIED?", "PERHAPS YOU CAN NOW*"], [ "DID YOU COME TO ME BECAUSE YOU ARE*", "HOW LONG HAVE YOU BEEN*", "DO YOU BELIEVE IT IS NORMAL TO BE*", "DO YOU ENJOY BEING*"], [ "DID YOU COME TO ME BECAUSE YOU ARE*", "HOW LONG HAVE YOU BEEN*", "DO YOU BELIEVE IT IS NORMAL TO BE*", "DO YOU ENJOY BEING*"], [ "WE WERE DISCUSSING YOU-- NOT ME.", "OH, I*", "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?"], [ "WHAT WOULD IT MEAN TO YOU IF YOU GOT*", "WHY DO YOU WANT*", "SUPPOSE YOU SOON GOT*", "WHAT IF YOU NEVER GOT*", "I SOMETIMES ALSO WANT*"], [ "WHY DO YOU ASK?", "DOES THAT QUESTION INTEREST YOU?", "WHAT ANSWER WOULD PLEASE YOU THE MOST?", "WHAT DO YOU THINK?", "ARE SUCH QUESTIONS ON YOU
Re: C to D convertor
On Tuesday, 24 August 2021 at 11:52:45 UTC, Dennis wrote: On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: Any more ? CPP2D https://github.com/lhamot/CPP2D Dennis, thank!
Re: C to D convertor
On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: Any more ? CPP2D https://github.com/lhamot/CPP2D
Re: C to D convertor
On Saturday, 21 August 2021 at 08:59:55 UTC, evilrat wrote: On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? `htod` is 1. Any more ? dstep https://code.dlang.org/packages/dstep dpp https://code.dlang.org/packages/dpp ohmygentool https://github.com/Superbelko/ohmygentool evilrat, thank you!
Re: C to D convertor
On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? `htod` is 1. Any more ? dstep https://code.dlang.org/packages/dstep dpp https://code.dlang.org/packages/dpp ohmygentool https://github.com/Superbelko/ohmygentool
C to D convertor
I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? Examples of what the wanted: // C typedef struct { uint32_t version; /* 0x5000 */ uint16_t num_glyphs; } MaxProTable; // D struct MaxProTable { uint32_t version; /* 0x5000 */ uint16_t num_glyphs; } // C #define ENABLE_SUBDIV 0 // D enum ENABLE_SUBDIV = 0; // C #include "triangulate.h" // D import triangulate; // C #include // D import core.stdc.string; // C #define cross2(a,b) ((a)[0]*(b)[1]-(a)[1]*(b)[0]) // D pragma( inline, true ) auto cross2( T1, T2 )( T1 a, T2 b ) { return ((a)[0]*(b)[1]-(a)[1]*(b)[0]); } // C double ab[2]; // D double[2] ab; // C trgu = calloc( 1, sizeof(*trgu) ); // D trgu = calloc( 1, (*trgu).sizeof ); // C PointFlag *point_flags = gt->flags; // D PointFlag *point_flags = gt.flags; `htod` is 1. Any more ?
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 19:06:42 UTC, Tejas wrote: But how scalable will this be? We have to get real D code to enrich our ambiguously-defined-small ecosystem. It says bindings generator, but it has to convert the code keeping the semantic as close as possible. It does direct translation on AST level (AST-to-source currently), there is quirks here and there, semantic discrepancies(for example sizeof/alignof differs in D vs C++), lack of struct inheritance and multiple inheritance, and other annoying stuff like implicit casts or implicit constructors, but overall this should work. Definitely better than doing it all by hand. I tried to run it on clang, phew, got 241k lines, and that's without .cpp files. Haven't even bothered with fixing it to compilable state (even then it will definitely have linking issues).
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 16:49:59 UTC, Dukc wrote: On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? This is article is about transpiling old C++ to newer C++, but the same problem applies with translating C++ to D: https://scottmeyers.blogspot.com/2015/11/the-brick-wall-of-c-source-code.html Damn that preprocessor! :@
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 16:50:41 UTC, evilrat wrote: On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? I leave this here, it does converts C++ to D to some extent https://github.com/Superbelko/ohmygento Yes I saw the announcement earlier. I was hoping for something native, rather than bindings. As you said youself, it's not exactly stable. Plus I don't want a hamster's death on my conscience. :( Please don't take this as me belittling your work, it is better than having nothing. But how scalable will this be? We have to get real D code to enrich our ambiguously-defined-small ecosystem.
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? See https://stackoverflow.com/questions/14589346/is-c-context-free-or-context-sensitive#answer-14589567 Mixing semantic with parsing isn't necessarily a good idea. Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. That doesn't solve the ABI compatibility to C++, only if source is available, but they may be compiled with compilers which can't build anymore with the current tool chain at least without to rebuild the tool chain. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? The problem is that old looking code doesn't become modern when it is transpired to D as the concepts to do things have changed.
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? I leave this here, it does converts C++ to D to some extent https://github.com/Superbelko/ohmygentool
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 15:57:44 UTC, Imperatorn wrote: On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? I'm guessing it's hard because of the grammar Well, still a grammar, though it was my little WTF moment. for example this C++ grammar(often used in STL) where min is simple minimum function ```cpp float min(float l, float r) { return (l < r) ? l : r; } ``` ```cpp float foo(float a, float b) { return (min)(a,b); } ``` and this direct translation to D doesn't works ```d float foo(float a, float b) { return (min)(a,b); // Error: C style cast illegal, use `cast(min)(a , b)` } ``` but this does ```d float foo(float a, float b) { return (&min)(a,b); // ok } ```
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? This is article is about transpiling old C++ to newer C++, but the same problem applies with translating C++ to D: https://scottmeyers.blogspot.com/2015/11/the-brick-wall-of-c-source-code.html
Re: Why can't we transpile C++ to D?
On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote: Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right? I'm guessing it's hard because of the grammar
Why can't we transpile C++ to D?
Sorry, I'm rather ignorant when it comes to this, but why can't we use [pegged](https://github.com/PhilippeSigaud/Pegged) to transpile C++ code to D? Then we won't need a nogc compatible std library and so many other things could get easier, like getting legacy code to use Dlang. It might not be worth it for C+17 and beyond, but older codebases could benefit significantly, right?
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
On Wed, Feb 21, 2018 at 11:16:44PM -0500, Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > Are there any tutorials or articles out there for "getting started > with converting a C++ codebase to D one module at a time?" Or at the > very least: tips, tricks, lessions learned, from those who have come > before. Here's a really nasty thing that I just came across today (cf. other thread as well), in translating C++ code that calls an external library via a C API: // C (called from original C++ code): typedef double mytype[1]; struct blah { mytype x; } void foo(mytype x); void bar(struct blah b); A naïve translation to D would be: // D (incorrect) alias mytype = double[1]; struct blah { mytype x; } void foo(mytype x); // Uh oh void bar(struct blah b); The problem is that in C, a function parameter declared as double[1] is actually the same as double* because of C's infamous array -> pointer degradation. So the parameter of foo should actually be declared as double*, not as double[1] (via the `mytype` alias). However, simply changing the definition of `mytype` to `double*` leads to another problem: the definition of struct blah will be wrong, because in C, a struct field declared as double[n] is actually equivalent to a D static array, i.e., it occupies the space of n doubles. Changing that to double* makes the D declaration of the struct incorrect. Furthermore, calling foo from D now requires explicitly writing `&x` instead of merely `x`. The solution I eventually settled on is to adopt the convention that whenever a C "static array" appears as a function parameter, declare it as `ref`. So: // D (correct) alias mytype = double[1]; struct blah { mytype x; } void foo(ref mytype x); // N.B.: add `ref` here void bar(struct blah b); This allows correct matching to the C API without requiring inserting `&`s everywhere. T -- What's an anagram of "BANACH-TARSKI"? BANACH-TARSKI BANACH-TARSKI.
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
On Thursday, 22 February 2018 at 04:16:44 UTC, Nick Sabalausky (Abscissa) wrote: Are there any tutorials or articles out there for "getting started with converting a C++ codebase to D one module at a time?" Or at the very least: tips, tricks, lessions learned, from those who have come before. AFAIK, visuald has a tool that just translated C++ to D https://github.com/dlang/visuald/tree/master/c2d
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
On Thursday, 22 February 2018 at 08:43:24 UTC, ketmar wrote: Nick Sabalausky (Abscissa) wrote: [...] from my experience (various codebases up to middle size, mostly C, some C++): fsck the "one module at a time" idea! even in D modules are interwined, and in C and C++ they're even more so. besides, converting tests is tedious, it is much funnier to have something working. so, i'm usually converting alot of code, up to the whole codebase. it is not fun when compler spits 100500 errors, but when it finally stops... oh, joy! trick: use 'sed' (or your favorite regexp search-and-replace tool) alot. basically, before HDD crash i almost had a set of scripts that does 80-90 percents of work translating C to D with sed. ;-) then use editor with "jump to error line" support, and simply compile your code, fixing errors one by one. tip: try to not rewrite code in any way until it works. i know how tempting it to replace "just this tiny thing, it is so ugly, and in D we have a nice idiom!" NEVAR. this is by far the most important thing to remember (at least for me), so i'll repeat it again: no code modifications until it works! personal memories: C code often using things like `a == &arr[idx]`, where idx can go just past the last array element. it got me when i was doing enet conversion. nasty trick. otherwise, sweat and blood, and patience. These are good starting point so we don't get lost in the process. Still not much exprience doing, but I think these pieces of advice are especially true if the codebase is big or complicated, making it difficult to understand what the C/C++ is doing. When we don't understand the code, re-writing from scratch is not possible.
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
On Thu, Feb 22, 2018 at 10:43:24AM +0200, ketmar via Digitalmars-d-learn wrote: > Nick Sabalausky (Abscissa) wrote: > > > Are there any tutorials or articles out there for "getting started > > with converting a C++ codebase to D one module at a time?" Or at the > > very least: tips, tricks, lessions learned, from those who have come > > before. > > from my experience (various codebases up to middle size, mostly C, > some C++): fsck the "one module at a time" idea! even in D modules are > interwined, and in C and C++ they're even more so. besides, converting > tests is tedious, it is much funnier to have something working. I'm in the middle of the process of converting an old C++ project right now (it's so old that most of it dates back to C++98, and needs to be compiled with options to suppress C++11 deprecations and errors). I started out with the idea of incremental conversion, and managed to get as far as converting main() to D via shims to transition between the D/C++ boundary. The straw that broke the camel's back, though: C++ exceptions that need to percolate all the way to the top-level. I know people have mentioned Calypso, etc., but I'm mainly using dmd right now, and I really don't like the idea of putting a bunch of effort into using a different toolchain just to be able to incrementally migrate a lousy C++ project. So I'm starting to agree with ketmar: just jump into D cold turkey and convert the whole dang thing in one go. Actually, what I ended up doing right now is no longer converting, but rewriting individual modules in D. It's more effort, but I'm aiming for more idiomatic D code, and also the whole reason I started out on this task is because I want to refactor the code to fix some fundamental design flaws, but I really do not want to work with C++ anymore. So it doesn't make sense to me to struggle with making C++ code compile in D, only to immediately afterwards rewrite it anyway. Why not rewrite it right now, using the C++ code as a reference rather than a direct source. [...] > tip: try to not rewrite code in any way until it works. i know how > tempting it to replace "just this tiny thing, it is so ugly, and in D > we have a nice idiom!" NEVAR. this is by far the most important thing > to remember (at least for me), so i'll repeat it again: no code > modifications until it works! So I'm taking the wrong approach, perhaps. :-D But basically, I'm starting out with the leaf node modules and rewriting it in D, complete with unittests and what-not, to ensure it's semantically correct. Perhaps when I get to the main code I may have to compromise on my rewrite approach, because it will be too big to rewrite in one go. But we'll see. One thing that's *really* helping is D's built-in unittests. With this approach, I can actually just comment out the C++ code, then gradually uncomment individual functions one at a time, translate to D, then add unittests to make sure it works correctly. This is extremely helpful because I don't need to have a working main() to test individual translated functions -- that wouldn't work because too many things depend on too many other things, so requiring a functional main() means rewriting the entire codebase before you get something that's testable. There's just too much room for human error there. Being able to translate C++ functions one at a time and have unittests to ensure I didn't introduce any bugs, is a HUGE help. It helps build confidence that I'm actually making progress (instead of writing a huge amount of code that ultimately doesn't work!). [...] > otherwise, sweat and blood, and patience. +1. Yep, it's a lot of work. But I'm chugging away at it. Can't wait till the thing is finally running in D, and I can kill off the old C++ sources forever. Just too much unmaintainable ugliness there that I'd rather not remember. T -- "I'm not childish; I'm just in touch with the child within!" - RL
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
also related: https://github.com/Syniurge/Calypso/issues/85 (feasibility of extending calypso to do source to source translation (eg C++ => D or C=>D) ) On Thu, Feb 22, 2018 at 12:43 AM, ketmar via Digitalmars-d-learn wrote: > Nick Sabalausky (Abscissa) wrote: > >> Are there any tutorials or articles out there for "getting started with >> converting a C++ codebase to D one module at a time?" Or at the very least: >> tips, tricks, lessions learned, from those who have come before. > > > from my experience (various codebases up to middle size, mostly C, some > C++): fsck the "one module at a time" idea! even in D modules are > interwined, and in C and C++ they're even more so. besides, converting tests > is tedious, it is much funnier to have something working. > > so, i'm usually converting alot of code, up to the whole codebase. it is not > fun when compler spits 100500 errors, but when it finally stops... oh, joy! > > trick: use 'sed' (or your favorite regexp search-and-replace tool) alot. > basically, before HDD crash i almost had a set of scripts that does 80-90 > percents of work translating C to D with sed. ;-) then use editor with "jump > to error line" support, and simply compile your code, fixing errors one by > one. > > tip: try to not rewrite code in any way until it works. i know how tempting > it to replace "just this tiny thing, it is so ugly, and in D we have a nice > idiom!" NEVAR. this is by far the most important thing to remember (at least > for me), so i'll repeat it again: no code modifications until it works! > > personal memories: C code often using things like `a == &arr[idx]`, where > idx can go just past the last array element. it got me when i was doing enet > conversion. nasty trick. > > otherwise, sweat and blood, and patience.
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
Nick Sabalausky (Abscissa) wrote: Are there any tutorials or articles out there for "getting started with converting a C++ codebase to D one module at a time?" Or at the very least: tips, tricks, lessions learned, from those who have come before. from my experience (various codebases up to middle size, mostly C, some C++): fsck the "one module at a time" idea! even in D modules are interwined, and in C and C++ they're even more so. besides, converting tests is tedious, it is much funnier to have something working. so, i'm usually converting alot of code, up to the whole codebase. it is not fun when compler spits 100500 errors, but when it finally stops... oh, joy! trick: use 'sed' (or your favorite regexp search-and-replace tool) alot. basically, before HDD crash i almost had a set of scripts that does 80-90 percents of work translating C to D with sed. ;-) then use editor with "jump to error line" support, and simply compile your code, fixing errors one by one. tip: try to not rewrite code in any way until it works. i know how tempting it to replace "just this tiny thing, it is so ugly, and in D we have a nice idiom!" NEVAR. this is by far the most important thing to remember (at least for me), so i'll repeat it again: no code modifications until it works! personal memories: C code often using things like `a == &arr[idx]`, where idx can go just past the last array element. it got me when i was doing enet conversion. nasty trick. otherwise, sweat and blood, and patience.
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
On Thursday, 22 February 2018 at 04:16:44 UTC, Nick Sabalausky (Abscissa) wrote: Are there any tutorials or articles out there for "getting started with converting a C++ codebase to D one module at a time?" Or at the very least: tips, tricks, lessions learned, from those who have come before. These are the resources I'm aware of: https://dlang.org/articles/cpptod.html https://wiki.dlang.org/Programming_in_D_for_C%2B%2B_Programmers Mike
Tuts/Aritcles: Incrementasl C++-to-D conversion?
Are there any tutorials or articles out there for "getting started with converting a C++ codebase to D one module at a time?" Or at the very least: tips, tricks, lessions learned, from those who have come before.
Re: Tried C++ to D. Wrong result.
On Tuesday, 28 November 2017 at 09:01:47 UTC, Temtaime wrote: https://pastebin.com/xJXPBh0n Converted it and it works as expected. What did you use for it? In future I'll be needed to convert some more C++ code. P.S. /And it works wrong, because uses unsafe pointer (ubyte *image). So, it takes wrong values (Blue of the next pixel instead of Alpha of the current pixel). Same with original code./ P.P.S. Anyway, I already found all things I did wrong. But also I found in your code that there is `swap` function, didn't know it. Thank you!
Re: Tried C++ to D. Wrong result.
On Tuesday, 28 November 2017 at 06:46:18 UTC, Dmitry wrote: On Monday, 27 November 2017 at 19:01:28 UTC, Ali Çehreli wrote: P.S. I think you have an unnecessary 'ref' on the D version because a slice is already a reference to elements: Fixed, thank you. https://pastebin.com/xJXPBh0n Converted it and it works as expected.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 19:01:28 UTC, Ali Çehreli wrote: P.S. I think you have an unnecessary 'ref' on the D version because a slice is already a reference to elements: Fixed, thank you.
Re: Tried C++ to D. Wrong result.
On 11/27/2017 10:47 AM, Dmitry wrote: > On Monday, 27 November 2017 at 18:40:41 UTC, Ali Çehreli wrote: > >> So, it looks like the original code was accessing out of bounds and >> probably that's why you inserted the ((index + 3) < N) check in the D >> version because D was catching that error at runtime. > Yes, it is. This is exactly the kind of bug Walter wanted to avoid when leaving C's arrays behind. (This includes C++'s std::vector because vector::operator[] is permissive. (To be safe, one needs to use .at() or check indexes explicitly.)) So, as advertised, port your programs to D and the results will likely be more correct. I like it! :) Ali P.S. I think you have an unnecessary 'ref' on the D version because a slice is already a reference to elements: // C++ void alpha_bleeding(unsigned char *image, int width, int height) // D private void alphaBleeding(ref ubyte[] data, int width, int height) You would need that 'ref' if you wanted to modify the original array itself by e.g. adding elements to it.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 18:40:41 UTC, Ali Çehreli wrote: So, it looks like the original code was accessing out of bounds and probably that's why you inserted the ((index + 3) < N) check in the D version because D was catching that error at runtime. Yes, it is. Which of course would skip the body of the if block, causing a difference from the original result. Yes. I fixed it in C++ version also and now both versions works same.
Re: Tried C++ to D. Wrong result.
On 11/27/2017 10:25 AM, Dmitry wrote: > On Monday, 27 November 2017 at 17:21:05 UTC, Dmitry wrote: >> It fixed a delay (you can see it on video I posted before), but result >> is same. > > It seems I found the problem. > > C++ version (line 93): > if (image[index + 3] != 0) > > I changed to > if (image[index] != 0) > > and it works. > > I don't understand why there was used "+ 3" (and why it works in C++ > version). So, it looks like the original code was accessing out of bounds and probably that's why you inserted the ((index + 3) < N) check in the D version because D was catching that error at runtime. // C++ if (image[index + 3] != 0) // D if (((index + 3) < N) && (data[index + 3] != 0)) Which of course would skip the body of the if block, causing a difference from the original result. Ali
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 17:21:05 UTC, Dmitry wrote: It fixed a delay (you can see it on video I posted before), but result is same. It seems I found the problem. C++ version (line 93): if (image[index + 3] != 0) I changed to if (image[index] != 0) and it works. I don't understand why there was used "+ 3" (and why it works in C++ version). Thank you all for help.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 17:01:29 UTC, Adam D. Ruppe wrote: In the C++ version they are declared std::vector pending; std::vector pendingNext; Ah, indeed. I thought that pending.reserve(N); pendingNext.reserve(N); initializes them (last time I used C++ about 17 years ago...) I suspect you will get better results by just making the D decls and leave the rest of the code the same and see what happens. It fixed a delay (you can see it on video I posted before), but result is same.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 14:35:39 UTC, Stefan Koch wrote: First I'd make sure that what you get out of dlib load is the same as the c++ version gets. Just use standard debugging techniques. Yes, it's same. As you can see, the top-middle area of the result is same. I wrote a video of process (D version, every 100-th frame) https://www.dropbox.com/s/hcw1x4cwjou69su/video.mpg C++ version: https://www.dropbox.com/s/i7xpa5mzddpz6nu/video_orig.mpg
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 14:08:27 UTC, Dmitry wrote: https://pastebin.com/GzZQ7WHt The first thing that jumped out to me is this: size_t[] pending = new size_t[N]; size_t[] pendingNext = new size_t[N]; That's giving it N elements of zero, then you append to it later with pending ~= i; In the C++ version they are declared std::vector pending; std::vector pendingNext; which doesn't put empty elements at it. I suspect you will get better results by just making the D decls size_t[] pending; size_t[] pendingNext; and leave the rest of the code the same and see what happens.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 14:08:27 UTC, Dmitry wrote: I tried translate C++ programm to D, but result is different. original: https://github.com/urraka/alpha-bleeding/blob/master/src/alpha-bleeding.cpp result (with removed alpha): https://github.com/urraka/alpha-bleeding/blob/master/media/alpha-bleeding-opaque.png my: https://pastebin.com/GzZQ7WHt result (with removed alpha): https://www.dropbox.com/s/xbjphlievboslv2/original-2.png What did I wrong? P.S. Also on an one image it was crashed at line 63 (range violation) https://pastebin.com/TenGusw0 so I added ((index + 3) < N) into condition. First I'd make sure that what you get out of dlib load is the same as the c++ version gets. Just use standard debugging techniques.
Re: Tried C++ to D. Wrong result.
On Monday, 27 November 2017 at 14:14:12 UTC, rikki cattermole wrote: Did you confirm that the image was loaded originally correctly? Yes. This image was used: https://github.com/urraka/alpha-bleeding/blob/master/media/original.png
Re: Tried C++ to D. Wrong result.
Did you confirm that the image was loaded originally correctly?
Tried C++ to D. Wrong result.
I tried translate C++ programm to D, but result is different. original: https://github.com/urraka/alpha-bleeding/blob/master/src/alpha-bleeding.cpp result (with removed alpha): https://github.com/urraka/alpha-bleeding/blob/master/media/alpha-bleeding-opaque.png my: https://pastebin.com/GzZQ7WHt result (with removed alpha): https://www.dropbox.com/s/xbjphlievboslv2/original-2.png What did I wrong? P.S. Also on an one image it was crashed at line 63 (range violation) https://pastebin.com/TenGusw0 so I added ((index + 3) < N) into condition.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:03:51 UTC, FreeSlave wrote: Funny thing: If I replace interface with abstract class, it works as it should. Also I noticed that removing inheritance in library and in application makes unexpected results. When I try to output field `field` I get incorrect random value. It looks like that the field is got by wrong address. For clearance I created branch `removed-inheritance`.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:03:51 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 16:02:06 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: [...] Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression. Funny thing: If I replace interface with abstract class, it works as it should. Reported issue: https://issues.dlang.org/show_bug.cgi?id=17293
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:02:06 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression. Funny thing: If I replace interface with abstract class, it works as it should.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test I've tested also on Ubuntu 16.04 and DMD v2.073.1 with gcc 5.4.0
Re: Interfacing C++ to D
On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test
Re: Interfacing C++ to D
On Saturday, 1 April 2017 at 07:37:25 UTC, ANtlord wrote: Hello! Can somebody give a relevant example shows how to use C++ classes in D? I've used the exmaple from https://dlang.org/spec/cpp_interface.html but I get a segmentation fault as result of D application. My application shows "Program exited with code -11" Thanks. This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS?
Interfacing C++ to D
Hello! Can somebody give a relevant example shows how to use C++ classes in D? I've used the exmaple from https://dlang.org/spec/cpp_interface.html but I get a segmentation fault as result of D application. My application shows "Program exited with code -11" Thanks.
Re: Classes. C++ to D
On Sunday, 3 May 2015 at 17:46:54 UTC, Meta wrote: This is not really doable right now in D. You can forward the function calls to a and b easily enough, but you can't inherit from more than one class. Once the multiple alias this patch gets merged you will be able to do this in D. On Sunday, 3 May 2015 at 18:17:26 UTC, Adam D. Ruppe wrote: I'd make class A and class B into mixin templates instead. mixin template A { string a() { return "foo"; } } mixin template B { string b() { return "bar"; } } class C { mixin A; mixin B; } If you still need class A and class B, just make a class that mixes in the template for them too. Since the C++ methods aren't virtual, I imagine you don't really need a base class for them, but if you do want a virtual base class, make interfaces and inherit from as many of them as you need. Thanks. On Sunday, 3 May 2015 at 20:03:00 UTC, QAston wrote: If you want to learn a language properly, translating the idioms directly from what you already know is a bad approach. You're going to be frustrated that something was easy (to you) in your old language and the new one is weird and different than the old one. Also - results are often suboptimal. I've seen this happen too many times to not warn you, but if you just want to carry over and you don't care about learning or quality of result then please carry on. At the moment, I do not do a complete study of the D, so the quality is not important to me. Start a complete study of D, I plan a little later.
Re: Classes. C++ to D
On Sunday, 3 May 2015 at 17:35:42 UTC, Dennis Ritchie wrote: Hi, How can I rewrite this code to the D? - #include #include class A { public: std::string a() { return std::string("foo"); } }; class B { public: std::string b(){ return std::string("bar"); } }; class C : public A, public B {}; int main () { C c; std::cout << c.a() << c.b() << std::endl; return 0; } If you want to learn a language properly, translating the idioms directly from what you already know is a bad approach. You're going to be frustrated that something was easy (to you) in your old language and the new one is weird and different than the old one. Also - results are often suboptimal. I've seen this happen too many times to not warn you, but if you just want to carry over and you don't care about learning or quality of result then please carry on.
Re: Classes. C++ to D
I'd make class A and class B into mixin templates instead. mixin template A { string a() { return "foo"; } } mixin template B { string b() { return "bar"; } } class C { mixin A; mixin B; } If you still need class A and class B, just make a class that mixes in the template for them too. Since the C++ methods aren't virtual, I imagine you don't really need a base class for them, but if you do want a virtual base class, make interfaces and inherit from as many of them as you need.
Re: Classes. C++ to D
On Sunday, 3 May 2015 at 17:35:42 UTC, Dennis Ritchie wrote: Hi, How can I rewrite this code to the D? - #include #include class A { public: std::string a() { return std::string("foo"); } }; class B { public: std::string b(){ return std::string("bar"); } }; class C : public A, public B {}; int main () { C c; std::cout << c.a() << c.b() << std::endl; return 0; } This is not really doable right now in D. You can forward the function calls to a and b easily enough, but you can't inherit from more than one class. Once the multiple alias this patch gets merged you will be able to do this in D.
Classes. C++ to D
Hi, How can I rewrite this code to the D? - #include #include class A { public: std::string a() { return std::string("foo"); } }; class B { public: std::string b(){ return std::string("bar"); } }; class C : public A, public B {}; int main () { C c; std::cout << c.a() << c.b() << std::endl; return 0; }
Re: C++ to D - recursion with std.variant
On Sunday, 5 April 2015 at 09:48:01 UTC, thedeemon wrote: On Friday, 3 April 2015 at 16:46:08 UTC, Dennis Ritchie wrote: Hi, Is it possible to write on D recursion using std.variant? Using Algebraic from std.variant and some additional templates: http://dpaste.dzfl.pl/65afd3a7ce52 (taken from this thread: http://forum.dlang.org/thread/yidovyrczgdiveqba...@forum.dlang.org?page=1 ) Thanks.
Re: C++ to D - recursion with std.variant
On Friday, 3 April 2015 at 16:46:08 UTC, Dennis Ritchie wrote: Hi, Is it possible to write on D recursion using std.variant? Using Algebraic from std.variant and some additional templates: http://dpaste.dzfl.pl/65afd3a7ce52 (taken from this thread: http://forum.dlang.org/thread/yidovyrczgdiveqba...@forum.dlang.org?page=1 )
C++ to D - recursion with std.variant
Hi, Is it possible to write on D recursion using std.variant? - #include #include struct Nil {}; auto nil = Nil{}; template struct Cons; template using List = boost::variant>>; template struct Cons { Cons(T val, List list) : head(val), tail(list) {} T head; List tail; }; template class length_visitor : public boost::static_visitor { public: int operator()(Nil) const { return 0; } int operator()(const Cons& c) const { return 1 + length(c.tail); } }; template auto cons(T head, List tail) { return List(Cons(head, tail)); } template auto cons(T head, Nil) { return List(Cons(head, List(Nil{}))); } template size_t length(const List& list) { return boost::apply_visitor(length_visitor(), list); } int main() { auto l = cons(3, cons(2, cons(1, nil))); std::cout << length(l) << std::endl; // prints 3 return 0; } - http://ideone.com/qBuOvJ
Re: C++ to D
On Wednesday, 1 April 2015 at 17:51:40 UTC, John Colvin wrote: Don't really see the point. Here's a neat thing that's definitely cheating because although it stores the results in the type system, the arithmetic is done in constant-folding: struct Integer(int a){} template Value(T) { static if (is(T == Integer!a, int a)) enum Value = a; else static assert(false, "Can't get Value for " ~ T.stringof); } alias Inc(T) = Integer!(Value!T + 1); But if you really insist on it being all type-system (until you wan't the answer of course): struct Zero{} template Succ(T) { static if (is(T == Pred!A, A)) alias Succ = A; else struct Succ{} } template Pred(T) { static if (is(T == Succ!A, A)) alias Pred = A; else struct Pred{} } enum isPositive(T) = is(T == Succ!A, A); enum isNegative(T) = is(T == Pred!A, A); enum isZero(T) = is(T == Zero); template Add(A, B) { static if (isZero!B) alias Add = A; else static if (isPositive!B) alias Add = Add!(Succ!A, Pred!B); else alias Add = Add!(Pred!A, Succ!B); } template Value(T, int seed = 0) { static if (isZero!T) enum Value = seed; else static if (isPositive!T) enum Value = Value!(Pred!T, seed+1); else enum Value = Value!(Succ!T, seed-1); } unittest { alias One = Succ!Zero; alias Two = Succ!One; alias MinusThree = Pred!(Pred!(Pred!Zero)); static assert (Value!Zero == 0); static assert (Value!One == 1); static assert (Value!Two == 2); static assert (Value!MinusThree == -3); static assert (Value!(Add!(One, MinusThree)) == -2); static assert (Value!(Add!(One, Two)) == 3); static assert (is(Add!(Add!(One, Two), MinusThree) == Zero)); } Thanks.
Re: C++ to D
On Wednesday, 1 April 2015 at 17:51:40 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 17:03:34 UTC, Dennis Ritchie wrote: On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; Don't really see the point. Here's a neat thing that's definitely cheating because although it stores the results in the type system, the arithmetic is done in constant-folding: struct Integer(int a){} template Value(T) { static if (is(T == Integer!a, int a)) enum Value = a; else static assert(false, "Can't get Value for " ~ T.stringof); } alias Inc(T) = Integer!(Value!T + 1); But if you really insist on it being all type-system (until you wan't the answer of course): struct Zero{} template Succ(T) { static if (is(T == Pred!A, A)) alias Succ = A; else struct Succ{} } template Pred(T) { static if (is(T == Succ!A, A)) alias Pred = A; else struct Pred{} } enum isPositive(T) = is(T == Succ!A, A); enum isNegative(T) = is(T == Pred!A, A); enum isZero(T) = is(T == Zero); template Add(A, B) { static if (isZero!B) alias Add = A; else static if (isPositive!B) alias Add = Add!(Succ!A, Pred!B); else alias Add = Add!(Pred!A, Succ!B); } template Value(T, int seed = 0) { static if (isZero!T) enum Value = seed; else static if (isPositive!T) enum Value = Value!(Pred!T, seed+1); else enum Value = Value!(Succ!T, seed-1); } unittest { alias One = Succ!Zero; alias Two = Succ!One; alias MinusThree = Pred!(Pred!(Pred!Zero)); static assert (Value!Zero == 0); static assert (Value!One == 1); static assert (Value!Two == 2); static assert (Value!MinusThree == -3); static assert (Value!(Add!(One, MinusThree)) == -2); static assert (Value!(Add!(One, Two)) == 3); static assert (is(Add!(Add!(One, Two), MinusThree) == Zero)); } If the is() expressions are confusing you, in this case they work like this; is (T == B!A, A) means is T the same type as B instantiated with A, for some type A? or more succinctly is T an instantiation of B? See http://dlang.org/expression.html#IsExpression, it's quite reminiscent of some mathematical set notation.
Re: C++ to D
On Wednesday, 1 April 2015 at 17:03:34 UTC, Dennis Ritchie wrote: On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; Don't really see the point. Here's a neat thing that's definitely cheating because although it stores the results in the type system, the arithmetic is done in constant-folding: struct Integer(int a){} template Value(T) { static if (is(T == Integer!a, int a)) enum Value = a; else static assert(false, "Can't get Value for " ~ T.stringof); } alias Inc(T) = Integer!(Value!T + 1); But if you really insist on it being all type-system (until you wan't the answer of course): struct Zero{} template Succ(T) { static if (is(T == Pred!A, A)) alias Succ = A; else struct Succ{} } template Pred(T) { static if (is(T == Succ!A, A)) alias Pred = A; else struct Pred{} } enum isPositive(T) = is(T == Succ!A, A); enum isNegative(T) = is(T == Pred!A, A); enum isZero(T) = is(T == Zero); template Add(A, B) { static if (isZero!B) alias Add = A; else static if (isPositive!B) alias Add = Add!(Succ!A, Pred!B); else alias Add = Add!(Pred!A, Succ!B); } template Value(T, int seed = 0) { static if (isZero!T) enum Value = seed; else static if (isPositive!T) enum Value = Value!(Pred!T, seed+1); else enum Value = Value!(Succ!T, seed-1); } unittest { alias One = Succ!Zero; alias Two = Succ!One; alias MinusThree = Pred!(Pred!(Pred!Zero)); static assert (Value!Zero == 0); static assert (Value!One == 1); static assert (Value!Two == 2); static assert (Value!MinusThree == -3); static assert (Value!(Add!(One, MinusThree)) == -2); static assert (Value!(Add!(One, Two)) == 3); static assert (is(Add!(Add!(One, Two), MinusThree) == Zero)); }
Re: C++ to D
On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; I need a code like this: - #include struct zero; template struct succ { }; template struct increment { using result = succ; }; template struct decrement; template struct decrement> { using result = T; }; template struct addition; template struct addition { using result = A; }; template struct addition> { using result = typename addition, T>::result; }; template struct to_int; template <> struct to_int { static constexpr auto result = 0; }; template struct to_int> { static constexpr auto result = 1 + to_int::result; }; template using inc = typename increment::result; template using dec = typename decrement::result; template using add = typename addition::result; int main() { using one = inc; using two = inc>; using four = inc>>>; using two_plus_one = add; std::cout << to_int::result << std::endl; // 4 std::cout << to_int::result << std::endl; // 3 return 0; }
Re: C++ to D
On Wednesday, 1 April 2015 at 13:59:10 UTC, Dennis Ritchie wrote: You can do this: import std.typetuple; //helper for staticReduce template Alias(alias a) { alias Alias = a; } // staticReduce should really be in std.typetuple, or // the soon to arrive std.meta package. template staticReduce(alias F, TL ...) if (TL.length >= 2) { static if (TL.length == 2) alias staticReduce = Alias!(F!(TL)); else alias staticReduce = staticReduce!(F, F!(TL[0..2]), TL[2..$]); } enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; alias staticSum(TL ...) = staticReduce!(Add, TL); void main() { //using two_plus_one = add; enum two_plus_one = 2 + 1; //std::cout << to_int::result << std::endl; static assert(two_plus_one == 3); //using l = list>>; alias l = TypeTuple!(1, 2, 4); //std::cout << length::result << std::endl; // prints 3 static assert(l.length == 3); //using res = sum::result>::result; enum res = staticSum!(staticMap!(Inc, l)); //std::cout << to_int::result << std::endl; // prints 10 static assert(res == 10); } but really, there's no point: import std.algorithm; //All at compile-time: static assert(1+2 == 3); static assert([1,2,4].length == 3); static assert([1,2,4].map!"a+1".sum == 10); Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess.
C++ to D
Hi, Please help rewrite this code to D: #include // Peano Arithmetic struct zero; template struct succ { }; template struct increment { using result = succ; }; template struct decrement; template struct decrement> { using result = T; }; template struct addition; template struct addition { using result = A; }; template struct addition> { using result = typename addition, T>::result; }; template struct to_int; template <> struct to_int { static constexpr auto result = 0; }; template struct to_int> { static constexpr auto result = 1 + to_int::result; }; template using inc = typename increment::result; template using dec = typename decrement::result; template using add = typename addition::result; class nil; template struct list { using head = T; using tail = Rest; }; template struct length; template <> struct length { static constexpr auto result = 0; }; template struct length> { // pattern-matching static constexpr auto result = 1 + length::result; }; template class Func, class List> struct map; template class Func> struct map { using result = nil; }; template class Func, class Head, class Tail> struct map> { // first-order function using result = list, typename mapTail>::result>; }; template class Func, class Init, class List> struct fold; template class Func, class Init> struct fold { using result = Init; }; template class Func, class Init, class Head, class Tail> struct fold> { using result = FuncTail>::result>; }; template struct sum { using result = typename fold::result; }; int main() { using one = inc; using two = inc>; using four = inc>>>; using two_plus_one = add; std::cout << to_int::result << std::endl; // prints 3 using l = list>>; std::cout << length::result << std::endl; // prints 3 using res = sum::result>::result; std::cout << to_int::result << std::endl; // prints 10 return 0; }
Re: C# to D
Ivan Kazmenko: arr.map !(to !(string)) .join (" ") .writeln; I suggest to not put a space before the bang (!), because it's confusing for me. Also, "arr.map !(to !(string))" is better written "arr.map!text". But even better is to use the range formatting of writefln, avoiding the "map", "to", and "join", something like: writefln("%(%d %)", arr); Bye, bearophile
Re: C# to D
On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote: This is still not very efficient (perhaps the last sorting has to be stable): void main() { import std.stdio, std.algorithm, std.typecons, std.array; [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8] .sort() .groupBy!((a, b) => a == b) .map!array .array .sort!q{a.length > b.length} .joiner .writeln; } On Wednesday, 25 March 2015 at 20:53:43 UTC, Ivan Kazmenko wrote: 5. An efficient version would be to count the integers by using an associative array (or a redBlackTree for guaranteed upper bound) and then use these. It is O (n) time and memory spent in precalculation phase and O (n log n) time for sorting. Looks like there is no way to write that as a chain of transforms, but many optimizations do require manual labor. - import std.algorithm, std.conv, std.range, std.stdio; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; int [int] counts; foreach (e; arr) { counts[e]++; } arr.multiSort !((a, b) => counts[a] > counts[b], (a, b) => a < b); arr.map !(to !(string)) .join (" ") .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } - Thank you very much, Ivan and bearophile! On Wednesday, 25 March 2015 at 20:53:43 UTC, Ivan Kazmenko wrote: Also, some of my previously posted codes do not compile under 2.066 or earlier unless you replace .join (' ') with .join (" ") there. I have long been updated :)
Re: C# to D
On Wednesday, 25 March 2015 at 20:17:57 UTC, bearophile wrote: Ivan Kazmenko: (1) For me, the name of the function is obscure. Something like sortBy would be a lot easier to find than schwartzSort. I've asked to change the name of that function for years. But Andrei Alexandrescu is a adamantly against changing that pet name he has chosen. This is irrational behavour: https://issues.dlang.org/show_bug.cgi?id=4909 There's lot of way to go for Phobos. And the only want to find holes, missed opportunities, sub-optimal performance spots, missing functions and features, and bad APIs and bad names is to actually try to use Phobos, like we are doing in this thread. On the bright side, the list under "Sorting" at the docs http://dlang.org/phobos/std_algorithm.html is short enough for the curious to just look at the entries and find it. The specific page http://dlang.org/phobos/std_algorithm_sorting.html does even contain a link explaining what that is, but I'd propose -"Sorts with the help of the Schwartzian transform." +"Sorts by key predicate with the help of the Schwartzian transform." or some similar wording.
Re: C# to D
On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote: Dennis Ritchie: A more effective solution for C ++: #include #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | copy | action::stable_sort( []( const auto& e1, const auto& e2 ) { return distance( e1 ) < distance( e2 ); } ); std::cout << ( rng ); } This is still not very efficient (perhaps the last sorting has to be stable): void main() { import std.stdio, std.algorithm, std.typecons, std.array; [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8] .sort() .groupBy!((a, b) => a == b) .map!array .array .sort!q{a.length > b.length} .joiner .writeln; } Bye, bearophile 5. An efficient version would be to count the integers by using an associative array (or a redBlackTree for guaranteed upper bound) and then use these. It is O (n) time and memory spent in precalculation phase and O (n log n) time for sorting. Looks like there is no way to write that as a chain of transforms, but many optimizations do require manual labor. - import std.algorithm, std.conv, std.range, std.stdio; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; int [int] counts; foreach (e; arr) { counts[e]++; } arr.multiSort !((a, b) => counts[a] > counts[b], (a, b) => a < b); arr.map !(to !(string)) .join (" ") .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } - Also, some of my previously posted codes do not compile under 2.066 or earlier unless you replace .join (' ') with .join (" ") there.
Re: C# to D
On Wednesday, 25 March 2015 at 20:02:20 UTC, Ivan Kazmenko wrote: Will file an issue soon. Here it is: https://issues.dlang.org/show_bug.cgi?id=14340 And another one, a 2.067 regression: https://issues.dlang.org/show_bug.cgi?id=14341
Re: C# to D
Ivan Kazmenko: (1) For me, the name of the function is obscure. Something like sortBy would be a lot easier to find than schwartzSort. I've asked to change the name of that function for years. But Andrei Alexandrescu is a adamantly against changing that pet name he has chosen. This is irrational behavour: https://issues.dlang.org/show_bug.cgi?id=4909 There's lot of way to go for Phobos. And the only want to find holes, missed opportunities, sub-optimal performance spots, missing functions and features, and bad APIs and bad names is to actually try to use Phobos, like we are doing in this thread. Bye, bearophile
Re: C# to D
Dennis Ritchie: A more effective solution for C ++: #include #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | copy | action::stable_sort( []( const auto& e1, const auto& e2 ) { return distance( e1 ) < distance( e2 ); } ); std::cout << ( rng ); } This is still not very efficient (perhaps the last sorting has to be stable): void main() { import std.stdio, std.algorithm, std.typecons, std.array; [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8] .sort() .groupBy!((a, b) => a == b) .map!array .array .sort!q{a.length > b.length} .joiner .writeln; } Bye, bearophile
Re: C# to D
On Wednesday, 25 March 2015 at 19:32:43 UTC, Dennis Ritchie wrote: On Wednesday, 25 March 2015 at 19:01:43 UTC, bearophile wrote: One solution: Thanks. On Wednesday, 25 March 2015 at 19:03:27 UTC, bearophile wrote: But calling "count" for each item is not efficient (in both C# and D). If your array is largish, then you need a more efficient solution. A more effective solution for C ++: #include #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | copy | action::stable_sort( []( const auto& e1, const auto& e2 ) { return distance( e1 ) < distance( e2 ); } ); std::cout << ( rng ); } Here is my take at it: 1. A more verbose comparison function: - import std.algorithm, std.conv, std.range, std.stdio; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr.sort !((x, y) => arr.count (x) > arr.count (y) || (arr.count (x) == arr.count (y) && x < y)) .map !(to !(string)) .join (" ") .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 0 7 7 } - This surprised me by printing ...0 7 7 instead of ...7 0 0, which is plain wrong. Reproducible in 2.066 and 2.067 on win32. With -debug, it triggers an assertion in Phobos: - core.exception.AssertError@c:\Tools\dmd\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(900): Failed to sort range of type int[] 0x0041708D in _d_assert_msg 0x00416C2F in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() 0x00416B47 in _d_run_main 0x00416848 in main 0x76AD33CA in BaseThreadInitThunk 0x770C9ED2 in RtlInitializeExceptionChain 0x770C9EA5 in RtlInitializeExceptionChain - Will file an issue soon. 2. As above, but use the other sorting algorithm: - import std.algorithm, std.conv, std.range, std.stdio; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr.sort !((x, y) => arr.count (x) > arr.count (y) || (arr.count (x) == arr.count (y) && x < y), SwapStrategy.stable) .map !(to !(string)) .join (" ") .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } - All fine here. 3. Sort by comparing a transform of the data, for some reason disguised by the name schwartzSort: - import std.algorithm, std.conv, std.range, std.stdio, std.typecons; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr.sort () .schwartzSort !(x => tuple (-arr.count (x), x)) .map !(to !(string)) .join (' ') .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } - Similar to bearophile's solution. (1) For me, the name of the function is obscure. Something like sortBy would be a lot easier to find than schwartzSort. (2) It does not offer multiple transforms (sort by this, then by that). This seems doable as a Phobos enhancement. 4. Sort by a few binary predicates in one pass. - import std.algorithm, std.conv, std.range, std.stdio; void main () { auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr.multiSort !((a, b) => arr.count (a) > arr.count (b), (a, b) => a < b); arr.map !(to !(string)) .join (' ') .writeln; // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } - Two concerns here. (1) It returns void instead of a sorted range, so can't be chained as the others. This seems doable as a Phobos enhancement. Or is there a reason not to? (2) The documentation says it is more efficient than the first version in the number of comparisons (verbose lambda with plain sort) [1], but I don't get how it is possible: unless we know than (not pred1(a,b)) and (not !pred1(a,b)), we can not proceed by evaluating pred2(a,b). Ivan Kazmenko.
Re: C# to D
On Wednesday, 25 March 2015 at 20:02:20 UTC, Ivan Kazmenko wrote: (2) The documentation says it is more efficient than the first version in the number of comparisons (verbose lambda with plain sort) [1], but I don't get how it is possible: unless we know than (not pred1(a,b)) and (not !pred1(a,b)), we can not proceed by evaluating pred2(a,b). [1] http://dlang.org/phobos/std_algorithm_sorting.html#.multiSort
Re: C# to D
On Wednesday, 25 March 2015 at 19:01:43 UTC, bearophile wrote: One solution: Thanks. On Wednesday, 25 March 2015 at 19:03:27 UTC, bearophile wrote: But calling "count" for each item is not efficient (in both C# and D). If your array is largish, then you need a more efficient solution. A more effective solution for C ++: #include #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | copy | action::stable_sort( []( const auto& e1, const auto& e2 ) { return distance( e1 ) < distance( e2 ); } ); std::cout << ( rng ); }
Re: C# to D
Ali Çehreli: Do you know the story about groupBy? It's a long messy story. Look for it with another name, like chunkBy or something like that. Bye, bearophile
Re: C# to D
On 03/25/2015 12:01 PM, bearophile wrote: bearophile Do you know the story about groupBy? I see it in the documentation but my git head does not have it: http://dlang.org/phobos/std_algorithm_iteration.html#.groupBy Ali
Re: C# to D
.schwartzSort!(x => tuple(-arr.count!(y => y == x), x)) But calling "count" for each item is not efficient (in both C# and D). If your array is largish, then you need a more efficient solution. Bye, bearophile
Re: C# to D
Dennis Ritchie: int[] arr = { 7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8 }; Console.WriteLine(string.Join(" ", arr.OrderByDescending(x => arr.Count(y => y == x)).ThenBy(x => x))); // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 One solution: void main() { import std.stdio, std.algorithm, std.typecons; auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr .schwartzSort!(x => tuple(-arr.count!(y => y == x), x)) .writeln; } Bye, bearophile
C# to D
Hi, Can you please tell how to rewrite this code to D? using System; using System.Linq; class Sort { static void Main() { int[] arr = { 7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8 }; Console.WriteLine(string.Join(" ", arr.OrderByDescending(x => arr.Count(y => y == x)).ThenBy(x => x))); // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 } } I want to sort the array in descending order of the number of elements in ascending order of elements.
Re: moving from c++ to D is easy?
On Thursday, 12 March 2015 at 21:41:07 UTC, Ali Çehreli wrote: On 03/12/2015 01:19 PM, Namespace wrote: > On Thursday, 12 March 2015 at 18:57:51 UTC, Ali Çehreli wrote: >> On 03/12/2015 06:01 AM, ayush wrote: >> >> > Is D a lot like c++ ? >> >> I came to D from C++. I remember the following being notable differences: >> >> - In D, classes have reference semantics. I quickly realized that this >> is not an issue because so many of my C++ types were >> hand-reference-typified :p by this idiom, almost everywhere: >> >> class C { /* ... */ }; >> typedef boost::shared_ptr CPtr; >> void foo(CPtr c); > > This is a common mistake. In 99 percent of cases you want to use a > std::unique_ptr. Agreed. Here is an excerpt from a comment from one of our header files: "We could not use boost::unique_ptr because the version of the Boost library that we currently use does not include it." > std::shared_ptr is rarely common and often an indication of an > error in design. In general, there is exactly one owner only. Of course. We had definitions like the following as well, where the C objects are stored in: typedef vector MyCs; > But I think you know that already. :) I think so. :) Maybe we should pass weak_ptrs around instead of shared_ptr. You could also pass raw pointers around. Since they have no owner it's fine. Or references. Anyway... That's old code and this is a D newsgroup. Ali Agreed.
Re: moving from c++ to D is easy?
On 03/12/2015 01:19 PM, Namespace wrote: > On Thursday, 12 March 2015 at 18:57:51 UTC, Ali Çehreli wrote: >> On 03/12/2015 06:01 AM, ayush wrote: >> >> > Is D a lot like c++ ? >> >> I came to D from C++. I remember the following being notable differences: >> >> - In D, classes have reference semantics. I quickly realized that this >> is not an issue because so many of my C++ types were >> hand-reference-typified :p by this idiom, almost everywhere: >> >> class C { /* ... */ }; >> typedef boost::shared_ptr CPtr; >> void foo(CPtr c); > > This is a common mistake. In 99 percent of cases you want to use a > std::unique_ptr. Agreed. Here is an excerpt from a comment from one of our header files: "We could not use boost::unique_ptr because the version of the Boost library that we currently use does not include it." > std::shared_ptr is rarely common and often an indication of an > error in design. In general, there is exactly one owner only. Of course. We had definitions like the following as well, where the C objects are stored in: typedef vector MyCs; > But I think you know that already. :) I think so. :) Maybe we should pass weak_ptrs around instead of shared_ptr. Anyway... That's old code and this is a D newsgroup. Ali
Re: moving from c++ to D is easy?
On Thursday, 12 March 2015 at 18:57:51 UTC, Ali Çehreli wrote: On 03/12/2015 06:01 AM, ayush wrote: > Is D a lot like c++ ? I came to D from C++. I remember the following being notable differences: - In D, classes have reference semantics. I quickly realized that this is not an issue because so many of my C++ types were hand-reference-typified :p by this idiom, almost everywhere: class C { /* ... */ }; typedef boost::shared_ptr CPtr; void foo(CPtr c); This is a common mistake. In 99 percent of cases you want to use a std::unique_ptr. std::shared_ptr is rarely common and often an indication of an error in design. In general, there is exactly one owner only. But I think you know that already. :)
Re: moving from c++ to D is easy?
On Thursday, 12 March 2015 at 18:57:51 UTC, Ali Çehreli wrote: If you are a mortal like myself, you may find out years later that you are still at the midway point. Happened to me several times when I was learning C++. :) О, yeah.
Re: moving from c++ to D is easy?
On 03/12/2015 06:01 AM, ayush wrote: > Is D a lot like c++ ? I came to D from C++. I remember the following being notable differences: - In D, classes have reference semantics. I quickly realized that this is not an issue because so many of my C++ types were hand-reference-typified :p by this idiom, almost everywhere: class C { /* ... */ }; typedef boost::shared_ptr CPtr; void foo(CPtr c); - Garbage collector took longer to get used to. There are some issues with the spec or implementation that some objects may never be destructed (or is it finalized?). Other than issues like that, everything in D feels like a fresh air. > I am currently midway through learning c++ If you are a mortal like myself, you may find out years later that you are still at the midway point. Happened to me several times when I was learning C++. :) > and I also want to learn D . So should i focus on one or learn > both together? Economically, C++ may make more sense. But if you are learning just for yourself, perhaps for fun, then I recommend D. > Will I find learning D easy if I already know c++ ? I think so. Ali
Re: moving from c++ to D is easy?
On Thursday, 12 March 2015 at 14:47:22 UTC, ketmar wrote: there are alot of books on C++ 'cause C++ is insanely complicated and inconsistend. D design is *MUCH* better, so D doesn't need so many books teaching arcane art of programming. Well, in principle, can be started with a D, but personally, I started actually with ANSI C.
Re: moving from c++ to D is easy?
On Thu, 12 Mar 2015 13:56:28 +, Dennis Ritchie wrote: > On Thursday, 12 March 2015 at 13:44:50 UTC, Daniel Kozák wrote: >> D is much easier to learn so I will start with it. And then you can try >> learn C++ if you still want and need it. > > Yes, but in D for beginners little literature, so I would recommend > starting with C++. there are alot of books on C++ 'cause C++ is insanely complicated and inconsistend. D design is *MUCH* better, so D doesn't need so many books teaching arcane art of programming. signature.asc Description: PGP signature
Re: moving from c++ to D is easy?
On Thursday, 12 March 2015 at 13:56:29 UTC, Dennis Ritchie wrote: On Thursday, 12 March 2015 at 13:44:50 UTC, Daniel Kozák wrote: D is much easier to learn so I will start with it. And then you can try learn C++ if you still want and need it. Yes, but in D for beginners little literature, so I would recommend starting with C++. There is no need for dozens of books. I would even go as far as to say that the existing ones are more than enough. http://wiki.dlang.org/Books
Re: moving from c++ to D is easy?
On Thu, 12 Mar 2015 13:35:18 + ayush via Digitalmars-d-learn wrote: > On Thursday, 12 March 2015 at 13:13:40 UTC, Dennis Ritchie wrote: > > On Thursday, 12 March 2015 at 13:01:31 UTC, ayush wrote: > >> Is D a lot like c++? > > > > Enough. > > > >> So should i focus on one or learn both together? > > > > You can study both together, although it is better to focus on > > one. > > > >> Will I find learning D easy if I already know c++? > > > > Yes. > > So on which language should I focus(learn) first D is much easier to learn so I will start with it. And then you can try learn C++ if you still want and need it.