Float values are wrong in union

2016-08-21 Thread stunaep via Digitalmars-d-learn
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes. This is working without 
issue in other languages so I'm really stumped. Here's an example:



union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;//int bits 0x7fb0 as float
test t3 = { f : t2 };
writefln("%x", t3.i);//prints 7ff0 NOT 0x7fb0


Re: Variant and immutable struct

2016-08-21 Thread Øivind via Digitalmars-d-learn

On Sunday, 10 January 2016 at 17:50:44 UTC, Vlad Leberstein wrote:


As I'm not very good at D, I would like to get some feedback 
about this solutions' viability. AFAIU memcpy-ing struct here 
is safe because all target arguments ever passed to tryPutting 
are internal to implementation(and SHOULD be void-initialized 
but it's currently not working AFAIK). Maybe postblit should 
also be called for new instance, but I'm not sure about current 
state of qualified postblit.


Any help would be greatly appreciated!


I am hitting the same problem. Trying to send an immutable 
hashmap of variants with std.concurrency.


Re: Is there a d analog of strncmp?

2016-08-21 Thread dan via Digitalmars-d-learn

On Monday, 22 August 2016 at 01:45:02 UTC, Jonathan M Davis wrote:
On Monday, August 22, 2016 00:14:31 Adam D. Ruppe via 
Digitalmars-d-learn wrote:

int strncmp(string a, string b, int n) {
  if(a.length > n)
  a = a[0 .. n];
  if(b.length > n)
  b = b[0 .. n];
  import std.algorithm.comparison : cmp;
  return cmp(a, b);
}


Aside from the imports, it can be turned into a one-liner if 
you use take:


return cmp(take(a, n), take(b, n));

- Jonathan M Davis


Thanks Adam and Jonathan for your solutions.

For reference, one of the imports Jonathan is referring to is
   import std.range;

I did not know about take.  Well, i also did not know about cmp.  
So my code is probably not very idiomatic.  But i do appreciate 
all of you d-learn people!




Re: Float values are wrong in union

2016-08-21 Thread jkpl via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes. This is working without 
issue in other languages so I'm really stumped. Here's an 
example:



union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;//int bits 0x7fb0 as float
test t3 = { f : t2 };
writefln("%x", t3.i);//prints 7ff0 NOT 0x7fb0


Ok on linux, 0x7fb0 is written, I tested under linux x86_64 
with latest dmd beta, ldc and also gdc.


Which compiler and version do you use ?
Which OS and archi ?


Re: Float values are wrong in union

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes.


I can already tell what this is going to be...
The problem is almost certainly nothing to do with your union, 
it's this line:

float t2 = t.f;
This will load 0x7fb0 into ST(0), which instantly converts it 
to 7FF0 because it's a signalling NaN, then store ST(0) in 
your float `t2`.


Signalling NaNs are an ongoing problem in D's codegen. See Don's 
remarks at this page: 
https://issues.dlang.org/show_bug.cgi?id=16105#c2


The reason it works in other languages is because they don't 
place floats in the floating point registers for non-arithmetic 
operations. I've been trying to patch DMD's backend to behave 
this way too, but it's much harder than I expected (difficult 
codebase to understand/navigate).


Re: Float values are wrong in union

2016-08-21 Thread jkpl via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:52:40 UTC, Cauterite wrote:

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes.


I can already tell what this is going to be...
The problem is almost certainly nothing to do with your union, 
it's this line:

float t2 = t.f;
This will load 0x7fb0 into ST(0), which instantly converts 
it to 7FF0 because it's a signalling NaN, then store ST(0) 
in your float `t2`.


Signalling NaNs are an ongoing problem in D's codegen. See 
Don's remarks at this page: 
https://issues.dlang.org/show_bug.cgi?id=16105#c2


The reason it works in other languages is because they don't 
place floats in the floating point registers for non-arithmetic 
operations. I've been trying to patch DMD's backend to behave 
this way too, but it's much harder than I expected (difficult 
codebase to understand/navigate).


That's a 32 bit codegen issue then because DMD64 's disasm shows 
that SSE regs are used:



void foo()
{
union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;
test t3 = { f : t2 };
}
===

yields to

===
004586D0h  push rbp
004586D1h  mov rbp, rsp
004586D4h  sub rsp, 10h
004586D8h  mov dword ptr [rbp-10h], 7FB0h
004586DFh  movss xmm0, dword ptr [rbp-10h]
004586E4h  movss dword ptr [rbp-0Ch], xmm0
004586E9h  movss xmm1, dword ptr [rbp-0Ch]
004586EEh  movss dword ptr [rbp-08h], xmm1
004586F3h  leave
004586F4h  ret
===


Re: DMD on ARM/Linux (for controlling EV3 Lego Mindstorm)?

2016-08-21 Thread Sai via Digitalmars-d-learn

Thanks all for your replies.

I tried to use GDC first, I couldn't find windows binary 
targeting windows (for initial testing) which I thought was 
weird. https://gdcproject.org/downloads


So I tried to build it in Cygwin env, using these instructions:
http://wiki.dlang.org/GDC/Installation/Generic
(I used gcc-5.2 sources for this).

Unfortunately, it failed with the following error. Any ideas?

I am tempting towards go, looks like their windows binary 
supports compiling to both windows and arm. Unfortunately I don't 
want to use go as it lacks templates (or generics) and operator 
overloading, as I tend to use lot of vector/matrix math in my 
programs.



gcc/d/dfrontend -Id 
../../gcc-5.2.0/gcc/d/dfrontend/filename.c
../../gcc-5.2.0/gcc/d/dfrontend/filename.c: In static 
member function ‘static bool FileName::ensurePathExists(const 
char*)’:
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:602:43: error: 
‘sep’ was not declared in this scope

 if (path[strlen(path) - 1] != sep)
   ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:611:21: error: 
‘r’ was not declared in this scope

 if (r)
 ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:616:25: error: 
‘errno’ was not declared in this scope

 if (errno != EEXIST)
 ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:616:34: error: 
‘EEXIST’ was not declared in this scope

 if (errno != EEXIST)
  ^
make[2]: *** [../../gcc-5.2.0/gcc/d/Make-lang.in:115: 
d/filename.o] Error 1

