Re: cannot implicitly convert char[] to string

2015-08-15 Thread Ali Çehreli via Digitalmars-d-learn

On 08/15/2015 04:45 AM, cym13 wrote:

 On Saturday, 15 August 2015 at 11:34:01 UTC, cym13 wrote:
 On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
 I made a PR to phobos where I modified `std.format.format`.
 https://github.com/D-Programming-Language/phobos/pull/3528

 However the auto builder fails, with the error message:
 runnable/test23.d(1219): Error: cannot implicitly convert expression
 (format(s = %s, s)) of type char[] to string

 The line which fails is `p = std.string.format(s = %s, s);`

 I don't understand why I can't convert a char[] to string.

 I think it has to do with the fact that string is an alias to
 immutable(char)[]   and you can't implicitely cast an immutable to a
 regular variable.

That's actually correct (for reference types). As long as there is no 
indirection, a value type can be casted implicitly:


struct S
{
int i;
}

void main()
{
auto i = immutable(S)();
auto m = S();

m = i;// copied; fine
}

 I phrased it completely wrong, an example will be better :

  import std.stdio;

  void fun(immutable(int)[] i) {
  i.writeln();
  }

  void main() {
  int[] i = [42];
  fun(i);
  }

 Will not compile because there is no certainty that fun() won't
 change the array

Actually, that's the job of 'const'. Here, it is not fun's ability to 
mutate but the caller's. 'immutable' on a function interface means a 
requirement: The caller *must* provide immutable data so that the 
function can rely on it not being changed by anyone.


Ali



Re: Template Collections of Different Types

2015-08-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 16 August 2015 at 02:42:18 UTC, BBasile wrote:

---
enum Ti {tibyte, tiubyte, ...}
Ti getTypeInfo(T)(T t){statif is(t == ubyte) return Ti.tibyte; 
else...}


You could also just use D's own run time typeinfo with the 
typeid() thing. It returns an instance of class TypeInfo. (This 
is what std.variant does btw)


Re: Use members of a Named Enum without using Enum name?

2015-08-15 Thread Ali Çehreli via Digitalmars-d-learn

On 08/15/2015 09:22 AM, QuizzicalFella wrote:

On Saturday, 15 August 2015 at 15:53:23 UTC, Adam D. Ruppe wrote:

On Saturday, 15 August 2015 at 15:37:42 UTC, QuizzicalFella wrote:

I'd like to be able to call someFunc(TRIANGLE) rather than
someFunc(PolygonT.TRIANGLE).


Two options come to mind:

alias TRIANGLE = PolygonT.TRIANGLE;
// etc


...if I wanted to write a mixin that iterated over all the elements in
an enum, how would I get a member to print its name without the type?
And how do I get the type to print itself?

foreach(member; enum)
 char[] output ~= alias
~member.name~=~enum.name~.~member.name~;




Fundamentally, __traits(allMembers) and .stringof but the following 
enumMembers present them as a range:


import std.stdio;

enum PolygonT : byte { TRIANGLE, RECTANGLE, STAR }

auto enumMembers(E)()
{
import std.conv : to;
import std.algorithm : map;

return [ __traits(allMembers, E) ].map!(a = a.to!string);
}

void info(E)()
{
writefln(The members of %s: %-(%s, %),
 E.stringof, enumMembers!PolygonT);
}

void main()
{
info!PolygonT();
}

Ali



Re: Template Collections of Different Types

2015-08-15 Thread BBasile via Digitalmars-d-learn

On Sunday, 16 August 2015 at 01:39:54 UTC, DarthCthulhu wrote:

Say I want to do something like:

Propertery!int pi = 42;
PropertyCollection pc;

pc.attach(Life_and_Everything, pi);

assert(pc.Life_and_Everything == 42);

Property!string ps = Hello World;

pc.attach(text, ps);

assert(pc.text == Hello World);

