Re: Capturing Caller UDAs as CT Template Function Parameters

2015-05-18 Thread anonymous via Digitalmars-d-learn

On Monday, 18 May 2015 at 21:35:44 UTC, Per Nordlöw wrote:

void yield(T)(ref T value)
{
mixin(alias caller =  ~ caller ~ ;);
}

doesn't work across module boundaries not even for 
`__PRETTY_FUNCTION__`.


Do we need need to fix the compiler, Walter?! ;)


You have to import the module, too:

void yield(T, string caller_str = __FUNCTION__)(ref T value)
{
import std.array: join, split;
enum module_str = caller_str.split(.)[0 .. $ - 1].join(.);
mixin(static import  ~ module_str ~  ;);
mixin(alias caller =  ~ caller_str ~ ;);
}


This fails for methods, of course. I guess you could remove 
elements from the back of __FUNCTION__ until it compiles as a 
module, and then import that.


Re: How to create a mutable array of strings?

2015-05-17 Thread anonymous via Digitalmars-d-learn

On Sunday, 17 May 2015 at 09:20:17 UTC, Dennis Ritchie wrote:

On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:

auto s = cast(char[][])[foo, bar];


Thanks. This version I was completely satisfied.


Remember that Daniel Kozak wrote if you are sure thats what you 
really need. I'm confident that you're not sure it's what you 
need. For starters, this crashes on linux:



auto s = cast(char[][])[foo, bar];
s[1][1] = 't';



Re: How to create a mutable array of strings?

2015-05-17 Thread anonymous via Digitalmars-d-learn

On Sunday, 17 May 2015 at 09:26:15 UTC, Dennis Ritchie wrote:

And no crashes on Windows :)


Yeah, on windows it's even worse.

void main()
{
auto s = cast(char[][])[foo, bar];
s[1][1] = 't';
import std.stdio;
writeln(bar);
}


Re: ICE?

2015-05-17 Thread anonymous via Digitalmars-d-learn

On Sunday, 17 May 2015 at 10:09:11 UTC, Daniel Kozak wrote:

On Sunday, 17 May 2015 at 09:25:33 UTC, Namespace wrote:

[...]
Error: e2ir: cannot cast malloc(length * 8u) of type void* to 
type char[]


I would say this is not an ICE just normal error message.


e2ir:  shouldn't be there, though.


Re: What wrong?

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

On Saturday, 2 May 2015 at 02:51:52 UTC, Fyodor Ustinov wrote:

Simple code:

http://pastebin.com/raw.php?i=7jVeMFXQ

This code works compiled by DMD v2.066.1 and LDC2 (0.15.1) 
based on DMD v2.066.1 and LLVM 3.5.0.


$ ./z
TUQLUE
42
11

Compiled by DMD v2.067.1 the program crashes:
$ ./aa
TUQLUE
Segmentation fault

What I'm doing wrong?


(Copying my reply to the post in the main group here:)

I investigated this further. std.variant is to blame. I filed an 
issue an made a pull request to fix it:


https://issues.dlang.org/show_bug.cgi?id=14585
https://github.com/D-Programming-Language/phobos/pull/3284


Re: Dynamic / resizable array type, and a crash problem

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

On Thursday, 14 May 2015 at 20:50:05 UTC, ivoras wrote:
I'm experimenting to get a feel for the language. Do you have a 
suggestion about this example code: https://goo.gl/F7LCAg to 
make it more D-like, idiomatic?