make[2]: *** Waiting for unfinished jobs
rm gcc.pod gdc.pod
make[2]: Leaving directory '/home/sai/gdc/objdir/gcc'
make[1]: *** [Makefile:4127: all-gcc] Error 2
make[1]: Leaving directory '/home/sai/gdc/objdir'
make: *** [Makefile:867: all] Error 2



Re: DMD on ARM/Linux (for controlling EV3 Lego Mindstorm)?

2016-08-21 Thread rikki cattermole via Digitalmars-d-learn

On 22/08/2016 5:22 PM, Sai wrote:

Thanks all for your replies.

I tried to use GDC first, I couldn't find windows binary targeting
windows (for initial testing) which I thought was weird.
https://gdcproject.org/downloads

So I tried to build it in Cygwin env, using these instructions:
http://wiki.dlang.org/GDC/Installation/Generic
(I used gcc-5.2 sources for this).

Unfortunately, it failed with the following error. Any ideas?

I am tempting towards go, looks like their windows binary supports
compiling to both windows and arm. Unfortunately I don't want to use go
as it lacks templates (or generics) and operator overloading, as I tend
to use lot of vector/matrix math in my programs.


gcc/d/dfrontend -Id ../../gcc-5.2.0/gcc/d/dfrontend/filename.c
../../gcc-5.2.0/gcc/d/dfrontend/filename.c: In static member
function ‘static bool FileName::ensurePathExists(const char*)’:
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:602:43: error: ‘sep’
was not declared in this scope
 if (path[strlen(path) - 1] != sep)
   ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:611:21: error: ‘r’
was not declared in this scope
 if (r)
 ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:616:25: error:
‘errno’ was not declared in this scope
 if (errno != EEXIST)
 ^
../../gcc-5.2.0/gcc/d/dfrontend/filename.c:616:34: error:
‘EEXIST’ was not declared in this scope
 if (errno != EEXIST)
  ^
make[2]: *** [../../gcc-5.2.0/gcc/d/Make-lang.in:115:
d/filename.o] Error 1
make[2]: *** Waiting for unfinished jobs
rm gcc.pod gdc.pod
make[2]: Leaving directory '/home/sai/gdc/objdir/gcc'
make[1]: *** [Makefile:4127: all-gcc] Error 2
make[1]: Leaving directory '/home/sai/gdc/objdir'
make: *** [Makefile:867: all] Error 2


I've seen that error before, specifically not finding errno. If I 
remember right its not using the right c++ language version. That is 
what you should try and Google. I would do it myself but I can't right 
this minute.




Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
1) If using the GC, but for whatever reason, I need to free 
something _right now_, is core.GC.free() the proper way to do 
this?


The main problem is that `new` does not necessarily give you a 
pointer to the start of an allocation, and `GC.free()` does not 
work if you give it a pointer to the interior of an allocated 
block.


You could use `GC.addrOf()` to get the base address from an 
interior pointer, but I don't know whether there could be other 
objects/arrays sharing the same memory block.


If you explicitly allocated the memory block yourself with 
`GC.malloc()` then you have full control over what is placed in 
it and can safely `GC.free()` the memory using the base address.


Keep in mind, `GC.free()` does not call finalisers.


Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 18:31:26 UTC, Zane wrote:
I see - That makes sense, but is there no way to "pause/stop" 
the GC, but still be able to use the 'new' syntax?


Oh you can use `new` when the GC is disabled, no problem. All the 
GC's functionality is still available.


But be careful about what I said with `new` not returning the 
base of the allocation. It might not be safe to explicitly 
`free()` memory allocated by `new` if there could be multiple 
objects in the same memory block. I honestly don't know the facts 
about this.


You can always `GC.free()` memory you've allocated yourself with 
`GC.malloc()`, so malloc+emplace is an option. You could define a 
template to give more convenient syntax.


Also I think you can overload the `new` operator. I've never 
tried it.


Regarding the marking, I guess my question is: what must be 
done to ensure something allocated with 'new' will be a 
candidate for auto-collection later (when GC is enabled)?


I don't think it's possible with a conservative garbage 
collector, because anything that looks like a pointer to your 
object can prevent it from being collected.


However, if there are no actual live pointers to it, the chances 
that it will be collected are very high, especially on 64-bit 
systems.


So for now, your best bet is to make sure your object is not 
accessible (set all live pointers to it to null). It will only 
stay in memory if you're very unlucky.


Once we have a precise garbage collector (should be soon) you can 
be sure an object will get collected if it is not accessible from 
any live pointers.


--

By the way, when I say "live pointer", I mean a pointer which is 
accessible (through any number of indirections) from the memory 
roots.


e.g. If you have a linked list on the heap, with each node 
pointing to the next, but no other pointers to any of the nodes 
(e.g. from the stack) those pointers are not live. The list as a 
whole is not accessible.


Re: Rebind template(bug?)

2016-08-21 Thread Engine Machine via Digitalmars-d-learn

On Sunday, 21 August 2016 at 06:28:25 UTC, Jack Applegame wrote:

On Sunday, 21 August 2016 at 00:06:07 UTC, Engine Machine wrote:

On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:

On 08/21/2016 12:11 AM, Engine Machine wrote:

Is there a way to rebind the arguments of a template?

template foo(X)
{
   // X is like A!(a,b,c)
   Y = Rebind!(X,d,e,f);
   // Y is like A!(d,e,f);
}

foo(A!(a,b,c));

?


template Rebind(alias instance, newArgs...)
{
import std.traits: TemplateOf;
alias tmpl = TemplateOf!instance;
alias Rebind = tmpl!newArgs;
}


This doesn't work because the rebound type is of type tmpl and 
not the original


e.g.,

Rebind!(T!b, a)

is tmpl!a not T!a.


You are wrong. tmpl is just alias of template T. So tmpl!a and 
T!a are the same type.


alias X = T!(int, short, char);
alias Y = Rebind!(X, short, char, int);
static assert(is(Y == T!(short, char, int))); // passes


I know you like to play the right or wrong game, but did you ever 
learn that a single example does not prove the truth of something?


How about something more complex?

import std.stdio;
import std.meta, std.traits;

class base { }

template Rebind(alias instance, newArgs...)
{
import std.traits: TemplateOf;
alias tmpl = TemplateOf!instance;
static if (newArgs.length > 0)
alias Rebind = tmpl!newArgs;
else
alias Rebind = base;
}