How would one store the Property objects in the 
PropertyCollection? You can't use something like an array 
because the two Properties are of different types. Do you 
really need to do something like make a member of 
PropertyCollection for every type of Property you are 
interested in storing and using static ifs to determine which 
variable it goes into?


I feel like there is an obvious solution here that I'm missing.


You would need a kind of type info system:

---
enum Ti {tibyte, tiubyte, ...}
Ti getTypeInfo(T)(T t){statif is(t == ubyte) return Ti.tibyte; 
else...}


pc.attach(Life_and_Everything, pi, getTypeInfo(pi));
pc.attach(BlaBlaBla, pi, getTypeInfo(pi));
pc.attach(zkfozekf, 42, getTypeInfo(42));
---

internally the container would store 3 infos (string, pointer to 
data and a Ti) and when you query a property from its identifier, 
it looks for the attached type info so that you can cast the 
result (let's say it would return a pointer).


---
TypeInfo getTypeInfo(string identifier);
void* getValue(string identifier);
---

These kind of mechanism are really common in languages that have 
a poor/none compile time reflection features, but in D you would 
have to build your own run time type info system. My example is a 
bit shitty but you should get the idea.


Re: Attributes not propagating to objects via typeinfo?

2015-08-15 Thread rsw0x via Digitalmars-d-learn

On Friday, 14 August 2015 at 15:39:39 UTC, Timon Gehr wrote:
I don't understand. It is evidently fixable. E.g. if TypeInfo 
was just a template without the mostly redundant additional 
compiler support, this would be a trivial fix.


It appears that this was suggested already after a bit of digging 
but nobody cares to fix it. IMO, compiler handles far too much 
stuff that should be in the runtime.


Re: Template Collections of Different Types

2015-08-15 Thread DarthCthulhu via Digitalmars-d-learn

On Sunday, 16 August 2015 at 01:51:36 UTC, Adam D. Ruppe wrote:

On Sunday, 16 August 2015 at 01:39:54 UTC, DarthCthulhu wrote:
How would one store the Property objects in the 
PropertyCollection?


You don't, not like that anyway. The attach call is the ruin of 
it. If it was all one definition, you could use something like 
std.typecons.Tuple, but multiple calls to attach need to be a 
runtime function, which means what you attach will lose the 
compile time type when you get it.




I see. Yeah, I thought that might be the case. Nice to know I 
wasn't just being ignorant.


That would work. You could write a plain struct definition and 
then the attach could be implemented as a allMembers/getMember 
assignment loop, similarly to this:

http://stackoverflow.com/questions/31993705/d-call-a-function-using-a-string-variable-with-its-name/31996526#31996526

but looking at data member assignments instead of method calls.




Oh, neat! Thanks!

Incidentally, I watched your dconf2015 talk Dynamic Types in D. 
That (along with Andrei's Generic Programming Must Go) actually 
inspired me to think about this particular problem. It's very 
appropriate that you would have the solution, then!




Re: using memset withing a pure function

2015-08-15 Thread anonymous via Digitalmars-d-learn

On Saturday, 15 August 2015 at 19:50:56 UTC, Temtaime wrote:

There's a problem with « dst[0 .. n] = val; ».
It should be « dst[0 .. n][] = val; »


No, you don't need the `[]`.


Template Collections of Different Types

2015-08-15 Thread DarthCthulhu via Digitalmars-d-learn

Say I want to do something like:

Propertery!int pi = 42;
PropertyCollection pc;

pc.attach(Life_and_Everything, pi);

assert(pc.Life_and_Everything == 42);

Property!string ps = Hello World;

pc.attach(text, ps);

assert(pc.text == Hello World);

How would one store the Property objects in the 
PropertyCollection? You can't use something like an array because 
the two Properties are of different types. Do you really need to 
do something like make a member of PropertyCollection for every 
type of Property you are interested in storing and using static 
ifs to determine which variable it goes into?


I feel like there is an obvious solution here that I'm missing.


Re: Template Collections of Different Types

2015-08-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 16 August 2015 at 01:39:54 UTC, DarthCthulhu wrote:
How would one store the Property objects in the 
PropertyCollection?


You don't, not like that anyway. The attach call is the ruin of 
it. If it was all one definition, you could use something like 
std.typecons.Tuple, but multiple calls to attach need to be a 
runtime function, which means what you attach will lose the 
compile time type when you get it.


Best you could do is something like pc.text!string which checks 
at runtime and throws if you asked for the wrong type, which is 
basically just a Variant[string].


You can't use something like an array because the two 
Properties are of different types. Do you really need to do 
something like make a member of PropertyCollection for every 
type of Property you are interested in storing and using static 
ifs to determine which variable it goes into?


That would work. You could write a plain struct definition and 
then the attach could be implemented as a allMembers/getMember 
assignment loop, similarly to this:

http://stackoverflow.com/questions/31993705/d-call-a-function-using-a-string-variable-with-its-name/31996526#31996526

but looking at data member assignments instead of method calls.




The attach would still check the type with a throw at runtime, 
since the member name you use is also a runtime thing.


Using replaceInPlace, string and char[]

2015-08-15 Thread TSalm via Digitalmars-d-learn

Hi,

A newbie question :

I wrote this simple code :

import std.array;
import std.stdio;

void main()
{

 char[] a = mon texte 1.dup;
 char[] b = abc.dup;
 size_t x   = 4;
 size_t y   = 9;
 replaceInPlace( a, x , y, b );
 writeln( a );
}

But compilation fails :

/usr/include/dmd/phobos/std/array.d(2052): Error: template 
std.algorithm.remove cannot deduce function from argument types 
!()(char[], Tuple!(immutable(uint), uint)), candidates are:
/usr/include/dmd/phobos/std/algorithm.d(8542):
std.algorithm.remove(SwapStrategy s = SwapStrategy.stable, Range, 
Offset...)(Range range, Offset offset) if (s != 
SwapStrategy.stable  isBidirectionalRange!Range  
hasLvalueElements!Range  hasLength!Range  Offset.length = 1)
/usr/include/dmd/phobos/std/algorithm.d(8623):
std.algorithm.remove(SwapStrategy s = SwapStrategy.stable, Range, 
Offset...)(Range range, Offset offset) if (s == 
SwapStrategy.stable  isBidirectionalRange!Range  
hasLvalueElements!Range  Offset.length = 1)
/usr/include/dmd/phobos/std/algorithm.d(8757):
std.algorithm.remove(alias pred, SwapStrategy s = 
SwapStrategy.stable, Range)(Range range) if 
(isBidirectionalRange!Range  hasLvalueElements!Range)
inout.d(13): Error: template instance 
std.array.replaceInPlace!(char, char[]) error instantiating


Don't understand why this doesn't work: it compiles fine and runs 
perfectly if I change char[] by string ... don't understand 
why since the documentation says :

  String literals are immutable (read only).

How this function can change a type that is immutable ?

Thanks for your help.
TSalm






Re: Using replaceInPlace, string and char[]

2015-08-15 Thread TSalm via Digitalmars-d-learn

On Saturday, 15 August 2015 at 08:07:43 UTC, Ali Çehreli wrote:
This looks like a bug to me. The template constraints of the 
two overloads are pretty complicated. This case should match 
only one of them.


Yes I understand. I've used ldc2. With DMD (v0.067.1) the error 
is more clear :
inout.d(11): Error: std.array.replaceInPlace called with argument 
types (char[], uint, uint, char[]) matches both:
/usr/include/dmd/phobos/std/array.d(2214): 
std.array.replaceInPlace!(char, char[]).replaceInPlace(ref char[] 
array, uint from, uint to, char[] stuff)

and:
/usr/include/dmd/phobos/std/array.d(2247): 
std.array.replaceInPlace!(char, char[]).replaceInPlace(ref char[] 
array, uint from, uint to, char[] stuff)

Must create a ticket for it ?


 Don't understand why this doesn't work: it compiles fine and
runs
 perfectly if I change char[] by string

You mean, this:

import std.array;
import std.stdio;

void main()
{
string a = mon texte 1;// -- now string
writeln(a.ptr);  // added
char[] b = abc.dup;
size_t x   = 4;
size_t y   = 9;
replaceInPlace( a, x , y, b );
writeln( a );
writeln(a.ptr);  // added
}

The output:

4BC480
mon abc 1
7FC2AB867210-- different

 ... don't understand why
 since the documentation says :
String literals are immutable (read only).

 How this function can change a type that is immutable ?

It cannot change the characters of the original string. 
replaceInPlace takes its first parameter by reference. What 
changes is 'a' itself. As evidenced by the output of the 
program, 'a' is now a slice to a new set of immutable 
characters.


If there were other slices to mon texte 1, they wouldn't see 
a change.


Yes I understand, thanks. In the other hand using string is not 
efficient since this certainly make a copy of the original 
string. Right ?
This is better to use replaceInPlace with char[], but this 
doesn't actually work :-(





Re: Using replaceInPlace, string and char[]

2015-08-15 Thread Ali Çehreli via Digitalmars-d-learn
This looks like a bug to me. The template constraints of the two 
overloads are pretty complicated. This case should match only one of them.


On 08/15/2015 12:43 AM, TSalm wrote:

 Don't understand why this doesn't work: it compiles fine and runs
 perfectly if I change char[] by string

You mean, this:

import std.array;
import std.stdio;

void main()
{
string a = mon texte 1;// -- now string
writeln(a.ptr);  // added
char[] b = abc.dup;
size_t x   = 4;
size_t y   = 9;
replaceInPlace( a, x , y, b );
writeln( a );
writeln(a.ptr);  // added
}

The output:

4BC480
mon abc 1
7FC2AB867210-- different

 ... don't understand why
 since the documentation says :
String literals are immutable (read only).

 How this function can change a type that is immutable ?

It cannot change the characters of the original string. replaceInPlace 
takes its first parameter by reference. What changes is 'a' itself. As 
evidenced by the output of the program, 'a' is now a slice to a new set 
of immutable characters.


If there were other slices to mon texte 1, they wouldn't see a change.

Ali



Re: using memset withing a pure function

2015-08-15 Thread D_Learner via Digitalmars-d-learn

On Saturday, 15 August 2015 at 01:13:02 UTC, Adam D. Ruppe wrote:

On Saturday, 15 August 2015 at 01:09:15 UTC, D_Learner wrote:
When writting a pure fucntion involving C non pure functions 
like

 memcpy() and   memset()


Those functions are pure already, and marked so in the newest 
dmd (and I think older ones too, though I haven't confirmed.


Your code compiled out of the box for me.

BTW D also has some syntax sugar for them:

arr[start .. end] = 0; // memset those bounds to 0
arr[start .. end] = arr2[start .. end]; // memcpy


You could be surprised am still trying to get my head around 
this. Considering the code :-


memcpy(skip[0], skip[0]+shift, (m-shift)*(int.sizeof));
memset(skip[0]+(m-shift),0, shift*(int.sizeof))

I was thinking conversion would be :-

skip[0 .. size-1] = skip[shift .. size-1   ];  //For the 
memcpy();

skip[0 .. size-1] = 0;//For memset()

But this doesn't seem to work for me as dmd(v2.066.1) gives the 
error slice [8..7] exceeds array bounds [0..8]  .Sure am 
missing something.










Re: using memset withing a pure function

2015-08-15 Thread anonymous via Digitalmars-d-learn

On Saturday, 15 August 2015 at 18:04:30 UTC, D_Learner wrote:

memcpy(skip[0], skip[0]+shift, (m-shift)*(int.sizeof));
memset(skip[0]+(m-shift),0, shift*(int.sizeof))

I was thinking conversion would be :-

skip[0 .. size-1] = skip[shift .. size-1   ];  //For the 
memcpy();


Those two slices have different lengths (when shift != 0). They 
must have equal lengths, and they must not overlap.



skip[0 .. size-1] = 0;//For memset()

But this doesn't seem to work for me as dmd(v2.066.1) gives the 
error slice [8..7] exceeds array bounds [0..8]  .Sure am 
missing something.


You can just do mechanical translations.
  memcpy(dst, src, n * T.sizeof);
becomes
  dst[0 .. n] = src[0 .. n];
Then simplify.

Original:
  memcpy(skip[0], skip[0]+shift, (m-shift)*(int.sizeof));
Identify the pieces:
  dst = skip[0]
  src = skip[0]+shift
  n = m-shift
Substitute:
  (skip[0])[0 .. m-shift] = (skip[0]+shift)[0 .. m-shift];
Simplify:
  skip[0 .. m-shift] = skip[shift .. $][0 .. m-shift];
  skip[0 .. m-shift] = skip[shift .. shift + m-shift];
  skip[0 .. m-shift] = skip[shift .. m];

I sure hope I didn't mess anyting up.

memset is very similar.
  memset(dst, val, n * T.sizeof);
becomes
  dst[0 .. n] = val;
Then simplify.



Re: cannot implicitly convert char[] to string

2015-08-15 Thread cym13 via Digitalmars-d-learn

On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


I think it has to do with the fact that string is an alias to   
immutable(char)[]   and you can't implicitely cast an immutable 
to a regular variable.


Re: cannot implicitly convert char[] to string

2015-08-15 Thread cym13 via Digitalmars-d-learn

On Saturday, 15 August 2015 at 11:34:01 UTC, cym13 wrote:

On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


I think it has to do with the fact that string is an alias to   
immutable(char)[]   and you can't implicitely cast an immutable 
to a regular variable.


I phrased it completely wrong, an example will be better :

import std.stdio;

void fun(immutable(int)[] i) {
i.writeln();
}

void main() {
int[] i = [42];
fun(i);
}

Will not compile because there is no certainty that fun() won't
change the array while the following will work

import std.stdio;

void fun(immutable(int)[] i) {
i.writeln();
}

void main() {
int[] i = [42];
fun(i.dup);

immutable(int)[] j = [42];
fun(j);

immutable(int[]) k = [42];
fun(k);
}



Re: cannot implicitly convert char[] to string

2015-08-15 Thread Timon Gehr via Digitalmars-d-learn

On 08/15/2015 01:54 PM, Timon Gehr wrote:

On 08/15/2015 01:25 PM, vladde wrote:

I made a PR to phobos where I modified `std.format.format`.
https://github.com/D-Programming-Language/phobos/pull/3528

However the auto builder fails, with the error message:

runnable/test23.d(1219): Error: cannot implicitly convert expression
(format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Get rid of the 'in' in format's signature.


Oh, I see, this is by design (which I don't like, but OK.)
The reason the conversion does not go through is that format is not 
marked as pure.


Re: Using replaceInPlace, string and char[]

2015-08-15 Thread Ali Çehreli via Digitalmars-d-learn

On 08/15/2015 01:47 AM, TSalm wrote:

 Must create a ticket for it ?

I think so. Unless others object in 10 minutes... :)

 In the other hand using string is not
 efficient since this certainly make a copy of the original string. 
Right ?

 This is better to use replaceInPlace with char[], but this doesn't
 actually work :-(

There is probably a workaround, which others will hopefully show. (I 
have to leave now. :) ) However, although not in your example, 
replaceInPlace would still copy if the result would not fit in the 
original char[]. Hm... Come to think of it, it cannot replace in place 
anyway, unless it knows that the slice is the only one looking at those 
characters. Otherwise, you would disturbing your other slices. (?)


Ali



Re: cannot implicitly convert char[] to string

2015-08-15 Thread Timon Gehr via Digitalmars-d-learn

On 08/15/2015 01:25 PM, vladde wrote:

I made a PR to phobos where I modified `std.format.format`.
https://github.com/D-Programming-Language/phobos/pull/3528

However the auto builder fails, with the error message:

runnable/test23.d(1219): Error: cannot implicitly convert expression
(format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Get rid of the 'in' in format's signature.


cannot implicitly convert char[] to string

2015-08-15 Thread vladde via Digitalmars-d-learn
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Use members of a Named Enum without using Enum name?

2015-08-15 Thread QuizzicalFella via Digitalmars-d-learn
I have a named enum that I'd like to keep named, that I'd like to 
use as a type, but every time I use a member I'd rather not write 
out the enum name. I have a situation like the following:


enum PolygonT : byte { TRIANGLE, RECTANGLE, STAR }

void someFunc(PolygonT shape) { //some stuff }

I'd like to be able to call someFunc(TRIANGLE) rather than 
someFunc(PolygonT.TRIANGLE). Being clear but not being too long 
is my aim. Writing the type makes it too verbose and I have lazy 
fingers...


I don't mind if adding another enum with members of the same name 
like this:


enum CelestialBodiesT : byte { MOON, SUN, BLACK_HOLE, STAR }

...would force me to call someFunc(PolygonT.STAR) by the 
compiler, but for the case where there's no ambiguity, I don't 
want to write out the type of the enum...


I know I can add in an 'alias this' for classes and structs, but 
I think I only get one and if it's an enum I'm using all over the 
place I don't want to 'alias this' it everywhere...


Is there a way I can do this while retaining type safety? (can I 
be lazy and protected at the same time?)


Re: Use members of a Named Enum without using Enum name?

2015-08-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 August 2015 at 15:37:42 UTC, QuizzicalFella wrote:
I'd like to be able to call someFunc(TRIANGLE) rather than 
someFunc(PolygonT.TRIANGLE).


Two options come to mind:

alias TRIANGLE = PolygonT.TRIANGLE;
// etc

Or at the usage site:

with(PolygonT) {
   someFunc(TRIANGLE);
}


I don't mind if adding another enum with members of the same 
name like this:


enum CelestialBodiesT : byte { MOON, SUN, BLACK_HOLE, STAR }

...would force me to call someFunc(PolygonT.STAR) by the 
compiler, but for the case where there's no ambiguity, I don't 
want to write out the type of the enum...


That'll work as long as the two enums are defined in separate 
modules, then only import the one you need to use at the time. 
Otherwise, they will conflict and it will force you to write it 
out long form again.


Re: Use members of a Named Enum without using Enum name?

2015-08-15 Thread QuizzicalFella via Digitalmars-d-learn

On Saturday, 15 August 2015 at 15:53:23 UTC, Adam D. Ruppe wrote:
On Saturday, 15 August 2015 at 15:37:42 UTC, QuizzicalFella 
wrote:
I'd like to be able to call someFunc(TRIANGLE) rather than 
someFunc(PolygonT.TRIANGLE).


Two options come to mind:

alias TRIANGLE = PolygonT.TRIANGLE;
// etc

...if I wanted to write a mixin that iterated over all the 
elements in an enum, how would I get a member to print its name 
without the type? And how do I get the type to print itself?


foreach(member; enum)
char[] output ~= alias 
~member.name~=~enum.name~.~member.name~;





Re: using memset withing a pure function

2015-08-15 Thread Temtaime via Digitalmars-d-learn

There's a problem with « dst[0 .. n] = val; ».
It should be « dst[0 .. n][] = val; »


Re: using memset withing a pure function

2015-08-15 Thread D_Learner via Digitalmars-d-learn

On Saturday, 15 August 2015 at 18:49:15 UTC, anonymous wrote:

On Saturday, 15 August 2015 at 18:04:30 UTC, D_Learner wrote:

[...]


Those two slices have different lengths (when shift != 0). They 
must have equal lengths, and they must not overlap.


[...]


Am now sorted. Thanks, your workout simplifies everything