Quoting from the code:


 for (int i = 0; i  count; i++) {


foreach(i; 0 .. count)


   try {
 auto choices = markov[current];

[...]

   } catch (RangeError e) {
 break;
   }


Don't catch Errors. Use the `in` operator to check if `current` 
is in `markov`:


if(current !in markov) break;

Or avoiding double lookup:

string[]* choicesp = current in markov;
if(choicesp is null) break;
auto choices = *choicesp;


int main(string[] args)


You cam omit the return type and `args` if you're not going to 
use them:


void main()


 foreach (c_line; stdin.byLine()) {
   auto line = to!string(c_line);


Could use byLineCopy:

foreach(line; stdin.byLineCopy)


 if (prev_token in markov) {
   markov[prev_token] ~= token;
 } else {
   markov[prev_token] = [token];
 }


I think you can just go with appending here:

markov[prev_token] ~= token;

But I'm not 100% sure about the implications.


Re: Dynamic / resizable array type, and a crash problem

2015-05-14 Thread anonymous via Digitalmars-d-learn

On Thursday, 14 May 2015 at 12:42:01 UTC, ivoras wrote:

https://gist.github.com/ivoras/2d7737c214c3dc937c28

The crash is at line 20:

core.exception.AssertError@/usr/include/dmd/phobos/std/container/array.d(334):

[...]


This is on DMD32 D Compiler v2.067.1


Seems to be fixed in git head.


Re: Cannot Qualify Variadic Functions with Lazy Arguments as nothrow

2015-05-14 Thread anonymous via Digitalmars-d-learn

On Thursday, 14 May 2015 at 09:53:20 UTC, Per Nordlöw wrote:

I'm almost satisified with it except that the lazy evaluation at

https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L45

cannot be made nothrow.

If I qualify the function as nothrow DMD complains as

algorithm_ex.d(45,16): Error: 'a' is not nothrow
algorithm_ex.d(46,29): Error: '_param_1' is not nothrow



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


Re: how does 'shared' affect member variables?

2015-05-09 Thread anonymous via Digitalmars-d-learn

On Saturday, 9 May 2015 at 18:41:59 UTC, bitwise wrote:

What does 'shared' do to member variables?


Makes them `shared`. :P

It makes sense to me to put it on a global variable, but what 
sense does it make putting it on a member of a class?


Globals are not the only way to pass data to other threads. E.g., 
you can std.concurrency.send a shared Object:



import core.thread: thread_joinAll;
import std.concurrency;
class C {int x;}
void main()
{
auto c = new shared C;
c.x = 1;
auto tid = spawn(() {
receive(
(shared C c) {c.x = 2;}
);
});
send(tid, c);
thread_joinAll();
assert(c.x == 2);
}


That shared C could come from a class/struct member, of course.

What happens if you try to access a member of a class/struct 
instance from another thread that is not marked 'shared'?


I think you're not supposed to be able to do that.


Re: how does 'shared' affect member variables?

2015-05-09 Thread anonymous via Digitalmars-d-learn

On Saturday, 9 May 2015 at 19:59:58 UTC, tcak wrote:
Stupidly, shared variables' value cannot be increased/decreased 
directly. Compiler says it is deprecated, and tells me to use 
core.atomic.atomicop. You will see this as well.


How's that stupid? Sounds like the compiler is doing its job 
guarding you from races.


Hey compiler! I know 100% that no other thing will be touching 
this variable.


Informing the compiler about this is done by casting shared away.


Re: Multiple template alias parameters

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

On Friday, 8 May 2015 at 22:29:28 UTC, Biotronic wrote:
Sadly, the ... syntax precludes the use of __LINE__ and 
__FILE__. :(


You can put them in the runtime parameters:


void traceVars(alias T, U...)(size_t line = __LINE__, string file 
= __FILE__) {

import std.stdio : writeln;
writeln(file, (, line, ) , T.stringof, : , T);
static if (U.length  0) {
traceVars!(U)(line, file);
}
}


Or you can nest two templates:


template traceVars(alias T, U...) {
void traceVars(size_t line = __LINE__, string file = 
__FILE__)() {

import std.stdio : writeln;
writeln(file, (, line, ) , T.stringof, : , T);
static if (U.length  0) {
alias t = .traceVars!U;
t!(line, file);
}
}
}



Re: Bitfield-style enum to strings?

2015-05-07 Thread anonymous via Digitalmars-d-learn

On Thursday, 7 May 2015 at 20:55:42 UTC, Nick Sabalausky wrote:

// There's gotta be a better way to convert EnumMembers!T
// to a range, right? But std.range.only() didn't work,
// due to a template instantiation error.
T[] members;
foreach(m; EnumMembers!(T))
members ~= m;


only(EnumMembers!T) should work and did work before 2.067. I 
filed a regression:

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


Re: Linker command

2015-05-06 Thread anonymous via Digitalmars-d-learn

On Wednesday, 6 May 2015 at 19:52:44 UTC, Paul wrote:

On Wednesday, 6 May 2015 at 19:30:33 UTC, anonymous wrote:

On Wednesday, 6 May 2015 at 19:26:40 UTC, Paul wrote:
but I don't understand the syntax. dmd --help mentions 
-Llinkerflag but what is '-L-L.' doing??


Passes '-L.' to the linker.


:D I can see that, but what does '-L.' mean exactly?


If the linker in question is ld, try `ld --help | grep \\-L` or 
`man ld`.


Re: Linker command

2015-05-06 Thread anonymous via Digitalmars-d-learn

On Wednesday, 6 May 2015 at 19:26:40 UTC, Paul wrote:
but I don't understand the syntax. dmd --help mentions 
-Llinkerflag but what is '-L-L.' doing??


Passes '-L.' to the linker.


Re: CTFE template predicates

2015-05-04 Thread anonymous via Digitalmars-d-learn

On Monday, 4 May 2015 at 11:22:16 UTC, Robert M. Münch wrote:
Hi, ok, just to better understand this (I have a C++ background 
(even quite old)): When I want to use some functions I need to 
specify the type? It's not possible to use T.length() which 
would compile if T is a string? I thought that it's just 
generic and I can throw in T.


In template parameter lists, a solitary identifier is a type 
parameter. You can only pass types in those.


In function (pointer) declarations, a solitary identifier is the 
type of the parameter.


In function/delegate literals, a solitary identifier is the name 
of the parameter and the type is inferred. I guess this is what 
you were thinking of.



void main()
{
template t(T) {} /* T is a template type parameter. */
alias i = t!int; /* It can be instantiated with the type int, 
for example, */
static assert(!__traits(compiles, t!123)); /* but not with a 
value. */


void function(int) fp; /* int is the type of the parameter. */
fp = (x) {}; /* x is the name of the parameter whose type is 
inferred from above. */

}



Re: CTFE template predicates

2015-05-04 Thread anonymous via Digitalmars-d-learn

On Monday, 4 May 2015 at 11:41:23 UTC, Robert M. Münch wrote:
Hi, I have one more questions: Is it possible to write 
something like this?


alias rules = StaticFilter!(startsNotWith(?, 'p'), org_rules);

The ? should be used for every memember of org_rules.


No, we don't have template literals.


Re: opEquals optimized away?

2015-05-04 Thread anonymous via Digitalmars-d-learn

On Tuesday, 5 May 2015 at 04:09:03 UTC, Manfred Nowak wrote:

class C{
  override bool opEquals( Object o){
return true;
  }
}
unittest{
  auto c= new C;
  assert( c == c);
}

`rdmd --main -unittest -cov' shows, that opEquals is not 
executed. Why?


-manfred


because `c is c`

https://github.com/D-Programming-Language/druntime/blob/0ac255d7276b9b825eb6f1e677e9ee4f5ad49ca2/src/object.di#L61


Re: CTFE template predicates

2015-05-03 Thread anonymous via Digitalmars-d-learn

On Sunday, 3 May 2015 at 21:46:11 UTC, Robert M. Münch wrote:
Hi, I have now played a around couple of hours (reading 
everything I could find) to get something to work, but I think 
I'm missing some basic concepts/understanding. Maybe someone 
can enlighten me how these things work. I thought that some 
code from David Nadlinger is what I'm searching for but don't 
know how to exactly make use of it.


Here is the code: I want to filter out some of the allMembers 
and use them in my code for a switch/final to check that call 
cases that were not filtered are covered. Trying to build the 
enum for the switch/final statement.


auto org_rules = TypeTuple!(__traits(allMembers,BolSource));
static assert(!isTypeTuple!(org_rules));

template startsNotWith(T,char C){
   static if (T[0] != C){
   enum startsNotWith = true;
   } else {
   enum startsNotWith = false;
   }
}


Here T would have to be a type. But you want to accept a string. 
So:


template startsNotWith(string s,char c){
enum startsNotWith = s.length == 0 || s[0] != c;
}



template StaticFilter(alias pred, T...) {
 static if (T.length == 0) {
   alias TypeTuple!() StaticFilter;
 } else static if (pred!(T[0])) {
   alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) 
StaticFilter;

 } else {
   alias StaticFilter!(pred, T[1 .. $]) StaticFilter;
 }
}

alias startsNotWithp = startsNotWith!(T,p); // doesn't 
compile: Error: undefined identifier T


You need to turn T into a parameter, so that StaticFilter can set 
it. (And it's really a string again, so I'm renaming to s.)



template startsNotWithp(string s)
{
enum startsNotWithp = startsNotWith!(s, 'p');
}
/* Shorthand syntax: enum startsNotWithp(string s) = 
startsNotWith!(s, 'p'); */




alias rules = StaticFilter!(startsNotWithp, org_rules);


While playing with this a couple of questions came up:

1. How do predicates get their argument(s)? I saw code where 
only the predicate was mentioned but no arguments. So, I assume 
there is some behind-the-curtain-magic going on. I read about 
things like a == b where I can reference 'a and 'b in a 
string.


Predicates are called/instantiated by the thing to which you pass 
them. StaticFilter instantiates pred for each element of the T 
tuple it's given. If some documentation doesn't say how the 
predicate will be called/instantiated, then it's probably assumed 
to be obvious.


String predicates are turned into functions behind the curtains. 
The thing you instantiate with a == b turns it into `(a, b) 
{return a == b;}` and uses that. I think we don't do string 
predicates for templates like StaticFilter, though.


2. enum startsNotwith = false So this is the return syntax 
for a CTFE for return(true) ?


It's the template syntax for return false. CTFE does normal 
functions at compile time, so there it's just return false.



/* Template: */
template t() {enum t = false;}
enum x = t!();
/* CTFE: */
bool f() {return false;}
enum y = f();


3. TupleType is a very missleading name when you are learning 
these things, because the tuple can hold values as well.


Yup. And std.traits.isTypeTuple only adds to the confusion.

Or is there a more extensive explanation for the name I don't 
get?


Not that I'm aware of.

4. Are there any tutorials about CTFE? This seems to be a very 
powerful but not so easy to use feature of D, but documentation 
is quite limited.


CTFE is rather simple. It just allows you to use certain 
functions in a static (i.e. compile time) context.


Templates are more tricky. If you mean templates, maybe having 
the right name helps.


Re: How to I translate this C++ structure/array

2015-05-03 Thread anonymous via Digitalmars-d-learn

On Sunday, 3 May 2015 at 02:31:51 UTC, WhatMeWorry wrote:

On Saturday, 2 May 2015 at 22:36:29 UTC, anonymous wrote:

[...]

[1] `Vertex triangle[6]` works, but please don't do that.


Thanks. I assume you would prefer I use triangle[] but with 
OpenGL calls the dynamic arrays don't work.  But maybe that is 
another question for another time.


No no, Vertex[6] as a type is fine. It's about where you put that 
[6]:

Vertex[6] triangle; /* D style - yay */
Vertex triangle[6]; /* C style - boo */


Re: How to I translate this C++ structure/array

2015-05-02 Thread anonymous via Digitalmars-d-learn

On Saturday, 2 May 2015 at 22:01:10 UTC, WhatMeWorry wrote:

struct Vertex
{
vec3 position;
vec3 color;
}

Vertex triangle[6] =
[
vec3(0.0,  1.0, 0.0),
vec3(1.0,  0.0, 0.0),   // red

   // code removed for brevity.
];

I keep getting the following:

MeGlWindow.d(171): Error: cannot implicitly convert expression 
(Vector([0.00F, 1.0F, 0.00F])) of type 
Vector!(float, 3) to Vertex


You have to be explicit:

Vertex[6] triangle = /* [1] */
[
Vertex(
vec3(0.0,  1.0, 0.0),
vec3(1.0,  0.0, 0.0),   // red
),
...
];

[1] `Vertex triangle[6]` works, but please don't do that.


Re: Calling functions using mixins

2015-05-01 Thread anonymous via Digitalmars-d-learn

On Friday, 1 May 2015 at 21:04:10 UTC, Dennis Ritchie wrote:

hi,
Is it possible to call functions using mixins in this way?

-
import std.stdio;

int fooTestMixin() {
return 5;
}

void main() {

enum t { fooTestMixin };
immutable string[] strArr = [ fooTestMixin ];

writeln(mixin(`mixin(t.fooTestMixin)`));


Don't know what you're trying to do here.


writeln(mixin(`mixin(strArr[0])`));


writeln(mixin(`mixin(strArr[0])`));

or without the pointless outer mixin:

writeln(mixin(strArr[0]));


}




Re: Calling functions using mixins

2015-05-01 Thread anonymous via Digitalmars-d-learn

On Friday, 1 May 2015 at 21:41:10 UTC, Dennis Ritchie wrote:

My final goal is to do something like this:

-
import std.stdio, std.string;

int foo() {
return 5;
}

int bar() {
return 10;
}

void main()
{
immutable string[] s = [ foo, bar ];

writeln(mixin(`format(%(%s, %), s)`));;
}


What's that supposed to do?


Re: How to reuse functions

2015-05-01 Thread anonymous via Digitalmars-d-learn

On Friday, 1 May 2015 at 03:34:53 UTC, Luigi wrote:

Hi everybody.

I am tring to use a function where its parameter is another 
function, and at the same time are both already made - they 
cannot be modified - and the second one has to be conditioned 
before to be passed as argument.


Let's say I have these function and I cannot modify:

-jac(+d) that works on function and return real

real jac(real function(real) fun, real x) {return d(fun, x);}
real d(real function(real) fun, real x) {return fun(x);}

-F1 that works on two reals and return real

real F1(real a, real b) {return a + b;}

So I need a way to condition F1 fixing b and then pass it to 
jac as argument.


To do that I've created a delegate 'simp' conditionig F1:

real delegate(real) simp(real function(real, real) f, real x) {
real _simp(real z) {
return f(z, x);
}
return _simp;
}
(here 'simp' fixes b at x).

My main is:

void main() {
real x_n = 1;
real x_m = -1;
real delegate(real) s_n = simp(F1, x_n);
	//auto J = jac(s_n, x_m); //Error: function app.jac (real 
function(real) fun, real x) is not callable using argument 
types (real delegate(real), real)

}

the code fails because jac expect as argument a function but I 
found only a delegate to obtain a simplified function without 
any touch at already made functions jac, d and F1.


There is a clean way to make it possible? I mean: without to 
touch (neither rewrite) jac, d and F1, obtain simplied F1 to 
pass to jac.


If x_n is a constant (enum), you can use that to create a 
function instead of a delegate:



void main() {
enum real x_n = 1;
real x_m = -1;
real function(real) s_n = z = F1(z, x_n);
auto J = jac(s_n, x_m);
}


If x_n is not constant, then the only way I see to make this 
work, is to use a module variable:



real x_n;
void main() {
x_n = 1;
real x_m = -1;
real function(real) s_n = z = F1(z, x_n);
auto J = jac(s_n, x_m);
}



Re: Factory pattern in D

2015-05-01 Thread anonymous via Digitalmars-d-learn

On Friday, 1 May 2015 at 11:01:29 UTC, Chris wrote:
This aside, how would I get something to load dynamically? It's 
either mismatched function return type or (with type check) 
variable X cannot be read at compile time:


void main(string[] args) {
 auto type = args[1];
 auto myType = factory!type();
}

So it's back to classes/interfaces again? H.


Obviously, myType's static type and factory's return type can't 
depend on a dynamic value like args[1].


You could let factory return a std.variant.Variant, but at that 
point maybe just go with classes.


Re: Delegate type deduction compile error

2015-04-25 Thread anonymous via Digitalmars-d-learn

On Saturday, 25 April 2015 at 10:23:25 UTC, ref2401 wrote:

struct MyStruct {}

void main(string[] args) {
string str = blah-blah;

auto d1 = (MyStruct) { writeln(delegate-str: , str); };

writeln(typeid(typeof(d1)));
}



dmd: 2067
os: Win8.1
build script: dmd main.d -ofconsole-app.exe -debug -unittest -wi

- if delegate has no params or param is declared as 
int/char/float then the code compiles successfully.

auto d1 = (int) { writeln(delegate-str: , str); };


This seems to be a special case for builtin types. Builtin types 
cannot be used for identifiers, so int is recognized as the 
type here.


- if I declare named param as string or MyStruct then the code 
compiles successfully too.

auto d1 = (MyStruct ms)  { writeln(delegate-str: , str); };


Here you give both type and name, so it's clear which is which, 
to both you and the compiler.


- if I declare anonymous parameter as string or MyStruct then 
the error compile occurs:

auto d1 = (MyStruct)  { writeln(delegate-str: , str); };

main.d(21): Error: variable main.main.d1 type void is inferred 
from initializer (MyStruct)


{

writeln(delegate-str: , str);

}

, and variables cannot be of type void
main.d(21): Error: template lambda has no value


Here MyStruct is interpreted as the _name_ of the parameter. 
Its type is inferred as void, because there's no context that 
says otherwise. Parameters cannot be typed void - error.


Generally, in function literals, a single identifier is 
interpreted as the name, because the type can often be inferred 
from context. And then it's nice not having to write the type out.



Why does it happen?


Re: o!(const(T)) parameter.

2015-04-25 Thread anonymous via Digitalmars-d-learn

On Saturday, 25 April 2015 at 14:52:45 UTC, sclytrack wrote:
I want a function with parameter o!(const(Form)) to accept both 
o!(Form) and o!(immutable(Form))


Is there a way to do it?





import std.stdio;
import std.traits;


class Form
{
int number = 10;
}

struct o(T)
{
T data;

this(T data)
{
this.data = data;
}

o!(const(Unqual!(T))) constify() const
{
return o!(const(Unqual!(T)))(data);
}

alias constify this;
}


void hello(o!(const(Form)) frm)
{
  writeln(frm.data.number);
  writeln(typeof(frm.data).stringof);
}

void main()
{
writeln(This application works nicely);
auto frm = o!(Form) (new Form());
//  auto ifrm = o!(immutable(Form)) (new immutable Form());

hello(frm);
//  hello(ifrm);
}


It works when you exclude the recursive alias this:
static if(!is(T == const)) alias constify this;

Your original program crashes the compiler, which is always a 
bug. I filed an issue:

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


Re: how does isInputRange(T) actually work?

2015-04-21 Thread anonymous via Digitalmars-d-learn

On Tuesday, 21 April 2015 at 19:17:56 UTC, kevin wrote:

On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote:

On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote:

On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:

enum bool isInputRange = is(typeof(
 (inout int = 0)
 {
 R r = R.init; // can define a range object
 if (r.empty) {}   // can test for empty
 r.popFront(); // can invoke popFront()
 auto h = r.front; // can get the front of the range
 }));

[...]

Don't lambdas need a = token?


No, D has two variants of function/delegate literal or lambda 
syntax:


1) with =: parameters = expression
Some examples:
(int a) = a + 2
a = a + 2
(a, b) = a + b
() = 2

2) with braces: (parameters) {statements}
Same examples as above:
(int a) {return a + 2;}
(a) {return a + 2;}
(a, b) {return a + b;}
{return 2;}

As you can see, a lot is optional there.

In the spec: http://dlang.org/expression.html#FunctionLiteral

Also, what is the purpose of typeof? I would have expected a 
simple is() to work just fine.


(In this most simple form,) `is` evaluates to true if the 
argument is a valid type. A function/delegate literal isn't a 
type.


If you passed the lambda expression itself to `is`, the result 
would always be false. As it is, the result is true when the 
lambda expression compiles (so it has a valid type).


More about the IsExpression: 
http://dlang.org/expression.html#IsExpression


Re: Templates: Array slices not recognized

2015-04-20 Thread anonymous via Digitalmars-d-learn

On Monday, 20 April 2015 at 10:14:27 UTC, Chris wrote:

string a = bla;
string b = blub;

auto res = doSomething(a, b);

If I didn't use auto ref or ref, string would get copied, 
wouldn't it?


auto ref doSomething(R needle, R haystack);

To avoid this, I would have to write a[0..$], b[0..$], which is 
not nice. Right or wrong?


Wrong. `a[0..$]` is the same as simply `a`. A `string` is just 
another slice: a pointer and a length.


Re: Weird link error

2015-04-20 Thread anonymous via Digitalmars-d-learn

On Monday, 20 April 2015 at 17:02:18 UTC, CodeSun wrote:
I have test a snippet of code, and I encountered with a weird 
link error.

The following is the demo:

import std.stdio;
interface Ti {
T get(T)(int num);
T get(T)(string str);
}

class Test : Ti {
T get(T)(int num) {
writeln(ok);
}
T get(T)(string str) {
writeln(str);
}
}
void main() {
Ti tt = new Test;
tt.get!string(test);
tt.get!string(123);
}


When I use dmd to compile this code snippet, the following link 
error was reported:
tt.d:(.text._Dmain+0x3b):‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ 
undefined reference
tt.d:(.text._Dmain+0x49):‘_D2tt2Ti12__T3getTAyaZ3getMFiZAya’undefined 
reference


And if I modigy the code to
Test tt = new Test;

then this code will work.


Template methods are non-virtual. That is, you can't override 
them.


So does it mean I can't declare function template inside 
interface? If so, why didn't dmd report the error while 
compiling instead of linking?


You can theoretically implement them elsewhere. For example, this 
works:



module test;

interface Ti {
T get(T)(int num);
T get(T)(string str);
}

pragma(mangle, _D4test2Ti12__T3getTAyaZ3getMFiZAya) string 
impl(int)

{
return foo;
}
pragma(mangle, _D4test2Ti12__T3getTAyaZ3getMFAyaZAya) string 
impl(string)

{
return bar;
}

class Test : Ti {}

void main() {
Ti tt = new Test;
tt.get!string(test);
tt.get!string(123);
}


It's really silly, though. I don't know if there's a more 
realistic use case.


And where I can find the D symbol definition, because 
information like ‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ makes me 
really confused.


That's a mangled name. There's a tool called ddemangle. It comes 
with the D releases. You can pipe the compiler output through it 
to get more readable symbol names (don't forget to redirect 
stderr to stdout). For this one it gives gives you 
immutable(char)[] 
tt.Ti.get!(immutable(char)[]).get(immutable(char)[]).


Re: Input ranges

2015-04-19 Thread anonymous via Digitalmars-d-learn

On Saturday, 18 April 2015 at 22:01:56 UTC, Ulrich Küttler wrote:

Input ranges from std.stdio are used for reading files. So
assuming we create a file

auto f = File(test.txt, w);
f.writeln(iota(5).map!(a = repeat(to!string(a), 
4)).joiner.joiner(\n));

f.close();

We should be able groupBy (chunkBy) its lines:

writeln(File(test.txt).byLine.groupBy!((a,b) = a == b));

The result is just one group, that is all lines are considered 
equal:


[[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 
2, 3, 3, 3, 3, 4, 4, 4, 4]]


Alas, byLine reuses the same buffer for each line and thus
groupBy keeps comparing each line with itself. There is a 
version

of byLine that makes copies:

writeln(File(test.txt).byLineCopy.groupBy!((a,b) = a == 
b));


Indeed, the result is as expected:

[[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 
2, 2], [3, 3, 3, 3], [4, 4, 4, 4]]


Yeah, byLine is dangerous. byLineCopy should probably have been 
the default. Maybe we should rename byLine to byLineNoCopy (doing 
the proper deprecation dance, of course).



A final test with the undocumented byRecord method (the mapping
after groupBy is for beauty only and does not change the 
result):


writeln(File(test.txt)
.byRecord!string(%s)
.groupBy!((a,b) = a == b)
.map!(map!(a = a[0])));

Here, the result is most peculiar:

[[0, 0, 0, 0], [1, 1, 1], [2, 2, 2], 
[3, 3, 3], [4, 4, 4]]


Is byRecord broken? (It is undocumented after all.) In a way,
because it does not contain any indirection. The current fields
tuple is a simple member of the ByRecord struct.

In contrast, the ByLineCopy struct is just a wrapper to a ref
counted ByLineCopyImpl struct with a simple note:

/* Ref-counting stops the source range's ByLineCopyImpl
 * from getting out of sync after the range is copied, 
e.g.
 * when accessing range.front, then using 
std.range.take,

 * then accessing range.front again. */

I am uncomfortable at this point. Simple and efficient input
ranges fail in unexpected ways. Internal indirections make all
the difference. It feels like input ranges are hiding something
that should not be hidden.

What am I missing?


I guess the problem is the mix of value and reference semantics. 
ByRecord's `current` is a value, but its `file` has reference 
semantics. So, a copy of a ByRecord affects one part of the 
original but not the other.


Maybe copying should be `@disable`d for such ranges/structs. Then 
you couldn't pass it by value to groupBy. Instead you would have 
to use something like (the fixed version of) refRange, which 
works properly.


Re: Input ranges

2015-04-19 Thread anonymous via Digitalmars-d-learn

On Sunday, 19 April 2015 at 21:42:23 UTC, Ulrich Küttler wrote:
groupBy is a nice example as it laboriously adds reference 
semantics to forward ranges but assumes input ranges to posses 
reference semantics by themselves.


All ranges are input ranges, though. Input ranges are the least 
specialised category. I think it's a mistake to assume/require 
anything only for input ranges that are not forward ranges.


I guess we could require reference semantics for all input ranges 
(including forward ranges and higher-ups). That would be a rather 
clean way out of this mess. But it would be a major effort. And I 
guess it would hurt performance, maybe a lot.


[...]
Again, I agree. Disallow copying for such ranges would prevent 
the error, still it would be a bit harsh. It is not just 
groupBy that goes astray. You can also get strange results from 
take:


auto r = File(test.txt).byRecord!string(%s);
foreach (i; 0 .. 5)
writeln(r.take(4).map!(a = a[0]));


That would also not be possible if ByRecord had an `@disable 
this(this);`. But I'm not at all sure that this is the way to go. 
It's bound to be forgotten, and there are probably places where 
it's needlessly restrictive.


I was hoping to find some communication how input ranges should 
be done.


I'm right there with you. This is all a bit iffy. I suspect that 
this is an oversight in the design of ranges, as the 
documentation of std.range doesn't say anything on the topic.


This may be too advanced for D.learn. I don't think Andrei and 
Walter come down here very often. Maybe take it to the general 
board.



At this point the solution in byLineCopy feels ad hoc.


I think byLineCopy solves a different problem. ByLine already has 
this:

https://github.com/D-Programming-Language/phobos/blob/v2.067.0/std/stdio.d#L1592-L1598


Re: Traits question and compiler crash

2015-04-14 Thread anonymous via Digitalmars-d-learn

On Tuesday, 14 April 2015 at 09:24:04 UTC, Filippo Fantini wrote:

Hello everyone!

I'm new to D.
While playing with around with traits,
I ended up writing this short example:


module test;

class Foo
{
private int _value = 21;

void foo()
{
import std.traits;

alias funs = MemberFunctionsTuple!( typeof( this ), 
bar );


version( crash )
{
void function( string ) b = funs[ 0 ];
b( world );
}

funs[ 0 ]( world );
}

void bar( string s )
{
import std.stdio;
writeln( hello , s, ! , _value );
}
}

void main()
{
auto f = new Foo();
f.foo();
}


My first question is why building this with
dmd test.d

the line:
funs[ 0 ]( world );

does not crash, as I would expect because there's no this 
pointer to access _value when calling the member function.


That's the same as `Foo.bar(world);`, which also works. The 
this pointer is passed even though the call does not show it. I 
don't know if or where this is specified, but I'm pretty sure 
it's supposed to work like this.



The second question is why when building with:
dmd -version=crash test.d

the compiler just crashes instead.


Every compiler crash is a bug. Please report it at 
http://issues.dlang.org/.


Re: CTFE UFCs?

2015-04-14 Thread anonymous via Digitalmars-d-learn

On Tuesday, 14 April 2015 at 15:20:37 UTC, bitwise wrote:

When I uncomment the nicer syntax, I get the errors below:

[1] Error: variable refl cannot be read at compile time
[2] Error: CTFE failed because of previous errors in base


class Base {
double d = 0.4;
}

class Test : Base {
int x = 4;
}

abstract class Refl {
@property abstract string name() const;
@property abstract string baseName() const;
}

class ClassRefl(T) : Refl {
@property override string name() const {
return T.stringof;
}

@property override string baseName() const {
alias BaseClassesTuple!T base_types;
return base_types[0].stringof;
}
}

const(Refl) reflect(T)() {
static const(Refl) refl = new ClassRefl!T;
return refl;
}

const(Refl) reflect(string name)() {
mixin(return reflect!( ~ name ~ ););
}

//const(Refl) base(const(Refl) refl) {
//return reflect!(refl.baseName());ERROR  [1]
//}

void main()
{
static const(Refl) refl = reflect!Test;

static const(Refl) baseRefl = reflect!(refl.baseName());

//static const(Refl) baseRefl = refl.base;   ERROR  [2]

writeln(refl.name);
writeln(baseRefl.name);
}


If anyone can offer a work around it would be much appreciated.


Minimal changes to what you have now; gives you `base!refl` 
instead of `refl.base`:


const(Refl) base(alias refl)() {
   return reflect!(refl.baseName());
}
static const(Refl) baseRefl = base!refl;


Digging deeper:

abstract class Refl {
@property abstract string name() const;
immutable(Refl) base() const;
}

class ClassRefl(T) : Refl {
@property override string name() const {
return T.stringof;
}

override immutable(Refl) base() const
{
alias BaseClassesTuple!T base_types;
static if(base_types.length  0)
{
static immutable(Refl) instance = new 
ClassRefl!(base_types[0]);

return instance;
}
else return null;
}
}
static const(Refl) baseRefl = refl.base;


Parting thoughts:
I don't know where you're heading with this. But so far I don't 
see what it would buy you over std.traits and 
TypeInfo/TypeInfo_Class.


Re: Formatted output ranges

2015-04-11 Thread anonymous via Digitalmars-d-learn

On Saturday, 11 April 2015 at 20:10:49 UTC, Dennis Ritchie wrote:

writefln(%(;; %(%s, %),\n%)., [
a[0 .. 15],
a[15 .. 30],
a[30 .. 45],
a[45 .. 60],
a[60 .. 75],
a[75 .. 90],
a[90 .. $]
]);


writefln(%(;; %(%s, %),\n%)., a.chunks(15));


Re: function shadowed

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

On Wednesday, 8 April 2015 at 12:05:00 UTC, ddos wrote:

vg.d:
module vg;
extern (C) void  vgSetParameterfv(VGHandle object, VGint 
paramType, VGint count, VGfloat *values);


openvg.d
module openvg;
public import vg;

void vgSetParameterfv(VGHandle object, VGint paramType, 
const(VGfloat[]) values)

{
	vg.vgSetParameterfv(object, paramType, cast(int)values.length, 
cast(VGfloat*)values);

}

test.d
import openvg;
vgSetParameterfv(object, paramType, length, values); // call to 
fun in vg.d


how can i call both functions? i'd like to avoid using the 
module prefix vg.vgSetParameterfv if possible


Add to openvg:
alias vgSetParameterfv = vg.vgSetParameterfv;


Re: function shadowed

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

On Wednesday, 8 April 2015 at 22:53:39 UTC, ddos wrote:

why not just make it callable without the alias?


It's to prevent hijacking: http://dlang.org/hijack.html


Re: Accessing a field of a containing class from within a nested class

2015-04-01 Thread anonymous via Digitalmars-d-learn

On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote:

Perhaps BTree needs to be a class?


yes


Re: is it std.datetime bug?

2015-03-31 Thread anonymous via Digitalmars-d-learn

On Tuesday, 31 March 2015 at 11:51:26 UTC, drug wrote:

import std.datetime;
import std.stdio;

void main()
{
long.max.SysTime.toISOExtString.writeln;
}

dmd 2.065 (dpaste.dzfl.pl):
+29228-09-14T02:48:05.4775807

dmd v2.067-devel-c6b489b (using Digger):
-29227-04-20T00:11:54.5224191

could somebody confirm it?


The difference is in time zones. So it's no surprise that the 
output is different.


The negative value is probably because the internal `long` wraps 
around when the difference from your time zone is added to the 
UTC time. I don't know if this is acceptable.


Re: string concatenation with %s

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 17:18:01 UTC, Suliman wrote:

same problem. I am preparing string to next SQL request:

string sss = format(SELECT * FROM test.imgs WHERE src LIKE 
CONCAT('%', REPLACE(CAST(CURDATE()as char), -, ), '%') OR 
CONCAT('%', CAST(CURDATE()as char), '%'));


Here's your code without SQL noise:

string sss = format(foo-, bar);

It should be obvious now that you forgot to escape those double 
quotes.


Re: rvalue based copy

2015-03-30 Thread anonymous via Digitalmars-d-learn
On Monday, 30 March 2015 at 17:21:53 UTC, Steven Schveighoffer 
wrote:

One solution is to overload

void opAssign(ref const S s) {...}
void opAssign(const S s) {...}

lvalues will go into the ref version, rvalues into the non-ref. 
There won't be any copying of data, so you still save a 
postblit and copying on the stack.


But you have to repeat the implementation.


You can call the ref version from the non-ref version:

void opAssign(ref const S s) {...}
void opAssign(const S s) {opAssign(s); /* calls the ref version 
*/}


Of course, only do this when the ref version doesn't store s.


Re: string concatenation with %s

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 17:34:20 UTC, Suliman wrote:

string sss = format(foo-, bar);

It should be obvious now that you forgot to escape those 
double quotes.


Thanks! Is there any way to stay string as is. without need of 
it's escaping and so on?


It's seems I have seen something like it in docs, but I am not 
sure about it...


There are various other string literal forms [1] where you don't 
need to escape double quotes:


AlternateWysiwygString - backticks as delimiters:
`foo -,  bar`

DelimitedString - can use delimiters of choice, here parentheses:
q(foo -,  bar)

TokenString - for D code, probably not a good choice here, but 
works:

q{foo -,  bar}

Of course, as they're all delimiter based, there will always 
something you can't put into the string verbatim.


[1] http://dlang.org/lex.html#StringLiteral


Re: Mapping with partial

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 19:11:10 UTC, matovitch wrote:

That settle the point for array as for [] ?


I though that was clear. [] doesn't copy.

I guess the documentation should have something to say about it 
too. ;)


hopefully


Re: Mapping with partial

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 19:15:25 UTC, matovitch wrote:

Language ref - Array - Slice
An array slice does not copy the data, it is only another 
reference to it.


So the total slice of a static array is a range using the 
underlying memory of the static array isnt it ?


yes


Re: Mapping with partial

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 19:03:05 UTC, matovitch wrote:

Well I have a bit of a similar problem with foreach.

If I use classic T[] range, I can do :

foreach(int i, auto t, myRange)...

But if I use an Array!T (from std.container) I get :

cannot infer argument types, expected 1 argument, not 2

Even if I add the brackets []. Any idea ? Thanks for your help 
! :)


The index is the problem. Generally, foreach doesn't do automatic 
indices for ranges. You can use std.range.enumerate or count 
yourself explicitly.


foreach(i, t; myRange.enumerate) {...}

size_t i = 0;
foreach(t; myRange) {... ++i;}


Re: Mapping with partial

2015-03-30 Thread anonymous via Digitalmars-d-learn

On Monday, 30 March 2015 at 18:37:53 UTC, matovitch wrote:

On Monday, 30 March 2015 at 18:34:19 UTC, Adam D. Ruppe wrote:

[...]
Aye, that would work too, but the slice I think is more 
efficient as I'm pretty sure... not completely sure, but I 
think .array makes a copy of static arrays, whereas the slice 
doesn't.


I was going to ask you the question does it just add the range 
shell or does it make a copy ? :/ Maybe someone else know.


Let's check the documentation. 
http://dlang.org/phobos/std_array.html#array says: Allocates an 
array and initializes it with copies of the elements of range r. 
Documentation says copy.


Let's check the actual behaviour.

void main()
{
int[1] a = [1];
import std.array: array;
a.array[0] = 2;
import std.stdio: writeln;
writeln(a[0]);
}

(also at http://dpaste.dzfl.pl/1191144a9acf)
This program prints 1. That's the output we'd expect when 
`array` makes a copy. Actual behaviour says copy.


So, copy.


Re: Associative Array of Const Objects?

2015-03-29 Thread anonymous via Digitalmars-d-learn

On Sunday, 29 March 2015 at 19:13:32 UTC, bitwise wrote:
Interesting, but I still don't understand why D doesn't have 
something like this:


const Test test;// or const(Test) test;
test = new Test()  // fine, underlaying data is const, the 
reference is not


Test const test = new Test();
test.a = 5;  // fine, test is read-only but 
underlaying data is not const

test = new Test();  // error: test is read-only

const(Test) const test = new Test();
test.a = 5;  // error, underlaying data is const
test = new Test();  // error: read-only


I think the semantics you propose here are not good. The first 
example would change the meaning of existing syntax (bad). The 
second one shows a const reference to mutable data (head const), 
which is a no-go for D so far.


Shuffling things around, this could be less disruptive addition 
to the language:


Test const test; /* mutable reference to const data */

But:

1) Such placement based syntax is foreign to D.

2) It would be special syntax just for class types.

3) It's not how C++ rolls.
`const Test test;` and `Test const test;` are equivalent in C++. 
You need that '*' in C++, too, to make a distinction between 
reference and data.


4) Rebindable works reasonably well, as far as I know. So there 
is not that much pressure to change the language.


Re: Associative Array of Const Objects?

2015-03-29 Thread anonymous via Digitalmars-d-learn

On Sunday, 29 March 2015 at 18:43:32 UTC, bitwise wrote:
I'm a little confused at this point why this doesn't work 
either:


const(Test) test = new Test();  // fine
test = new Test(); // error


In C++, There is a clear distinction:

const Test *test1 = nullptr; // const before type
test1 = new Test();  // fine

Test *const test2 = nullptr; // const before identifier
test2 = new Test();  // error: test2 is readonly

Isn't there such a distinction in D?


Notice how you have that '*' there that allows you to distinguish 
the data from the reference.


You can have a mutable pointer to const data in D, too:

struct Test {}
const(Test)* test1 = null;
test1 = new Test; /* fine */
const(Test*) test2 = null;
/* equivalent variant: const Test* test2 = null; */
test2 = new Test; /* Error: cannot modify const expression test2 
*/


You cannot have a mutable class object reference to const data, 
because syntactically that distinction isn't made in D. There is 
std.typecons.Rebindable, though:


import std.typecons: Rebindable;
class Test {}
Rebindable!(const Test) test = null;
test = new Test; /* fine */

I would have suggested that I got things backward, but this 
doesn't work either:


const Test test = new Test();
test = new Test(); // error: cannot modify const expression


`const Test test` is the same as `const(Test) test`.


Re: Associative Array of Const Objects?

2015-03-29 Thread anonymous via Digitalmars-d-learn

On Sunday, 29 March 2015 at 20:29:50 UTC, bitwise wrote:

3) It's not how C++ rolls.
`const Test test;` and `Test const test;` are equivalent in 
C++. You need that '*' in C++, too, to make a distinction 
between reference and data.


I'm a little confused. I was comparing a C++ pointer-to-class 
to a D reference, which are basically the same under the hood. 
I wasn't trying to bring up C++ value types. I'm not sure how 
they're relevant to the argument.


`Test` can be a pointer type:

class C {};
typedef C *Test;
const Test test1 = 0;
Test const test2 = 0; /* same type as test1 */

The point is that C++ shares the problem: If all you have is one 
identifier (and no pointer star), you can't distinguish the data 
from the pointer.


So C++ syntax could only be properly adopted into D, if D class 
references got something like the pointer star. At that point, 
current D syntax with parentheses would work, too.



4) Rebindable works reasonably well, as far as I know.


The verbosity and blatant disregard for DRY makes me CRY.
See what I did there.. ;)

Anyways, IMO, D could benefit from having tailconst but I 
think it's a moot point.


Yeah, I don't like Rebindable very much either. But it works ok, 
so whatever. If you have strong arguments, maybe post to the 
general forum. For me it's just about aesthetics.


Re: need help with CTFE

2015-03-26 Thread anonymous via Digitalmars-d-learn

On Thursday, 26 March 2015 at 16:19:17 UTC, Dmitri Makarov wrote:

When I compile version DOES_NOT_WORK, I get the following error:
c/tool.d(13): Error: variable name cannot be read at compile 
time
c/tool.d(13):while looking for match for 
hasMember!(Tool, name)


However, the other version ('else' case) compiles, runs, and 
outputs (as expected):

this is a screwdriver.
unknown tool transmogrifier.

What's the fundamental difference that makes the variable 
'name' readable in one version and unreadable in another?


Should the version DOES_NOT_WORK not be compilable in principle 
or is it only a limitation of the current CTFE implementation 
in the front-end?


In DOES_NOT_WORK you're trying to pass `name` in a template value 
parameter. You cannot do that, because `name` is a dynamic 
value but you can only pass a static value there. (There may 
be better terms than dynamic/static value.)


You may think: But it all happens in CTFE, so all values are 
compile time values or static values, aren't they?


They aren't. The semantics during CTFE are the same as for run 
time. `name` is still a dynamic value. If it doesn't fly for run 
time execution, it doesn't fly in CTFE.


To solve the problem at hand, here's one solution that's similar 
to what you tried:


string generate()
{
import std.traits : isCallable;
foreach(memberName; __traits(allMembers, Tool))
{
if(memberName == name)
{
alias M = typeof(mixin(this. ~ memberName));
static if(isCallable!M)
{
return `writeln(this is a ` ~
mixin(this. ~ memberName ~ ()) ~ 
`.);`;

}
}
}
return `writeln(unknown tool ` ~ name ~ `.);`;
}

The foreach is (implicitly) a 'static' one, because 
__traits(allMembers, ...) results in a static/type/expression 
tuple (I don't know what's the best name to set it apart from 
other kinds of tuples).


That means, `memberName` is a static value. And so it can be used 
in mixin, whereas `name` cannot be used there.


Re: D's type classes pattern ?

2015-03-24 Thread anonymous via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 16:56:13 UTC, matovitch wrote:

Thanks, just to be clear :

void Bar(T : Foo)(T t){
}

is the same as

void Bar(T)(T t) if (is(T == Foo)){
}

and it is checked only at compile time ? (for the runtime I 
know that what interface were meant for ;)).


Ali already mentioned the difference between == and :.

In addition to that, template specializations (like `Bar(T : 
Foo)(T t)`) and template constraints (like `Bar(T)(T t) if(is(T : 
Foo))`) are similar but generally not interchangeable.


A template with a specialization is considered a better match 
than one without. Whereas a template constraint doesn't add to 
the quality of the match.


An example:

module test;
import std.stdio;

void f(T)(T t) {writeln(generic);}
void f(T : int)(T t) {writeln(with specialization);}
void f(T)(T t) if(is(T : Object)) {writeln(with constraint);}

void main()
{
f(some string); /* - generic */
f(42); /* - with specialization */
version(none) f(new Object); /* Doesn't compile, because it 
matches both the generic version and the one with the constraint. 
*/

}


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread anonymous via Digitalmars-d-learn

On Saturday, 21 March 2015 at 08:37:59 UTC, Dennis Ritchie wrote:

Tell me, please, why this code works correctly always:

[...]

And this code works correctly is not always:

import std.stdio;

readf(%s\n, n);

char[200010] s, t;
scanf(%s%s, s.ptr, t.ptr);


Please go into more detail about how it doesn't work.


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread anonymous via Digitalmars-d-learn

On Saturday, 21 March 2015 at 15:05:56 UTC, Ivan Kazmenko wrote:

Generate a 10-character string:
-
import std.range, std.stdio;
void main () {'a'.repeat (10).writeln;}
-

Try to copy it with D scanf and printf:
-
import std.stdio;
void main () {
char [10] a;
scanf (%s, a.ptr);
printf (%s\n, a.ptr);
}
-

Only 32767 first characters of the string are actually copied.


That doesn't happen on linux, but I could reproduce it in wine. 
Seems to be a bug in the C runtime (snn.lib). I filed an issue:

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


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread anonymous via Digitalmars-d-learn

On Saturday, 21 March 2015 at 23:00:46 UTC, Ivan Kazmenko wrote:
To me, it looks like a bug somewhere, though I don't get where 
exactly.  Is it in bits of DigitalMars C/C++ compiler code 
glued into druntime?


As far as I understand, the bug is in snn.lib's scanf.

snn.lib is Digital Mars's implementation of the C standard 
library (aka C runtime library or just C runtime). By default, 
some version of the C runtime is linked into every D program, so 
that you (and phobos and druntime) can use it. snn.lib is used 
for Windows x86. For other targets, other implementations of the 
C runtime are used (which don't have that bug).


Re: std.typecons.Proxy + inheritance breaks cast'ing to inherited type

2015-03-17 Thread anonymous via Digitalmars-d-learn

On Tuesday, 17 March 2015 at 07:56:19 UTC, Ali Çehreli wrote:

 Why can't you do this instead?

 t opCast(t)()
 if (is(typeof(cast(T)this)))
 {
  return cast(T)this;
 }

That has the same problem: 'cast(T)this' happens to be an 
explicit cast, which is disabled by the opCast overload for int.


Ali


For classes, `T opCast(T)() {return cast(T) super;}` may be 
viable.


For structs, it's seems more difficult to me.

`return this.to!T;` may try a cast(T), so it has the same problem 
as `return cast(T) this;`: infinite recursion. Example:


struct StdConvTo
{
int* p;
int opCast(T : int)() {return 42;}
T opCast(T)() {import std.conv; return this.to!T;}
}
unittest
{
assert((cast(int) StdConvTo()) == 42); /* ok */
auto i = cast(immutable StdConvTo) StdConvTo(); /* infinite 
recursion */

}

This applies to classes, too.

A reinterpret cast would allow casts that should be rejected:

struct Reinterpet
{
int* p;
int opCast(T : int)() {return 42;}
T opCast(T)() {return * cast(T*) this;}
}
unittest
{
assert((cast(int) Reinterpet()) == 42); /* ok */
auto s = cast(float) Reinterpet(); /* compiles, but shouldn't 
*/

}


Here's something that might work. Construct a tuple of the 
struct's fields (i.e. same data but no opCast). Then cast that to 
T.


struct TupleOf
{
int* p;
int opCast(T : int)() {return 42;}
T opCast(T)()
{
static struct Tuple(S) {S stuff;}
static Tuple!S tuple(S)(S stuff) {return Tuple!S(stuff);}
return cast(T) tuple(this.tupleof);
}
}
unittest
{
assert((cast(int) TupleOf()) == 42); /* ok */
auto i = cast(immutable TupleOf) TupleOf(); /* ok */
static assert(!__traits(compiles, cast(float) TupleOf())); /* 
ok */

}

This is probably not perfect either.


Re: How to test for type without refs?

2015-03-17 Thread anonymous via Digitalmars-d-learn

On Tuesday, 17 March 2015 at 14:06:19 UTC, Charles Hixson wrote:

I thought that in:
T* user(T)()
{static assert (T.sizeof  bfHdr.user_.length);
  static assert (__traits(isPOD, T) );
  returncast(T*) bfHdr.user_.ptr;
}
the line:
static assert (__traits(isPOD, T) );

would test for there not being any embedded refs, pointers, 
etc., but

unittest
{
...
structthead2{stringtest;}
autouserTest2=bf.user!(thead2)();
}
executes without complaint.  Is there a better way?


There's std.traits.hasIndirections 
http://dlang.org/phobos/std_traits.html#hasIndirections.


Re: ref for (const) variables

2015-03-16 Thread anonymous via Digitalmars-d-learn

On Monday, 16 March 2015 at 18:47:00 UTC, Namespace wrote:
const(Matrix)* m = t.getCurrentModelViewMatrix(); // 
currently

}


But IMO it would be a lot nicer if I could store the reference 
like this:


ref const(Matrix) m = t.getCurrentModelViewMatrix(); // nicer


[Of course the name is exaggerated for the purpose of 
demonstration.]


May this be worth of an enhancement request?


Maybe, but I think you'd have to present a better argument. It's 
not obvious to me how `ref T x = y;` is supposed to be a lot 
nicer than `T* x = y;`.



Or was this  already rejected?


I don't know. But since it's a C++ thing, it's probably been 
discussed.


Re: Using std.format required std.string?

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

On Sunday, 15 March 2015 at 18:03:55 UTC, Robert M. Münch wrote:

On 2015-03-15 17:36:24 +, Robert M. Münch said:
Is there a way to use version(...) to have code sections 
depending on compiler version? Something like:


version(dmd = 2.067) or version(dmd  2.067)?


Answerting myself:

static if (__traits(compiles, version_minor  67))
 import std.string; // format() for versions  2.0.67
else
 import std.format; // format() for versions = 2.0.67


That doesn't do what you want.

You need to `import std.compiler;` for version_minor. Without 
that import, `__traits(compiles, version_minor  67)` is always 
false, because version_minor is undefined.


And if you add the import, `__traits(compiles, version_minor  
67)` is always true, no matter the value of version_minor. Use 
`static if(version_minor  67)` instead.


Also, if you check version_minor, it's probably a good idea to 
check (or static assert) version_major, too.


Finally, there's need for this (yet). `std.string.format` is fine 
with 2.067, too. So unless you're going for (far) future 
compatiblity, you can just do `import std.string;`.


Re: What is: Orphan format arguments: args[0..1]

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

On Sunday, 15 March 2015 at 18:46:52 UTC, Charles Hixson wrote:

What is:  Orphan format arguments: args[0..1]
It appears to come from within unittest at the line:
strings={0}.format(cast(int)d2[i]);


It means you gave `format` more arguments than placeholders. 
`format` uses C style % placeholders, not the brace syntax like 
C#(?).


So make that:
strings=%s.format(cast(int)d2[i]);

By the way, I don't see a need for the cast.


Re: get from tuple by type

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

On Sunday, 15 March 2015 at 23:13:58 UTC, Charles Cooper wrote:
And yes, I could use names. But then you are subject to name 
clashes and using strings instead of types as member 
identifiers is more prone to error anyways. Ever gotten this 
wrong before --

void CRITICAL_TO_GET_THIS_RIGHT(uint cents, uint dollars);

alias params_t = Tuple!(uint, dollars, uint, cents);

params_t params;
params.dollars = 0;
params.cents = 99;
CRITICAL_TO_GET_THIS_RIGHT(params.expand);
// compilation succeeds, bank fails.


How would GetByType help here? Both members are uint, so you 
can't distinguish them by type. And if you gave them distinct 
types, the bad example here wouldn't compile anymore either.


Re: get from tuple by type

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

On Sunday, 15 March 2015 at 21:59:18 UTC, Charles Cooper wrote:

C++14 has:
templateclass T, class... Types constexpr T 
get(tupleTypes... t);
Which allows you to get a member of the tuple struct by type. 
Is there an idiomatic / library way to do this in D? Preferably 
by indexing.


I don't think there is. I don't know if there should be. 
Distinguishing tuple fields by their type doesn't seem very 
useful to me, since multiple fields can have the same type.



Here is what I have, it is ugly but works:
/* CODE */
static import std.stdio;
static import std.typecons;
template GetByType(alias tuple_instance, member_t)
{
ref member_t GetByType() nothrow @nogc @safe {
alias tuple_t = typeof(tuple_instance);
static assert(std.typecons.isTuple!tuple_t);
enum long idx = std.typetuple.staticIndexOf!(member_t, 
tuple_instance.Types);

static if(-1 != idx)
return tuple_instance[idx];
else static assert(false); //better error message
}
}

static assert(2.5 == GetByType!(std.typecons.tuple(1,2.5), 
double));
static assert(2.5 == GetByType!(std.typecons.tuple(1,2.5,3.1), 
double));

void main() {
auto foo = std.typecons.tuple(1,2.5);
std.stdio.writeln(GetByType!(foo, double));
}
/* CODE */

Is there a better way to do this?


I went over it (some notes below):


import std.typecons: Tuple;

auto ref inout(T) getFirst(T, Types ...)(auto ref 
inout(Tuple!Types) t)

{
import std.typetuple: staticIndexOf;
enum idx = staticIndexOf!(T, Types);
static if(-1 != idx)
return t[idx];
else static assert(false); //better error message
}

unittest
{
import std.typecons: tuple;

assert(2.5 == tuple(1, 2.5).getFirst!double);
assert(2.5 == tuple(1, 2.5, 3.1).getFirst!double);
static assert(2.5 == tuple(1, 2.5).getFirst!double); // CTFE

static assert(!__traits(compiles, tuple(1, 
2.5).getFirst!string));


// lvalue tuple = lvalue result
auto m = tuple(1, 2.5);
m.getFirst!double = 2.1;
assert(m[1] == 2.1);

// rvalue tuple = rvalue result
static assert(!__traits(compiles, tuple(1, 
2.5).getFirst!double));


// immutable/const
immutable i = tuple(1, 2.5);
assert(2.5 == i.getFirst!double);
const c = tuple(1, 2.5);
assert(2.5 == c.getFirst!double);

}

void main()
{
import std.stdio: writeln;
import std.typecons: tuple;
auto foo = tuple(1, 2.5);
writeln(foo.getFirst!double);
}


Using combined syntax for function template.

Made the tuple a function parameter like in the C++ version. I 
don't see the point in having it a template alias parameter.


Dropped `nothrow @nogc @safe`, since copying the member might not 
be any of that. They are inferred when possible.


Employing inout and `auto ref`.

More tests. unittest block instead of `static assert`s.

Bikeshedding:

Changed name to getFirst, since subsequent values of the same 
type are ignored.


Named things more like the C++ version: member_t - T, 
tuple_instance - t.


Use selective imports instead of static imports.

Use more common casing: types and type templates are PascalCased, 
everything else is camelCased.


Brace placement.


Re: Garbage collector returning pointers

2015-03-14 Thread anonymous via Digitalmars-d-learn

On Saturday, 14 March 2015 at 18:26:34 UTC, Robert M. Münch wrote:

Hi, I have a question about how the GC handles this case:

export extern(C) char* foo(){
 char[] x = This is a dynamic D string..dup;

 return(cast(char*)x);
}


Returning `x.ptr` would look a little nicer.



Since x is pointer to array data  length if it goes out of 
scope, it's destroyed and the last reference to the array data 
is gone. Hence, the GC could kick in and free the array data. 
Is this correct?


No.

Or will the GC know, that there was a pointer to the array data 
returned and hence a new reference exists as long until someone 
tells the GC that the pointer is no longer used?


Yes. The returned pointer is a reference. Once that reference is 
gone, the GC can collect the array. You don't need to explicitly 
inform the GC when you're done with the pointer.


My situation is, that the returned pointer is used to copy the 
result to some interpreter internal state. Depending on the 
answers above, there could be a short time where the memory 
state is collectable before the coyping was finished.


I think you're safe.


Re: Parallelization of a large array

2015-03-10 Thread anonymous via Digitalmars-d-learn

On Tuesday, 10 March 2015 at 20:41:14 UTC, Dennis Ritchie wrote:

Hi.
How to parallelize a large array to check for the presence of 
an element matching the value with the data?


std.stdio;
std.algorithm;
std.parallelism;


You forgot a couple imports here.



void main() {

int[] a = new int[100];

foreach (i, ref elem; a)
elem = i;


Type mismatch here. i is a size_t, but elem is an int.



/*if (find(parallel(a), 895639).length != 0)
writeln(Yes);
else
writeln(No);*/
}


I guess you'd have to write your own find. Since 
std.algorithm.find is just linear search, that shouldn't be hard. 
Something like this:


bool found = false;
foreach(x; parallel(a))
{
if(x == 895639)
{
found = true;
/* Maybe figure out how to break all parallel loops. */
}
}

std.algorithm.find would work on mere input ranges, and it would 
return the tail of the range and not just a bool. Both of those 
don't make sense with a parallel search, though.


Also, with a trivial predicate like integer equality, 
parallelization might not buy you anything.


Re: Int to float?

2015-03-05 Thread anonymous via Digitalmars-d-learn

On Thursday, 5 March 2015 at 20:03:09 UTC, Benjamin Thaut wrote:

int someValue = 5;
float sameBinary = *(cast(float*)cast(void*)someValue);


The cast(void*) isn't necessary.


Re: Object as function argument

2015-03-05 Thread anonymous via Digitalmars-d-learn

On Thursday, 5 March 2015 at 19:51:09 UTC, Max Klyga wrote:
If you really need the actual pointer to object data you can 
use `*cast(void**)myObject`. Compiler cannot cast object 
reference to `void*` but we can trick it ;)


It can, actually. A class can define its own cast(void*) though, 
so the reinterpret way may be more robust. Also, I'm not sure if 
any of this is specified. So watch out for undefined (or 
underspecified) behaviour.


Re: Int to float?

2015-03-05 Thread anonymous via Digitalmars-d-learn

On Thursday, 5 March 2015 at 20:21:18 UTC, badlink wrote:

On Thursday, 5 March 2015 at 20:16:55 UTC, anonymous wrote:
On Thursday, 5 March 2015 at 20:03:09 UTC, Benjamin Thaut 
wrote:

int someValue = 5;
float sameBinary = *(cast(float*)cast(void*)someValue);


The cast(void*) isn't necessary.


Actually even the cast is unecessary, just use a uniform.

union N {
int i;
float f;
}

http://dpaste.dzfl.pl/58b6eddcf725


That's not really simpler, though.


Re: strage heisenbug (has scoped destruction, cannot build closure)

2015-03-03 Thread anonymous via Digitalmars-d-learn

On Tuesday, 3 March 2015 at 07:26:13 UTC, ketmar wrote:

hi.

the following (manually dustmited ;-)) code gives the error 
from subj

on git HEAD:

=== ztest.d ===
  module ztest;

  auto streamAsRange(STP) (STP st) {
static struct StreamRange(ST) {
private:
  ST strm;
public:
  void put (const(ubyte)[] data) { strm.rawWrite(data); }
}
return StreamRange!STP();
  }

  void zcompress(RO) (RO ro) {
ubyte[1] obuf;

void writeOBuf () {
  static if (is(typeof(() {
ubyte[2] b;
ro.put(b);
  }))) {
ro.put(obuf);
  }
}

writeOBuf();
  }

  void test () {
import std.stdio;
auto fo = File();
zcompress(streamAsRange(fo));
  }

  void main () {
  }
==


Reduced further:


module ztest;

struct StreamRange {
  ~this() {}
  void put() {}
}

void zcompress(StreamRange ro) {
  void writeOBuf() {
enum e = is(typeof({ro.put();}));
ro.put();
  }
  writeOBuf();
}

void main() {
  zcompress(StreamRange());
}


Looks like a compiler bug to me.


Re: Strange alias behaviour in template arguments

2015-03-03 Thread anonymous via Digitalmars-d-learn

On Tuesday, 3 March 2015 at 13:42:09 UTC, Stefan Frijters wrote:
So this is a strange thing I ran into while trying to 
streamline some templates in my code, where fixed-length arrays 
are passed as runtime arguments. I started out by trying 
variant fun2(), which disappointingly didn't work. fun3() then 
did its job but I was suspicious and tried fun4() and fun(5), 
which also worked but shouldn't. Is this a bug or am I doing 
something bad?


struct Connectivity(uint _d, uint _q) {
  enum d = _d; // Number of dimensions
  enum q = _q;
}

alias d2q9 = Connectivity!(2,9);

// Stores fixed-size array of base type T, and the length of 
the array is determined by the connectivity.

struct Field(T, alias c) {
  alias conn = c;
  T[conn.d] payload;

  this(in T[conn.d] stuff) {
payload = stuff;
  }
}

// Ok
void fun(T)(T field) {
  pragma(msg, T);
  pragma(msg, T.conn);
  pragma(msg, T.conn.d);
  pragma(msg, T.conn.q);
}

// cannot deduce function from argument types
void fun2(T)(T field, double[T.conn.d] foo) {
  pragma(msg, T);
  pragma(msg, T.conn);
  pragma(msg, T.conn.d);
  pragma(msg, T.conn.q);
  field.payload = foo;
}

// Ok!
void fun3(T, alias d = T.conn.d)(T field, double[d] foo) {
  pragma(msg, T);
  pragma(msg, T.conn);
  pragma(msg, T.conn.d);
  pragma(msg, T.conn.q);
  pragma(msg, typeof(foo)); // 2, okay
  field.payload = foo;
}

// Huh?
void fun4(T, alias d = T.conn.q)(T field, double[d] foo) {
  pragma(msg, T);
  pragma(msg, T.conn);
  pragma(msg, T.conn.d);
  pragma(msg, T.conn.q);
  pragma(msg, typeof(foo)); // expect 9, get 2
  field.payload = foo;
}

// Huh?
void fun5(T, alias d = T.conn)(T field, double[d] foo) {
  pragma(msg, T);
  pragma(msg, T.conn);
  pragma(msg, T.conn.d);
  pragma(msg, T.conn.q);
  pragma(msg, typeof(foo)); // don't know what to expect, still 
get 2

  field.payload = foo;
}

void main() {
  double[d2q9.d] foo;
  auto f = Field!(double, d2q9)(foo);

  f.fun(); // Sure, this works
  // f.fun2(foo);  // Won't work without additional alias
  f.fun3(foo); // Works, so are we happy?
  f.fun4(foo); // No! This isn't supposed to work...
  f.fun5(foo); // Nor this...
}

Any thoughts?


I don't know if there's a reason why fun2 doesn't work. I don't 
see one.


fun4 and fun5 work correctly. They are the same as fun3, just 
with other default values for d. Those default values are not 
used, because d is inferred from the argument to be 2. If you 
pass a double[3], d is inferred to be 3 (and the compiler 
complains on `field.payload = foo`).


You can use a static assert or a template constraint to work 
around fun2 not working:


void fun6(T, size_t d)(T field, double[d] foo)
{
  static assert(d == T.conn.d);
  ...
}
void fun7(T, size_t d)(T field, double[d] foo) if(d == T.conn.d)
{
  ...
}


Re: On opCmp

2015-02-27 Thread anonymous via Digitalmars-d-learn

On Friday, 27 February 2015 at 11:04:51 UTC, Nordlöw wrote:
Is there a more compact way to describe the opCmp function in 
the following struct


struct Hit
{
size_t count; // number of walkers that found this node
NWeight rank; // rank (either minimum distance or maximum 
strength)


auto opCmp(const Hit rhs) const
{
if  (this.count  rhs.count)
{
return -1;
}
else if (this.count  rhs.count)
{
return +1;
}
else
{
if  (this.rank  rhs.rank)
{
return -1;
}
else if (this.rank  rhs.rank)
{
return +1;
}
else
{
return 0;
}
}
}
}

by reusing something like

auto opCmp(const Hit rhs) const
{
if  (this.count  rhs.count)
{
return -1;
}
else if (this.count  rhs.count)
{
return +1;
}
else
{
return this.rank.standardOpCmp(rhs.rank)
}
}


Two things come to mind:

A) std.algorithm.cmp


auto opCmp(const Hit rhs) const
{
import std.algorithm: cmp;
import std.range: only;
if(auto c = cmp(only(count), only(rhs.count)))
{
return c;
}
else /* 'count' values are equal. */
{
return cmp(only(rank), only(rhs.rank));
}
}


Maybe there should be a std.algorithm.cmp for non-ranges, too, so 
that `only` wouldn't be needed here.


B) std.typecons.Tuple has an opCmp that compares all fields in 
order.



auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return tuple(count, rank).opCmp(tuple(rhs.count, rhs.rank));
}


This exact behaviour is not documented, though. So I guess it 
should not be relied on. Maybe the documentation should be more 
specific. In the meantime, you could duplicate the functionality 
in a function of your own:



import std.typecons: Tuple;

/** Put a proper, specific description here.
*/
int cmpTuples(Types ...)(Tuple!Types a, Tuple!Types b)
{
// copied from std.typecons.Tuple.opCmp
foreach (i, Unused; Types)
{
if (a[i] != b[i])
{
return a[i]  b[i] ? -1 : 1;
}
}
return 0;
}

struct Hit
{
size_t count;
NWeight rank;

auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return cmpTuples(tuple(count, rank), tuple(rhs.count, 
rhs.rank));

}
}




Re: @trusted and return ref

2015-02-26 Thread anonymous via Digitalmars-d-learn
On Thursday, 26 February 2015 at 10:15:07 UTC, Ola Fosheim 
Grøstad wrote:

On Wednesday, 25 February 2015 at 22:59:01 UTC, anonymous wrote:
rule-breaking that's going on there. A public trusted_malloc 
would invite the un-initiated to shoot their feet.


That's entirely social...


Sure.

A @trusted function that's not actually memory-safe is against 
the definition of @trusted. Breaking that rule on a public 
function is not acceptable. Breaking it locally is apparently ok 
as long as the surrounding entity (RCArray) is actually 
memory-safe in the end.


I'm not trying to argue that this is good. Maybe the current 
system allows for a better way to solve such issues. If it 
doesn't, maybe the @safe/@trusted system needs an upgrade.


[...]
If you can inject new code that is not marked @trusted 
explicitly into already written code that is marked @trusted, 
then the trust type system is broken.


The whole point of @trusted is to be able to call @system code. 
It doesn't matter if that code is injected or not. @safe 
prevents calling @system code.


[...]

It infers @safe, but it does not provide validation.


Yup. RCArray is de-facto trusted, i.e. verified memory-safe by 
the programmer. It's not compiler verified safe, even though it 
ends up being labeled @safe.


Re: Installing DMD From Zip

2015-02-26 Thread anonymous via Digitalmars-d-learn
On Thursday, 26 February 2015 at 10:55:40 UTC, Jonathan M Davis 
wrote:
I think that it was the same page, though I could be 
remembering wrong.
Several articles are missing as well (e.g. the one on 
std.datetime and the
one on arrays), so I don't know how careful they really were in 
updating the

website.


The pages are still there, they're just not linked from anywhere 
(except for the sitemap). I don't know what happened.


On dmd (installation, flags, etc):
http://dlang.org/dmd-linux.html
http://dlang.org/dmd-windows.html
http://dlang.org/dmd-osx.html
http://dlang.org/dmd-freebsd.html

Introduction to std.datetime:
http://dlang.org/intro-to-datetime.html

D Slices:
http://dlang.org/d-array-article.html


Re: @trusted and return ref

2015-02-26 Thread anonymous via Digitalmars-d-learn
On Thursday, 26 February 2015 at 20:56:52 UTC, Ola Fosheim 
Grøstad wrote:
But it should matter, because when you mark a unit @trusted you 
basically are signing off a certificate that says it acts 
like @safe in @safe code. How can you verify anything if you 
allow injections?


If you allow @system injections, you can't verify safety, 
obviously. Such code must not be @trusted. That's why RCArray is 
not @trusted.


You can only verify what is known when the verification took 
place. After that it should be frozen so that injections of 
non-verified code only goes into @safe slots.


I don't know if it should work like that. I don't have a good 
enough understanding of the matter to argue for or against any 
one design.


[...]
Well, but @safe code is not verified either... It is inferred 
@safe based on a fixed set of criterions, but not verified. To 
verify you need more, and you have to start with strong typing.


The criterion being: doesn't call @system code. If that's not 
enough to ensure memory-safety (given proper usage of @trusted) 
then I guess the current system has failed, or the implementation 
has bugs.


I don't think that the ability to break the type system (as done 
in RCArray) means that @safe has failed, though. We can 
forcefully break the type system in many ways. That doesn't mean 
it's not sound.


I'm probably not the guy to discuss weak and strong typing 
with. As I don't have a good understanding of type system theory.


Re: @trusted and return ref

2015-02-25 Thread anonymous via Digitalmars-d-learn
On Wednesday, 25 February 2015 at 07:07:00 UTC, Ola Fosheim 
Grøstad wrote:

On Wednesday, 25 February 2015 at 00:12:41 UTC, anonymous wrote:

[...]
That sounds more attractive than the provided example, but the 
right thing to do is to establish proper encapsulation. That 
means you need a protection level that is stronger than 
private that restricts unsafe state to a @trusted vetted 
construct. Like unique_ptr informally does in C++.


I'm not knowledgeable enough to agree or disagree here.

But why is malloc and free not considered safe by default 
then?


Well, because they aren't.


So that should change?


We can't make malloc and free actually memory-safe, can we? We 
must not mark public unsafe functions @safe/@trusted.


You mean outside RCArray, iff RCArray as a whole is manually 
verified?  But that would surely mean that the @trusted region 
is RCArray and neither the constructor or malloc/free?


RCArray as a whole is the actually trusted region, yes, since it 
must be manually verified that RCArray.array isn't leaked. But 
you can't mark it @trusted, because E may be unsafe.


The @trusted malloc/free dance is a mean hack to solve a problem. 
There may be other solutions that don't require breaking 
@trusted. Those may be better.


And that assumes strong typing, which D currently does not 
provide. Without strong typing it will be very difficult for 
the compiler to infer anything across compilation units.


I don't follow.


Re: How can I do that in @nogc?

2015-02-25 Thread anonymous via Digitalmars-d-learn

On Wednesday, 25 February 2015 at 19:32:50 UTC, Namespace wrote:


void glCheck(lazy void func, string file = __FILE__, uint line 
= __LINE__) {

func();
glCheckError(file, line);
}


How can I specify that 'func' is @nogc? Or can define the 
function otherwise?


First of all, if glCheck always uses/evaluates func, then there 
is no point in making it lazy.


On to the @nogc vs. lazy issue.

Simpler test case:
---
void glCheck(scope lazy int thing) @nogc {auto x = thing;}
int costly() @nogc {return 42;}
void main() @nogc
{
glCheck(costly()); /* A */
int x; glCheck(x); /* B */
}
---

I guess, the compiler could see that the delegate made for the 
lazy parameter must be @nogc. But it doesn't. So it tries to call 
a non-@nogc delegate in a @nogc function which fails of course.


You can make the delegate explicit so that you can tag the 
delegate as @nogc yourself:

---
void glCheck(scope int delegate() @nogc thing) @nogc {auto x = 
thing();}

int costly() @nogc {return 42;}
void main() @nogc
{
glCheck(()=costly());
int x; glCheck(()=x);
}
---

The calls are not as nice, requiring an explicit delegate 
(()=), but it works.


It may be possible to hack through this limitation - NOT 
THOUGHT-OUT, NOT TESTED, NOT RECOMMENDED:

---
void glCheck(scope lazy int thing) @nogc;
pragma(mangle, glCheck.mangleof) void glCheckImpl(scope int 
delegate() @nogc thing) @nogc {auto x = thing();}

int costly() @nogc {return 42;}
void main() @nogc
{
glCheck(costly());
int x; glCheck(x);
}
---


Re: How can I do that in @nogc?

2015-02-25 Thread anonymous via Digitalmars-d-learn

On Wednesday, 25 February 2015 at 20:36:33 UTC, Namespace wrote:

On Wednesday, 25 February 2015 at 20:15:10 UTC, anonymous wrote:

[...]
It may be possible to hack through this limitation - NOT 
THOUGHT-OUT, NOT TESTED, NOT RECOMMENDED:

---
void glCheck(scope lazy int thing) @nogc;
pragma(mangle, glCheck.mangleof) void glCheckImpl(scope int 
delegate() @nogc thing) @nogc {auto x = thing();}

int costly() @nogc {return 42;}
void main() @nogc
{
   glCheck(costly());
   int x; glCheck(x);
}
---


That last thing works. But I have no clue why. o.O
Anyway, thanks a lot!


I advise you to not use it. It's a hack that relies on 
implementation details of the compiler.


As for how it works:

pragma(mangle, ...) sets the mangled name of the following 
symbol. The mangled name is similar to the fully qualified 
name, but it includes parameter types and such. So different 
overloads of a function have different mangled names, while 
sharing one fully qualified name.


Giving glCheckImpl the same mangled name as glCheck means they 
then refer to the same code despite having different signatures. 
This bypasses the type system. DON'T DO THIS.


So, whenever glCheck is called, really glCheckImpl is called, and 
the `scope lazy int` argument is interpreted as a `scope int 
delegate() @nogc` argument.


This works, because currently the compiler creates delegates for 
lazy arguments and calls those delegates when the arguments are 
accessed. So right now, `lazy int` is the same as `int 
delegate()` under the hood. But this is not guaranteed. The 
compiler is free to do this differently. It may depend on 
compiler flags, etc. SO DON'T DO THIS.


Re: @trusted and return ref

2015-02-25 Thread anonymous via Digitalmars-d-learn
On Wednesday, 25 February 2015 at 22:16:14 UTC, Ola Fosheim 
Grøstad wrote:
My point was that there is no conceptual difference between 
having a named function trusted_malloc!int() and trusted_free() 
and wrapping them up individually unnamed.


An ad-hoc declared @trusted malloc is just as unsafe as a public 
one, of course. But there's a difference in exposure. People 
working on RCArray are supposed to know about the rule-breaking 
that's going on there. A public trusted_malloc would invite the 
un-initiated to shoot their feet.


RCArray as a whole is the actually trusted region, yes, since 
it must be manually verified that RCArray.array isn't leaked. 
But you can't mark it @trusted, because E may be unsafe.


But the semantic analysis should verify that code isn't 
injected unless it is also @trusted?


You mean the compiler should enforce E to be @safe/@trusted? That 
wouldn't happen with an @trusted RCArray, because @trusted code 
may call @system code.


It would be done with an @safe RCArray. But I guess that's deemed 
too limiting. RCArray is supposed to work with unsafe E types, 
too.


And that assumes strong typing, which D currently does not 
provide. Without strong typing it will be very difficult for 
the compiler to infer anything across compilation units.


I don't follow.


C is not strongly typed, and neither is D. That means there are 
holes in the type system.


I'm a bit lost. What I meant was that the compiler infers @safe 
for methods of templated structs when they don't call any @system 
code.


Here: RCArray's this/~this are inferred @safe iff E's 
__postblit/__dtor are @safe/@trusted.


This is how it works right now, regardless of any holes in the 
type system.


Re: @trusted and return ref

2015-02-24 Thread anonymous via Digitalmars-d-learn
On Tuesday, 24 February 2015 at 22:37:58 UTC, Ola Fosheim Grøstad 
wrote:
1. My understanding is that @trusted is supposed to give memory 
safety escapes by providing a context which reestablish a 
memory safety context on return.


Yep, that's how I got it, too. A @trusted function is supposed to 
be memory-safe.


Yet in this thread 
http://forum.dlang.org/thread/mcik3j$153g$1...@digitalmars.com it 
is stated that this paradigm is an example of «careful use of 
@trusted»:


count = (() @trusted = cast(uint*) malloc(uint.sizeof))();
…arbitrary code…
(() @trusted = free(count))();

They way I see it, this is equivalent to typing a 
reinterpret_casting malloc and free as memorysafe operations in 
isolation, basically providing a malloc!int() and free() as 
memory safe functions.


Yep. Careful use: You have be careful when you (ab)use @trusted 
like this.


The idea is that the compiler enforces safety for the rest of the 
code. You have to be cautious about the effects of the @trusted 
malloc/free, but the compiler checks the other stuff. If the 
whole function was @trusted, the compiler wouldn't catch other 
safety violations that are not related to malloc/free.


The downside is that @safe on that function then doesn't mean 
compiler verified memory-safe anymore. Instead it means 
compiler assisted @trusted.


There's also the other way around: Mark the function as @trusted 
and throw ()@safe{...}() covers over the non-problematic parts. 
This doesn't work when a template parameter affects the safety, 
though.



But why is malloc and free not considered safe by default then?


Well, because they aren't.

These @trusted functions clearly cannot prevent leaks within 
their own context. You would need a @trusted-only storage class 
on the receiving pointer to do that and a @trusted move type.


If this is careful use of @trusted, then I don't see the point 
of having @trusted at all. What is the purpose? What is it 
meant to cover? In order for @trusted to make sense in this 
code segment ( http://dpaste.dzfl.pl/f3d854feede9 ) I would say 
that the whole class will have to be marked @trusted. Is that 
possible?


The goal is to have human verified, compiler recognized 
memory-safety, when E allows for it.


You can't:
* mark nothing @safe/@trusted, because malloc/free are not safe;
* mark the methods @trusted, because E may be unsafe.

@trusted malloc/free is a hack, but it allows the compiler to 
infer @safe iff E is safe.


Re: Passing variadic arguments to C

2015-02-22 Thread anonymous via Digitalmars-d-learn

On Sunday, 22 February 2015 at 17:09:27 UTC, Foo wrote:

Is this possible?

Example:

void foo(Args...)(auto ref Args args) {
sprintf(str.ptr, fmt.ptr, args);
}



yes


Re: What is the Correct way to Malloc in @nogc section?

2015-02-21 Thread anonymous via Digitalmars-d-learn

On Saturday, 21 February 2015 at 13:41:41 UTC, Foo wrote:
Finally, I tried to take your criticism objectively and, as far 
as I can tell, I resolved the issues. Is there still any 
objections or misconduct?


Nice. I think you fixed everything I had pointed out.


Re: Best practices for reading public interfaces

2015-02-21 Thread anonymous via Digitalmars-d-learn

On Saturday, 21 February 2015 at 20:46:09 UTC, Kenny wrote:

b) Write DDocs and read documentation. The problem here is that
I'm going to use D only for my own projects and in the last time
I tend to write less documentation, for example I do not write 
it

for the most methods of Vector3D.


If you're only interested in the signatures, empty documentation 
comments give you that.


Re: Type-Strict Indexes: IndexedBy

2015-02-18 Thread anonymous via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 19:46:09 UTC, Nordlöw wrote:

Superb! I'd like to see this getting into std.typecons.

Having this in the language will attract (more) Ada programmers 
to D.


Should I do PR for std.typecons.[iI]ndexedBy?


I'm not familiar with Ada, and I don't immediately see what 
indexedBy is good for. So maybe gather some examples where it's 
beneficial, before going for Phobos.


Re: Type-Strict Indexes: IndexedBy

2015-02-17 Thread anonymous via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 13:38:41 UTC, Per Nordlöw wrote:
This looses most of the meaning of my idea. I still want my 
range to inherit all the powers of its wrapped range.


Is there no way to disable member functions in D?


I hadn't thought of @disable. Played around with it a bit. The 
following code seems to work. I didn't really test it or think 
very hard about it, though.


Regarding opIndexAssign: Without it, alias this jumps in on 
assignments, and the ref opIndex is not considered. This may be a 
compiler bug.


Be aware that with alias this, IndexedBy!(R, I) implicitly 
converts to R. So it's easy to (accidentally) fall back to a 
plain R, where nothing is `@disable`d. I don't know if this is 
desirable or not.



struct Ix(T = size_t)
{
@safe pure: @nogc nothrow:
this(T ix) { this._ix = ix; }
alias _ix this;
private T _ix = 0;
}

struct IndexedBy(R, I)
{
auto ref opIndex(I ix) inout { return _r[ix]; }
void opIndexAssign(V)(V value, I ix) {_r[ix] = value;}
alias RI = size_t; /* TODO: Extract this from R somehow. */
static if(!is(RI == I))
{
@disable void opIndex(RI i);
@disable void opIndexAssign(V)(V value, RI i);
}
R _r;
alias _r this;
}

auto indexedBy(I, R)(R range)
{
return IndexedBy!(R, I)(range);
}

unittest
{
import std.stdio;
auto x = [1, 2, 3];
alias I = int;
auto ix = x.indexedBy!I;
ix[0] = 11;

alias J = Ix!size_t;
auto jx = x.indexedBy!J;
jx[J(0)] = 11;
static assert(!__traits(compiles, (jx[0] = 11)));
}



Re: Type-Strict Indexes: IndexedBy

2015-02-16 Thread anonymous via Digitalmars-d-learn

On Monday, 16 February 2015 at 20:09:09 UTC, Nordlöw wrote:

How can I prevent

jx[0] = 11;

from compiling?


Remove that `alias _r this;`. You don't want to forward opIndex, 
so you can't use alias this which forwards everything that 
doesn't compile. opDispatch may be an option to forward 
everything but opIndex.


Re: ranges reading garbage

2015-02-16 Thread anonymous via Digitalmars-d-learn

On Sunday, 15 February 2015 at 22:38:20 UTC, anonymous wrote:

And more:

import std.stdio;
struct MapResult(alias fun)
{
@property int front() {return fun();}
@property auto save() {return typeof(this)();}
}
void main()
{
int ys_length = 4;
auto dg = {return MapResult!({return ys_length;})();};
writeln(dg().front); /* 4, correct */
writeln(dg().save.front); /* garbage */
}


It's already in bugzilla: 
https://issues.dlang.org/show_bug.cgi?id=9685


Re: shared interfaces

2015-02-15 Thread anonymous via Digitalmars-d-learn
On Sunday, 15 February 2015 at 10:43:46 UTC, Andrey Derzhavin 
wrote:
what is wrong in declarations, if I need to declare shared 
classes D and C?


`shared` on a class/interface makes all members shared. And 
that's all it does.


So this:


interface IA
{
void fnA();
}
shared class C : IA
{
override void fnA() {}
}


is the same as this:



interface IA
{
void fnA();
}
class C : IA
{
override void fnA() shared {}
}


But you can't override a non-shared method with a shared one, 
hence the error.


So, if you need to override non-shared methods, you can't mark 
the whole class shared. Instead, you have to mark the shared 
members individually. Like so:



interface IA
{
void fnA();
}
shared interface IC : IA
{
void fnC();
}
class D : IC
{
override void fnC() shared {}
override void fnA() {}
}



Re: shared interfaces

2015-02-15 Thread anonymous via Digitalmars-d-learn
On Sunday, 15 February 2015 at 12:34:50 UTC, Andrey Derzhavin 
wrote:

On Sunday, 15 February 2015 at 11:30:46 UTC, anonymous wrote:

[...]


interface IA
{
   void fnA();
}
shared interface IC : IA
{
   void fnC();
}
class D : IC
{
   override void fnC() shared {}
   override void fnA() {}
}


Try to compile your example, it is wrong.


Hm? Works for me. What error do you get, or what doesn't work? 
Which compiler are you using, which version?


Re: ranges reading garbage

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

On Sunday, 15 February 2015 at 18:13:44 UTC, John Colvin wrote:

Simplified from something bigger:

import std.range, std.algorithm, std.stdio;

void foo(float[] data, float[] xs, float[] ys)
{
auto indices = iota(0, data.length, ys.length)
.map!(xBase =
iota(xBase, xBase + ys.length - 1)
.map!(y =
only(y, y+ys.length, y+ys.length+1, y+1))
.joiner())
.joiner();
writeln(indices);
}

void main()
{
foo([1,2,3,4,5,6,7,8],
[0.1,0.2], [10,20,30,40]);
}

prints things like [0, 4, 5, 1, 1, 1459971595, 1459971596, 2, 
2, 1459971596, 1459971597, 3, 4, 8, 9, 5, 5, 4441427819, 
4441427820, 6, 6, 4441427820, 4441427821, 7] but the output 
isn't consistent, the big numbers change on each run.


Reduced some more:

import std.algorithm, std.stdio;
void main()
{
int ys_length = 4;
auto indices = [0]
.map!(xBase = [0].map!(y = ys_length))
.joiner();
writeln(indices);
}


Re: ranges reading garbage

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

On Sunday, 15 February 2015 at 19:54:45 UTC, anonymous wrote:

Reduced some more:

import std.algorithm, std.stdio;
void main()
{
int ys_length = 4;
auto indices = [0]
.map!(xBase = [0].map!(y = ys_length))
.joiner();
writeln(indices);
}


And more:

import std.stdio;
struct MapResult(alias fun)
{
@property int front() {return fun();}
@property auto save() {return typeof(this)();}
}
void main()
{
int ys_length = 4;
auto dg = {return MapResult!({return ys_length;})();};
writeln(dg().front); /* 4, correct */
writeln(dg().save.front); /* garbage */
}


Re: dmd-2.067.0-b1

2015-02-13 Thread anonymous via Digitalmars-d-learn
On Friday, 13 February 2015 at 13:25:55 UTC, Steven Schveighoffer 
wrote:
Yes, the operator precedence (curiously not defined in the 
spec) is here:


http://wiki.dlang.org/Operator_precedence

Conditional operator is above assignment operators.


It's specified through the grammar [1]:


AssignExpression:
ConditionalExpression
ConditionalExpression = AssignExpression
[...]

ConditionalExpression:
OrOrExpression
OrOrExpression ? Expression : ConditionalExpression


The third operand of ConditionalExpression cannot be an 
AssignExpression without parentheses.


So `foo ? bar : baz = qux` can only be interpreted as `(foo ? bar 
: baz) = qux`.


[1] http://dlang.org/expression.html


Re: What is the Correct way to Malloc in @nogc section?

2015-02-13 Thread anonymous via Digitalmars-d-learn

On Thursday, 12 February 2015 at 23:52:41 UTC, Foo wrote:

This is something I've done recently.
Would be glad if my code will help you:
https://github.com/Dgame/m3
Especially the m3.d module could be useful for you.


/* Class and Struct */

emplace: You can't assume zero-initialization for structs.
destruct: Is not memory-safe, and must not be marked @trusted.

/* Array */

make: You can't assume zero-initialization. T.sizeof is not the 
size of an element.
reserve: Not safe (you're freeing the old memory), must not be 
@trusted.
append: T.sizeof is not the size of an element. You're 
multiplying twice with T.sizeof; in `append`, and also in 
`reserve`.

destruct: Not safe, must not be @trusted.


Re: What is the Correct way to Malloc in @nogc section?

2015-02-13 Thread anonymous via Digitalmars-d-learn

On Friday, 13 February 2015 at 23:04:25 UTC, Foo wrote:
Don't understand me wrong. My code is not perfect, but maybe it 
can be helpful for someone.


As it is right now, I fear it may do more harm than good.


Re: Cannot use the same template arguments on function as the ones on struct

2015-02-11 Thread anonymous via Digitalmars-d-learn

On Wednesday, 11 February 2015 at 22:14:44 UTC, MrSmith wrote:

http://dpaste.dzfl.pl/5f1d5d5d9e19

Instead I need to use template constraint which is less compact.
http://dpaste.dzfl.pl/571ae84d783e

Why such behavior happens?


Seems to work when you add an empty template argument list to 
`accepter()`, making it `accepter!()()`: 
http://dpaste.dzfl.pl/2ec186453907


So, compiler bug, I guess? The error message says it tried 
!()(), but explicit !()() actually works. And the empty 
template argument list should be optional anyway.


Re: Fun with floating point

2015-02-07 Thread anonymous via Digitalmars-d-learn

On Saturday, 7 February 2015 at 22:46:56 UTC, Ali Çehreli wrote:

1.0 is famously not representable exactly.


1.0 is representable exactly, though.


Re: strange work of GC

2015-02-06 Thread anonymous via Digitalmars-d-learn
On Friday, 6 February 2015 at 20:38:07 UTC, Andrey Derzhavin 
wrote:
As I think, the garbage collector should start destoying of the 
C1 and C2 objects of arr array during the while cycle 
prosess, but this does not

happen. Dtors are not called.


Garbage is only collected when you allocate memory. You're just 
`sleep`ing in the loop which doesn't allocate anything, and so it 
doesn't trigger garbage collections.


If I use the manual destroying of objects C1 and C2 by 
destroy method, the dtors of C1 and C2 objects are normally 
called, but it can't be safe.


right

If I use the GC.collect method after fn1, I get an error: 
core.exception.InvalidMemoryOperationError@(0).

Is this a bug of GC or I do something wrong?


This is you GC allocating in a destructor (the writeln calls). 
The GC can't handle that.


Re: Syntax for checking if an element exists in a list

2015-02-05 Thread anonymous via Digitalmars-d-learn
On Thursday, 5 February 2015 at 13:31:21 UTC, Nicholas Wilson 
wrote:

Note that D does NOT have default fall through. i.e.
 switch(myopt)
{
case opt1, opt2, opt3:
do_A();
break;
case opt4:
do_B();
break;
default:
do_C();
 }
is equivalent to
switch(myopt)
{
case opt1, opt2, opt3:
do_A();
case opt4:
do_B();
default:
do_C();
 }


No, that's not right.

The docs [1] say that [a] ScopeStatementList must either be 
empty, or be ended with a ContinueStatement, BreakStatement, 
ReturnStatement, GotoStatement, ThrowStatement or assert(0) 
expression unless this is the last case.


That's different from what you said. `case opt1: doA(); case 
4: do_B();` is supposed to be forbidden. It's not supposed to 
have an implicit break.


And apparently, dmd is not there (yet?). Implicit fall-through is 
only a warning at the moment (which have to be switched on). It's 
not an error.


[1] http://dlang.org/statement.html#switch-statement


Re: is it bug?

2015-01-30 Thread anonymous via Digitalmars-d-learn

On Friday, 30 January 2015 at 13:39:05 UTC, BBaz wrote:

On Friday, 30 January 2015 at 13:34:57 UTC, drug wrote:

On 30.01.2015 16:31, BBaz wrote:

On Friday, 30 January 2015 at 12:32:05 UTC, drug wrote:


  static init()
  {
  auto instance = new typeof(this)();
  instance._cont = new Container();
  return instance;
  }


have you tried

---
static typeof(this) init()
{
auto instance = new typeof(this)();
instance._cont = new Container();
return instance;
}
---

?

because currently either void or a type is missing.


Type is inferred automatically.


right, i've forgot that init() is a built-in property.
But it seemsthat i'm not the only one...


I think that doesn't matter here. Still works fine if you name it 
something other than init. I don't know if this works as 
designed, or if an auto return type should be required.


Besides, it's a bad idea to call a member init, because it 
steals the name of the default initializer. It doesn't override 
the default initializer, it just takes its name. The compiler 
should not accept it, in my opinion.


Re: is it bug?

2015-01-30 Thread anonymous via Digitalmars-d-learn

On Friday, 30 January 2015 at 13:11:35 UTC, anonymous wrote:

Lines 846-850:

static if(less == a  b)
auto vals = [1, 2, 3, 4, 5];
else
auto vals = [5, 4, 3, 2, 1];
assert(equal(r, vals));


(Tab + Enter strikes again.)

That test looks wrong. So, Phobos bug I think.


Re: is it bug?

2015-01-30 Thread anonymous via Digitalmars-d-learn

On Friday, 30 January 2015 at 12:32:05 UTC, drug wrote:


```
import std.container: RedBlackTree;

class Manager(TT, alias Cmp = ab)
{
alias Container = RedBlackTree!(TT, Cmp);
Container _cont;

static init()
{
auto instance = new typeof(this)();
instance._cont = new Container();
return instance;
}
}

unittest
{
alias IntManager = Manager!int;
auto im = IntManager.init();
}

void main() {}
```

run it using
rdmd -unittest filename.d

it fails in a RedBlackTree unittest with 2.065 and 2.066, is it 
bug?


Reduced:

import std.container: RedBlackTree;
alias Container = RedBlackTree!(int, ab);

Error: [...]/std/container/rbtree.d(850): unittest failure

Lines 846-850:

static if(less == a  b)
auto vals = [1, 2, 3, 4, 5];
else
auto vals = [5, 4, 3, 2, 1];
assert(equal(r, vals));


Re: static class vs. static struct

2015-01-26 Thread anonymous via Digitalmars-d-learn

On Monday, 26 January 2015 at 21:33:10 UTC, Piotrek wrote:

On Monday, 26 January 2015 at 14:11:32 UTC, bearophile wrote:

Non-static structs/classes have an extra pointer.

Bye,
bearophile


Since when structs have an extra pointer? Maybe you are talking 
about nested structs?


Non-static means nested.


Re: Segfault upon modifying immutable AA in static this

2015-01-24 Thread anonymous via Digitalmars-d-learn

On Saturday, 24 January 2015 at 13:24:02 UTC, Nordlöw wrote:

This snippet

static immutable words = [ `zero`, `one`, `two` ];

static immutable ubyte[string] wordsAA;

static this()
{
foreach (ubyte i, e; words) { wordsAA[e] = i; }
}

compiles and links on dmd git master but run segfaults.

Removing immutable qualifier from wordsAA avoids the segfeault.

Are static module ctors allowed to modify immutable data or 
this a DMD bug?


They are definitely allowed to initialize immutable data, i.e. 
write once. I don't know if you're allowed to change it 
repeatedly.


You can change your code to write only once:

static this()
{
import std.exception: assumeUnique;
ubyte[string] tmp;
foreach (ubyte i, e; words) { tmp[e] = i; }
wordsAA = assumeUnique(tmp); /* Don't alter tmp from here on. 
*/

}


Re: What to do with InvalidMemoryOperationError

2015-01-23 Thread anonymous via Digitalmars-d-learn

On Friday, 23 January 2015 at 21:25:01 UTC, Nordlöw wrote:

On Friday, 23 January 2015 at 10:13:43 UTC, Joakim wrote:
InvalidMemoryOperationError generally means that you are 
performing certain disallowed memory operations during a full 
garbage collection, such as allocating while the gc is running.


If my app is single-threaded this cannot happen then.


Single-/multi-threaded doesn't make a difference. This happens 
with a single thread, too. The GC calls destructors. When a 
destructor allocates then, it allocates during a GC run.


<    1   2   3   4   5   6   >