Decouple package modules with package interfaces
I just came across a problem where I either has a cyclic dependency, pass around three delegates, implement an interface or somehow hack some communication between two modules. A simple way would be to add an interface, but interfaces require implementations to be public. The methods should be package protected though. It would have been nice if the implementation for an interface wouldn't have to be more visible than the interface itself. If an interface is "package", it cannot escape that package, so why would the implementation required to be public? The same goes for "private". Should I add an enhancement request for this, or does it have problems I'm not seeing? --- module b; package interface I { void doit(); } void f(I i) { i.doit(); } --- module a; import b; class C : I { // Error: class a.C interface function 'void doit()' is not implemented package void doit() {} } void main() { auto c = new C; f(c); }
Re: Trouble with destroy
On Monday, September 23, 2013 22:45:33 H. S. Teoh wrote: > On Tue, Sep 24, 2013 at 05:18:38AM +0200, Meta wrote: > > On Monday, 23 September 2013 at 19:11:53 UTC, Namespace wrote: > > >As always. As soon as you wrote it, you've got the solution. > > > > > >destroy!A(a); > > > > > > > This still seems like it should be worth reporting. I can't > > remember... Is partial ordering done between multiple matching > > template functions like it is with regular functions? If so, there > > should be no ambiguity in choosing the second one. > > IIRC, D templates don't have best-match like C++ does; it was an > explicit design choice that multiple matching templates is an error. Correct. For IFTI to work, the arguments need to pass exactly one of the overloads' template constraints. If they pass the template constraints for multiple overloads, then it's an ambiguity error. There is no attempt to figure out which matches "better." - Jonathan M Davis
Re: Trouble with destroy
On Tue, Sep 24, 2013 at 05:18:38AM +0200, Meta wrote: > On Monday, 23 September 2013 at 19:11:53 UTC, Namespace wrote: > >As always. As soon as you wrote it, you've got the solution. > > > >destroy!A(a); > > > > This still seems like it should be worth reporting. I can't > remember... Is partial ordering done between multiple matching > template functions like it is with regular functions? If so, there > should be no ambiguity in choosing the second one. IIRC, D templates don't have best-match like C++ does; it was an explicit design choice that multiple matching templates is an error. T -- Lawyer: (n.) An innocence-vending machine, the effectiveness of which depends on how much money is inserted.
Re: Trouble with destroy
On Tuesday, September 24, 2013 05:18:38 Meta wrote: > On Monday, 23 September 2013 at 19:11:53 UTC, Namespace wrote: > > As always. As soon as you wrote it, you've got the solution. > > > > destroy!A(a); > > > > This still seems like it should be worth reporting. I can't > remember... Is partial ordering done between multiple matching > template functions like it is with regular functions? If so, > there should be no ambiguity in choosing the second one. The problem is that the type matches two different templated functions, and as it stands, there is no way for the compiler to disambiguate. They're both equally valid. The only way that they could be disambiguated would be if the compiler preferred the actual type over the aliased one (which arguably, it should, but it clearly it doesn't at this point, and I don't know what all of the ramifications are if it did). But I don't think that there's anything wrong with destroy in this case. If there's a problem, it's with how alias this is handled when determining which overloaded template to use. - Jonathan M Davis
Re: Trouble with destroy
On Monday, 23 September 2013 at 19:11:53 UTC, Namespace wrote: As always. As soon as you wrote it, you've got the solution. destroy!A(a); This still seems like it should be worth reporting. I can't remember... Is partial ordering done between multiple matching template functions like it is with regular functions? If so, there should be no ambiguity in choosing the second one.
Re: Unable to use tradional tools to find memory leaks
Might be related to or even the same issue reported here: http://forum.dlang.org/thread/bug-1005...@http.d.puremagic.com/issues/ This is a Valgrind issue though and not DMD related.
Re: const and immutable members
On Monday, September 23, 2013 13:49:59 Daniel Davidson wrote: > > But if your concern is client code messing with your member > > variable, then > > don't give them access to it in the first place. > > Not quite as much messing with the member as messing with what it > points to. In the setup - rich data, read from the wire or disk, > lots of nesting of lists, associative arrays, json like data, > etc, the POD data is being read and stored into nested structs > all prior to coming to my class. I want to ensure that the memory > that I know both of us (S and the client code who built data to > pass to S and other users) is not being modified. Then your member variable is going to be a reference type, and you can make it tail-const - except in the case of AAs, but if you simply return a const AA from a getter, then client code can't change it. In order to actually have tail-const AAs, we'd need something like Rebindable but for AAs (or maybe Rebindable could be made to work with AAs). But in general, if you want to share data and want to avoid copying, making the data is a good move, but you do it by making the data immutable and not what refers to it (i.e. tail- immutable). Then the data itself can be safely shared, but you don't run into all of the problems that come when you make a member variable in a struct fully const or immutable. - Jonathan M Davis
Re: Unable to use tradional tools to find memory leaks
On Monday, 23 September 2013 at 21:35:21 UTC, Flamaros wrote: On Monday, 23 September 2013 at 20:06:20 UTC, Flamaros wrote: On Saturday, 21 September 2013 at 14:30:19 UTC, Flamaros wrote: I tried to used Valgrind (Linux) and Dr Memory (Windows) without success to find a big leak I have in my application. But both tools can't launch my application without make it crash. Do I need do something particular, to have a chance to see one of those tool working fine with my application? It can be really hard to find leaks manually, maybe some option of the gc can help me? Here is my Valkyrie output : ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#253: static bool VkCfg::checkConfigDir(const QString&): ===valkyrie:3014=== No existing config dir '/tmp/valkyrie_flamaros/' => creating. ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#702: void VkCfgProj::openProject(const QString&): ===valkyrie:3014=== Can't open project: File doesn't exist, or is not readable: '/home/flamaros/development/personnal/dquick/data/dquick.cfg' ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#636: void VkCfgProj::replaceConfig(QSettings*): ===valkyrie:3014=== Replacing current config with: /home/flamaros/development/personnal/dquick/dquick.cfg ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) Valkyrie::runTool( 0, 0) Current path: /home/flamaros/development/personnal/dquick/. [OpenGLContext] OpenGL Version: 2.1 Mesa 9.1.4 rootItem main vex amd64->IR: unhandled instruction bytes: 0x48 0xDF 0x1C 0x24 0x48 0xD9 0x6C 0x24 vex amd64->IR: REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=0 vex amd64->IR: VEX=0 VEX.L=0 VEX.n=0x0 ESC=NONE vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 ==3017== valgrind: Unrecognised instruction at address 0x5bad9a. ==3017== Your program just tried to execute an instruction that Valgrind ==3017== did not recognise. There are two possible reasons for this. ==3017== 1. Your program has a bug and erroneously jumped to a non-code ==3017==location. If you are running Memcheck and you just saw a ==3017==warning about a bad jump, it's probably your program's fault. ==3017== 2. The instruction is legitimate but Valgrind doesn't handle it, ==3017==i.e. it's Valgrind's fault. If you think this is the case or ==3017==you are not sure, please let us know and we'll try to fix it. ==3017== Either way, Valgrind will now raise a SIGILL signal which will ==3017== probably kill your program. ToolObject::processDone( 0, 1 ) ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#687: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== Error running VgProcess: process failed (1) ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#714: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== VgProcess finished with error: stop VgReader ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#440: void ToolObject::stopProcess(): ===valkyrie:3014=== Stopping VgProcess ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#488: void ToolObject::stopProcess(): ===valkyrie:3014=== VgProcess already stopped (or never started). ===valkyrie:3014=== PS : Code was generated with gdc, my application crash exactly like with dmd, so it doesn't seems to be a linker issue. Maybe a D spec issue or Valgrind one. I found some leaks, but not the critical one. It seems my objects aren't correctly released when I simply set variables on a class to null. Calling explicitly clear() force immediate call of destructors. I certainly need dig into that way to find my issue. PS : MTuner can launch my application without make it crash, but it doesn't see memory of GC. OK I just found my leak. That was not a real leak!!! A piece of code was turn off the GC and never put it back on.
Re: Unable to use tradional tools to find memory leaks
On Monday, 23 September 2013 at 20:06:20 UTC, Flamaros wrote: On Saturday, 21 September 2013 at 14:30:19 UTC, Flamaros wrote: I tried to used Valgrind (Linux) and Dr Memory (Windows) without success to find a big leak I have in my application. But both tools can't launch my application without make it crash. Do I need do something particular, to have a chance to see one of those tool working fine with my application? It can be really hard to find leaks manually, maybe some option of the gc can help me? Here is my Valkyrie output : ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#253: static bool VkCfg::checkConfigDir(const QString&): ===valkyrie:3014=== No existing config dir '/tmp/valkyrie_flamaros/' => creating. ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#702: void VkCfgProj::openProject(const QString&): ===valkyrie:3014=== Can't open project: File doesn't exist, or is not readable: '/home/flamaros/development/personnal/dquick/data/dquick.cfg' ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#636: void VkCfgProj::replaceConfig(QSettings*): ===valkyrie:3014=== Replacing current config with: /home/flamaros/development/personnal/dquick/dquick.cfg ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) Valkyrie::runTool( 0, 0) Current path: /home/flamaros/development/personnal/dquick/. [OpenGLContext] OpenGL Version: 2.1 Mesa 9.1.4 rootItem main vex amd64->IR: unhandled instruction bytes: 0x48 0xDF 0x1C 0x24 0x48 0xD9 0x6C 0x24 vex amd64->IR: REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=0 vex amd64->IR: VEX=0 VEX.L=0 VEX.n=0x0 ESC=NONE vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 ==3017== valgrind: Unrecognised instruction at address 0x5bad9a. ==3017== Your program just tried to execute an instruction that Valgrind ==3017== did not recognise. There are two possible reasons for this. ==3017== 1. Your program has a bug and erroneously jumped to a non-code ==3017==location. If you are running Memcheck and you just saw a ==3017==warning about a bad jump, it's probably your program's fault. ==3017== 2. The instruction is legitimate but Valgrind doesn't handle it, ==3017==i.e. it's Valgrind's fault. If you think this is the case or ==3017==you are not sure, please let us know and we'll try to fix it. ==3017== Either way, Valgrind will now raise a SIGILL signal which will ==3017== probably kill your program. ToolObject::processDone( 0, 1 ) ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#687: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== Error running VgProcess: process failed (1) ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#714: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== VgProcess finished with error: stop VgReader ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#440: void ToolObject::stopProcess(): ===valkyrie:3014=== Stopping VgProcess ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#488: void ToolObject::stopProcess(): ===valkyrie:3014=== VgProcess already stopped (or never started). ===valkyrie:3014=== PS : Code was generated with gdc, my application crash exactly like with dmd, so it doesn't seems to be a linker issue. Maybe a D spec issue or Valgrind one. I found some leaks, but not the critical one. It seems my objects aren't correctly released when I simply set variables on a class to null. Calling explicitly clear() force immediate call of destructors. I certainly need dig into that way to find my issue. PS : MTuner can launch my application without make it crash, but it doesn't see memory of GC.
Re: Unable to use tradional tools to find memory leaks
On Saturday, 21 September 2013 at 14:30:19 UTC, Flamaros wrote: I tried to used Valgrind (Linux) and Dr Memory (Windows) without success to find a big leak I have in my application. But both tools can't launch my application without make it crash. Do I need do something particular, to have a chance to see one of those tool working fine with my application? It can be really hard to find leaks manually, maybe some option of the gc can help me? Here is my Valkyrie output : ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#253: static bool VkCfg::checkConfigDir(const QString&): ===valkyrie:3014=== No existing config dir '/tmp/valkyrie_flamaros/' => creating. ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#702: void VkCfgProj::openProject(const QString&): ===valkyrie:3014=== Can't open project: File doesn't exist, or is not readable: '/home/flamaros/development/personnal/dquick/data/dquick.cfg' ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) ===valkyrie:3014=== DEBUG: utils/vk_config.cpp#636: void VkCfgProj::replaceConfig(QSettings*): ===valkyrie:3014=== Replacing current config with: /home/flamaros/development/personnal/dquick/dquick.cfg ===valkyrie:3014=== MainWindow::runTool( tool: 0, proc: 0 ) Valkyrie::runTool( 0, 0) Current path: /home/flamaros/development/personnal/dquick/. [OpenGLContext] OpenGL Version: 2.1 Mesa 9.1.4 rootItem main vex amd64->IR: unhandled instruction bytes: 0x48 0xDF 0x1C 0x24 0x48 0xD9 0x6C 0x24 vex amd64->IR: REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=0 vex amd64->IR: VEX=0 VEX.L=0 VEX.n=0x0 ESC=NONE vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 ==3017== valgrind: Unrecognised instruction at address 0x5bad9a. ==3017== Your program just tried to execute an instruction that Valgrind ==3017== did not recognise. There are two possible reasons for this. ==3017== 1. Your program has a bug and erroneously jumped to a non-code ==3017==location. If you are running Memcheck and you just saw a ==3017==warning about a bad jump, it's probably your program's fault. ==3017== 2. The instruction is legitimate but Valgrind doesn't handle it, ==3017==i.e. it's Valgrind's fault. If you think this is the case or ==3017==you are not sure, please let us know and we'll try to fix it. ==3017== Either way, Valgrind will now raise a SIGILL signal which will ==3017== probably kill your program. ToolObject::processDone( 0, 1 ) ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#687: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== Error running VgProcess: process failed (1) ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#714: void ToolObject::processDone(int, QProcess::ExitStatus): ===valkyrie:3014=== VgProcess finished with error: stop VgReader ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#440: void ToolObject::stopProcess(): ===valkyrie:3014=== Stopping VgProcess ===valkyrie:3014=== ===valkyrie:3014=== DEBUG: objects/tool_object.cpp#488: void ToolObject::stopProcess(): ===valkyrie:3014=== VgProcess already stopped (or never started). ===valkyrie:3014=== PS : Code was generated with gdc, my application crash exactly like with dmd, so it doesn't seems to be a linker issue. Maybe a D spec issue or Valgrind one.
Re: [Question] About mixin, template and alias
Code below shows that I would achieve: / fire.d alias void delegate() EventHandler; class Event(T) { private T[] _events; public void opOpAssign(string op)(T param) if (op == "~") { _events ~= param; } public void opCall(ParamType ...)(ParamType params) { this.emit(params); } protected void emit(ParamType ...)(ParamType params) { foreach (event; _events) event(params); } } mixin template AddEvent(DelegateType, string member) { private Event!DelegateType _eventObserver; @property auto get() { if (_eventObserver is null) _eventObserver = new Event!DelegateType(); return _eventObserver; } void doEventObserver(ParamType ...)(ParamType params) { mixin (member ~ "()(params);"); } mixin ("alias get " ~ member ~ ";"); mixin ("alias doEventObserver do" ~ member ~ ";"); } class Fire { public mixin AddEvent!(EventHandler, "click"); } class DoubleFire { private Event!EventHandler _click; public this() { _click = new Event!EventHandler(); } @property public Event!EventHandler click() { return _click; } public void doClick(ParamType ...)(ParamType params) { click()(params); } } / water.d import std.stdio; import fire; class Water : Fire { } void main() { Fire element; element = new Fire(); element.click ~= () { writeln("Fire!"); }; element.click()(); // Not needed with DIP 23 element = new Water(); element.click ~= () { writeln("Water!"); }; element.click()(); // Not needed with DIP 23 DoubleFire df = new DoubleFire(); df.click ~= () { writeln("Double Fire!"); }; df.doClick(); // Workaround element.doclick(); // Workaround } / Output Fire! Water! Double Fire! Water! Thanks)
In what state of DIP23?
by subject) "Read" properties with the @property annotation Applying the "()" to a property will simply apply it to the result of the property. THIS IS A CHANGE OF BEHAVIOR. unittest { @property int function() prop1() { return () => 42; } assert(prop1() == 42); } What is about this part?
Re: [Question] About mixin, template and alias
I understand. So, at least it's has interesting behaviour and big question)
Re: Trouble with destroy
On Monday, 23 September 2013 at 19:06:48 UTC, Namespace wrote: Code: import std.stdio; struct A { public: int[4] val; alias val this; } void main() { A a; a.destroy(); } /d824/f630.d(13): Error: template object.destroy matches more than one template declaration, /opt/compilers/dmd2/include/object.di(593):destroy(T)(ref T obj) if (is(T == struct)) and /opt/compilers/dmd2/include/object.di(604):destroy(T : U[n], U, ulong n)(ref T obj) Nice. What should I do? As always. As soon as you wrote it, you've got the solution. destroy!A(a);
Trouble with destroy
Code: import std.stdio; struct A { public: int[4] val; alias val this; } void main() { A a; a.destroy(); } /d824/f630.d(13): Error: template object.destroy matches more than one template declaration, /opt/compilers/dmd2/include/object.di(593):destroy(T)(ref T obj) if (is(T == struct)) and /opt/compilers/dmd2/include/object.di(604):destroy(T : U[n], U, ulong n)(ref T obj) Nice. What should I do?
Re: cast(immutable) vs extra variable
On 09/23/2013 06:34 AM, Daniel Davidson wrote: > I've stepped away from D for several months and just getting > back into it. > the first time at D Conf Actually, I've been thinking about you recently. My apologies for forgetting your last name. That's why I couldn't recognize you. :( > I will try to out the use of pure when returning data that is > to be passed into immutable contexts. I don't think there is anything wrong with marking as many functions as pure. Indeed, the compiler does that for lambdas anyway. I am not sure where things are regarding regular functions. > just to be sure, my use of a direct pointer ensures that even > if my one pointer is the last remaining reference to the data, > it will not be garbage collected? Correct. Ali
Re: cast(immutable) vs extra variable
On Sunday, 22 September 2013 at 17:26:01 UTC, Ali Çehreli wrote: You are not alone. I tried to answer some of these questions in my DConf 2013 talk. I think I have only scratched the surface: http://dconf.org/talks/cehreli.html Ali Ali, thank you for providing great feedback and suggestions. I've stepped away from D for several months and just getting back into it. I will try to out the use of pure when returning data that is to be passed into immutable contexts. Regarding, "the why not make this a pointer as well?" for immutable(Portfolio)* portfolio - that might be good to consider. So far I have not used pointers in D directly - so just to be sure, my use of a direct pointer ensures that even if my one pointer is the last remaining reference to the data, it will not be garbage collected? I really enjoyed your talk the first time at D Conf. Now I'm enjoying it again online. Thanks.
Re: Multiline String Literals without linefeeds?
On Monday, 23 September 2013 at 11:30:18 UTC, bearophile wrote: Dicebot: Rationale / link to discussion? I use it extensively. http://d.puremagic.com/issues/show_bug.cgi?id=3827 Bye, bearophile Thanks. Well, then we will have _guaranteed_ const-folding of adjacent concatenated string literals, I will be perfectly fine with this but it does not seem to be the case right now.
Re: const and immutable members
On Monday, 23 September 2013 at 03:51:41 UTC, Jonathan M Davis wrote: Doesn't using immutable there present the same problem as with the slice? S is no longer assignable. But who would recommend not using immutable in this case if you want aarr to be stable. If you do not use immutable then who knows when your array will grow without your expecting it? At least with the slice your memory safety is in the control of your module if you make it private. But with associative array it would depend entirely on client code providing the data still having a handle on it. Of course, it's the same for AAs. Or classes. Or pointers. Or int. Or float. It's the same for _any_ type. If you make any of them fully immutable, then you can't reassign the struct, which makes the struct unusable in a number of situations. But if your concern is client code messing with your member variable, then don't give them access to it in the first place. Not quite as much messing with the member as messing with what it points to. In the setup - rich data, read from the wire or disk, lots of nesting of lists, associative arrays, json like data, etc, the POD data is being read and stored into nested structs all prior to coming to my class. I want to ensure that the memory that I know both of us (S and the client code who built data to pass to S and other users) is not being modified. I think of it like: int, double, char[10], immutable(T)[] (and string) are all similar in that there is no troublesome aliasing (even though there may be sharing). Associative array is different in that string[string] has troubling aliasing and your data can change from under you - unless you copy it deeply. It seems the suggestion from above would be copy in postblits. But I don't think that scales from a nested class perspective. The problem is where and how to copy. Actually, that was the approach I was taking before, copying the data up front in postblits. In fact I created a generalized dup function that given type T will recursively copy all fields, giving care to deep copy those with potential for mutable aliasing. The general comments in one of the related threads then was it was silly to copy the data up front. Walter in fact said he would avoid all copying data on struct construction, preferring lazy copy on write semantics. Walter's comment in this thread http://forum.dlang.org/thread/k8ti2b$1iqj$1...@digitalmars.com?page=7 Have you ever written a struct that requires a deep copy? I have, and I always wound up redoing it so the deep copy was unnecessary. I believe I asked how that would be done in the general sense but I don't think there were any good mechanisms. By, "in the general sense" I'm talking about dealing with composition at maybe 5 to 7 layers and each struct containing types with mutable aliasing with lots of associative arrays. If you're making your member variables const or immutable so that client code can't mutate them, then you're just causing yourself problems because you didn't use proper encapsulation. I'm now *considering* making them const because I don't want a large composition hierarchy of plain old data with postblits aggressively copying data unnecessarily before it gets finalized and passed to my struct S that is really only holding onto it as reference data/read only/forever immutable.
Re: Multiline String Literals without linefeeds?
Dicebot: Rationale / link to discussion? I use it extensively. http://d.puremagic.com/issues/show_bug.cgi?id=3827 Bye, bearophile
Re: Multiline String Literals without linefeeds?
On Monday, 23 September 2013 at 11:10:07 UTC, bearophile wrote: simendsjo: Isn't "some" "string" replaced with "somestring" early on? Yes, unfortunately. And it's something Walter agreed with me to kill, but nothing has happened... Bye, bearophile Rationale / link to discussion? I use it extensively.
Re: Multiline String Literals without linefeeds?
simendsjo: Isn't "some" "string" replaced with "somestring" early on? Yes, unfortunately. And it's something Walter agreed with me to kill, but nothing has happened... Bye, bearophile
Re: Multiline String Literals without linefeeds?
On Monday, 23 September 2013 at 09:42:59 UTC, bearophile wrote: John Carter: is there a similar mechanism in D? Or should I do... string foo = "long" "string" "without" "linefeeds" ; Genrally you should do: string foo = "long" ~ "string" ~ "without" ~ "linefeeds"; See also: http://d.puremagic.com/issues/show_bug.cgi?id=3827 You could also write a string with newlines and then remove them at compile-time with string functions. Bye, bearophile Isn't "some" "string" replaced with "somestring" early on?
Re: User defined attributes use
On Monday, 23 September 2013 at 07:47:32 UTC, Jacob Carlborg wrote: On 2013-09-20 16:12, simendsjo wrote: You could of course fix this in a library too. enum AttributeUsage { struct_ = 1 << 0, class_ = 1 << 1, //etc } struct attribute { AttributeUsage usage; } Then the library could give a compile-time error if you tries to use it where it's not meant to be. I'm not sure how I could do that. You can recurse into UDAs for attributes and pass along the type that had the uda. A static assert could verify that it's used on the correct type. (For my library, that would mean editing my getMembersAndAttributes template.)
Re: Multiline String Literals without linefeeds?
John Carter: is there a similar mechanism in D? Or should I do... string foo = "long" "string" "without" "linefeeds" ; Genrally you should do: string foo = "long" ~ "string" ~ "without" ~ "linefeeds"; See also: http://d.puremagic.com/issues/show_bug.cgi?id=3827 You could also write a string with newlines and then remove them at compile-time with string functions. Bye, bearophile
Re: Regression or bugfix?
On 2013-09-22 15:49, simendsjo wrote: In 2.063.2, (T!int).stringof == "T!(int)". In current head, it's "T!int". Even (T!(int)).stringof == "T!int". So is this a regression bug or a bugfix? Apparently you shouldn't rely on the format of .stringof. See the comment the ones that follow: http://d.puremagic.com/issues/show_bug.cgi?id=10722#c4 -- /Jacob Carlborg
Re: User defined attributes use
On 2013-09-20 16:12, simendsjo wrote: You could of course fix this in a library too. enum AttributeUsage { struct_ = 1 << 0, class_ = 1 << 1, //etc } struct attribute { AttributeUsage usage; } Then the library could give a compile-time error if you tries to use it where it's not meant to be. I'm not sure how I could do that. -- /Jacob Carlborg
Re: [Question] About mixin, template and alias
On Monday, 23 September 2013 at 06:31:01 UTC, monarch_dodra wrote: I'm filing a bug report right now. http://d.puremagic.com/issues/show_bug.cgi?id=11107
Re: Multiline String Literals without linefeeds?
On Monday, 23 September 2013 at 04:43:16 UTC, John Carter wrote: In C/C++ in the presence of the preprocessor a string char foo[] = "\ long\ string\ without\ linefeeds\ "; Is translated by the preprocessor to char foo[] = "longstringwithoutlinefeeds"; is there a similar mechanism in D? Or should I do... string foo = "long" "string" "without" "linefeeds" ; If I'm not mistaken, this is exactly the way to do it. A side note - Ds CTFE is quite good, so you can usually build up strings at compile-time using regular functions.