Re: Using private constructor with std.experimental.allocater:make

2016-05-01 Thread Basile B via Digitalmars-d-learn

On Monday, 2 May 2016 at 04:19:48 UTC, earthfront wrote:

On Sunday, 1 May 2016 at 19:18:38 UTC, Basile B wrote:

CT make(CT, Alloc, A...)(auto ref Alloc al, A a)


This works. Thank you. Good point about __ctor alone not being 
sufficient.



auto memory = al.allocate(size);

... 

GC.addRange(memory.ptr, size, typeid(CT));


Nit: "GC.addRange..." -- this attempts to clean memory 
allocated manually.


The problem is that the template make and emplace() are 
**elsewhere** so they cannot see A.this() (== A.__ctor).


A common way to fix this kind of problem is to make a template 
mixin with the template that has the visibility and to mix it 
in the current scope


I guess this is the best workaround at the moment.

There's a discontinuity between the GC and std.allocators.
"new A(1)" works, because the GC has implicit private access to 
classes.
I would love to see allocators in wider use. Workarounds are an 
obstacle to this.


Possible solutions:
* Emulate c++'s "friend" keyword somehow. D's rationale 
eschew's this.

* Somehow designate friendship via [selective] module import?
* Secret upcoming solution from Walter/Andrei. Weren't they 
discussing some sort of built in ref counting system?


Other solution: give "super powers" to the __traits()... used to 
inspect, like suggested in this bugzilla ticket: 
https://issues.dlang.org/show_bug.cgi?id=15371.


The worst with this problem is that it's extremely easy to fix in 
the compiler source code. But it's extremely hard to make people 
understand that this is a real problem.




Re: Can't use std.algorithm.remove on a char[]?

2016-05-01 Thread ag0aep6g via Digitalmars-d-learn

On 02.05.2016 01:51, TheGag96 wrote:

That's a shame. I'd really like to be able to remove a character from a
character array... I supplier I just have to get used to casting to
ubyte[] or maybe just using dchar[] instead.


Instead of casting you can also use `representation`[1] and 
`assumeUTF`[2] to convert to ubyte[] and back:



char[] thing = ['a', 'b', 'c'];
thing = thing.representation.remove(1).assumeUTF;



[1] https://dlang.org/phobos/std_string.html#.representation
[2] https://dlang.org/phobos/std_string.html#.assumeUTF


Re: Using private constructor with std.experimental.allocater:make

2016-05-01 Thread earthfront via Digitalmars-d-learn

On Sunday, 1 May 2016 at 19:18:38 UTC, Basile B wrote:

CT make(CT, Alloc, A...)(auto ref Alloc al, A a)


This works. Thank you. Good point about __ctor alone not being 
sufficient.



auto memory = al.allocate(size);

... 

GC.addRange(memory.ptr, size, typeid(CT));


Nit: "GC.addRange..." -- this attempts to clean memory allocated 
manually.


The problem is that the template make and emplace() are 
**elsewhere** so they cannot see A.this() (== A.__ctor).


A common way to fix this kind of problem is to make a template 
mixin with the template that has the visibility and to mix it 
in the current scope


I guess this is the best workaround at the moment.

There's a discontinuity between the GC and std.allocators.
"new A(1)" works, because the GC has implicit private access to 
classes.
I would love to see allocators in wider use. Workarounds are an 
obstacle to this.


Possible solutions:
* Emulate c++'s "friend" keyword somehow. D's rationale eschew's 
this.

* Somehow designate friendship via [selective] module import?
* Secret upcoming solution from Walter/Andrei. Weren't they 
discussing some sort of built in ref counting system?




Re: Using private constructor with std.experimental.allocater:make

2016-05-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Sun, 01 May 2016 18:27:51 +
Lass Safin via Digitalmars-d-learn 
wrote:

> On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote:
> > Hello!
> > [...]
> >  class A
> >{ int b; private this(int a){b=a;} }
> > [...]
>
> I don't think classes are supposed to be able to have a private
> constructor...