template EraseLast(A...)
{
static if (A.length > 0)
alias EraseLast = Erase!(A[$-1], A);
else
alias EraseLast = base;
}



class T(A...) : Rebind!(T!A, EraseLast!A)
{
int x;
static if (A.length > 0 && A[0] == "Animal")
{
int y;
static if (A.length > 1 && A[1] == "Dog")
{
int z;
static if (A.length > 2 && A[2] == "Pug")
int s;
}

}
}


pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal", "Dog")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : base));
pragma(msg, is(T!("Animal", "Dog") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog") : base));
pragma(msg, is(T!("Animal") : base));

// all true



void main()
{
auto t = new T!("Animal", "Dog", "Pug")();
T!("Animal", "Dog") q = t;
//T!("Animal", "Dog", "Pug") q = t; works but then q is 
not the super of t

t.x = 3;
t.y = 4;
t.z = 6;
t.s = 123;

q.y = 1;
writeln(t, ", ", typeof(t).stringof);
writeln(q, ", ", typeof(q).stringof);
writeln("---");
writeln(t.x);
writeln(t.y);
writeln(t.z);
writeln(t.s);
writeln("---");
writeln(q.x);
writeln(q.y);
writeln(q.z);
writeln("---");
writeln(t.y);
writeln("---");
writeln();
writeln();

}

Since the pragma's are true, it is obvious that the inheritance 
should work chain works. Yet q is not a reference to t as it 
should be, why is this? If aliases were truly aliases as you 
think(your generic response) then it should work because rebind 
and erase only use aliases.













Re: Sequence separation

2016-08-21 Thread Alexandru Ermicioi via Digitalmars-d-learn
On Wednesday, 17 August 2016 at 19:38:22 UTC, Engine Machine 
wrote:
Well, the is does work and that probably is the best solution. 
I don't mind the extra type at this point. Of course, a library 
solution for this type of stuff would be nice. I'd rather not 
have to even use a type but rather use arrays:

[a,b,[c,d]].


Maybe you can use Tuple from std.typecons, instead of custom 
structs, that group the arguments.


Ex:

alias seqWithSubSeq = AliasSeq!(a, b, Tuple!(c, d))

http://dlang.org/phobos/std_typecons.html#.Tuple


Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
5) Is there a way to do simple heap allocation with 'new' while 
ensuring the GC doesn't deallocate until I want it to?


While my earlier suggestion of using malloc/emplace is one 
option, another is to use `GC.addRoot(objPtr)`. It ensures the 
object is never deallocated until you call 
`GC.removeRoot(objPtr)`.


Re: Thread affinity?

2016-08-21 Thread cpupinner via Digitalmars-d-learn

On Wednesday, 4 December 2013 at 23:23:51 UTC, Rob T wrote:

On Wednesday, 4 December 2013 at 08:38:12 UTC, qznc wrote:


You should file an issue [0] as this should actually be in 
core.thread.


[0] https://d.puremagic.com/issues/enter_bug.cgi


I filed an enhancement request for the thread module.

Digging deeper, I notice that module core.sys.posix.pthread is 
missing the affinity related functions, so I'll file that as a 
bug.


--rt


:(

https://issues.dlang.org/show_bug.cgi?id=11686


Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Guillaume Piolat via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:

Hey all,

My knowledge of GCs is limited, but my faith in them (for most 
applications) has greatly increased with advances (like with 
Golang's recent updates). I am now trying to get a better sense 
for the direction D is going regarding memory management, both 
in relation to the GC and without it. Excuse my ignorance, but 
can someone clarify the following for me?


1) If using the GC, but for whatever reason, I need to free 
something _right now_, is core.GC.free() the proper way to do 
this?


If you need to destroy a class object right now, the proper way 
is to call .destroy on it (or use something that uses it like 
Scoped!T, Unique!T, Refcounted!T...).


If you need to destroy a struct object right now, the proper way 
is to end the scope.


If you need to free memory right now, better not allocate it from 
the GC, but instead with malloc/free. The GC does not guarantee 
to collect freed memory when you want.



2) Does calling object.destroy() mean that the object is marked 
for future collection? If not, how can I ensure it is properly 
marked.


Calling .destoy on an object calls its destructor but does not 
mark it for collection.


Objects are collected when they are not reachable anymore.
At this point, the destructor is called if it wasn't already (and 
then the object is overwritten with .init).


Actually you shouldn't have to worry when an object memory is 
collected.



3) How can I mark a non-object for future collection? For 
example, a dynamic array: int[] a = new int[10];. Do I just set 
any references to null?


Yes, it is marked for future collection when it's not reachable 
anymore.


Then again, the GC might not reclaim memory right now because 
it's imprecise and you could have "false pointers".



4) What if I want to immediately deallocate a dynamically 
allocated non-object (such as the dynamic array) - Can I use 
core.GC.free?


I don't know if this will deallocate with 100% certainty.

5) Is there a way to do simple heap allocation with 'new' while 
ensuring the GC doesn't deallocate until I want it to?


Keep a reference somewhere reachable (by default: stack, heap, 
globals: everything is reachable and scanned).




6) If the GC is off, how is allocation/deallocation handled?


If you have called GC.disable, no GC collect is performed on any 
allocation.
This is only suitable if you don't have a long-running software 
that would risk running out of memory.

This is known to speed-up short processes.


Can I still use new for example


You can still use new.


(and how do I dealloc)?


I don't know then if you can deallocate.





Re: Rebind template(bug?)

2016-08-21 Thread Jack Applegame via Digitalmars-d-learn

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
I know you like to play the right or wrong game, but did you 
ever learn that a single example does not prove the truth of 
something?


How about something more complex?
Your demagogy will not help you learn the basics of the D 
language. And you're wrong again, young arrogant padawan.


Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
5) Is there a way to do simple heap allocation with 'new' while 
ensuring the GC doesn't deallocate until I want it to?


I can answer this at least,
If you don't want the GC to ever collect the object itself, 
here's the best way:
Allocate the object with a non-GC allocator (such as std.c.malloc 
), then use `emplace` to construct the object in that memory ( 
http://dlang.org/phobos/std_conv.html#.emplace ).





Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Zane via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:38:09 UTC, Cauterite wrote:

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
5) Is there a way to do simple heap allocation with 'new' 
while ensuring the GC doesn't deallocate until I want it to?


