Explicit casting of enum -- intentional restriction?
I just tried to compile an old project and the following failed: --- enum Paths : string { bitmapDir = "content/image", fontDir = "content/font", soundDir = "content/sound", ... if (Paths.preferences.exists) ... --- It turns out members of Paths are no longer implicitly converted to string, and I needed to use if ((cast(string)Paths.preferences).exists) Is this an intentional limitation or a regression? I didn't see it in the last few changelogs but I'll admit I didn't check them rigorously.
Re: Privacy violation depending on who passes a compile-time argument?
On Sunday, 14 August 2016 at 17:23:06 UTC, Basile B. wrote: It is private: https://dpaste.dzfl.pl/83fcca84dde3, so the code you've posted in the first message could be a bug. Ah, you're correct. I'm not able to use either of them in runtime code. The deprecation message also since this case has nothing to do with the transition period due to fix 314 (because your import is not selective). Makes sense. I still wonder whether using something like getUDAs on a symbol exposed like this is valid, but I guess that hasn't been decided yet (https://github.com/dlang/phobos/pull/4724#issuecomment-239424693). Thanks for the insights!
Re: Privacy violation depending on who passes a compile-time argument?
On Sunday, 14 August 2016 at 15:47:16 UTC, Basile B. wrote: No it's the opposite, only mixins gets the scope of the instantiation's location. Right, if it were a mixin, it would get the scope of the instantiation (the main module) and `i` would be inacessible. Since it isn't a mixin, I would expect the scope to be in module s, where it _can_ access `i`. Try to compile this: struct S { private int i; int j; alias getMember(string name) = Identity!(__traits(getMember, S, name)); alias getMember_i = getMember!"i"; unittest { pragma(msg, __traits(getProtection, S.getMember!"i")); // private pragma(msg, __traits(getProtection, S.getMember!"j")); // public } } You'll see that this is even not a matter of module. Actually your "getMember" is not a member function, it's an alias to the source, i.e the same symbol with the same protection. Ok, so S.getMember!"i" is really the same as S.i, so I get why it's private. But getMember_i is just an alias to that, so shouldn't it also be private? It makes sense if you accept the following: struct S { private int _i; alias i = i; } Which I used to accept without thinking about it, but now I'm wondering why that works.
Privacy violation depending on who passes a compile-time argument?
Can someone help me understand why the first line is fine, but the second triggers a deprecation warning for access to a private variable? --- import std.traits; import s; pragma(msg, hasUDA!(S.getMember_i, attr)); // fine pragma(msg, hasUDA!(S.getMember!"i", attr)); // deprecated /++ in module 's' import std.traits; struct attr { } struct S { @attr private int i; alias getMember(string name) = Identity!(__traits(getMember, S, name)); alias getMember_i = getMember!"i"; } ++/ --- getMember is not a mixin template, so it seems like __traits(getMember, S, "i") should be resolved within the 's' module in both cases. Why is passing the string "i" from another module a violation even when getMember_i is doing the same thing internally?
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Saturday, 23 April 2016 at 00:55:07 UTC, rcorre wrote: On Friday, 22 April 2016 at 10:25:34 UTC, Chris wrote: On Friday, 22 April 2016 at 09:49:02 UTC, Rene Zwanenburg wrote: On Thursday, 21 April 2016 at 16:29:14 UTC, rcorre wrote: - What happens when you compile a binary without phobos and druntime, and with a custom entry point? I've never done that myself and don't remember how to do that off the top of my head, but the info should be somewhere on dlang.org. I'll look into it. Declaring a C-like main and the -defaultlib switch do the trick: cmain.d extern(C) void main() nothrow {} --- dmd cmain.d -defaultlib="" If even that fails to link I honestly wouldn't know where to look next.. This seems odd. Have you tried to reinstall dmd? You could use dvm [1] to install different versions of dmd and see what happens. It seems as if there's something wrong with your installation. I have Ubuntu at work and ArchLinux at home. It works fine, there shouldn't be any problem with compiling your program. [1] https://github.com/jacob-carlborg/dvm No luck with cmain.d. Its definitely an environmental problem -- I have an almost identical Archlinux desktop that is fine. I thought I'd try my dev DMD, but realized I can't even compile it now that DMD is written in D >.< Got it! I installed hardening-wrapper to build python34. gcc was pointing to /usr/bin/hardening-wrapper/gcc. I had to look up what hardening-wrapper even is -- and I found my way straight to the archwiki article describing exactly my problem: https://wiki.archlinux.org/index.php/D_(programming_language)#hardening-wrapper Thank you to everyone who tried to help!
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Friday, 22 April 2016 at 10:25:34 UTC, Chris wrote: On Friday, 22 April 2016 at 09:49:02 UTC, Rene Zwanenburg wrote: On Thursday, 21 April 2016 at 16:29:14 UTC, rcorre wrote: - What happens when you compile a binary without phobos and druntime, and with a custom entry point? I've never done that myself and don't remember how to do that off the top of my head, but the info should be somewhere on dlang.org. I'll look into it. Declaring a C-like main and the -defaultlib switch do the trick: cmain.d extern(C) void main() nothrow {} --- dmd cmain.d -defaultlib="" If even that fails to link I honestly wouldn't know where to look next.. This seems odd. Have you tried to reinstall dmd? You could use dvm [1] to install different versions of dmd and see what happens. It seems as if there's something wrong with your installation. I have Ubuntu at work and ArchLinux at home. It works fine, there shouldn't be any problem with compiling your program. [1] https://github.com/jacob-carlborg/dvm No luck with cmain.d. Its definitely an environmental problem -- I have an almost identical Archlinux desktop that is fine. I thought I'd try my dev DMD, but realized I can't even compile it now that DMD is written in D >.<
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Thursday, 21 April 2016 at 12:57:36 UTC, Rene Zwanenburg wrote: On Thursday, 21 April 2016 at 11:54:27 UTC, rcorre wrote: Thanks for the tip. Here's the linking code it shows: cc d.o -o d -m64 -L/usr/lib -L/usr/lib32 -Xlinker --export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC I tried `cc d.o -o d -m64 -fPIC and still get the error. Right, the -fPIC should be used while compiling the source code, but that's a gcc option. I think DMD is supposed to always generates position independent code. Here are a few things you can try to narrow the problem down. I'm not too familiar with this stuff though, so I'm just shooting in the dark here and not all of it may make sense ^^ - What happens when you mark main() as nothrow? That personality symbol has to do with exception handling. Nothing. - Is it possible the linker is picking up 32 bit libraries? That -L/usr/lib32 switch is a bit suspicious. Sure is. I tried manually linking without that but get the same error. As a matter of fact, I tried removing all the linker flags and still get that error (just `cc d.o -o d`). - What happens when you compile for 32 bit? /usr/bin/ld: skipping incompatible /usr/lib/libphobos2.a when searching for -lphobos2 /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../libphobos2.a when searching for -lphobos2 /usr/bin/ld: skipping incompatible /usr/lib/libphobos2.a when searching for -lphobos2 /usr/bin/ld: cannot find -lphobos2 /usr/bin/ld: skipping incompatible /usr/lib/libpthread.so when searching for -lpthread /usr/bin/ld: skipping incompatible /usr/lib/libpthread.a when searching for -lpthread collect2: error: ld returned 1 exit status - What happens when you compile a binary without phobos and druntime, and with a custom entry point? I've never done that myself and don't remember how to do that off the top of my head, but the info should be somewhere on dlang.org. I'll look into it. - What happens when you compile some D code as a static lib, and link it with a main written in C? Same error. Oh, and I take it you've already tried to simply reinstall DMD? If you uninstall DMD, look if there are still sc.ini's and libphobos.a's floating around. I did. /etc/dmd.conf looks normal, aside from the inclusion of 32-bit libs: [Environment] DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib -L-L/usr/lib32 -L--export-dynamic But that's how it gets set up after a fresh install.
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Thursday, 21 April 2016 at 09:55:30 UTC, Rene Zwanenburg wrote: On Thursday, 21 April 2016 at 01:20:27 UTC, rcorre wrote: s/compile/link I _can_ compile a D library, but as soon as I try to link anything compiled with DMD it falls over. What is dmd's verbose output? (add -v switch) Some of the things it outputs are the location of the config file it uses, you can inspect that file to see if it has been borked somehow. Near the bottom you can find the used link command, that could also reveal the problem. Thanks for the tip. Here's the linking code it shows: cc d.o -o d -m64 -L/usr/lib -L/usr/lib32 -Xlinker --export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC I tried `cc d.o -o d -m64 -fPIC and still get the error.
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Thursday, 21 April 2016 at 01:18:14 UTC, rcorre wrote: On Wednesday, 20 April 2016 at 19:24:49 UTC, Chris wrote: On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote: === $ dmd /tmp/d.d /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC d.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 === I'm seeing the above trying to compile a simple d program. /tmp/d.d: === void main() { } === Any idea what this might be? I'm on dmd 2.071.0 on Archlinux. I had a similar error. Could you show us the code? Do you refer/link to a dynamic library? The code is shown above. Literally `void main() { }`. I can't compile anything. s/compile/link I _can_ compile a D library, but as soon as I try to link anything compiled with DMD it falls over.
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Wednesday, 20 April 2016 at 19:24:49 UTC, Chris wrote: On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote: === $ dmd /tmp/d.d /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC d.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 === I'm seeing the above trying to compile a simple d program. /tmp/d.d: === void main() { } === Any idea what this might be? I'm on dmd 2.071.0 on Archlinux. I had a similar error. Could you show us the code? Do you refer/link to a dynamic library? The code is shown above. Literally `void main() { }`. I can't compile anything.
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Wednesday, 20 April 2016 at 12:48:46 UTC, rcorre wrote: On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote: === $ dmd /tmp/d.d /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC d.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 === I'm seeing the above trying to compile a simple d program. /tmp/d.d: === void main() { } === Any idea what this might be? I'm on dmd 2.071.0 on Archlinux. My desktop is fine (Archlinux, same DMD version, both recently updated). I'm guessing this is some weird misconfiguration on my laptop that happened fairly recently. Compiling with -fPIC doesn't help.
Re: Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
On Wednesday, 20 April 2016 at 12:04:45 UTC, rcorre wrote: === $ dmd /tmp/d.d /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC d.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 === I'm seeing the above trying to compile a simple d program. /tmp/d.d: === void main() { } === Any idea what this might be? I'm on dmd 2.071.0 on Archlinux. My desktop is fine (Archlinux, same DMD version, both recently updated). I'm guessing this is some weird misconfiguration on my laptop that happened fairly recently.
Linker error for d.o: relocation R_X86_64_32 against `__dmd_personality_v0'
=== $ dmd /tmp/d.d /usr/bin/ld: d.o: relocation R_X86_64_32 against `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC d.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status --- errorlevel 1 === I'm seeing the above trying to compile a simple d program. /tmp/d.d: === void main() { } === Any idea what this might be? I'm on dmd 2.071.0 on Archlinux.
@nogc inconsistent for array comparison depending on mutability of elements
@nogc unittest { int[2] a = [1, 2]; assert(a == [1, 2]); // OK immutable(int)[2] b = [1, 2]; assert(b == [1, 2]); // fail: array literal may cause allocation } Is there any logic behind allowing the comparison with `a` but not `b`, or is this a compiler bug?
Re: How to sort a range
On Wednesday, 9 March 2016 at 16:53:08 UTC, Xinok wrote: On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote: Still curious as to why it fails; maybe the range is getting copied at some point? I guess I need to step through it. That's my suspicion as well. It seems that OnlyResult is pass-by-value so every time it gets passed to another function, it creates a copy of all the elements. A simple solution is to provide a wrapper type which refers to the elements in the original container. However, I'm going to argue that the sort function is fine but the modifications you made to OnlyResult are incorrect. I tried running your example of only(...).sort but got a compilation error. Similarly, trying to sort a static array also gives a compilation error. However, if I slice the static array before passing it to sort (thus passing by reference), then it works just fine. Got it. sort calls to quicksort (for unstable, at least) which uses swapAt. swapAt takes the range by value, so it just swaps the values in its local copy. The original OnlyResult is untouched. I guess a static array slice maintains a pointer to the underlying array (which is why returning one from a function errors with 'escaping reference to local variable'). Meanwhile, I've realized my code probably doensn't need to remove duplicates anyways, so its a moot point, but still an interesting discovery :)
Re: How to sort a range
On Wednesday, 9 March 2016 at 14:28:11 UTC, cym13 wrote: Note that an input range isn't even remotely a container, it's a way to iterate on a container. As you don't have all elements at hand you can't sort them, that's why you have to use array here. Oh, I think it just clicked. I was thinking 'sort takes a range, so it must be used for sorting ranges', but I should have thought 'sort takes a range so it can sort a container via a range over that container'.
Re: How to sort a range
On Wednesday, 9 March 2016 at 14:28:11 UTC, cym13 wrote: On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote: On Wednesday, 9 March 2016 at 09:15:01 UTC, Edwin van Leeuwen wrote: I'm not sure why your fix didn't work, but generally I work around this by converting the OnlyResult into an array: import std.array : array; assert(only(3,1,2).array.sort.equal(only(1,2,3))); I'd like to avoid allocating here. Note that an input range isn't even remotely a container, it's a way to iterate on a container. As you don't have all elements at hand you can't sort them, that's why you have to use array here. In the general case, yes. However only is a range wrapper around a static array, and does have all elements at hand. Maybe I should just be using a static array... Still curious as to why it fails; maybe the range is getting copied at some point? I guess I need to step through it. I did try different SwapStrategies with no luck.
Re: How to sort a range
On Wednesday, 9 March 2016 at 12:31:18 UTC, Edwin van Leeuwen wrote: On Wednesday, 9 March 2016 at 12:21:55 UTC, rcorre wrote: If you are looking for a lazy uniq that works on non sorted ranges, I implemented one not to long ago: http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d That sounds like the kind of thing I was looking for. I'll take a look, thanks! Well that one does allocate, because it keeps track of which values have already been seen. Yup, just noticed that >.<
Re: How to sort a range
On Wednesday, 9 March 2016 at 09:15:01 UTC, Edwin van Leeuwen wrote: I'm not sure why your fix didn't work, but generally I work around this by converting the OnlyResult into an array: import std.array : array; assert(only(3,1,2).array.sort.equal(only(1,2,3))); I'd like to avoid allocating here. If you are looking for a lazy uniq that works on non sorted ranges, I implemented one not to long ago: http://github.com/BlackEdder/ggplotd/blob/master/source/ggplotd/range.d That sounds like the kind of thing I was looking for. I'll take a look, thanks!
How to sort a range
I was in a situation where I wanted to remove duplicates from an OnlyResult. To do this with uniq, I needed to sort it. OnlyResult doesn't satisfy the template constraints of sort, but this seems easy enough to fix. I made front, back, and opIndex return by ref. With this, the following compiles: assert(only(3,1,2).sort.equal(only(1,2,3))); However, it fails with: core.exception.AssertError@std/algorithm/sorting.d(1052): Failed to sort range of type OnlyResult!(int, 3LU) So, if you have a range for which sort compiles, what does it take to make sorting actually work? For reference, my two attempts were: https://github.com/rcorre/phobos/commit/d89b3cfab7a0938e178a506b4ceb8faae6ecbfe2 https://github.com/rcorre/phobos/commit/512d9b8db6f311db6a9b6ccb077a691cec66ce70
Re: Is this nogc? dmd and gdc disagree
On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote: On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote: I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is @nogc. Here's a semi-reduced test-case: Here's an @nogc version of `byKeyValue()`: @nogc auto byKeyValue() const { static immutable keys = [EnumMembers!K]; return zip(keys[], _store[]); } Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V. I'm on the DMD 2.070 release, so maybe its fixed in master. Either way, thanks for the suggestion! Somehow I didn't realize what I was doing was an over-complicated zip :)
Re: Is this nogc? dmd and gdc disagree
On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote: On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote: Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V. I'm on the DMD 2.070 release, so maybe its fixed in master. Either way, thanks for the suggestion! Somehow I didn't realize what I was doing was an over-complicated zip :) Though it appears (in 2.070 at least) that zip's range primitives aren't nogc: --- import std.range; immutable a = [1,2,3]; immutable b = [1,2,3]; @nogc void main() { foreach(x, y ; a[].zip(b[])) { } } --- other.d(7): Error: @nogc function 'D main' cannot call non-@nogc function 'std.range.Zip!(immutable(int)[], immutable(int)[]).Zip.empty' other.d(7): Error: @nogc function 'D main' cannot call non-@nogc function 'std.range.Zip!(immutable(int)[], immutable(int)[]).Zip.popFront' ---
Is this nogc? dmd and gdc disagree
I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is @nogc. Here's a semi-reduced test-case: --- import std.range; import std.traits: EnumMembers; import std.typecons : tuple, staticIota; import std.algorithm : map; struct Enumap(K, V) if(EnumMembers!K == staticIota!(0, EnumMembers!K.length)) { enum length = EnumMembers!K.length; private V[length] _store; ref auto opIndex(K key) inout { return _store[key]; } @nogc auto byKeyValue() const { return only(EnumMembers!K).map!(key => tuple(key, this[key])); } } @nogc void main() { import std.typecons : tuple; import std.algorithm : map; enum E { a, b, c, d }; immutable elements = Enumap!(E, int)([1,2,3,4]); auto pairs = elements.byKeyValue.map!(pair => tuple(pair[0], pair[1] + 1)); } --- GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it @nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure.
UFCS assignment syntax for templated function
The following works: --- struct Foo { float x; } auto val(Foo foo) { return foo.x; } auto val(ref Foo foo, float val) { return foo.x = val; } unittest { auto f = Foo(); f.val = 5; assert(f.val == 5); } --- But the following fails to compile with 'val(b) is not an lvalue'. --- struct Bar(T) { T x; } auto val(T)(Bar!T bar) { return bar.x; } auto val(T)(ref Bar!T bar, float val) { return bar.x = val; } unittest { auto b = Bar!int(); b.val = 5; assert(b.val == 5); } --- Is there a way to invoke a templated function using the UFCS assignment syntax? That is, can `obj.fun = val` be translated to `fun(obj, val)` when fun is a templated function?
Re: UFCS assignment syntax for templated function
On Friday, 1 January 2016 at 11:59:39 UTC, rcorre wrote: auto val(T)(ref Bar!T bar, float val) { return bar.x = val; } Uh, never mind. That `float` should have been `T`. Seems to work now.
Deducing a template argument from an aliased parameter
In the following example, it seems like the signatures of fun1 and fun2 should be equivalent. Both accept a Vector!(T, 2), the only difference is that fun2 goes through an alias. struct Vector(T, int N) { } alias Vector2(T) = Vector!(T, 2); void fun1(T)(Vector!(T, 2) vec) { } void fun2(T)(Vector2!T vec) { } unittest { fun1(Vector!(float, 2).init); fun2(Vector!(float, 2).init); } Why can fun1 deduce `T`, but fun2 can't? Failure: "template d.fun2 cannot deduce function from argument types !()(Vector!(float, 2))"?
Re: Massive linker error after upgrade to DMD 2.068.1-1
On Sunday, 13 September 2015 at 00:21:22 UTC, Nicholas Wilson wrote: there was talk of adding symbol name compression some time ago ( to reduce lib size ( and maybe make ddemangle not fail on long syms?). This might be the cause of your problems i.e. the new compiler emitting references to compressed names but built with the old compiler using the not compressed ones. Try rebuilding everything and see if that fixes it. I tried deleting ~/.dub and the .dub folder in every referenced project and rebuilding, but unfortunately no luck.
Massive linker error after upgrade to DMD 2.068.1-1
After upgrading from DMD 2.068.0-1 to DMD 2.068.1-1, my project began producing a large linker error (when built using dub). I was able to trace it down to a single line: target = target.adjacent(Diagonals.yes).randomSample(1).front; target is of type RowCol (https://github.com/rcorre/dtiled/blob/master/src/dtiled/coords.d#L36), which has an `adjacent` property that leverages chain, only, and take. When I comment this line out (or build on a system with DMD 2.068.0-1), I can build fine. When uncommented, I see (post ddemangle): http://dpaste.com/1PJB35V I've tried to break this down into a reduced example to prove that I can call randomSample on the range returned by RowCol.adjacent (http://dpaste.com/13G9WDE). This runs fine, so it seems to be a deeper issue with my build environment (full project at https://github.com/rcorre/damage_control if you're curious). I don't want to turn this into "please debug my project for me", but do people have general hints on how to track down issues like this? Thanks! Side note: I see src/transition.d in the output, but I don't see how it is relevant to the error (it isn't even imported by the file causing the error).
Re: Are Lua tables possible to do with D?
On Thursday, 16 July 2015 at 07:20:16 UTC, Fusxfaranto wrote: An associative array of Variant[string] ought to do the job well enough. http://dlang.org/phobos/std_variant.html For extra fun, you can implement the '.' style syntax pretty easily: --- import std.variant; struct LuaTable { Variant[string] _table; alias _table this; auto opDispatch(string s)() { return _table[s]; } void opDispatch(string s, T)(T val) { _table[s] = Variant(val); } } unittest { LuaTable table; table.foo = 5; table.bar = s; assert(table.foo == 5); assert(table.bar == s); } ---
Implicit conversion in constructor
Is there any reason why implicit conversion from Foo to Thing is permitted in a regular method but not in a constructor? Trying to figure out whether this is a bug or some sort of constructor-specific safety precaution. struct Thing { Foo foo; alias foo this; } class Foo { } class Bar { Thing thing; void fine() { thing = new Foo(); // ok } this() { thing = new Foo(); // nope! } }
Re: Implicit conversion in constructor
On Saturday, 18 July 2015 at 02:28:09 UTC, tcak wrote: I even am not sure how in the world it allows implicit conversion from class to struct in fine at all. The 'alias this' in the struct permits implicit conversion. I _think_ that is intended behavior, though I admit I'm not actually sure now. I've been taking it for granted for awhile...
Re: @property on free function for UFCS?
On Sunday, 14 June 2015 at 12:36:43 UTC, Adam D. Ruppe wrote: You can use @property there, but you don't have to because you can call it with optional parenthesis anyway. Thanks. Is there a good reference for the current state of @property? I know it was hotly debated for awhile (and maybe still is?). I'm just never sure when I should be using it (if at all).
@property on free function for UFCS?
Suppose I have a function defined like so: void foo(int i) { } intended to be called like: 5.foo Should it be labeled with @property? Or is @property only for true member functions?
Re: Returning an empty range of a given type
So I thought this might work: struct MaybeEmpty(R) if (isInputRange!R) { private bool _isEmpty; private R_input; alias _input this; this(bool isEmpty, R input) { _input = input; _isEmpty = isEmpty; } @property bool empty() { return _isEmpty || _input.empty; } } auto maybeEmpty(R)(bool empty, R input = R.init) if (isInputRange!R) { return MaybeEmpty!R(empty, input); } It's kind of ugly, but it can be used like: auto a = maybeEmpty!MyRange(true); auto b = maybeEmpty!MyRange(false, actualRange); static assert(is(typeof(a) == typeof(b))); However, it fails the input range test: static assert(isInputRange!MyRange); //pass static assert(isInputRange!(typeof(a))); // fail But it seems to be something weird with cross-module template instantiation. If I replace `import std.range` with a copy-paste of `isInputRange`, the above passes. Either that or I'm doing something stupid because I'vebeen staring at this too long. I'm wondering if the isInputRange thing is a bug, so here's a gist if anyone wants to play with it: https://gist.github.com/rcorre/7a62395c53baf3c0bfbc
Re: Returning an empty range of a given type
On Thursday, 14 May 2015 at 06:41:45 UTC, Ali Çehreli wrote: I am lucky because although the returned type is opaque to me, I know that it is constructed by a void lambda. Yeah, in this case I control the container so I may just add an emptySlice property, but it does seem like it might be a common need (to return an empty range of a given type without having that range constructed beforehand).
Re: Returning an empty range of a given type
On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote: How about a more flexible solution? http://dpaste.dzfl.pl/2f99cc270651 Neat, thanks! On Thursday, 14 May 2015 at 18:44:58 UTC, Steven Schveighoffer wrote: It depends on the guts of MyContainer.Range. I'm assuming MyContainer.Range has SOME sort of references (i.e. pointers) to the data in the container, so why not just have: bool empty() { return someRef == null || yourCurrentTest; } -Steve In this case, I want to return an empty range when the container instance itself is null. I could have a static method MyContainer.emptySlice, but I feel like I've seen this general situation crop up a lot with small variations.
Re: Returning an empty range of a given type
On Friday, 15 May 2015 at 03:22:43 UTC, rcorre wrote: On Thursday, 14 May 2015 at 14:57:26 UTC, Idan Arye wrote: How about a more flexible solution? http://dpaste.dzfl.pl/2f99cc270651 Neat, thanks! The range I don't pick may be an expression that would fail, so I tweaked it to: SelectRange!T selectRange(T...)(size_t index, lazy T ranges) Other than that, it seems to be just what I needed. Thanks again!
Returning an empty range of a given type
I've run into this situation a lot: I have a function that returns a range (in this case, a slice of a custom container). In some cases, the function needs to return an empty range. It sounded like takeNone was what I wanted: @nogc auto fun() { return (some_condition) ? getRange() : getRange.takeNone; } but there is a return type ambiguity. I finally ended up doing this: @nogc auto fun() { return (some_condition) ? getRange().take(size_t.max) : getRange.takeNone; } I'm not sure if this is clever or insane. It works, but just looks a bit crazy to me. Does anyone else run into this situation? Have any cool ways to solve it? MyRange is an inputRange, and I can't use a wrapper (InputRange) and keep the @nogc.
Re: Returning an empty range of a given type
Actually, this doesn't even seem to work with a custom range: import std.range; import std.stdio; import std.algorithm; struct MyContainer { @nogc auto opSlice() { struct Range { @property bool empty() { return true; } @property int front() { return 9; } void popFront() { } } return Range(); } } /// Return a slice of aa[key], or an empty slice if not found @nogc auto maybeGetRange(MyContainer[string] aa, string key) { alias RangeType = typeof(MyContainer.init[]); auto val = key in aa; return (val is null) ? takeNone!RangeType : (*val)[].take(size_t.max); } Is there any way to create an empty MyContainer.Range() without creating a new container?
Private alias escaping -- is this a bug?
I ran into this infuriatingly confusing situation just now: static assert(is(typeof(Parent.init.new Child) == Parent.Child)); // fine alias P = Parent; alias T = Parent.Child; static assert(is(typeof(P.init.new T) == T)); // nope! Wat??? After much confusion, I finally discovered this in my class: class Parent { class Child { } mixin MyMixin; } mixin Template MyMixin() { private alias T = ...; // the culprit! } Should the private alias be able to escape? Is this a bug or expected behavior? Also, is there a nice way to create template-level aliases in mixin templates that don't leak into the class? MyMixin generates multiple functions that all use T.
Re: std.json questions
On Saturday, 25 April 2015 at 09:56:25 UTC, tired_eyes wrote: A brief look at code.dlang.org gives us 7 (!) additional JSON libraries. Keeping in mind that D community isn't so huge, I think I'm not the only person struggling with std.json. Are there any plans on upgrading it? See http://wiki.dlang.org/Review_Queue. std.data.json is the proposed replacement for the current phobos json implementation. There is also supposedly std.serialization in the works.
Re: std.typecons.Flag -- public import for API users?
On Tuesday, 24 March 2015 at 16:41:28 UTC, Rene Zwanenburg wrote: Should not be necessary. privately import Flag and make a public alias: module a; import std.typecons : Flag; alias SomeFlag = Flag!SomeFlag; SomeFlag.Yes and SomeFlag.No should be usable in other modules without additional imports. Nice idea Rene, thanks!
std.typecons.Flag -- public import for API users?
If I am developing a library and some of my functinos take a std.typecons.Flag as an argument, should I 'public import std.typecons: Flag, Yes, No'? It seems like it would be a pain for users of the library to have to import this separately whenever they use my library, but I'm not sure what the stance is on having your modules `public import` standard-library modules. In general, is it considered bad form to 'public import' modules from phobos?