There's no reason why you shouldn't be able to. Other, public constructors
could call it, and other code within the module could call it. You can even
have entire classes which are private. So, private constructors need to be
possible.

Now, whether that will ever work with something like emplace or the
allocators, I don't know, since they're going to have access to the
constructor to do their thing, but they're in different modules, which
wouldn't normally have access to any constructors which aren't private
(including protected and package, not just private).

- Jonathan M Davis


simple idea for error messages

2016-05-01 Thread Laeeth Isharc via Digitalmars-d-learn

when it cannot match a prototype eg:

module foo;
enum Foo
{
foo
}
void bar(Foo foo)
{
}
module bar;
enum Foo
{
foo
}

void fooBar(Foo foo)
{
  bar(foo);
}

rather than complain the type X does not match the type X - an 
unhelpful message - could the compiler not check to see if the 
type descriptions are identical, and if so print a clarifying 
message about which modules they come from.  it's easy the second 
time, but another source of friction in learning the language in 
the beginning.





Re: Can't use std.algorithm.remove on a char[]?

2016-05-01 Thread TheGag96 via Digitalmars-d-learn

On Sunday, 1 May 2016 at 09:11:22 UTC, ag0aep6g wrote:
It's because of auto-decoding. char[] is an array of chars, but 
it's been made a range of dchars. Calling front on a char[] 
decodes up to four chars into one dchar.


Obviously you can't take the address of the dchar, because it's 
just a return value.


You can't assign through front, because the number of chars 
could be different from what's currently there. The whole array 
would have to be re-arranged then, which would be unexpectedly 
costly for the user.


The auto-decoding behavior was chosen to make dealing with 
char[] less bug-prone. With auto-decoding you don't have to 
worry about cutting a multibyte sequence in half (can still cut 
a grapheme cluster in half, though). However, as you see, it 
creates other headaches, and it's considered a mistake by many. 
Getting rid of it now would be a major breaking change. Could 
be worthwhile, though.


That's a shame. I'd really like to be able to remove a character 
from a character array... I supplier I just have to get used to 
casting to ubyte[] or maybe just using dchar[] instead. I'm 
honestly surprised I haven't encountered this behavior sooner.


It's interesting - as I keep coding in D and learning about how 
amazing it is to use, I always find these weird quirks here and 
there to remind me that it isn't flawless... I guess it can't be 
perfect, haha.





Re: Setting a list of values

2016-05-01 Thread Xinok via Digitalmars-d-learn

On Sunday, 1 May 2016 at 05:42:00 UTC, Ali Çehreli wrote:

On 04/30/2016 10:05 PM, Joel wrote:
> This has no effect:
> _bars.each!(a => { a._plots.fillColor = Color(255, 180, 0);
});

This is a common issue especially for people who know lambdas 
from other languages. :)


Your lambda does not do any work. Rather, your lambda returns 
another lambda, which is promptly ignored:


Those are some discrete semantics. I know D pretty well and even 
I didn't see the problem initially. Anybody else think it's worth 
adding a warning to the compiler for this specific case? If this 
is the user's intended behavior, then they can rewrite it like 
this to be explicit and disable the warning:


_bars.each!(a => (){ a._plots.fillColor = Color(255, 180, 0); });
//   ^^ add empty parenthesis before the curly brace


Re: Using private constructor with std.experimental.allocater:make

2016-05-01 Thread Basile B via Digitalmars-d-learn

On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote:

Hello!

This code fails:
-
void main(){
 class A
   { int b; private this(int a){b=a;} }
   //{ int b; this(int a){b=a;} }

 import std.conv:emplace;
 import std.experimental.allocator.mallocator:Mallocator;
 import std.experimental.allocator:make;

 {
   auto ptr = make!A(Mallocator.instance, 42);
   assert (ptr.b == 42);
 }
}
---

with error message:
"/usr/include/dmd/phobos/std/conv.d(4115): Error: static assert
 "Don't know how to initialize an object of type A with 
arguments (int)"