I can answer this at least,
If you don't want the GC to ever collect the object itself, 
here's the best way:
Allocate the object with a non-GC allocator (such as 
std.c.malloc ), then use `emplace` to construct the object in 
that memory ( http://dlang.org/phobos/std_conv.html#.emplace ).


I see - That makes sense, but is there no way to "pause/stop" the 
GC, but still be able to use the 'new' syntax? I like how clear 
the syntax is, I just don't _always_ want the GC. I'm thinking of 
something like:


core.memory.GC.disable();
Obj o = new Obj();
/* ...use o... */
core.memory.GC.free(o); // or whatever

if possible, is there a drawback to this (other than no automatic 
GC) compared to say, malloc?


Regarding the marking, I guess my question is: what must be done 
to ensure something allocated with 'new' will be a candidate for 
auto-collection later (when GC is enabled)?


Re: Rebind template

2016-08-21 Thread Alexandru Ermicioi via Digitalmars-d-learn

On Saturday, 20 August 2016 at 22:18:57 UTC, Engine Machine wrote:
On Saturday, 20 August 2016 at 22:11:40 UTC, Engine Machine 
wrote:

Is there a way to rebind the arguments of a template?

template foo(X)
{
   // X is like A!(a,b,c)
   Y = Rebind!(X,d,e,f);
   // Y is like A!(d,e,f);
}

foo(A!(a,b,c));

?


I'd also be happy if I could just remove the last element from 
A.


template EraseLast(X)
{
// returns A!(a,b) when X = A!(a,b,c)
}


Check for ApplyLeft and ApplyRight in std.meta, maybe it can help 
you.


http://dlang.org/phobos/std_meta.html#.ApplyLeft
http://dlang.org/phobos/std_meta.html#.ApplyRight


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 21 August 2016 at 20:36:54 UTC, Engine Machine wrote:
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta 
wrote:

[...]


You're right. I didn't realize that variables could be shadowed 
in classes. Seems dangerous. D doesn't allow shadowing in a 
normal context and gives an error so I don't know why it 
wouldn't do that in classes. (since it wasn't giving an error I 
thought it wasn't shadowing)


You are right. It is very bad. But as far as I know Java and C++ 
allow this too.
I will open an enhancement request (if there's none about this), 
to gather some feedback on the matter.


Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
2) Does calling object.destroy() mean that the object is marked 
for future collection? If not, how can I ensure it is properly 
marked.


Because the GC is not of the incremental type, it can't perform 
any marking outside of a stop-the-world mark/sweep cycle. 
Instead, what `destroy()` does is finalise an object: that is, 
runs any destructors and puts it in an invalid state — in 
particular, all pointers contained within the object are 
nullified, so it doesn't reference any other objects.


When I say 'object' I mean anything; class instance, structure, 
array, primitive, whatever.


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta 
wrote:

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:

[...]


The problem of this code has nothing to do with aliases. They 
work correctly. The problem is variable shadowing. In the 
following code, Child has two x variables, one of which is only 
accessible from a Parent reference, the other only from a Child 
reference.


class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}

void main()
{
Child child = new Child();
Parent parent = child;

child.x = child.y = 3;
parent.x = 2;

assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);

assert(parent is child); // same object (remember that a 
class is already a pointer);
assert( != ); // but there are two different 
pointers on the stack (pointing to the same object)

}


A patch to your code that makes it work, with the parts not 
displayed unchanged:


class base
{
int x;
}

class T(A...) : Rebind!(T!A, EraseLast!A)
{
static if(A[$-1] == "Animal")
int y;
else static if (A[$-1] == "Dog")
int z;
else static if (A[$-1] == "Pug")
int s;
}


Re: Rebind template(bug?)

2016-08-21 Thread Engine Machine via Digitalmars-d-learn
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta 
wrote:

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:

[...]


The problem of this code has nothing to do with aliases. They 
work correctly. The problem is variable shadowing. In the 
following code, Child has two x variables, one of which is only 
accessible from a Parent reference, the other only from a Child 
reference.


class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}

void main()
{
Child child = new Child();
Parent parent = child;

child.x = child.y = 3;
parent.x = 2;

assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);

assert(parent is child); // same object (remember that a 
class is already a pointer);
assert( != ); // but there are two different 
pointers on the stack (pointing to the same object)

}


You're right. I didn't realize that variables could be shadowed 
in classes. Seems dangerous. D doesn't allow shadowing in a 
normal context and gives an error so I don't know why it wouldn't 
do that in classes. (since it wasn't giving an error I thought it 
wasn't shadowing)







Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Sunday, 21 August 2016 at 16:14:53 UTC, Zane wrote:
6) If the GC is off, how is allocation/deallocation handled? 
Can I still use new for example (and how do I dealloc)?


All the allocation/deallocation functionality is the same as 
normal, except the GC won't start a collection cycle unless it's 
out of memory.


You can still use `free()` to deallocate, and it will free memory 
straight away.


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:

[...]


The problem of this code has nothing to do with aliases. They 
work correctly. The problem is variable shadowing. In the 
following code, Child has two x variables, one of which is only 
accessible from a Parent reference, the other only from a Child 
reference.


class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}

void main()
{
Child child = new Child();
Parent parent = child;

child.x = child.y = 3;
parent.x = 2;

assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);

assert(parent is child); // same object (remember that a 
class is already a pointer);
assert( != ); // but there are two different 
pointers on the stack (pointing to the same object)

}



Re: Mem Mgmt: With & Without the GC

2016-08-21 Thread Zane via Digitalmars-d-learn
Thanks to both of you. I think that answers everything, except if 
new'd objects can be freed when GC is disabled. I guess I could 
always enable and call collect().


How to avoid ctRegex (solved)

2016-08-21 Thread cy via Digitalmars-d-learn
At seconds PER (character range) pattern, ctRegex slows down 
compilation like crazy, but it's not obvious how to avoid using 
it, since Regex(Char) is kind of weird for a type. So, here's 
what I do. I think this is right.


in the module scope, you start with:
auto pattern = ctRegex!"foobar";

and you substitute with:
typeof(regex("")) pattern;
static this() {
  pattern = regex("foobar");
}

That way you don't have to worry about whether to use a 
Regex!char, or a Regex!dchar, or a Regex!ubyte. It gives you the 
same functionality, at the cost a few microseconds slowdown on 
running your program. And once you're done debugging, you can 
always switch back, so...