/usr/include/dmd/phobos/std/experimental/allocator/package.d(456):
instantiated from here: emplace!(A, int)
./helloworld.d(25):instantiated from here: make!(A, 
shared(Mallocator), int)"



If I make the constructor public, no problem.
It seems that emplace (specialized for classes) doesn't work if 
the class has a private constructor.



I added the following snippet to confirm:
--
 {
   auto ptr = 
Mallocator.instance.allocate(__traits(classInstanceSize, A));

   auto aPtr = emplace(ptr,34);
   assert( aPtr.b == 34 );
 }
--
And I get the same error message.


Google gave me:
http://forum.dlang.org/post/kot0t1$uls$1...@digitalmars.com


That guy's ultimate fix was explicitly calling the class's 
__ctor method, instead of emplace. The __ctor method is 
undocumented, as far as I can tell.



Is there a better solution now? More widespread use of 
allocators will likely result in more of this problem.



__ctor is not enough, the "static layout" must be copied to get 
the status of the initialized variables. Also there is not always 
a __ctor. Anyway you can put this in the module where is located 
the class with a private ctor:



import std.traits;

CT make(CT, Alloc, A...)(auto ref Alloc al, A a)
if (is(CT == class) && !isAbstractClass!CT)
{
auto size = typeid(CT).init.length;
auto memory = al.allocate(size);
memory[0 .. size] = typeid(CT).init[];
static if (__traits(hasMember, CT, "__ctor"))
(cast(CT) (memory.ptr)).__ctor(a);
import core.memory: GC;
GC.addRange(memory.ptr, size, typeid(CT));
return cast(CT) memory.ptr;
}

void main(string[] args)
{
class A {int b; private this(int a){b=a;} }

import std.experimental.allocator.mallocator;
auto ptr = make!A(Mallocator.instance, 42);
assert (ptr.b == 42);
}


The problem is that the template make and emplace() are 
**elsewhere** so they cannot see A.this() (== A.__ctor).


A common way to fix this kind of problem is to make a template 
mixin with the template that has the visibility and to mix it in 
the current scope:


 module stuff -
mixin template fixProtection()
{
import std.traits;
CT make(CT, Alloc, A...)(auto ref Alloc al, A a)
if (is(CT == class) && !isAbstractClass!CT)
{
auto size = typeid(CT).init.length;
auto memory = al.allocate(size);
memory[0 .. size] = typeid(CT).init[];
static if (__traits(hasMember, CT, "__ctor"))
(cast(CT) (memory.ptr)).__ctor(a);
import core.memory: GC;
GC.addRange(memory.ptr, size, typeid(CT));
return cast(CT) memory.ptr;
}
}
-

- module other stuff -
mixin fixProtection;

void main(string[] args)
{
class A {int b; private this(int a){b=a;} }

import std.experimental.allocator.mallocator;
auto ptr = make!A(Mallocator.instance, 42);
assert (ptr.b == 42);
}
-

Many things related to __traits are affected (getMember, 
getOverload, ...).





Re: Using private constructor with std.experimental.allocater:make

2016-05-01 Thread Lass Safin via Digitalmars-d-learn

On Sunday, 1 May 2016 at 11:17:27 UTC, earthfront wrote:

Hello!
[...]
 class A
   { int b; private this(int a){b=a;} }
[...]


I don't think classes are supposed to be able to have a private 
constructor...


Re: Using a string generated at compile-time in a @nogc function

2016-05-01 Thread Basile B via Digitalmars-d-learn

On Sunday, 1 May 2016 at 13:22:27 UTC, Mithun Hunsur wrote:

On Sunday, 1 May 2016 at 10:37:23 UTC, Anonymouse wrote:

On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote:

Hi all,

I'm working on removing the string mixins from my code, but 
have run into an issue:


http://dpaste.dzfl.pl/ecd7eb53947e

As far as I can tell, this should work; the enum should force 
compile-time execution (which it does, as evidenced by the 
pragma). [...]


That does seem buggy but I don't know enough to say for 
certain. I'd suggest filing a bug report anyway; the worst 
thing that can happen is that it gets closed. Unreported bugs 
can only be fixed by accident.