string defineRegex(string name, string pattern)() {
  import std.string: replace;
  return q{
debug {
pragma(msg, "fast $name");
import std.regex: regex;
typeof(regex("")) $name;
static this() {
$name = regex(`$pattern`);
}
} else {
pragma(msg, "slooow $name");
import std.regex: ctRegex;
auto $name = ctRegex!`$pattern`;
}
}.replace("$pattern",pattern)
.replace("$name",name);
}

mixin(defineRegex!("naword",r"[\W]+"));
mixin(defineRegex!("alnum",r"[a-zA-Z]+"));
mixin(defineRegex!("pattern","foo([a-z]*?)bar"));
mixin(defineRegex!("pattern2","foobar([^0-9z]+)"));

void main() {
}

/*
$ time rdmd -release /tmp/derp.d
slooow naword
slooow alnum
slooow pattern
slooow pattern2
slooow naword
slooow alnum
slooow pattern
slooow pattern2
rdmd -release /tmp/derp.d  17.57s user 1.57s system 82% cpu 
23.210 total


$ time rdmd -debug /tmp/derp.d
fast naword
fast alnum
fast pattern
fast pattern2
fast naword
fast alnum
fast pattern
fast pattern2
rdmd -debug /tmp/derp.d  2.92s user 0.37s system 71% cpu 4.623 
total

*/

...sure would be nice if you could cache precompiled regular 
expressions as files.


Re: Rebind template(bug?)

2016-08-21 Thread ag0aep6g via Digitalmars-d-learn

On 08/21/2016 09:29 PM, Engine Machine wrote:

I know you like to play the right or wrong game, but did you ever learn
that a single example does not prove the truth of something?


But you can show in a single example that something doesn't work. You 
tried to do that, and you did it with a simple example, which is always 
appreciated. But apparently, you were wrong. Happens to the best. And 
when the compiler prints "tmpl!a" that's indeed a little misleading.


You being wrong there doesn't mean that the Rebind template as I posted 
it works correctly, of course. But Jack didn't claim that. He just said 
that your example for how it doesn't work is wrong. And as far as I see, 
Rebind does work as expected. But I wouldn't be surprised if there is 
some edge case where things fall apart.


Also, if you're looking for help or civil discussion, I suggest you try 
a less antagonistic approach. Things like "I know you like to [play 
games]" and "did you ever learn [whatever]" do not set the tone for that.



How about something more complex?

import std.stdio;
import std.meta, std.traits;

class base { }


Style nitpick: Class names in PascalCase, please.


template Rebind(alias instance, newArgs...)
{
import std.traits: TemplateOf;
alias tmpl = TemplateOf!instance;
static if (newArgs.length > 0)
alias Rebind = tmpl!newArgs;
else
alias Rebind = base;
}

template EraseLast(A...)
{
static if (A.length > 0)
alias EraseLast = Erase!(A[$-1], A);


This line can be simplified: alias EraseLast = A[0 .. $ - 1];


else
alias EraseLast = base;


This is quite surprising for a template that's called "EraseLast". I 
renamed it to "EraseLastOrBase" for myself when looking at this.



}



class T(A...) : Rebind!(T!A, EraseLast!A)


The core idea of Rebind isn't needed here, is it? You've got T, so you 
can just pass it directly. No need to extract it from T!A.


So, instead of using some form of Rebind, you can use a simpler template:


/* Instantiates tmpl with args, or if no args given, returns base. */
template InstantiateOrBase(alias tmpl, args ...)
{
static if (args.length == 0) alias InstantiateOrBase = base;
else alias InstantiateOrBase = tmpl!args;
}

class T(A...) : InstantiateOrBase!(T, EraseLast!A)



{
int x;


Note that this means that every instantiation of T brings its own x. 
That is, T!foo declares an x, and T!(foo, bar) which inherits from T!foo 
adds another x. The same happens with y, z, and s, of course.



static if (A.length > 0 && A[0] == "Animal")
{
int y;
static if (A.length > 1 && A[1] == "Dog")
{
int z;
static if (A.length > 2 && A[2] == "Pug")
int s;
}

}
}


pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal", "Dog")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : base));
pragma(msg, is(T!("Animal", "Dog") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog") : base));
pragma(msg, is(T!("Animal") : base));


Asserts are great to show that something holds. When someone like me 
makes changes to your code in order to understand it, the complier 
throws a nice loud error in their face when they mess up. So I changed 
these to static asserts for myself.



// all true



void main()
{
auto t = new T!("Animal", "Dog", "Pug")();
T!("Animal", "Dog") q = t;
//T!("Animal", "Dog", "Pug") q = t; works but then q is not the
super of t
t.x = 3;
t.y = 4;
t.z = 6;
t.s = 123;

q.y = 1;
writeln(t, ", ", typeof(t).stringof);
writeln(q, ", ", typeof(q).stringof);
writeln("---");
writeln(t.x);
writeln(t.y);
writeln(t.z);
writeln(t.s);
writeln("---");
writeln(q.x);
writeln(q.y);
writeln(q.z);
writeln("---");
writeln(t.y);
writeln("---");
writeln();
writeln();

}

Since the pragma's are true, it is obvious that the inheritance should
work chain works. Yet q is not a reference to t as it should be, why is
this?


It would help a lot if you would point out what parts of the output are 
surprising to you. If you let the reader figure it out themselves, 
chances are 1) people are not going to bother, and 2) if they do bother, 
they might miss your point.


Labeling the output also helps. By that I mean, if you write 
`writeln("t.x: ", t.x);`, the output can be read much more easily. I 
also think that you could have made your point with less output, which 
would again make it easier to follow. That is, just looking t.x/q.x 
would have been enough, no?


I guess you expect q.x and friends to be the same as t.x and friends. 
And since you put it there, you may also expect  to be the same as 


About the members being different: That's because every instantiation 
brings its own x/y/z, as mentioned above. Lodovico has shown what 
happens here in his Child/Parent example.


About  and : Those are the 

Is there a d analog of strncmp?

2016-08-21 Thread dan via Digitalmars-d-learn
In c, there's this very nice function strncmp(s1,s2,count) which 
compares two c strings, using at most count characters.  count 
can be less than, more than, or equal to either or both of the 
lengths of the two strings.  It can be used to see if two 
c-strings have the same prefix of some length.


Now, strncmp indeed seems to be packaged up in core.stdc.string, 
but i would like to use some something like it on 2 d strings 
(which, as i understand it, need not be zero-terminated).


I suppose it would be possible to do some conversion with 
toStringz() or something and then invoke the strncmp(), but that 
seems very wordy and also it's not clear that it would handle all 
pairs of d strings (e.g., what if there were some 0's in the 
first count characters?).


So i would like to call a d function which works on d strings, 
but don't want to write my own if one already exists.  (At the 
very least, i'd have to get a much sharper understanding of d 
strings, whether internal 0's can occur, etc.  And i would not 
want to do egregious string allocation.)


TIA for any info!




Re: Creating an array of user-defined structs

2016-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 21 August 2016 at 23:57:27 UTC, brian wrote:
I understand it's a map, but does my syntax not define an 
Associative Array??


yeah, it is. If that's what you want, good!


So I wanted something dynamic.


OK, then you should use pointers so you can have several 
references to the same object in different maps (so you can have 
one for ID, one for name, etc.).


Just make it

testStruct*[int] testStructArray;

and then try compiling the rest basically as it is, newing the 
struct, it should work.


Re: Is there a d analog of strncmp?

2016-08-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, August 22, 2016 00:14:31 Adam D. Ruppe via Digitalmars-d-learn 
wrote:
> int strncmp(string a, string b, int n) {
>   if(a.length > n)
>   a = a[0 .. n];
>   if(b.length > n)
>   b = b[0 .. n];
>   import std.algorithm.comparison : cmp;
>   return cmp(a, b);
> }

Aside from the imports, it can be turned into a one-liner if you use take:

return cmp(take(a, n), take(b, n));

- Jonathan M Davis



Re: Is there a d analog of strncmp?

2016-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn

int strncmp(string a, string b, int n) {
if(a.length > n)
a = a[0 .. n];
if(b.length > n)
b = b[0 .. n];
import std.algorithm.comparison : cmp;
return cmp(a, b);
}


Re: Rebind template(bug?)

2016-08-21 Thread Engine Machine via Digitalmars-d-learn

On Sunday, 21 August 2016 at 21:11:37 UTC, ag0aep6g wrote:

On 08/21/2016 09:29 PM, Engine Machine wrote:
I know you like to play the right or wrong game, but did you 
ever learn

that a single example does not prove the truth of something?


But you can show in a single example that something doesn't 
work. You tried to do that, and you did it with a simple 
example, which is always appreciated. But apparently, you were 
wrong. Happens to the best. And when the compiler prints 
"tmpl!a" that's indeed a little misleading.


You being wrong there doesn't mean that the Rebind template as 
I posted it works correctly, of course. But Jack didn't claim 
that. He just said that your example for how it doesn't work is 
wrong. And as far as I see, Rebind does work as expected. But I 
wouldn't be surprised if there is some edge case where things 
fall apart.


Also, if you're looking for help or civil discussion, I suggest 
you try a less antagonistic approach. Things like "I know you 
like to [play games]" and "did you ever learn [whatever]" do 
not set the tone for that.



How about something more complex?

import std.stdio;
import std.meta, std.traits;

class base { }


Style nitpick: Class names in PascalCase, please.


template Rebind(alias instance, newArgs...)
{
import std.traits: TemplateOf;
alias tmpl = TemplateOf!instance;
static if (newArgs.length > 0)
alias Rebind = tmpl!newArgs;
else
alias Rebind = base;
}

template EraseLast(A...)
{
static if (A.length > 0)
alias EraseLast = Erase!(A[$-1], A);


This line can be simplified: alias EraseLast = A[0 .. $ - 1];


else
alias EraseLast = base;


This is quite surprising for a template that's called 
"EraseLast". I renamed it to "EraseLastOrBase" for myself when 
looking at this.



}



class T(A...) : Rebind!(T!A, EraseLast!A)


The core idea of Rebind isn't needed here, is it? You've got T, 
so you can just pass it directly. No need to extract it from 
T!A.


So, instead of using some form of Rebind, you can use a simpler 
template:



/* Instantiates tmpl with args, or if no args given, returns 
base. */

template InstantiateOrBase(alias tmpl, args ...)
{
static if (args.length == 0) alias InstantiateOrBase = base;
else alias InstantiateOrBase = tmpl!args;
}

class T(A...) : InstantiateOrBase!(T, EraseLast!A)



{
int x;


Note that this means that every instantiation of T brings its 
own x. That is, T!foo declares an x, and T!(foo, bar) which 
inherits from T!foo adds another x. The same happens with y, z, 
and s, of course.



static if (A.length > 0 && A[0] == "Animal")
{
int y;
static if (A.length > 1 && A[1] == "Dog")
{
int z;
static if (A.length > 2 && A[2] == "Pug")
int s;
}

}
}


pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal", 
"Dog")));

pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : base));
pragma(msg, is(T!("Animal", "Dog") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog") : base));
pragma(msg, is(T!("Animal") : base));


Asserts are great to show that something holds. When someone 
like me makes changes to your code in order to understand it, 
the complier throws a nice loud error in their face when they 
mess up. So I changed these to static asserts for myself.



// all true



void main()
{
auto t = new T!("Animal", "Dog", "Pug")();
T!("Animal", "Dog") q = t;
//T!("Animal", "Dog", "Pug") q = t; works but then q 
is not the

super of t
t.x = 3;
t.y = 4;
t.z = 6;
t.s = 123;

q.y = 1;
writeln(t, ", ", typeof(t).stringof);
writeln(q, ", ", typeof(q).stringof);
writeln("---");
writeln(t.x);
writeln(t.y);
writeln(t.z);
writeln(t.s);
writeln("---");
writeln(q.x);
writeln(q.y);
writeln(q.z);
writeln("---");
writeln(t.y);
writeln("---");
writeln();
writeln();

}

Since the pragma's are true, it is obvious that the 
inheritance should
work chain works. Yet q is not a reference to t as it should 
be, why is

this?


It would help a lot if you would point out what parts of the 
output are surprising to you. If you let the reader figure it 
out themselves, chances are 1) people are not going to bother, 
and 2) if they do bother, they might miss your point.