Tacking an .idup after .toLower seems to make it work, at 
least on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would 
have thought both toLower and idup returned a normal string, 
but unsure.



enum loweredName = member.to!string.toLower.idup;
pragma(msg, loweredName);

if (member == test)
return loweredName;


Yup - that works. How odd! Along the same lines is

enum loweredName = "" ~ member.to!string.toLower;

which also works without issues. This makes me think that the 
result of `member.to!string.toLower` isn't being treated as a 
string, despite being typed as one - and by using `idup` or 
concatenating to it, we essentially retype it as a string.


Another solution:


import std.traits;
import std.conv;
import std.uni;
import std.stdio;

enum Test { A, B, C }

auto enumToString(Test test) @nogc nothrow
{
@property string function() result = {return "";};
foreach (member; EnumMembers!Test)
{
if (member == test)
{
result = {return member.to!string.toLower;};
break;
}
}
return result;
}

void main()
{
enumToString(Test.A)().writeln;
}


returns a delegate, although the call is quite unfriendly, 
despite of the @property.


Re: Method doesn't compile when defined in a mixin, but is fine without?

2016-05-01 Thread pineapple via Digitalmars-d-learn

On Sunday, 1 May 2016 at 13:46:14 UTC, ag0aep6g wrote:

On 01.05.2016 15:32, pineapple wrote:
static string vectorpropertymixin(string name, string 
SDL_getter, string

SDL_setter){

[...]

mixin(vectorpropertymixin(
 "minsize", "SDL_GetWindowMinimumSize", 
"SDL_GetWindowMinimumSize"

));


Should the second one be "SDL_SetWindowMinimumSize" here? 
("Set" instead of "Get".)


See, of course it was going to be something stupid like that. 
Would be nice if compile errors were kinder to mixins, might've 
realized where the error actually was. Any tips on that?




Re: Method doesn't compile when defined in a mixin, but is fine without?

2016-05-01 Thread ag0aep6g via Digitalmars-d-learn

On 01.05.2016 15:32, pineapple wrote:

static string vectorpropertymixin(string name, string SDL_getter, string
SDL_setter){

[...]

mixin(vectorpropertymixin(
 "minsize", "SDL_GetWindowMinimumSize", "SDL_GetWindowMinimumSize"
));


Should the second one be "SDL_SetWindowMinimumSize" here? ("Set" instead 
of "Get".)


Re: Method doesn't compile when defined in a mixin, but is fine without?

2016-05-01 Thread pineapple via Digitalmars-d-learn
Strangely, though I'm getting this error when wrapping 
SDL_GetWindowMinimumSize and SDL_GetWindowMaximumSize, I don't 
get any compilation errors wrapping the identically-signatured 
SDL_GetWindowSize and SDL_GetWindowPosition using the same mixin.


Method doesn't compile when defined in a mixin, but is fine without?

2016-05-01 Thread pineapple via Digitalmars-d-learn
I'm working on an SDL wrapper based on the derelict sdl2 and 
opengl3 bindings and so I've got a method like this I wrote:


@property Vector2!int minsize(){
int x, y;
SDL_GetWindowMinimumSize(this.window, &x, &y);
return Vector2!int(x, y);
}

I've got several almost identical methods for maximum size, and 
window size, and window position, and so I thought I'd make a 
mixin to cut down on the redundancy.


So I made my mixin, which looks like this - having definitions 
for both the getter above and also setters that seem to work fine:


static string vectorpropertymixin(string name, string SDL_getter, 
string SDL_setter){

return "
@property Vector2!int " ~ name ~ "(){
int x, y;
" ~ SDL_getter ~ "(this.window, &x, &y);
return Vector2!int(x, y);
}
@property void " ~ name ~ "(in Vector2!int vector){
this.set" ~ name ~ "(vector.x, vector.y);
}
void set" ~ name ~ "(in int x, in int y){
" ~ SDL_setter ~ "(this.window, x, y);
}
";
}

And then I put this in the class body, replacing the non-mixin 
getters that compiled without incident:


mixin(vectorpropertymixin(
"minsize", "SDL_GetWindowMinimumSize", 
"SDL_GetWindowMinimumSize"

));

And using the mixin I get this error when attempting to compile:

E:\Dropbox\Projects\d\mach\sdl\window.d-mixin-285(295): Error: 
function pointer SDL_GetWindowMinimumSize (SDL_Window*, int*, 
int*) is not callable using argument types (SDL_Window*, 
const(int), const(int))


What's going on here? I feel like I must be making a really 
stupid obvious oversight.




Re: Using a string generated at compile-time in a @nogc function

2016-05-01 Thread Mithun Hunsur via Digitalmars-d-learn

On Sunday, 1 May 2016 at 10:37:23 UTC, Anonymouse wrote:

On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote:

Hi all,

I'm working on removing the string mixins from my code, but 
have run into an issue:


http://dpaste.dzfl.pl/ecd7eb53947e

As far as I can tell, this should work; the enum should force 
compile-time execution (which it does, as evidenced by the 
pragma). [...]


That does seem buggy but I don't know enough to say for 
certain. I'd suggest filing a bug report anyway; the worst 
thing that can happen is that it gets closed. Unreported bugs 
can only be fixed by accident.


Tacking an .idup after .toLower seems to make it work, at least 
on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would have 
thought both toLower and idup returned a normal string, but 
unsure.



enum loweredName = member.to!string.toLower.idup;
pragma(msg, loweredName);

if (member == test)
return loweredName;


Yup - that works. How odd! Along the same lines is

enum loweredName = "" ~ member.to!string.toLower;

which also works without issues. This makes me think that the 
result of `member.to!string.toLower` isn't being treated as a 
string, despite being typed as one - and by using `idup` or 
concatenating to it, we essentially retype it as a string.


Cannot link daimos glfw using x64

2016-05-01 Thread ParticlePeter via Digitalmars-d-learn

I am failing to link statically to glfw library with deimos glfw.

The repo includes an example for glfw2. I downloaded the latest 
glfw2.lib and tried build the example with -m64 and got these 
errors:
C:\ ... \deimos-glfw>dmd GLFW.lib 
examples/glfw2/openwindow/openwindow.d -m64
MSVCRT.lib(MSVCR120.dll) : error LNK2005: free already defined in 
LIBCMT.lib(free.obj)
MSVCRT.lib(MSVCR120.dll) : error LNK2005: strchr already defined 
in LIBCMT.lib(strchr.obj)
MSVCRT.lib(MSVCR120.dll) : error LNK2005: malloc already defined 
in LIBCMT.lib(malloc.obj)
MSVCRT.lib(MSVCR120.dll) : error LNK2005: __iob_func already 
defined in LIBCMT.lib(_file.obj)
MSVCRT.lib(MSVCR120.dll) : error LNK2005: fprintf already defined 
in LIBCMT.lib(fprintf.obj)
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of 
other libs; use /NODEFAULTLIB:library


Next I tried to build the library myself with the /NODEFAULTLIB 
option set but still getting the same errors.


What am I doing wrong?


Using private constructor with std.experimental.allocater:make

2016-05-01 Thread earthfront via Digitalmars-d-learn

Hello!

This code fails:
-
void main(){
 class A
   { int b; private this(int a){b=a;} }
   //{ int b; this(int a){b=a;} }

 import std.conv:emplace;
 import std.experimental.allocator.mallocator:Mallocator;
 import std.experimental.allocator:make;

 {
   auto ptr = make!A(Mallocator.instance, 42);
   assert (ptr.b == 42);
 }
}
---

with error message:
"/usr/include/dmd/phobos/std/conv.d(4115): Error: static assert  
"Don't know how to initialize an object of type A with arguments 
(int)"

/usr/include/dmd/phobos/std/experimental/allocator/package.d(456):
instantiated from here: emplace!(A, int)
./helloworld.d(25):instantiated from here: make!(A, 
shared(Mallocator), int)"



If I make the constructor public, no problem.
It seems that emplace (specialized for classes) doesn't work if 
the class has a private constructor.



I added the following snippet to confirm:
--
 {
   auto ptr = 
Mallocator.instance.allocate(__traits(classInstanceSize, A));

   auto aPtr = emplace(ptr,34);
   assert( aPtr.b == 34 );
 }
--
And I get the same error message.


Google gave me:
http://forum.dlang.org/post/kot0t1$uls$1...@digitalmars.com


That guy's ultimate fix was explicitly calling the class's __ctor 
method, instead of emplace. The __ctor method is undocumented, as 
far as I can tell.



Is there a better solution now? More widespread use of allocators 
will likely result in more of this problem.


Re: Setting a list of values

2016-05-01 Thread Marc Schütz via Digitalmars-d-learn

On Sunday, 1 May 2016 at 05:42:00 UTC, Ali Çehreli wrote:

On 04/30/2016 10:05 PM, Joel wrote:
> This has no effect:
> _bars.each!(a => { a._plots.fillColor = Color(255, 180, 0);
});

This is a common issue especially for people who know lambdas 
from other languages. :)


Your lambda does not do any work. Rather, your lambda returns 
another lambda, which is promptly ignored:


import std.stdio;
import std.algorithm;

void main() {
auto arr = [ 1, 2 ];
arr.each!(a => { writeln(a); });  // returns lambda for 
each a

}

The lambda that 'each' takes above is "given a, produce this 
lambda". . To do the intended work, you need to remove the 
curly braces (and the semicolon):


arr.each!(a => writeln(a));

Or, you could insert empty () to call the returned lambda but 
that would completely be extra work in this case:


arr.each!(a => { writeln(a); }());


Or, remove the arrow:

arr.each!((a) { writeln(a); });


Re: Getting all struct members and values with introspection avoiding string mixins

2016-05-01 Thread ParticlePeter via Digitalmars-d-learn

On Sunday, 1 May 2016 at 10:13:47 UTC, H. S. Teoh wrote:
On Sun, May 01, 2016 at 09:42:37AM +, ParticlePeter via 
Digitalmars-d-learn wrote:
I am logging arbitrary POD struct types with member names and 
data:


void printStructInfo( T )( T info ) {
  foreach( i, A; typeof( T.tupleof )) {
enum attribName = T.tupleof[i].stringof;
writefln( "%s : %s", attribName, mixin( "info." ~ 
attribName ));

  }
}

Is there is some other way to evaluate info.attribName without 
using string mixins?

[...]

Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd 
do it:


void printStructInfo( T )( T info ) {
import std.stdio : writefln;
foreach (memb; __traits(allMembers, T)) {
writefln("%s: %s", memb,
__traits(getMember, info, memb));
}
}

(For structs that have members other than data fields, you'll 
need a static if to filter out non-value members, but this 
should get you started.)



T


Thanks, I was searching for that!
The given example is a simplification of my code. I do examine 
each member separately and treat accordingly, but eventually used 
the mixin version to get the build-in type values.




Re: Using a string generated at compile-time in a @nogc function

2016-05-01 Thread Anonymouse via Digitalmars-d-learn

On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote:

Hi all,

I'm working on removing the string mixins from my code, but 
have run into an issue:


http://dpaste.dzfl.pl/ecd7eb53947e

As far as I can tell, this should work; the enum should force 
compile-time execution (which it does, as evidenced by the 
pragma). [...]


That does seem buggy but I don't know enough to say for certain. 
I'd suggest filing a bug report anyway; the worst thing that can 
happen is that it gets closed. Unreported bugs can only be fixed 
by accident.


Tacking an .idup after .toLower seems to make it work, at least 
on dpaste (http://dpaste.dzfl.pl/8abed3d3ec6c). I would have 
thought both toLower and idup returned a normal string, but 
unsure.



enum loweredName = member.to!string.toLower.idup;
pragma(msg, loweredName);

if (member == test)
return loweredName;


Re: Using a string generated at compile-time in a @nogc function

2016-05-01 Thread Mithun Hunsur via Digitalmars-d-learn

On Sunday, 1 May 2016 at 08:14:43 UTC, Nicholas Wilson wrote:

On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote:

Hi all,

I'm working on removing the string mixins from my code, but 
have run into an issue:


http://dpaste.dzfl.pl/ecd7eb53947e

As far as I can tell, this should work; the enum should force 
compile-time execution (which it does, as evidenced by the 
pragma). I've worked around this by employing a string mixin, 
but it's not as clean:


http://dpaste.dzfl.pl/021c4a849b32

Any insight would be appreciated :)


Have you tried using a static (as in inside the function) 
static array of strings?


I considered it briefly, but opted against it because it adds 
unnecessary overhead (both time and space) - while minor, I'm not 
going to concede that quickly :P


Re: Getting all struct members and values with introspection avoiding string mixins

2016-05-01 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, May 01, 2016 at 09:42:37AM +, ParticlePeter via Digitalmars-d-learn 
wrote:
> I am logging arbitrary POD struct types with member names and data:
> 
> void printStructInfo( T )( T info ) {
>   foreach( i, A; typeof( T.tupleof )) {
> enum attribName = T.tupleof[i].stringof;
> writefln( "%s : %s", attribName, mixin( "info." ~ attribName ));
>   }
> }
> 
> Is there is some other way to evaluate info.attribName without using
> string mixins?
[...]

Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it:

void printStructInfo( T )( T info ) {
import std.stdio : writefln;
foreach (memb; __traits(allMembers, T)) {
writefln("%s: %s", memb,
__traits(getMember, info, memb));
}
}

(For structs that have members other than data fields, you'll need a
static if to filter out non-value members, but this should get you
started.)


T

-- 
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.


Getting all struct members and values with introspection avoiding string mixins

2016-05-01 Thread ParticlePeter via Digitalmars-d-learn
I am logging arbitrary POD struct types with member names and 
data:


void printStructInfo( T )( T info ) {
  foreach( i, A; typeof( T.tupleof )) {
enum attribName = T.tupleof[i].stringof;
writefln( "%s : %s", attribName, mixin( "info." ~ attribName 
));

  }
}

Is there is some other way to evaluate info.attribName without 
using string mixins?


Cheers, PP



Re: Can't use std.algorithm.remove on a char[]?

2016-05-01 Thread ag0aep6g via Digitalmars-d-learn

On 01.05.2016 07:29, TheGag96 wrote:

Why exactly is it like this? I would understand why strings (immutable
character arrays) behave like this, but I feel like plain old character
arrays should work the same as an array of ubytes when treated as a
range... Or is there some other string-related behavior that would get
broken by this?


It's because of auto-decoding. char[] is an array of chars, but it's 
been made a range of dchars. Calling front on a char[] decodes up to 
four chars into one dchar.


Obviously you can't take the address of the dchar, because it's just a 
return value.


You can't assign through front, because the number of chars could be 
different from what's currently there. The whole array would have to be 
re-arranged then, which would be unexpectedly costly for the user.


The auto-decoding behavior was chosen to make dealing with char[] less 
bug-prone. With auto-decoding you don't have to worry about cutting a 
multibyte sequence in half (can still cut a grapheme cluster in half, 
though). However, as you see, it creates other headaches, and it's 
considered a mistake by many. Getting rid of it now would be a major 
breaking change. Could be worthwhile, though.


Re: Using a string generated at compile-time in a @nogc function

2016-05-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 1 May 2016 at 05:28:36 UTC, Mithun Hunsur wrote:

Hi all,

I'm working on removing the string mixins from my code, but 
have run into an issue:


http://dpaste.dzfl.pl/ecd7eb53947e

As far as I can tell, this should work; the enum should force 
compile-time execution (which it does, as evidenced by the 
pragma). I've worked around this by employing a string mixin, 
but it's not as clean:


http://dpaste.dzfl.pl/021c4a849b32

Any insight would be appreciated :)


Have you tried using a static (as in inside the function) static 
array of strings?