Labeling the output also helps. By that I mean, if you write 
`writeln("t.x: ", t.x);`, the output can be read much more 
easily. I also think that you could have made your point with 
less output, which would again make it easier to follow. That 
is, just looking t.x/q.x would have been enough, no?


I guess you expect q.x and friends to be the same as t.x and 
friends. And since you put it there, you may also expect  to 
be the same as 


About the members being different: That's because every 
instantiation brings its own x/y/z, as mentioned above. 
Lodovico has 

Re: Creating an array of user-defined structs

2016-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 21 August 2016 at 23:28:14 UTC, brian wrote:

/* creates(?) an empty array of structs */
testStruct[int] testStructArray;


That's not actually an array per se, that is a key/value map 
where the keys are ints.


So you can set values to it at any position in it but not append 
or do other traditional array operations.


An ordinary array is defined with

testStruct[] testStructArray;


though what you have isn't necessarily wrong.


auto newStruct = new testStruct;


This is the cause of the pointer mismatch error - new struct 
returns a pointer to it. If you just want an ordinary struct you 
define it:


testStruct newStruct;

like that.


newStruct.aa = a.dup;
newStruct.bb = b.dup;


No need for the .dup there because strings aren't going to be 
changing under you anyway.



1) I'm assuming by the error that line 23 defines a pointer 
rather than a ... not-pointer thing. I'm not sure why it is 
doing that, and would like some explanation please. :)


It is just how new works in D, it returns a reference. For 
structs, that means a pointer to it.


2) Is this the best way to do what I am trying to do, which is 
dynamically grow an array of user defined structs?


Either do a traditional array and copy struct values onto it or 
do an array of pointers and new them. Which option is bsed 
depends on the details of what you're doing.


Re: Creating an array of user-defined structs

2016-08-21 Thread brian via Digitalmars-d-learn

Thanks Adam.

Couple of follow up questions, if you don't mind:

On Sunday, 21 August 2016 at 23:37:38 UTC, Adam D. Ruppe wrote:

testStruct[int] testStructArray;
That's not actually an array per se, that is a key/value map 
where the keys are ints.
I understand it's a map, but does my syntax not define an 
Associative Array?? https://dlang.org/spec/hash-map.html
That's kinda what I wanted because I want to be able to look up 
the Structs by the value of int.


Either do a traditional array and copy struct values onto it or 
do an array of pointers and new them. Which option is bsed 
depends on the details of what you're doing.


This was a simple example of what I wanted to illustrate the 
problem. What I probably want for my future program state is some 
sort of hash map, as I'll be using this "array" as a lookup table.

So conceptually something like:

userid | username | structs

0001   | brian| structAboutBrian
0002   | john | structAboutJohn

I probably want to be able to look up info using either userid, 
or username, but I can settle for one of them
I'm creating the entries during execution of the program, so I 
have no idea how big the structure is going to be. So I wanted 
something dynamic.


I'm a bit of a novice in terms of theoretical comp sci, so I'm 
not sure what data structure would be best suited to something 
like that, or how to implement. Happy to take advice. :)


Re: Rebind template(bug?)

2016-08-21 Thread ag0aep6g via Digitalmars-d-learn

On 08/22/2016 12:06 AM, Engine Machine wrote:

T!()'s "data" is specified in the class just like all the other
derivations. I don't want to have to specify an external base class as
in your InstaniateOrBase. Why? Because!!! (There should be no need to,
and if one goes this route of creating classes, it should be all or
nothing, else there is no real benefit)


You make it sound like I came up with the external base class, but I 
just took that from your code.


[...]

It seems that when one uses `class T(A...) : X`, one can't, for some X,
not have inheritance. The compiler expects X to be something inheritable
from no matter what.


I didn't know it, but your code shows that X can also be an empty 
compile time list (Seq). I have no idea if this is in the spec, or if it 
just happens to work with dmd.


If it's valid D, you just need a template that goes from T and A to 
T!(A[0 .. $ - 1]), or if A is already empty, to the empty Seq.


Like so:


template InstantiateOrEmptySeq(alias tmpl, args...)
{
alias Seq(T...)=T;
static if (args.length > 0)
alias InstantiateOrEmptySeq = tmpl!(args[0 .. $ - 1]);
else
alias InstantiateOrEmptySeq = Seq!();
}

class T(A...) : InstantiateOrEmptySeq!(T, A)
{
...
}





Re: Rebind template(bug?)

2016-08-21 Thread Engine Machine via Digitalmars-d-learn

On Monday, 22 August 2016 at 00:22:48 UTC, ag0aep6g wrote:

On 08/22/2016 12:06 AM, Engine Machine wrote:

T!()'s "data" is specified in the class just like all the other
derivations. I don't want to have to specify an external base 
class as
in your InstaniateOrBase. Why? Because!!! (There should be no 
need to,
and if one goes this route of creating classes, it should be 
all or

nothing, else there is no real benefit)


You make it sound like I came up with the external base class, 
but I just took that from your code.


No, what I meant was I don't want a base. I only added it in my 
code so it would compile/do what I want.



[...]
It seems that when one uses `class T(A...) : X`, one can't, 
for some X,
not have inheritance. The compiler expects X to be something 
inheritable

from no matter what.


I didn't know it, but your code shows that X can also be an 
empty compile time list (Seq). I have no idea if this is in the 
spec, or if it just happens to work with dmd.


If it's valid D, you just need a template that goes from T and 
A to T!(A[0 .. $ - 1]), or if A is already empty, to the empty 
Seq.


Like so:


template InstantiateOrEmptySeq(alias tmpl, args...)
{
alias Seq(T...)=T;
static if (args.length > 0)
alias InstantiateOrEmptySeq = tmpl!(args[0 .. $ - 1]);
else
alias InstantiateOrEmptySeq = Seq!();
}

class T(A...) : InstantiateOrEmptySeq!(T, A)
{
...
}



Yes! I though I tried that from Timon's original solution.

The following code works and does what I want!

template InstantiateOrEmptySeq(alias tmpl, args...)
{
alias Seq(T...)=T;
static if (args.length > 0)
alias InstantiateOrEmptySeq = tmpl!(args[0 .. $-1]);
else
alias InstantiateOrEmptySeq = Seq!();
}


class T(A...) : InstantiateOrEmptySeq!(T, A)
{   
static if (A.length == 0)
{
// Base class
int x;
} else  
static if (A[$-1] == "Animal")
{
int y;
} else
static if (A[$-1] == "Dog")
{
int z;
} else
static if (A[$-1] == "Pug")
{
int s;
	} else static assert(A[$-1]~" not a defined class of 
"~this.stringof);

}

The only down side is that the static if's are flat. They don't 
show the relationship between, say, Dog an Animal, that a nested 
set of static if's would show, but I think this is not possible 
due to the recursion and shadowing(I imagine one could test if 
the variables exist but that is messy).


Anyways, Thanks for the help.

I think this is just Timons answer anyways. What the original 
confusion was, was the shadowing, which I thought would not 
happen(or at least expected an error), Lodovico solved that.







Is it's possible to install DMD/LDC/GDC on CoreOS?

2016-08-21 Thread Suliman via Digitalmars-d-learn
I would like to create small VPS instance with Linux distrib on 
VPS. Can I use CoreOS as image? Would it possible to install 
dlang there?


Re: Rebind template

2016-08-21 Thread Jack Applegame via Digitalmars-d-learn

On Sunday, 21 August 2016 at 00:06:07 UTC, Engine Machine wrote:

On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:

On 08/21/2016 12:11 AM, Engine Machine wrote:

Is there a way to rebind the arguments of a template?

template foo(X)
{
   // X is like A!(a,b,c)
   Y = Rebind!(X,d,e,f);
   // Y is like A!(d,e,f);
}

foo(A!(a,b,c));

?


template Rebind(alias instance, newArgs...)
{
import std.traits: TemplateOf;
alias tmpl = TemplateOf!instance;
alias Rebind = tmpl!newArgs;
}


This doesn't work because the rebound type is of type tmpl and 
not the original


e.g.,

Rebind!(T!b, a)

is tmpl!a not T!a.


You are wrong. tmpl is just alias of template T. So tmpl!a and 
T!a are the same type.


alias X = T!(int, short, char);
alias Y = Rebind!(X, short, char, int);
static assert(is(Y == T!(short, char, int))); // passes



Re: Is it's possible to install DMD/LDC/GDC on CoreOS?

2016-08-21 Thread David Nadlinger via Digitalmars-d-learn

On Sunday, 21 August 2016 at 11:38:09 UTC, Suliman wrote:
I would like to create small VPS instance with Linux distrib on 
VPS. Can I use CoreOS as image? Would it possible to install 
dlang there?


For LDC, you can just download the latest release from 
https://github.com/ldc-developers/ldc/releases and you are good 
to go.


Just make sure you have "gcc" available on your system for 
linking.


 — David


Re: Is it's possible to install DMD/LDC/GDC on CoreOS?

2016-08-21 Thread Seb via Digitalmars-d-learn

On Sunday, 21 August 2016 at 11:38:09 UTC, Suliman wrote:
I would like to create small VPS instance with Linux distrib on 
VPS. Can I use CoreOS as image? Would it possible to install 
dlang there?


An alternative would be to compile your application locally, then 
copy it over to your container. I don't know how similar CoreOs 
to a typical Linux distribution is, but if it comes with the 
typical shared libraries (libm.so, libc.so, lipthread.so), this 
should be possible ;-)


Re: Is it's possible to install DMD/LDC/GDC on CoreOS?

2016-08-21 Thread David Nadlinger via Digitalmars-d-learn

On Sunday, 21 August 2016 at 14:57:15 UTC, Seb wrote:
An alternative would be to compile your application locally, 
then copy it over to your container. I don't know how similar 
CoreOs to a typical Linux distribution is, but if it comes with 
the typical shared libraries (libm.so, libc.so, lipthread.so), 
this should be possible ;-)


LDC also allows you to create fully statically linked executables 
(-static). It allows you to sidestep issues with shared library 
version incompatibilities, but of course there has been a few 
technical issues and lot more politicking regarding fully 
statically linked executables on Linux.


 — David


Re: Is it's possible to install DMD/LDC/GDC on CoreOS?

2016-08-21 Thread Seb via Digitalmars-d-learn

On Sunday, 21 August 2016 at 15:25:59 UTC, David Nadlinger wrote:

On Sunday, 21 August 2016 at 14:57:15 UTC, Seb wrote:
An alternative would be to compile your application locally, 
then copy it over to your container. I don't know how similar 
CoreOs to a typical Linux distribution is, but if it comes 
with the typical shared libraries (libm.so, libc.so, 
lipthread.so), this should be possible ;-)


LDC also allows you to create fully statically linked 
executables (-static). It allows you to sidestep issues with 
shared library version incompatibilities, but of course there 
has been a few technical issues and lot more politicking 
regarding fully statically linked executables on Linux.


 — David



Oh I totally forgot about this, despite I think it's a great 
feature.
Btw @Suliman fully static linking with LDC is used for the DLang 
Tour, which is built with Vibe.d and deployed using a docker 
container (based on busybox). Maybe that's worth looking at:


https://github.com/stonemaster/dlang-tour/blob/master/Dockerfile
https://github.com/stonemaster/dlang-tour/blob/master/dub.sdl
https://github.com/stonemaster/dlang-tour/blob/master/.travis.yml

(it adds a bit more, because the dockerized DLang Tour runs 
docker containers for each run)


Mem Mgmt: With & Without the GC

2016-08-21 Thread Zane via Digitalmars-d-learn

Hey all,

My knowledge of GCs is limited, but my faith in them (for most 
applications) has greatly increased with advances (like with 
Golang's recent updates). I am now trying to get a better sense 
for the direction D is going regarding memory management, both in 
relation to the GC and without it. Excuse my ignorance, but can 
someone clarify the following for me?


1) If using the GC, but for whatever reason, I need to free 
something _right now_, is core.GC.free() the proper way to do 
this?


2) Does calling object.destroy() mean that the object is marked 
for future collection? If not, how can I ensure it is properly 
marked.


3) How can I mark a non-object for future collection? For 
example, a dynamic array: int[] a = new int[10];. Do I just set 
any references to null?


4) What if I want to immediately deallocate a dynamically 
allocated non-object (such as the dynamic array) - Can I use 
core.GC.free?


5) Is there a way to do simple heap allocation with 'new' while 
ensuring the GC doesn't deallocate until I want it to?


6) If the GC is off, how is allocation/deallocation handled? Can 
I still use new for example (and how do I dealloc)?


Thank you for any help you can provide.