Re: Accessing __FILE__ and __LINE__ of caller in combination with varargs?

2016-04-16 Thread Simen Kjaeraas via Digitalmars-d-learn
On Saturday, 16 April 2016 at 00:03:59 UTC, Jonathan M Davis 
wrote:
On Friday, April 15, 2016 20:52:42 WebFreak001 via 
Digitalmars-d-learn wrote:



void assertf(string file = __FILE__, size_t line = __LINE__,
Args...)(lazy bool condition, in string message, Args args) {


Yes, you can do that, but do _not_ do that unless you really 
have no other choice. What you need to realize is that because 
the file and line number arguments will be unique for every 
call to this function, it will generate a new instantiation of 
it _every_ time it is called. So, you're going to get a lot of 
code bloat. There are rare cases where such bloat would be 
acceptable, but in the general case, it's a terrible thing to 
do. This particular case might be acceptable given how short it 
is, but in general, using __FILE__ or __LINE__ as template 
arguments should be avoided like the plague.


A few tricks to reduce this bloat:

- Write a small wrapper. This will still give bloat, but only of
small functions:

void assertf(string file = __FILE__, size_t line = __LINE__, 
Args...)(lazy bool condition, in string message, Args args) {

assertfImpl(file, line, condition, message, args);
}

- Only care about line numbers in debug mode. Makes debug more 
bloated, code less readable, and you lose out on line numbers in 
release. Still worth it occasionally:


version (debug) {
void foo(string file = __FILE__, size_t line = __LINE__, 
Args...)(Args args) {

// Stuffs.
}
} else {
void assertf(Args...)(Args args) {
// Stuffs.
}
}

I'd love to have a way to pass the file and line number info as 
regular parameters, though. Something like:


void foo(Args...)(Args args, string file = __FILE__, int line = 
__LINE__) {}


Sadly, currently not possible. Maybe we could overload @disable 
for this purpose?


void foo(Args...)(Args args, @disable string file = __FILE__, 
@disable int line = __LINE__) {}


--
  Simen


Re: infer type argument in classe constructor?

2016-03-29 Thread Simen Kjaeraas via Digitalmars-d-learn

On Tuesday, 29 March 2016 at 10:13:28 UTC, Puming wrote:

Hi,

I'm writing a generic class:

```d

struct Message { ... }

class Decoder(MsgSrc) {
}
```

When using it, I'd have to include the type of its argument:

```
void main() {
   Message[] src = ...;

   auto decoder = new Decoder!(Message[])(src);

   ...
}
```

Can it be inferred so that I only need to write?

```d
auto decoder = new Decoder(src); // you can infer the type from 
src.

```


Nope. To see why, consider a class like this:

class A(T) {
  T data;
  this(int n) {
  }
}

void main() {
   auto a = new A(3); // What is T?
}

The common solution is a simple 'create' function:

Decoder!T decoder(T)(T msg) {
return new Decoder!T(msg);
}

--
  Simen


Re: Does something like std.algorithm.iteration:splitter with multiple seperators exist?

2016-03-23 Thread Simen Kjaeraas via Digitalmars-d-learn

On Wednesday, 23 March 2016 at 18:10:05 UTC, ParticlePeter wrote:

Thanks Simen,
your tokenCounter is inspirational, for the rest I'll take some 
time for testing.


My pleasure. :) Testing it on your example data shows it to work 
there. However, as stated above, the documentation says it's 
undefined, so future changes (even optimizations and bugfixes) to 
Phobos could make it stop working:


"This predicate must be an equivalence relation, that is, it must 
be reflexive (pred(x,x) is always true), symmetric (pred(x,y) == 
pred(y,x)), and transitive (pred(x,y) && pred(y,z) implies 
pred(x,z)). If this is not the case, the range returned by 
chunkBy may assert at runtime or behave erratically."



But some additional thoughts from my sided:
I get all the lines of the file into one range. Calling array 
on it should give me an array, but how would I use find to get 
an index into this array?
With the indices I could slice up the array into four slices, 
no allocation required. If there is no easy way to just get an 
index instead of an range, I would try to use something like 
the tokenCounter to find all the indices.


The chunkBy example should not allocate. chunkBy itself is lazy, 
as are its sub-ranges. No copying of string contents is 
performed. So unless you have very specific reasons to use 
slicing, I don't see why chunkBy shouldn't be good enough.


Full disclosure:
There is a malloc call in RefCounted, which is used for 
optimization purposes when chunkBy is called on a forward range. 
When chunkBy is called on an array, that's a 6-word allocation 
(24 bytes on 32-bit, 48 bytes on 64-bit), happening once. There 
are no other dependencies that allocate.


Such is the beauty of D. :)

--
  Simen


Re: Does something like std.algorithm.iteration:splitter with multiple seperators exist?

2016-03-23 Thread Simen Kjaeraas via Digitalmars-d-learn

On Wednesday, 23 March 2016 at 11:57:49 UTC, ParticlePeter wrote:
I need to parse an ascii with multiple tokens. The tokens can 
be seen as keys. After every token there is a bunch of lines 
belonging to that token, the values.

The order of tokens is unknown.

I would like to read the file in as a whole string, and split 
the string with:

splitter(fileString, [token1, token2, ... tokenN]);

And would like to get a range of strings each starting with 
tokenX and ending before the next token.


Does something like this exist?

I know how to parse the string line by line and create new 
strings and append the appropriate lines, but I don't know how 
to do this with a lazy result range and new allocations.


Without a bit more detail, it's a bit hard to help.

std.algorithm.splitter has an overload that takes a function 
instead of a separator:


import std.algorithm;
auto a = "a,b;c";
auto b = a.splitter!(e => e == ';' || e == ',');
assert(equal(b, ["a", "b", "c"]));

However, not only are the separators lost in the process, it only 
allows single-element separators. This might be good enough given 
the information you've divulged, but I'll hazard a guess it isn't.


My next stop is std.algorithm.chunkBy:

auto a = ["a","b","c", "d", "e"];
auto b = a.chunkBy!(e => e == "a" || e == "d");
auto result = [
tuple(true, ["a"]), tuple(false, ["b", "c"]),
tuple(true, ["d"]), tuple(false, ["e"])
];

No assert here, since the ranges in the tuples are not arrays. My 
immediate concern is that two consecutive tokens with no 
intervening values will mess it up. Also, the result looks a bit 
messy. A little more involved, and according to documentation not 
guaranteed to work:


bool isToken(string s) {
return s == "a" || s == "d";
}

bool tokenCounter(string s) {
static string oldToken;
static bool counter = true;
if (s.isToken && s != oldToken) {
oldToken = s;
counter = !counter;
}
return counter;
}

unittest {
import std.algorithm;
import std.stdio;
import std.typecons;
import std.array;

auto a = ["a","b","c", "d", "e", "a", "d"];
auto b = a.chunkBy!tokenCounter.map!(e=>e[1]);
auto result = [
["a", "b", "c"],
["d", "e"],
["a"],
["d"]
];
writeln(b);
writeln(result);
}

Again no assert, but b and result have basically the same 
contents. Also handles consecutive tokens neatly (but consecutive 
identical tokens will be grouped together).


Hope this helps.

--
  Simen


Re: How do I extend an enum?

2016-03-19 Thread Simen Kjaeraas via Digitalmars-d-learn

On Saturday, 19 March 2016 at 17:40:27 UTC, Lass Safin wrote:

Why:

enum Base {
A,
B,
}

enum Derived : Base {
C, // Gives error, says it can't implicitly convert 
expression to Base.

D = 1, // Same error
E = cast(Base)294, // Finally works. Can only be 
cast(Derived) instead.

}

void func(Derived d) {}

func(Derived.E); // works.
func(Derived.A); // Gives error, says it can't call function 
with Base.A.

func(cast(Derived)Derived.A); // Works.

So, what's the proper way of extending an enum?


There is no way to extend an enum. When you think about it, it's 
actually the opposite of what you'd generally want. Given  two 
classes:


class A {}
class B : A {}

Every instance of B is a valid A. That is, given a variable of 
type A, you could assign any B to it.


Now consider enums:

enum A { x, y, z }
enum B : A {}

Which values could you put in B? Only those that would be valid 
for A. That is, only x, y and z. Imagine that we could:


enum B : A { w }

A foo = B.w;

foo now holds a value that is not valid for its type. Hence, you 
simply cannot.


Are there cases where you want to define a new enum that contains 
all the items in a 'base' enum in addition to some new items? 
Absolutely, and D lacks a good way to do that. But subtyping 
would in any case not be the correct way to do it.


Are there cases where you want to extend an enum by making a 
subtype with more items? I would argue that's a strong code smell 
in D, but I can see why you'd want to.


--
  Simen


Re: classInstanceSize and vtable

2014-10-24 Thread Simen Kjaeraas via Digitalmars-d-learn

On Friday, 24 October 2014 at 00:21:52 UTC, Etienne Cimon wrote:

On 2014-10-23 20:12, bearophile wrote:
In D all class instances contain a pointer to the class and a 
monitor
pointer. The table is used for run-time reflection, and for 
standard

virtual methods like toString, etc.

Bye,
bearophile


So what's the point of making a class or methods final? Does it 
only free some space and allow inline to take place?


Like bearophile said the vtable is required for virtual methods. 
Consider this code:


import std.stdio : writeln;

class A { void foo() {writeln(A);} }
final class B : A { override void foo() {writeln(B);} }

void main() {
A a = new B();
a.foo();
}

In order for the call to foo to run the correct version of foo, B 
needs to have a vtable. Since all classes in D implicitly inherit 
from Object, which has some virtual methods, all classes need to 
have a vtable.


--
  Simen


Re: this() immutable

2013-10-16 Thread Simen Kjaeraas

On 2013-10-16, 18:54, Daniel Davidson wrote:


On Thursday, 13 June 2013 at 12:29:57 UTC, Simen Kjaeraas wrote:
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels  
stephan_schiff...@mac.com wrote:


For example, is there a way of instantiating an object normally (i.e.  
mutable), and then later freeze it to immutable via a simple cast or  
so?


In std.exception there is assumeUnique. It's basically just a cast, but
might be good enough for you.


Is there any other recourse here?

Why does making `this(...) immutable` fix things below?
Shouldn't that immutable designation mean no members of this will be  
modified? But that is the whole point of an initializer? Why does  
immutable make sense in this context at all?


Immutable in the case of constructors means that the instance will be
created using only data implicitly castable to immutable. That way, when
construction is finished, it is safe for the type system to mark the
result as immutable.


My problem is a bit more elaborate and unfortunately to initialize  
members I need to call standard functions that have not been made pure  
(but should be).


If you're calling functions that are not marked pure in order to create
immutable data, you will need to cast to immutable afterwards. If you
know this is safe, no problem.

It would benefit us all if you reported these functions or created a pull
request for Phobos, of course.

--
  Simen


Re: How to check for instantiation of specific template?

2013-10-10 Thread Simen Kjaeraas

On 2013-10-10, 19:23, H. S. Teoh wrote:


I have a template used for storing compile-time values:

template Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

How do I define a template isDef that, given some template alias A,
evaluates to true if A is some instantiation of Def?

template isDef(alias A) {
enum A = ... /* what to put here? */
}


This seems to be impossible. The standard way of doing this would be
with an isExpression[0], but that only works for types.

A solution would be to beef up your Def template by turning it into
a struct:

struct Def(int x, string y) {
alias impl = TypeTuple!(x,y);
}

With this definition, the following works:

template isDef(alias A) {
enum isDef = is(A == Def!T, T...);
// Or enum isDef = is(A == Def!(x, y), int x, string y);
}

This is a shortcoming of the language, and I have filed an enhancement
request for it[1].

The problems of using an actual type for this, is that someone might
instantiate that type (unlikely), and that the compiler will generate
TypeInfo for it, which will bloat your executable. A Sufficienctly
Smart Compiler[2] would see that the type is never used and thus not
include the TypeInfo. Something which the compiler could do without
a lot of smarts, is optimize away final abstract classes, which you
cannot derive from and cannot instantiate. That oughta be enough.

[0]: http://dlang.org/expression#IsExpression
[1]: http://d.puremagic.com/issues/show_bug.cgi?id=11219
[2]: http://c2.com/cgi/wiki?SufficientlySmartCompiler
--
Simen


Re: fill array using a lambda function

2013-10-10 Thread Simen Kjaeraas

On 2013-10-10, 16:04, bearophile wrote:


dominic jones:

I want to fill an array with random numbers without resorting to loops,  
i.e. by doing something like the following, if it were possible:


  fill!(function double(){ return uniform(0.0, 1.0);})(x[]);

Is there a simple way of doing this?


Generally it's a good idea to use only pure functions inside the higher  
order functions of Phobos. using impure functions like uniforms could  
lead to bugs or performance problems.


This is a way to do it (untested):

x.copy(x.length.iota.map!(_ = uniform(0.0, 1.0));


You've got the order wrong - copy takes first the source, then the target.
Also, is it faster to use .length.iota than simply mapping on x?
My solution:

x.map!(_=uniform(0.0, 1.0)).copy(x);

--
Simen


Re: What's about virtual?

2013-09-10 Thread Simen Kjaeraas
On Tue, 10 Sep 2013 02:28:24 +0200, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



On 9/9/13 12:47 PM, H. S. Teoh wrote:

On Mon, Sep 09, 2013 at 09:37:07PM +0200, Namespace wrote:

It's been a while since Manu convinced Walter and Andrei to
introduce a virtual Keyword and to change the default from virtual
methods to final methods.
Anything new? Anybody working on that? I would love to see that
soon.


This is going to break a lot of code. We'd need some kind of deprecation
path. And even then, it may anger a lot of existing users.


T


After I've seen a pretty cool demo of clang-modernize  
(http://clang.llvm.org/extra/ModernizerUsage.html), I think the best way  
to attack this and similar problems is to add a class hierarchy  
analyzer: a command-line utility that is fed an entire project and adds  
as many 'final' as possible without changing semantics.


Time has come to migrate such functionality to tools. We keep on telling  
that nobody uses the tools but it seems experience contradicts that  
belief.


So the catastrophe that is virtual by default will not be changed?

--
Simen


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Simen Kjaeraas

On 2013-08-29, 10:25, Jonathan M Davis wrote:


On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:

On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
wrote:
[..]

 as any integral value in a float will fit in an
 int.

[..]

Will it? Most of them will not fit


Sure, they will. float has 32 bits, just like int, so it can't possibly  
hold a

value larger than an int can hold. This code passes with flying colors

foreach(i; int.min .. int.max)
assert(cast(float)i == i);


First, that's showing the exact opposite of what you're saying it does.
Second, it doesn't even show that.

Your code is equivalent to:

foreach(i; int.min .. int.max)
assert(cast(float)i == cast(float)i);

If that does not pass with flying colors, I'd be surprised. Now try this:

foreach(i; int.min .. int.max) {
float f = i; // DMD optimizes out cast(int)cast(float)int
assert(cast(int)f == i);
}

It will fail for odd numbers in the range 16,777,216-33,554,432, and for
numbers not divisible by 4 in the range to the next power of two, then 8,
and so on. These numbers are simply not representable by a float.

For more information:
http://floating-point-gui.de/formats/fp/

--
  Simen


Re: Get class size of object

2013-08-11 Thread Simen Kjaeraas

On 2013-08-11, 20:33, JS wrote:

I think you're missing the point to some degree(I realize there is a  
diff between an object and a type, but I should be able to easily get  
the class size of an object at run time regardless if the object is  
typed as a base class). The code below does this, but at a cost of  
verbosity.


Here is code that exactly demonstrates what I am essentially trying to  
do. The only drawback now is having to mixin the template for each class  
which I would want to automate and it would be nice to wrap the RT and  
CT methods in subclasses without overhead.


It would appear that some information is lost when calling typeid from an
interface. I would have expected this to work:

interface I {
final
size_t size() {
return typeid(this).init.length;
}
}

class A {}

class B : A, I {
int a;
}

void test1() {
I i = new B();
assert(i.size  0); // Fails.
}


A bit more experimentation shows:

void test2() {
B b = new B();
I i = b;
A a = b;

assert(typeid(a) == typeid(b)); // Passes.
assert(typeid(i) == typeid(b)); // Fails.

assert(typeid(b).init.length  0); // Passes.
assert(typeid(i).init.length  0); // Fails.
}


It appears thus that the error is in typeid(interface), which does not
give the actual typeid.

The workaround is as follows:


interface I {
final
size_t size() {
return typeid(cast(Object)this).init.length;
}
}


Is this what you want? Is it good enough? I have no idea, as you're
notoriously bad at describing what you want, but pretty good at
attacking people.

If you're looking for a no-overhead solution, then this might not be
good enough. I'm surprised that a virtual function call is fine,
though.


Re: Types of regex

2013-07-15 Thread Simen Kjaeraas

On 2013-07-15, 11:32, Larry wrote:


Hello,

I read the library reference for regex.

I really miss python's equivalent of finditer.

Sometimes matching is not on purpose and one will want to match all the  
occurences to iterate over it since it is much more regarding concerning  
the orders and repetitions.



my code :
-
version(Tango) extern (C) int printf(char *, ...);

import std.stdio;
import std.regex;
import std.file;
import std.format;

int main(char[][] args)
{
 string fl = readText(testregexd.txt);

 auto m = match(fl, regex(`(n=(?:hello|goodbye))*`,g));
 auto c = m.captures;

 writeln(c);

 return 0;
}

---

Content of testregexd.txt:


n=hello n=goodbye



Any way to workaround ?

Thanks !

Larry


Have you tried iterating over m? This works for me:

import std.stdio;
import std.regex;
import std.file;
import std.format;

int main(char[][] args)
{
string fl = 
n=hello n=goodbye
;

auto m = match(fl, regex(`(n=(?:hello|goodbye))`,g));
foreach (c; m)
writeln(c);

return 0;
}

--
Simen


Re: Conditional Inheritance

2013-07-14 Thread Simen Kjaeraas

On 2013-07-14, 07:00, JS wrote:


I need to conditionally inherit:

interface A(T) : conditionallyInherit!(isBasicType!T, B);

A!(double) will inherit B but A!(mytype) won't.


template conditionallyInherit(bool choice, T...) {
static if (choice) {
alias conditionallyInherit = T;
} else {
import std.typetuple : TypeTuple;
alias conditionallyInherit = TypeTuple!();
}
}

Should work.

--
Simen


Re: Conditional Inheritance

2013-07-14 Thread Simen Kjaeraas

On 2013-07-14, 07:40, JS wrote:


On Sunday, 14 July 2013 at 05:30:57 UTC, lomereiter wrote:

On Sunday, 14 July 2013 at 05:04:37 UTC, JS wrote:

and while I'm at it I need to conditionally constrain types.

interface A(T) where(!isBasicType!T, (T : B));

which is suppose to require T to inherit from B if T is not basic type.


interface A(T) if (isBasicType!T || is(T : B))


Thanks, works. I remember seeing code like this somewhere but couldn't  
find any docs about it.


Here. I admit there should probably be more examples, and perhaps also
some info on the classes/interfaces/structs  unions pages.

http://dlang.org/template.html#Constraint

--
Simen


Re: Style question

2013-07-12 Thread Simen Kjaeraas

On 2013-07-11, 20:22, Namespace wrote:


What should he do?

As far as I can see he has 3 options:
1. An external file with the enum information. Both classes would import  
it and could use the same enum. But he cannot change the API, so this is  
no real option.


2. Change test1 into this:

void test1() {
B b = cast(B) this.a;
MyStaticClass.test2(b);
}

This works fine. But is it safe? And is it good style?
And how is this cast converted? Is it cheap?

3. Change test2 so that it accepts (even) (u)int. But then he lose the  
Type safety.


Does anyone have any advice?


This might be an option:


version (unittest) {
enum A {
foo = 1,
bar = 2,
}

enum B {
foo = 1,
bar = 2,
}

enum C {
foo = 3,
bar = 4,
}

enum D {
baz,
qux,
}
}

template sameMembers(T, U) {
template sameValue(string member) {
enum sameValue = __traits(getMember, T, member) ==  
__traits(getMember, U, member);

}
import std.typetuple : allSatisfy;
enum sameMembers =
sameMemberNames!(T,U) 
allSatisfy!(sameValue, __traits(allMembers, T));
} unittest {
assert(sameMembers!(A,A));
assert(sameMembers!(A,B));
assert(sameMembers!(B,A));
assert(sameMembers!(B,B));

assert(!sameMembers!(A,C));
assert(!sameMembers!(B,C));
assert(!sameMembers!(C,A));
assert(!sameMembers!(C,B));
}

template sameMemberNames(T, U) {
template Has(Type) {
template Has(string member) {
enum Has = __traits(hasMember, Type, member);
}
}
import std.typetuple : allSatisfy;
enum sameMemberNames =
allSatisfy!(Has!T, __traits(allMembers, U)) 
allSatisfy!(Has!U, __traits(allMembers, T));
} unittest {
assert(sameMemberNames!(A,A));
assert(sameMemberNames!(A,B));
assert(sameMemberNames!(A,C));
assert(sameMemberNames!(B,A));
assert(sameMemberNames!(B,B));
assert(sameMemberNames!(B,C));
assert(sameMemberNames!(C,A));
assert(sameMemberNames!(C,B));
assert(sameMemberNames!(C,C));
assert(sameMemberNames!(D,D));

assert(!sameMemberNames!(A,D));
assert(!sameMemberNames!(B,D));
assert(!sameMemberNames!(C,D));
assert(!sameMemberNames!(D,A));
assert(!sameMemberNames!(D,B));
assert(!sameMemberNames!(D,C));
}

T ConvertEnum(T,U)(U value) if (sameMembers!(T,U)) {
return cast(T)value;
}

T ConvertEnum(T,U)(U value) if (sameMemberNames!(T,U)   
!sameMembers!(T,U)) {

final switch (value) {
foreach (e; __traits(allMembers, U)) {
case __traits(getMember, U, e):
return __traits(getMember, T, e);
}
}
assert(false);
} unittest {
assert(ConvertEnum!A(B.foo) == A.foo);
assert(ConvertEnum!A(B.bar) == A.bar);
assert(ConvertEnum!A(C.foo) == A.foo);
assert(ConvertEnum!A(C.bar) == A.bar);

assert(ConvertEnum!B(A.foo) == B.foo);
assert(ConvertEnum!B(A.bar) == B.bar);
assert(ConvertEnum!B(C.foo) == B.foo);
assert(ConvertEnum!B(C.bar) == B.bar);

assert(ConvertEnum!C(A.foo) == C.foo);
assert(ConvertEnum!C(A.bar) == C.bar);
assert(ConvertEnum!C(B.foo) == C.foo);
assert(ConvertEnum!C(B.bar) == C.bar);

assert(!__traits(compiles, { auto tmp = ConvertEnum!D(A.foo); }));
assert(!__traits(compiles, { auto tmp = ConvertEnum!D(B.foo); }));
assert(!__traits(compiles, { auto tmp = ConvertEnum!D(C.foo); }));
assert(!__traits(compiles, { auto tmp = ConvertEnum!A(D.foo); }));
assert(!__traits(compiles, { auto tmp = ConvertEnum!B(D.foo); }));
assert(!__traits(compiles, { auto tmp = ConvertEnum!C(D.foo); }));
}


The function ConvertEnum safely converts from one enum to another, given
that the same members exist in both. If the enums are equal (same values  
for

each member), a simple cast is used. If the names are equal, but values are
different, a switch/case is built, and A.Foo is converted to B.Foo.

--
Simen


Re: for loop parens

2013-07-12 Thread Simen Kjaeraas

On 2013-07-12, 22:38, ixid wrote:


On Friday, 12 July 2013 at 20:30:59 UTC, bearophile wrote:

ixid:

Similarly what are D user's potential issues with Go-like semi-colon  
rules? And would this be possible as a subset of current D code?


Such changes will not happen even in D4. Walter is strongly against the  
idea of optional semicolons, on the base that semicolons help the  
parser, so they allow better error recovery and error messages.


Bye,
bearophile


Is there any evidence that these are issues in Go?


I'm not sure how much of a problem it is, especially given that Go has a
strict style guide, but the objection has come up that these two are
very different:

  if i  f() {
  g()
  }

and

  if i  f()
  {
  g()
  }

In the second case, a semicolon is inserted on the same line as the if.

However, like I said, in idiomatic Go, this is simply not a done thing.

--
Simen


Re: Style question

2013-07-11 Thread Simen Kjaeraas

On 2013-07-11, 20:22, Namespace wrote:


What should he do?

As far as I can see he has 3 options:
1. An external file with the enum information. Both classes would import  
it and could use the same enum. But he cannot change the API, so this is  
no real option.


2. Change test1 into this:

void test1() {
B b = cast(B) this.a;
MyStaticClass.test2(b);
}

This works fine. But is it safe? And is it good style?
And how is this cast converted? Is it cheap?

3. Change test2 so that it accepts (even) (u)int. But then he lose the  
Type safety.


Does anyone have any advice?


It seems to me that MyClass has access to MyStaticClass, and thus should
also have access to B. If this is the case, why is MyClass using an A
instead of a B?

One option might be to use alias A = B; This would ensure the two enums
are always the same.

Last ditch, I would say option #2 is the best. It's not safe, in that
if one enum changes and the other does not, the cast will blithely
ignore that and use the same uint value. It is however efficient, as it
is a simple reinterpretation of the bits.

--
Simen


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread Simen Kjaeraas

On 2013-07-08, 11:03, bearophile wrote:


Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?


Filed:

http://d.puremagic.com/issues/show_bug.cgi?id=10569

And created a pull request:

https://github.com/D-Programming-Language/phobos/pull/1400

--
Simen


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread Simen Kjaeraas

On 2013-07-07, 21:55, QAston wrote:

I have a large enum in my code (opcodes for a protocol) - using  
std.traits.EnumMembers gives me a recursive template error.


How can i increase max number recursive template expansions?


You can't. However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:



import std.typetuple;

template EnumMembers(E)
if (is(E == enum))
{
// Supply the specified identifier to an constant value.
template WithIdentifier(string ident)
{
static if (ident == Symbolize)
{
template Symbolize(alias value)
{
enum Symbolize = value;
}
}
else
{
mixin(template Symbolize(alias ~ ident ~)
 ~{
 ~alias ~ ident ~ Symbolize;
 ~});
}
}

template EnumSpecificMembers(names...)
{
static if (names.length  200)
{
alias TypeTuple!(
EnumSpecificMembers!(names[0..$/2]),
EnumSpecificMembers!(names[$/2..$]),
) EnumSpecificMembers;
}
else static if (names.length  0)
{
alias TypeTuple!(
WithIdentifier!(names[0])
.Symbolize!(__traits(getMember, E, names[0])),
EnumSpecificMembers!(names[1 .. $]),
) EnumSpecificMembers;
}
else
{
alias TypeTuple!() EnumSpecificMembers;
}
}

alias EnumSpecificMembers!(__traits(allMembers, E)) EnumMembers;
}



Here, this line:
static if (names.length  200)
uses divide-and-conquer to reduce the number of template instantiations.

--
Simen


Re: ref tuples

2013-07-03 Thread Simen Kjaeraas

On 2013-07-03, 02:22, Brad Anderson wrote:

C++11's std::tuple includes a function std::tie that takes references to  
the arguments and returns a tuple that maintains the references to the  
arguments.


Along with the usual cases where you'd want reference semantics it also  
enables this interesting construct for unpacking tuples.


int a, b;
tie(a, b) = make_tuple(1, 2);

assert(a == 1  b == 2);

Is there any way to do something similar with std.typecons.Tuple?


Not that I know of. But, Philippe Sigaud's dranges[1] library includes
a RefTuple[2], which should do what you want.

[1]: https://github.com/dawgfoto/dranges/
[2]: https://github.com/dawgfoto/dranges/blob/master/reftuple.d

--
Simen


Re: Windows parameter

2013-06-30 Thread Simen Kjaeraas

On Sun, 30 Jun 2013 20:24:17 +0200, shuji cravs...@hotmail.com wrote:



int setHWND(HWND extHwnd){
hwnd = extHwnd;
return 0;
}

And:


extern (C++) {
int setHWND(HWND hwnd);
}



See how these are different? One of them is an extern (C++) function, the  
other is a D function.


In other words, this should work:

//funcs.lib
//windows includes...
HWND hwnd;
extern (C++) { // This line!
int setHWND(HWND extHwnd){
hwnd = extHwnd;
return 0;
}
}

//main.d
pragma(lib, gdi32.lib);
import core.runtime;
import core.sys.windows.windows;
extern (C++) {
int setHWND(HWND hwnd);
}
int main(int argc, char **argv) {
//windows initializers
setHWND(hwnd);
return 0;
}



--
Simen


Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread Simen Kjaeraas
On Fri, 28 Jun 2013 20:07:23 +0200, MattCoder mattco...@hotmail.com  
wrote:



Hi,

I would like to know if it's possible to pass the return of a function  
as argument to another function as below:


import std.stdio;

auto foo(int x, int y){
writeln(x, y);
return 3, 4;
}

void main(){
foo(foo(1,2));
}

I would like to print:
1 2
3 4

PS: I tried return a tuple but it doesn't works.

Thanks,

Matheus.


Not directly,  no. But this should work:


import std.stdio;
import std.typecons : tuple;

auto foo(int x, int y){
writeln(x, y);
return tuple(3, 4);
}

void main(){
foo(foo(1,2).tupleof);
}
--
Simen


Re: mutable constant?

2013-06-25 Thread Simen Kjaeraas
On Wed, 26 Jun 2013 00:07:38 +0200, Namespace rswhi...@googlemail.com  
wrote:


I want to ask if this code should compile or if it's a bug, because I  
circumvent the const system:



import std.stdio;

struct Point {
int x, y;
}

Point*[] points;

struct TplPoint(T) {
public:
Point _point;

T x, y;

const uint id;

this(T x, T y) {
this.x = x;
this.y = y;

points ~= this._point;

id = points.length - 1;
}

@property
inout(Point)* ptr() inout {
points[this.id].x = cast(int) this.x;
points[this.id].y = cast(int) this.y;

return cast(inout Point*) points[this.id];
}
}

void main() {
const TplPoint!float my = TplPoint!float(42, 23);
writeln(my._point, ::, my._point);
writeln(*my.ptr, ::, my.ptr);
}


Or is the fact that it compiles ok and it's only unsafe?


This is perfectly fine.

--
Simen


Re: Possble bug ? Adding

2013-06-24 Thread Simen Kjaeraas

On 2013-06-24, 22:30, Temtaime wrote:


Hello, guys !

http://dpaste.1azy.net/8917c253


I'm not sure I've seen this bug before, but yes, it is one.
The cause is that the grammar for the new alias syntax is apparently not  
complete.

Please file: http://d.puremagic.com/issues/enter_bug.cgi

--
Simen


Re: Multiple return type from object factory possible?

2013-06-22 Thread Simen Kjaeraas

On Sat, 22 Jun 2013 18:58:22 +0200, deed n...@none.none wrote:


class A  { ... }
class NonContainer : A   { ... }
class Container : A  { A[] container; }
class NC1 : NonContainer {}
...
class C1 : Container {}
...

A getO(string info)
{
 switch (info)
 {
 default : return new NonContainer();
 case info1: return new C1();
 case info2: return new NC1();
 case info3: return new Container();
 case info4: return new NonContainer();
 ...
 }
}

void foo()
{
 auto o = getO(some information);
 if (is(typeof(o) == Container) { ... }  // Doesn't work.
 // Type is always A.
 ...
}

Is there a way to make getO return the most specialized type of the  
instantiated object in the switch statement to enable this pattern?


The type of an expression in D is determined at compile time, and getO
returns an A. Hence, o will always have static type A, and is(typeof(...
only checks the static type.

If you want to check the dynamic (run-time) type of o, you should
instead see if it is castable to Container:

auto o = getO(info3);
if (cast(Container)o != null) { ... }

--
Simen


Re: A little of coordination for Rosettacode

2013-06-18 Thread Simen Kjaeraas

On 2013-06-18, 05:00, bearophile wrote:

With your code I have found a dmd compiler bug, are you able and willing  
to further reduce this?


Tried this with 2.063.2, and there are three errors in the code -  
deserializeInto

should return its buffer, the switch on line 19 needs a default: case, and
deserializeInto tries to modify its non-buffer argument (which in this  
case is a

const string. None of these seem to be a compiler bug.

--
Simen


Re: this() immutable

2013-06-13 Thread Simen Kjaeraas
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels  
stephan_schiff...@mac.com wrote:


For example, is there a way of instantiating an object normally (i.e.  
mutable), and then later freeze it to immutable via a simple cast or  
so?


In std.exception there is assumeUnique. It's basically just a cast, but
might be good enough for you.

--
Simen


Re: Why TypeTuple can be assigned to a variable

2013-06-12 Thread Simen Kjaeraas

On Wed, 12 Jun 2013 10:01:59 +0200, Zhenya zh...@list.ru wrote:


Hi!

I was just surprised when realized, that this code compiles and runs:

import std.typetuple;
import std.stdio;

void main()
{
  auto foo = TypeTuple!(foo,bar);
writeln(typeid(typeof(foo)));
  writeln(foo);
}

If I were compiler expert,I'd say that it's a bug.But I am not)
So, can anybody explain why it's work?


It is the equivalent of:

  TypeTuple!(string, string) foo;
  foo[0] = foo;
  foo[1] = bar;

The ability to have a tupetuple as a variable is very useful - if that
had not been possible one would need something akin to this:

struct Tuple(T...) {
T[0] head;
static if (T.length) {
Tuple!(T[1..$]) tail;
}
}

And to access the third element of a tuple one'd need to write:

myTuple.tail.tail.head = foo;

Clearly this is suboptimal, so D has better ways of doing such things.

--
Simen


Re: Why TypeTuple can be assigned to a variable

2013-06-12 Thread Simen Kjaeraas

On Wed, 12 Jun 2013 11:44:19 +0200, Zhenya zh...@list.ru wrote:


OK,you say that TypeTuple!(foo,bar) is a cool value of type
TypeTuple!(string,string),right?


Well, yes and no, not really. It's a bit magical. In your case,
it's assigned to an auto variable, and that variable gets that type.
There are other ways to use a TypeTuple where it has other semantics,
as you write yourself.

As explained below, a TypeTuple is just a bag of template parameters,
and thus obeys the rules for a bag of template parameters.



This behaviour confuses me a bit.


Understandable. It's not entirely straightforward, because the
concerns of usability weigh heavier than those of consistency.



And I just don't understand why do we need TypeTuple's value
semantic
to implement std.Tuple,because AFAIK it use variadic template
parameter pack
   != TypeTuple.


The definition od std.typetuple.TypeTuple is:

template TypeTuple(T...){
alias TypeTuple = T;
}

So a TypeTuple is exactly the same as a variadic template
parameter pack.



Sorry for my english.


No need to be, your English is great.

--
Simen


Re: Why there is too many uneccessary casts?

2013-06-11 Thread Simen Kjaeraas

On Tue, 11 Jun 2013 12:12:25 +0200, Temtaime temta...@gmail.com wrote:


ubyte k = 10;
ubyte c = k + 1;

This code fails to compile because of: Error: cannot implicitly convert  
expression (cast(int)k + 1) of type int to ubyte


Why? It's pain in the ass, i think. My code contains only casts then.


Because it's unsafe. The compiler does not know if k+1 fits in a ubyte.

(True, in this case it could know it, but it does not, and in the general
case it can't know)

--
Simen


Re: Why there is too many uneccessary casts?

2013-06-11 Thread Simen Kjaeraas

On Tue, 11 Jun 2013 12:39:47 +0200, Temtaime temta...@gmail.com wrote:


There is overflow and it can be with int too.
It's standard behavior.


Indeed. And a class is a void* is an int is a char is a double? That's
perfectly possible - it's all just memory anyway. D has chosen to do
it like this to prevent common errors. If you think the cast stands
out like a sore thumb, use:

ubyte k = 10;
ubyte c = (k + 1)  0xFF;

That way, value range propagation ensures the result fits in a ubyte,
and the code compiles happily.

--
Simen


Re: Why there is too many uneccessary casts?

2013-06-11 Thread Simen Kjaeraas
On Tue, 11 Jun 2013 13:15:11 +0200, Simen Kjaeraas  
simen.kja...@gmail.com wrote:



On Tue, 11 Jun 2013 12:39:47 +0200, Temtaime temta...@gmail.com wrote:


There is overflow and it can be with int too.
It's standard behavior.


Indeed. And a class is a void* is an int is a char is a double? That's
perfectly possible - it's all just memory anyway. D has chosen to do
it like this to prevent common errors. If you think the cast stands
out like a sore thumb, use:

ubyte k = 10;
ubyte c = (k + 1)  0xFF;

That way, value range propagation ensures the result fits in a ubyte,
and the code compiles happily.


Also worth noting: both  0xFF and cast(ubyte) shows that the programmer
has considered the possibility of overflow (or just programmed blindly,
but let's assume a rational programmer), something your original code did
not.

Looking at this code:

  ubyte a = foo();
  ubyte b = a + 1;
  doSomethingWith(b);

It's not possible for me to know if that code works correctly if foo()
returns 255 - perhaps it should actually be saturated (255+1 == 255),
perhaps it should even throw an exception. With this code:

  ubyte a = foo();
  ubyte b = cast(ubyte)(a + 1); // or (a + 1)  0xFF;
  doSomethingWith(b);

The programmer has documented something: If this causes an overflow,
the value in b is still correct. Explicit is better than implicit.

--
Simen


Re: Why there is too many uneccessary casts?

2013-06-11 Thread Simen Kjaeraas

On Tue, 11 Jun 2013 13:46:11 +0200, Temtaime temta...@gmail.com wrote:


No. I means, that

uint a = uint.max;
uint b = a + 1;
writeln(b);

Works OK.
Why? Compiler doesn't know if a + b fits in uint, right?
Then why overflow with ints are accepted?


Because there's a limit to how far this goes without introducing
arbitrary-precision numbers. There is indeed an argument for uint+uint
giving a ulong answer, and I'm confused myself at why this is not the
case.



So your example is meaningless.


No.

--
Simen


Re: alias this

2013-05-31 Thread Simen Kjaeraas

On 2013-05-31, 14:12, Namespace wrote:


I thougth that in dmd 2.063 alias this : foo; would be allowed.
That was what the preview of dmd 2.063 said:
http://dlang.org/changelog.html#new2_062
Why wasn't it implemented?


Probably not enough time. I've not read anything about it no
longer being planned.

--
Simen


Re: Are heap objects never moved by the garbage collector?

2013-05-31 Thread Simen Kjaeraas

On 2013-05-31, 18:31, Carl Sturtivant wrote:



The D Programming Language (TDPL) p.178 asserts the following.

The objects themselves stay put, that is their locations in memory  
never change after creation.


I take this to mean that the D garbage collector doesn't move live  
objects and adjust all references to them the way that some garbage  
collectors do. That is to say, the addresses of objects are not changed  
by the garbage collector.


Does D guarantee this?


The current D GC does guarantee this. Some future collectors might not,
but there will always be implementations that guarantee it.

--
Simen


Re: and/or/not/xor operators

2013-05-30 Thread Simen Kjaeraas

On 2013-05-30, 13:56, Shriramana Sharma wrote:


Hello. I have always loved the readability of C++'s and/or/not/xor
word-like logical operators but It doesn't seem to be available in D.
Isn't this possible in D? I tried doing:

alias  and ;
import std.stdio ;
void main () {
writeln ( true and true ) ;
}

but I get errors:

$ dmd foo.d
foo.d(1): Error: basic type expected, not 
foo.d(1): Error: no identifier for declarator int
foo.d(1): Error: semicolon expected to close alias declaration
foo.d(1): Error: Declaration expected, not ''
foo.d(7): Error: found 'and' when expecting ',

Thanks.


While that's not possible, D's operator overloading allows you to
implement it yourself:

struct And {
struct AndImpl {
private bool payload;
this( bool value ) {
payload = value;
}
bool opBinary(string op : /)(bool value) const {
return payload  value;
}
}
AndImpl opBinaryRight(string op : /)(bool value) {
return AndImpl( value );
}
}

struct Or {
struct OrImpl {
private bool payload;
this( bool value ) {
payload = value;
}
bool opBinary(string op : /)(bool value) const {
return payload || value;
}
}
OrImpl opBinaryRight(string op : /)(bool value) {
return OrImpl( value );
}
}

And and;
Or or;


void main( ) {
assert( true /and/ true );
assert( true /or/ false );
}

Of course, if you ever use this, watch out for the flood of WTFs
and curse words.

--
Simen


Re: Passing large or complex data structures to threads

2013-05-27 Thread Simen Kjaeraas
On Mon, 27 May 2013 14:08:12 +0200, Joseph Rushton Wakeling  
joseph.wakel...@webdrake.net wrote:



On 05/26/2013 05:59 PM, Ali Çehreli wrote:

On 05/26/2013 05:38 AM, Simen Kjaeraas wrote:



 Tuple!(size_t, size_t)[][] data = createData();
 immutable dataImm = assumeUnique(data);
 data = null; // Simply to ensure no mutable references exist.


The last line is not needed. assumeUnique already does that. :)


That's fantastic, thank you both very much.  Does that also work for  
arbitrary
data structures (e.g. also associative arrays, complex structs/classes  
etc.)?


Absolutely. So long as your code does not squirrel away other, mutable
references to the data, assumeUnique is perfectly safe.


Related question -- assume that I now want to store that immutable data  
inside a

broader storage class, but I want that storage class to be agnostic as to
whether the data is immutable, const or mutable.

Something like this:

class MyDataStore
{
float[] someData;
uint[] someMoreData;
Tuple!(size_t, size_t)[][] importedData;

this(float[] sd, uint[] smd, Tuple!(size_t, size_t)[][] id)
{
someData = sd;
someMoreData = smd;
importedData = id;
}
}

... which of course fails if you try passing it immutable data for any  
of the

parameters.  So, is there a way to make this broader storage class
type-qualifier-agnostic?

I guess applying inout to the input parameters is necessary, but it's  
clearly

not sufficient as the code then fails when trying to assign to the class'
internal variables.


A few questions:

Why use a class? Will MyDataStore be subclassed?

Will you have some instances of MyDataStore that will be mutated, and
others that will always stay the same?

If the answer was yes, will these be in the same array?


Short answer: If you will have mixed arrays, no. There's no way to make
that safe. If you don't have mixed arrays, there are ways.

This will work:

import std.stdio : writeln;
import std.exception : assumeUnique;
import std.typecons : Tuple, tuple;

class MyDataStore
{
float[] someData;
uint[] someMoreData;
Tuple!(size_t, size_t)[][] importedData;

inout this(inout float[] sd, inout uint[] smd, inout Tuple!(size_t,  
size_t)[][] id)

{
someData = sd;
someMoreData = smd;
importedData = id;
}
}

void main( ) {
float[] sdMut = [1,2,3];
uint[] smdMut = [4,5,6];
Tuple!(size_t, size_t)[][] idMut = [[tuple(0u, 0u), tuple(0u,  
1u)],[tuple(1u, 0u), tuple(1u, 1u)]];

immutable float[] sdImm = [1,2,3];
immutable uint[] smdImm = [4,5,6];
immutable Tuple!(size_t, size_t)[][] idImm = [[tuple(0u, 0u),  
tuple(0u, 1u)],[tuple(1u, 0u), tuple(1u, 1u)]];


auto a = new MyDataStore(sdMut, smdMut, idMut);
immutable b = new immutable MyDataStore(sdImm, smdImm, idImm);
const c = new const MyDataStore(sdImm, smdMut, idImm);
}

(Tested with 2.063 beta, it's possible there are complications in 2.062)

--
Simen


Re: Passing large or complex data structures to threads

2013-05-26 Thread Simen Kjaeraas
On Sun, 26 May 2013 14:06:39 +0200, Joseph Rushton Wakeling  
joseph.wakel...@webdrake.net wrote:



On 05/24/2013 04:39 PM, Simen Kjaeraas wrote:

First, *is* it read-only? If so, store it as immutable and enjoy free
sharing. If not, how and why not?


I can confess that it's as simple as feeling extremely uncomfortable  
dealing

with immutable where it relates to any kind of complex data structure.

I mean, for that double array structure I'd have to do something like,

Tuple!(size_t, size_t)[][] dataCopy;

foreach(x; data) {
Tuple!(size_t, size_t)[] xCopy;
foreach(y; x) {
immutable(Tuple!(size_t, size_t)) yCopy = y.idup;
xCopy ~= cast(Tuple!(size_t, size_t)) yCopy;
}
immutable xImm = assumeUnique(xCopy);
dataCopy ~= cast(Tuple!(size_t, size_t)[]) xImm;
}

immutable dataImm = assumeUnique(dataCopy);

... no?  Which feels like a lot of hassle compared to just being able to  
pass

each thread the information to independently load the required data.

I'd be delighted to discover I'm wrong about the hassle of converting  
the data

to immutable -- I don't think I understand how to use it at all well, bad
experiences in the past have meant that I've tended to avoid it.


That looks very complex for what it purports to do.

I understand data is the original data before sharing?

If so, will that a

--
Simen


Re: Passing large or complex data structures to threads

2013-05-26 Thread Simen Kjaeraas

On Sun, 26 May 2013 14:06:39 +0200, Joseph Rushton Wakeling
joseph.wakel...@webdrake.net wrote:


On 05/24/2013 04:39 PM, Simen Kjaeraas wrote:

First, *is* it read-only? If so, store it as immutable and enjoy free
sharing. If not, how and why not?


I can confess that it's as simple as feeling extremely uncomfortable  
dealing

with immutable where it relates to any kind of complex data structure.

I mean, for that double array structure I'd have to do something like,

Tuple!(size_t, size_t)[][] dataCopy;

foreach(x; data) {
Tuple!(size_t, size_t)[] xCopy;
foreach(y; x) {
immutable(Tuple!(size_t, size_t)) yCopy = y.idup;
xCopy ~= cast(Tuple!(size_t, size_t)) yCopy;
}
immutable xImm = assumeUnique(xCopy);
dataCopy ~= cast(Tuple!(size_t, size_t)[]) xImm;
}

immutable dataImm = assumeUnique(dataCopy);

... no?  Which feels like a lot of hassle compared to just being able to  
pass

each thread the information to independently load the required data.

I'd be delighted to discover I'm wrong about the hassle of converting  
the data

to immutable -- I don't think I understand how to use it at all well, bad
experiences in the past have meant that I've tended to avoid it.


That looks very complex for what it purports to do.

I understand data is the original data before sharing?

If so, will that array ever change again?


I think a bit more information is needed. I'm going to assume this is
(roughly) how things work:

1. Read from file/generate/load from database/create data.
2. Share data with other threads.
3. Never change data again.

If this is correct, this should work:


Tuple!(size_t, size_t)[][] data = createData();
immutable dataImm = assumeUnique(data);
data = null; // Simply to ensure no mutable references exist.
sendToOtherThreads(dataImm);


And that's it. If nobody's going to change the data again, it's perfectly
safe to tell the compiler 'this is now immutable'. No copies need to be
made, no idup, no explicit casting (except that done internally by
assumeUnique), no troubles.

--
Simen


Re: Passing large or complex data structures to threads

2013-05-26 Thread Simen Kjaeraas

On Sun, 26 May 2013 17:59:32 +0200, Ali Çehreli acehr...@yahoo.com wrote:


On 05/26/2013 05:38 AM, Simen Kjaeraas wrote:


   Tuple!(size_t, size_t)[][] data = createData();
   immutable dataImm = assumeUnique(data);
   data = null; // Simply to ensure no mutable references exist.

The last line is not needed. assumeUnique already does that. :)


Cool. I thought it might.


--
Simen


Re: Passing large or complex data structures to threads

2013-05-24 Thread Simen Kjaeraas

On 2013-05-24, 15:26, Joseph Rushton Wakeling wrote:


Hello all,

Are there any recommended strategies for passing large or complex data
structures (particularly reference types) to threads?

For the purpose of this discussion we can assume that it's read-only  
data, so if
we're talking about just an array (albeit perhaps a large one) I guess  
just
passing an .idup copy would be best.  However, the practical situation I  
have is

a data structure of the form,

Tuple!(size_t, size_t)[][]

... which I _could_ .idup, but it's a little bit of a hassle to do so,  
so I'm

wondering if there are alternative ways or suggestions.


First, *is* it read-only? If so, store it as immutable and enjoy free
sharing. If not, how and why not?

--
Simen


Re: class MyClass(T) : Base if (ConstraintExpression) {} compilation error

2013-05-24 Thread Simen Kjaeraas

On 2013-05-24, 16:49, ref2401 wrote:


Version D 2.062

Please explain what is causing the error

class Base
{ }

class Class(T) : Base
if (is(T == int))
{ }

Error: unrecognized declaration
Error: members expected
Error: Declaration expected, not 'if'
Error: { } expected following aggregate declaration


I'm confused too. This works:

class Base
{ }

class Class(T)
if (is(T == int)) : Base
{ }

void foo() {
   Base a = new Class!int;
}

--
Simen


Re: Copy instead of reference?

2013-05-23 Thread Simen Kjaeraas
On Thu, 23 May 2013 13:29:49 +0200, Namespace rswhi...@googlemail.com  
wrote:



That was what I also expected. But opAssign is not called.


Because you have a postblit. It's called instead of opAssign.

--
Simen


Re: WindowProc in a class - function and pointer problem

2013-05-22 Thread Simen Kjaeraas

On 2013-05-22, 21:30, D-sturbed wrote:

Hello, is there a way to wrap a WindowProc (so LRESULT WindowProc(HWND  
hWnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow) in a class  
and to link it to a WindowClass without puting it as static ?


Because defacto every datum used in the WindowProc must also be static.
The problem technically is that if static is not specified, the  
compiler won't allow this: MyWinClass.lpfnWndProc =  
TheWindowProcInMyClass.


I've also tried this: MyWinClass.lpfnWndProc =  
(TheWindowProcInMyClass).funcptr but, while it compiles, it  
drastically fails at the run-time...


Not possible, no. What you *can* do is have some way to translate from
hwnd to class instance, and fetch the right instance inside the static
wndProc to call a member function on that.

--
Simen


Re: how to have alias this with an unaccessible member?

2013-05-19 Thread Simen Kjaeraas
On Sat, 18 May 2013 02:12:00 +0200, Timothee Cour  
thelastmamm...@gmail.com wrote:



so in what you suggest, the exact same problem remains with 'get' being
exposed instead of 'x', so the situation didn't improve...

looks like it's impossible to achieve this?



Well, there is also opDot:

struct A(T) {
  private T x;

  T opDot() {
return x;
  }
}

void main(){
  auto a = A!int;
  a++; //should do a.x++;
  static assert(!__traits(compiles, a.x)); // This now holds!
}

However, now A!int is not an int (you can't pass it to functions taking  
int).


--
Simen


Re: how to have alias this with an unaccessible member?

2013-05-17 Thread Simen Kjaeraas
On Sat, 18 May 2013 01:13:00 +0200, Timothee Cour  
thelastmamm...@gmail.com wrote:



How to have alias this with an unaccessible member (x below).
Making the member private won't work as it'll disable all operations on
said member.


struct A(T){
  T x;
  //private T x would prevent alias this from doing anything useful
  alias x this;
}
void main(){
  auto a=A!int;
  a++;//should do a.x++;
  static assert(!__traits(compiles,a.x)); // I want this to hold

}




The common way to do it is with a read-only property:

struct A(T) {
  private T x;

  @property
  T get() {
return x;
  }

  alias get this;
}

void main(){
  auto a = A!int;
  a++; //should do a.x++;
  static assert(!__traits(compiles, a.x)); // This now holds!
  static assert(__traits(compiles, a.get)); // As does this, which may or  
may not be palatable. :(

}

This has been discussed numerous times before, but I believe the current  
behavior is here to stay.


--
Simen


Re: Recursive mixin templates

2013-05-16 Thread Simen Kjaeraas
On Thu, 16 May 2013 17:01:54 +0200, Sebastian Graf  
sebastiang...@t-online.de wrote:



I aim to use a simplistic, rough edged property generator, but
I'm having issues.
See http://dpaste.dzfl.pl/72837a7a.
My code and mixin logic seems to work basically, but it gets
hairy when using mixinMap to generate getters and setters from a
list in a recursive template fashion. It won't work if I generate
both getters and setters with mixinMap, but it compiles fine if I
e.g. want only getters.
Any help? I smell a compiler bug if I haven't done something
stupid.


This is one of those weird things. I believe it is intentional, but
I feel it should be a bug. Basically, overload sets cannot cross
mixin borders. So if two mixins create a function with the same name,
they don't overload properly.

I'd say add it to BugZilla if it's not already there. Comment on the
relevant bug if it is - this is not good for the language.

--
Simen


Re: Cross product template

2013-05-15 Thread Simen Kjaeraas

On Wed, 15 May 2013 03:31:40 +0200, Diggory digg...@googlemail.com wrote:

I have a vector struct, Vector(T, uint N) templated on the type T and  
number of components, N. I'm trying to write a function cross which  
will calculate the cross product of a number of vectors.


For a given number of components, N, the cross function should take N-1  
arguments, each one a Vector!(?, N) and will return a vector  
perpendicular to the vectors passed in. The ? means the type is free to  
be anything.


The problem is that however I try to write it, the template argument  
deduction isn't powerful enough to work out which instantiation to use.


I thought something like this would work to deduce the parameters and  
then I could use constraints to enforce the other rules, but no:

auto cross(T, N, U...)(Vector!(T, N) a, U b) { return 0; }


auto cross(T, uint N, U...)(Vector!(T,N) a, U b) { return 0; }

Oughta work.

--
Simen


Re: Structure's inheritance

2013-05-12 Thread Simen Kjaeraas

On 2013-05-12, 14:00, evilrat wrote:


On Sunday, 12 May 2013 at 11:56:53 UTC, Maxim Fomin wrote:


You can place base struct instance inside nested and use alias
this. Note that currently multiple alias this are not supported.
Also note that you cannot override functions because there are no
virtual table for structs.


why multiple alias this not supported? i know it was broken in 2.060 but  
with 2.061 it was fixed right?


It's simply never been implemented.

--
Simen


Re: Check if tuple contains value at compile time

2013-05-04 Thread Simen Kjaeraas

On 2013-05-05, 01:42, Diggory wrote:

I'm trying to test using a static if statement if a tuple of strings  
contains a particular string. What's the easiest/best way to do this?


http://dlang.org/phobos/std_typetuple#.staticIndexOf

--
Simen


Re: a FOR loop and floating variables

2013-05-02 Thread Simen Kjaeraas

On 2013-05-02, 20:14, Carlos wrote:


I have this code :

import std.stdio;
import std.c.stdlib;
void main()
{
int fahr;
write(F\tC\n);
for (fahr = 0; fahr = 300; fahr = fahr + 20)
write(fahr, \t, (5.0/9.0)*(fahr-32), \n);
write(Done!\n);
exit (0);
}
  Which works. but if I change the 5.0 for 5 I get cero on the  
celsius side.


import std.stdio;
import std.c.stdlib;
void main()
{
int fahr;
write(F\tC\n);
for (fahr = 0; fahr = 300; fahr = fahr + 20)
write(fahr, \t, (5/9)*(fahr-32), \n);
write(Done!\n);
exit (0);
}

So why is this ?


Both 5 and 9 in the second example are integers (int). When you divide
one int by another, the result is an int, and hence (5/9) is 0.

--
Simen


Re: Calculation differences between Debug and Release mode

2013-04-20 Thread Simen Kjaeraas
On Sat, 13 Apr 2013 18:36:21 +0200, Jeremy DeHaan  
dehaan.jerem...@gmail.com wrote:


I'm on Windows, and I my compilation was nothing more than dmd -O  
-release main.d to get the issue I described.


Turns out, the problem starts here:

static const(float) pi = 3.141592654f;

If we compare that to std.math.PI, we see that they're different:

 writeln( 3.141592654f - std.math.PI );
4.10207e-10

If, however, we assign these values to some temporary floats, we see that
they're equal:

 float a = 3.141592654f;
 float b = std.math.PI;
 writeln( a - b );
0

Replace float with double or real in the above, and the difference  
reappears.


So, we have established that 3.141592654f is a valid approximation to pi  
for a
float. The problem thus has to be one of precision. I'm not sure if it's a  
valid
optimization for the compiler to use doubles instead of floats (it  
certainly
seem innocuous enough). I'd say file a bug on it. Worst case, it gets  
closed as

invalid.

--
Simen


Re: Why are fixed length arrays passed by value while variable are passed by reference?

2013-04-18 Thread Simen Kjaeraas

On 2013-04-18, 16:20, ixid wrote:

An array is represent using a struct with a pointer to the array data  
and the length, like this:


struct Array
{
void* ptr;
size_t length;
}

The struct is passed by value, but since it contains a pointer to the  
data it will be passed by reference. Note that if you do:


void foo (int[] a)
{
a ~= 3;
}

auto b = [3, 4];
foo(b);

The caller will not see the change made by foo.

Don't know if this explanation helped you to understand.


What does a fixed length array look like when passed, doesn't it have a  
similar payload of data and length? I take it you mean the struct method  
is the variable length array.



The fixed length array is much more similar to a struct. An int[2], for
instance, is in many ways equivalent to struct { int a; int b; }.
Two ways this is visible is that static arrays are allocated on the stack,
and take up space in a struct or class the same way a struct would:

struct S1 {
int[] a;
}
static assert( S1.sizeof == int[].sizeof );

struct S2 {
int[17] a;
}
static assert( S2.sizeof == 17 * int.sizeof );


Also, like Jacob wrote, there is the difference of ref/value semantics
when embedded in a struct/class. If I have these two functions:

void foo1( S1 s ) {
   s.a[0] = 7;
}

void foo2( S2 s ) {
   s.a[0] = 7;
}

void test( ) {
   S1 s1 = S1(new int[4]);
   S2 s2 = S2();
   foo1(s1);
   foo2(s2);
}

The values in s1 will have changed, while those in s2 will not.

All in all, static arrays are treated as value types everywhere else,
and so treating them as value types when passed to a function makes
more sense.

--
Simen


Re: Use enum base type?

2013-04-17 Thread Simen Kjaeraas

On 2013-04-17, 19:15, Janissary wrote:


Is it possible to evaluate an enum's base type? Ideally something like:

enum somestrs : string { ... }
enum d = 0.0;
template EnumBaseType(E) if (is(E==enum)) { ... }
unittest {
static assert( is(EnumBaseType!somestrs == string) );
static assert( is(EnumBaseType!d : float) );
static assert(!is(EnumBaseType!d == float) );
}

A template like this would make at least my life easier.


Whenever you want to do weird stuff with types, std.traits[1] should
be your #1 stop. And quite correctly, std.traits.OriginalType[2] does
what you want:

  enum E : int { a }
  typedef E F;
  typedef const F G;
  static assert(is(OriginalType!G == const int));

[1]: http://dlang.org/phobos/std_traits
[2]: http://dlang.org/phobos/std_traits#.OriginalType
--
Simen


Re: Calculation differences between Debug and Release mode

2013-04-13 Thread Simen Kjaeraas
On Sat, 13 Apr 2013 08:07:39 +0200, Jeremy DeHaan  
dehaan.jerem...@gmail.com wrote:


In debug mode this works as expected. Let's say the radius is 50.  
getPoint(0) returns a vector that prints X: 50 Y: 0. For some reason,  
the same function will return a vector that prints X: 50 Y: 4.77673e-14.  
Now, 4.77673e-14 is a crazy small number that might as well be 0, but  
why the difference?


Sounds to me like a bug. I've tried recreating the problem on my machine
(Win7, dmd 2.062 32-bit, no flags other than debug/release), but can't see
it happen here. My (perceived) version of your code:

import std.stdio : writeln;
import std.math : sin, cos;

struct Vector2f {
float x,y;
}

int m_pointCount = 25;
float m_radius = 50;
Vector2f getPoint(uint index)
{

static const(float) pi = 3.141592654f;

float angle = index * 2 * pi / m_pointCount - pi / 2;


float x = cos(angle) * m_radius;
float y = sin(angle) * m_radius;


return Vector2f(m_radius + x, m_radius + y);
}

void main( string[] args ) {
writeln( getPoint( 0 ) );
}

Could you please post here the minimum code necessary to get the
behavior you describe, as well as the platform and compiler flags
you're using?


--
Simen


Re: operator +=

2013-04-08 Thread Simen Kjaeraas

On 2013-04-08, 14:23, Minas Mina wrote:


How can I define operator += for a struct?


http://dlang.org/operatoroverloading.html

In short:

struct S {
auto opOpAssign( string op : + )( S other ) {
// Do stuff here.
}
}

--
Simen


Re: Variadic constructor conflict

2013-01-30 Thread Simen Kjaeraas

On 2013-01-30, 17:08, andrea9940 wrote:


This code compiles fine:

struct Vector(T, uint SIZE)
{
T[SIZE] vector;

this(T value) {
foreach (ref v; vector) v = value;
}
}
alias Vector!(int, 3) Vec3i;


but if I add a variadic constructor:


struct Vector(T, uint SIZE)
{
[...]

this(T...)(T values) if (values.length == SIZE) {
foreach (i, v; values) vector[i] = v;
}
}
alias Vector!(int, 3) Vec3i;


I get:
main.d(54): Error: template main.Vector!(int, 3).Vector.__ctor(T...)(T  
values) if (values.length == SIZE) conflicts with constructor  
main.Vector!(int, 3).Vector.this at main.d(46)
main.d(111): Error: template instance main.Vector!(int, 3) error  
instantiating



I think that should not happen because when there is a conflict call  
like Vec3i(3) the compiler must(?) use the specialized function...


Known bug. For the moment, the workaround is to templatize all  
constructors:


struct Vector(...)
{
this()(T value ) {
...

--
Simen


Re: UFCS opDispatch

2013-01-16 Thread Simen Kjaeraas

On 2013-01-16, 22:02, Nick Sabalausky wrote:


Unfortunately, opDispatch [silently] takes precedence over
UFCS. I don't suppose there's any way to make a UFCS function call
override opDispatch without either ditching UFCS or altering/removing
the opDispatch itself?


Only solution I know of is to use constraints on opDispatch.

--
Simen


Re: Does the new alias syntax not support extern for function types?

2013-01-15 Thread Simen Kjaeraas

On 2013-04-15 13:01, Mike Parker aldac...@gmail.com wrote:


On Monday, 14 January 2013 at 21:00:12 UTC, Simen Kjaeraas wrote:

alias foo = extern(System) void function();

Gives me an error about expecting basic type, not extern.


extern(System) alias void function() foo;


But that's the old syntax, with which one can do this:

alias extern(System) void function() foo;

I'm talking about the new syntax, with =. Apparently, this does
support prefix extern, as you show:

extern(System) alias foo = void function();

I guess that's the solution, but it seems weird to me that it
does not support extern where the old syntax does.

--
Simen


Re: Specifying eponymous template internal parameter

2013-01-08 Thread Simen Kjaeraas

On 2013-55-08 09:01, monarch_dodra monarchdo...@gmail.com wrote:

Sometimes (especially in phobos), one defines a parametrized template,  
that resolves to a templated function.


This is a nifty trick, because it allows specifying a vararg before the  
current type parameter, eg:


//
auto r = [1, 2, 3];
auto m = map!(++a, --a)(r);
//

As you can see, the template guessed the type of r, even though we used  
a vararg. This would not have worked with a single template function.


My question though: I have a similar use case, but I NEED to be able to  
explicitly specify the type of r: as such:


//
auto m = fun!(++a, --a, ubyte)(1);
auto m = fun!(++a, --a)!(ubyte)(1);
auto m = fun!(++a, --a).fun!ubyte(1);
//
None of them work. In this specific case, I *need* to specify that 1 is  
of type ubyte, but I really can't do it :/


Simplified example: in my use case, it is a immutable(int[]): Failure  
to specify the type means the compiler strips tail immutability...


The only workaround I can find to make such a thing, is to *not* use  
eponymous temples, and explicitly call an inner function. This is ugly  
as sin, and it makes specifying the internal parameter mandatory.


Any thoughts?


A non-eponymous template is currently the only way to do this. Strangely,  
this works:


  alias fun2 = fun!(++a, --a);
  auto m = fun2!(ubyte)(1);

--
Simen


Re: Specifying eponymous template internal parameter

2013-01-08 Thread Simen Kjaeraas

On 2013-16-08 11:01, monarch_dodra monarchdo...@gmail.com wrote:


On Tuesday, 8 January 2013 at 09:59:26 UTC, Simen Kjaeraas wrote:

  alias fun2 = fun!(++a, --a);
  auto m = fun2!(ubyte)(1);


Nice!

And now, for the 1M$ question: Can I rely on this behavior, or is this  
an accepts invalid...?


You can rely on it.

--
Simen


Re: Why is immutable not possible as a result of a reduce expression?

2013-01-05 Thread Simen Kjaeraas

On 2013-52-05 20:01, Michael Engelhardt m...@mindcrime-ilab.de wrote:


Hi,
just playing around with the functional capabilities of D. One concept  
of the pure functional programming is that variables should not be  
reassigned, so the best(?) way to assure this is using immutable:


 immutable auto gen = sequence!(n);
 immutable auto seq = take(gen,10);
 immutable auto filtered = filter!(a % 3 == 0 || a % 5 ==0)(seq);
 immutable auto sum = reduce!(a+b)(filtered);

but the last line gives a compiler error:

Error: template instance  
std.algorithm.reduce!(a+b).reduce!(immutable(FilterResult!(unaryFun,immutable(Take!(immutable(Sequence!(n,Tuple!(  
error instantiating


It compiles and run as expected if I remove the immutable constraint on  
the reduce expression. So what is happening here? I thought reduce will  
create a new data structure containing the resulting values like filter  
and other operations too? That seems not to be the case, maybe someone  
could give me a deeper understanding of this.


The reason is that ranges may not be immutable or const.

Ranges need to be mutated (popFront) to be iterable, and your filtered
range cannot be mutated, by virtue of being immutable. I'm surprised that
seq and filtered work, but I guess there may be specializations that
circumvent the problem.

In other words, remove immutable from the first three lines, and the
program should compile.

A little details is that immutable auto is unnecessary, as immutable
implies auto (the details are more complex, but that's the short version).
--
Simen


Re: std.range lockstep is not input range but opApply entity. Workarounds?

2012-12-29 Thread Simen Kjaeraas

On 2012-48-29 14:12, mist n...@none.none wrote:


I basically want to be able to do stuff like this:
auto result = map!( (a, b) = a+b )( lockstep(range1, range2) );

Are there any standard short ways to wrap an input range around struct  
with opApply (which Lockstep is)?


Also what about redesigning Lockstep as a proper range? I could do a  
pull request but not sure about current intentions.


Use std.range.zip instead:

  auto result = map!( (a, b) = a+b )( zip(range1, range2) );

The reason there are two ways is lockstep works better with foreach:

  foreach (a, b; lockstep(A, B) ) {
  // Use a and b here.
  }

Contrast with zip:

  foreach (a; zip(A, B) ) {
  // Use a[0] and a[1] here.
  }

There have been suggestions to better integrate tuples in the language,
so in the future zip may have all the advantages of lockstep (and vice
versa), but don't cross your fingers.

--
Simen


Re: std.range lockstep is not input range but opApply entity. Workarounds?

2012-12-29 Thread Simen Kjaeraas

On 2012-52-29 20:12, mist n...@none.none wrote:


Not clever enough to expand like this though:
map!( (a, b) = a+b )( zip(Range1, Range2) );

Using a = a[0]+a[1] is not that big deal though.


That oughta be doable. However, seeing as std.functional only contains
unaryFun and binaryFun (dranges has naryFun), this approach cannot
currently extend to tuples with more than two fields.

--
Simen


Re: checking whether the number is NaN

2012-12-28 Thread Simen Kjaeraas

On 2012-42-28 16:12, Zhenya zh...@list.ru wrote:


Hi!
Tell me please,are there any way to check whether number is NaN?


us std.math.isNaN. But if you really don't want to:

float x = ...;

if (x != x) {
writeln( x is NaN );
}

I'm unsure how aggressive the optimizer is allowed to be in cases
like this. Theoretically it could assume x is always equal to x,
but I'd think it's not allowed to for floats.

If you're wondering how a float value could compare different to
the exact same value, consider that this would otherwise be true:

sqrt(-1) == 0/0

--
Simen


Re: bio parser

2012-12-16 Thread Simen Kjaeraas
On 2012-09-16 17:12, bioinfornatics bioinfornat...@fedoraproject.org  
wrote:



Dear,
I wrote a fasta format parser and fastq format parser. These parser used
MmFile and do not load all file these will save memory.

Fastq http://dpaste.dzfl.pl/9b23574d
Fasta http://dpaste.dzfl.pl/228dba11

The way to iterate over it is really close and i search a way to have
one struct bySection one template doIndex for both file format.

If you have any suggestion to improve this, please tell to me.


As this is something that might be useful to others, you should probably
post it to digitalmars.D.announce. I'd also advice setting up a github rep
for it and placing a link on wiki.dlang.org.

--
Simen


Re: Operator overloading of native types?

2012-12-13 Thread Simen Kjaeraas

On 2012-12-14, 00:19, H. S. Teoh wrote:


I'd like to overload the '*' operator to work with string arguments. Is
it possible? I tried the following, but apparently operator overloading
doesn't work at the package level?

string opBinary(string op)(string repeatMe, int thisManyTimes)
if (op==*)
{
auto app = appender!string();
while (thisManyTimes  0) {
app.put(repeatMe);
thisManyTimes--;
}
return app.data;
}

void main() {
writeln(spam * 3);  // compile error
}

Or is this just a very bad idea? ;-)


Like bearophile said, overloaded operators need to be defined inside
one of the types on which they should operate. Since built-in types
cannot be modified, one cannot overload operators on them.

--
Simen


Re: constructor is not callable using argument types ()

2012-12-06 Thread Simen Kjaeraas

On 2012-12-06, 20:17, Suliman wrote:

I am learning D classes and I am getting error when I am try to make  
instance of class. erorr:
C:\code\main.d(9): Error: constructor GetFileName.GetFileName.this  
(string name) is not callable using argument types ()


http://www.everfall.com/paste/id.php?xie09xz9upth


You have supplied the string you promised to.

You have this constructor:

this(string name)

And call it like this:

new GetFileName();

Where's the string the constructor expects?

Instead, you should call it like thus:

new GetFileName(test);

--
Simen


Re: constructor is not callable using argument types ()

2012-12-06 Thread Simen Kjaeraas

On 2012-12-06, 20:48, Suliman wrote:


When I should use keyword this?
I dropped it from my class and now I can make instance of class without  
in sych way:


auto file = new GetFileName();
file.name = test;


Indeed. If you have not defined a constructor, the language defines one
for you, which is parameterless. It does nothing but allocate and
initialize memory.

The moment you define a constructor of your own, the compiler decides
you probably want to define the parameterless constructor yourself, or
not at all, and thus does not define it for you.

If you want both, then define both:

class MyClass {
string name;
this() {
name = Foo!;
}
this(string name) {
this.name = name;
}
}

--
Simen


Re: Getting memory size of class

2012-12-05 Thread Simen Kjaeraas

On 2012-12-05, 20:03, js.mdnq wrote:



sizeof always returns 4 or 8 regardless of size of class:

class myclass(T)
{
public:
T v1;
T v2;
T v3;
T v4;
T v5;
T v6;
}

writeln((myclass!byte).sizeof, (myclass!double).sizeof);

or even

writeln((myclass!int).classinfo.init.sizeof,  
(myclass!double).classinfo.init.sizeof);


from

http://forum.dlang.org/thread/dp9hct$nuf$1...@digitaldaemon.com

So how does one get the actual memory usage of a class?


__traits( classInstanceSize, myclass!int )

http://dlang.org/traits.html

--
Simen


Re: Can operators return type?

2012-11-29 Thread Simen Kjaeraas

On 2012-11-29, 17:33, Zhenya wrote:


Hi!
It would useful for some my project,if operators could be a  
template,that return

type.Something like

alias TypeTuple!(int,char) types;

static assert(types[1] == char) //opIndex

So can I define something like that?


This works out of the box. If you want to define your own
TypeTuple-like construct, the answer is most likely going to be no.

--
Simen


Re: how to count number of letters with std.algorithm.count / std.algorithm.reduce / std.algorithm.map ?

2012-11-16 Thread Simen Kjaeraas

On 2012-11-16, 16:49, bioinfornatics wrote:


hi,

I would like to count number of one ore more letter into a string or  
list of string (string[]) without use a for loop but instead using  
std.algorithm to compute efficiently.


if you have:
  string   seq1 = ACGATCGATCGATCGCGCTAGCTAGCTAG;
  string[] seq2 = [ACGATCGATCGATCGCGCTAGCTAGCTAG,  
ACGATGACGATCGATGCTAGCTAG];


i try :

reduce!( (seq) = seq.count(G), seq.count(C))(tuple(0LU,0LU),seq1)

and got:
Error: undefined identifier seq, did you mean import std?

in morre count seem to request a range then to do multiple count into  
one string it is not easy.


Thanks to show to me how do this


There are several problems here. First, as the compiler is trying to
tell you, the part after the comma is not a valid delegate. It should
look like this:

reduce!( (seq) = seq.count(G), (seq) =  
seq.count(C))(tuple(0LU,0LU),seq1)


Now, that's not really all that closer to the goal. The parameters to
these delegates (seq) are characters, not arrays of characters. Thus,
seq.count does not do what you want.

Next iteration would be:

reduce!( (seq) = seq == G, (seq) = seq == C )(tuple, 0LU, 0LU,  
seq1)


Not there yet. seq is an element, G is a string - an array. One more:

reduce!( (seq) = seq == 'G', (seq) = seq == 'G' )(tuple, 0LU, 0LU,  
seq1)


Lastly, reduce expects delegates that take two parameters - the current
value of the accumulator, and the value to be considered:

reduce!( (acc, seq) = acc + (seq == 'G'), (acc, seq) = acc + (seq ==  
'C') )(tuple(0LU, 0LU), seq1)


There. Now it works, and returns a Tuple!(ulong,ulong)(8, 8).

One thing I think is ugly in my implementation is acc + (seq == 'G'). This
adds a bool and a ulong together. For more points, replace that with
acc + (seq == 'G' ? 1 : 0).

--
Simen


Re: how to count number of letters with std.algorithm.count / std.algorithm.reduce / std.algorithm.map ?

2012-11-16 Thread Simen Kjaeraas

On 2012-11-16, 17:37, bearophile wrote:


Simen Kjaeraas:


There. Now it works, and returns a Tuple!(ulong,ulong)(8, 8).

One thing I think is ugly in my implementation is acc + (seq == 'G').  
This

adds a bool and a ulong together. For more points, replace that with
acc + (seq == 'G' ? 1 : 0).


I use a pragmatic approach: I use such higher order functions when they  
give me some advantage, like more compact code, or less-bug-prone code,  
etc (because they usually don't give me faster code). In this case a  
normal loop that increments two counters is faster and far more easy to  
read and understand :-)


Absolutely. But after trying to make sense of the mess presented in the
OP, I wanted to document the voyage.

--
Simen


Re: shouldn't const cast always be allowed (even if shunned)

2012-11-15 Thread Simen Kjaeraas

On 2012-23-15 15:11, Dan dbdavid...@yahoo.com wrote:


There are times when casting away const is needed.  Structs that
define opCast can get in the way of this.  For instance, the cast
below fails, but I think it should always be allowed. So, if the
source type and cast type are the same except for const qualifiers,
there is no need to consider custom opCast members. Is a reasonable
suggestion for the language?

The cast here fails because it is considering custom opCast methods,
but that is not helpful.

Thanks
Dan

-
import std.bitmanip;
void main() {
   const(BitArray) cba;
   cast()cba;
}



That does indeed seem reasonable. File an enhancement request.

--
Simen


Re: Fasta parser

2012-11-11 Thread Simen Kjaeraas
On 2012-34-11 18:11, bioinfornatics bioinfornat...@fedoraproject.org  
wrote:



Hi,
I wrote a fasta parser for biology computing
http://pastebin.geany.org/yheQN/

I would like to get your experience to know if the writer could be
better. The given parser use MmFile and Phobos range.

fasta specification format = http://en.wikipedia.org/wiki/FASTA_format


Not available (anymore). That's a bummer.

Also, obligatory 'Red unz go fasta!'

--
Simen


Re: Extracting template parameters

2012-11-06 Thread Simen Kjaeraas

On 2012-11-06, 16:20, Joseph Rushton Wakeling wrote:

Suppose that I have two struct templates which take identical parameter  
lists:


 struct Foo(T1, T2, T3)
 {
 ...
 }

 struct Bar(T1, T2, T3)
 {
 ...
 }

Now suppose that I have a Foo which has been instantiated with a given  
set of parameters.  Is there any way for me to say, now instantiate a  
Bar with the same parameters?


The use-case I'm thinking of is a function something like this (somewhat  
pseudo-code-y):


 auto fooToBar(FooInstance f)
 {
 Bar!(f.T1, f.T2, f.T3) b;
 // set values etc.
 return b;
 }

Of course the f.T1 notation is my fiction, but it gives the idea of what  
is needed -- is there a means to extract and use template parameters in  
this way? I assume something from std.traits but it's not entirely clear  
what or how ...


In addition to Dan's answer, let me present a general solution:

template InstantiationInfo( T ) {
static if ( is( T t == U!V, alias U, V... ) ) {
alias U Template;
alias V Parameters;
} else {
static assert(false, T.stringof ~  is not a template type  
instantiation.);

}
}

With this, you can extract the parameters to a template
(InstantiationInfo!Foo.Parameters) or the template used
(InstantiationInfo!Foo.Template).

--
Simen


Re: Tuples and variable-length template parameter lists

2012-11-05 Thread Simen Kjaeraas

On 2012-11-05, 15:53, Joseph Rushton Wakeling wrote:


Hello all,

Suppose I want to define a tuple type which may have a variable length,  
e.g.:


template Tup(ID, Properties...)
{
static if(Properties.length == 0)
alias Tuple!(ID, id) Tup;
else
alias Tuple!(ID, id, Properties) Tup;
}

Now, it's trivial to include an arbitrary selection of named values in  
this, e.g.


auto t1 = Tup!(size_t, real, value)(3, 4.5);
writeln(t1);
writeln(t1.id,  , t1.value);

auto t2 = Tup!(size_t, real, value, bool, active)(3, 4.5, true);
writeln(t2);
writeln(t2.id,  , t2.value,  , t2.active);

However, suppose now I want to define a container struct which holds an  
array of

tuples of the specified type.  Here's what I came up with:

struct Container(ID, Properties...)
{
Tup!(ID, Properties)[] contents;

void add(ID i, Properties p)
{
static if(Properties.length == 0)
contents ~= Tup!(ID)(i);
else
contents ~= Tup!(ID, Properties)(i, p);
}
}

Now, if I make properties empty, this works just fine:

auto c1 = Container!(size_t)();
c1.add(3);
c1.add(7);
c1.add(2);
writeln(c1);
foreach(t, tup; c1.contents)
writeln([, t, ] , tup.id);
writeln();

... and likewise if I pass the container a list of value types without  
value names:


auto c2 = Container!(size_t, real, real)();
c2.add(5, 3.2, 5.6);
writeln(c2);
writeln();

... but if I try asking the container to store a tuple with _named_  
values, e.g.


auto c3 = Container!(size_t, real, value)();

then compilation fails with the following error message:


tupcontainer.d(7): Error: tuple Properties is used as a type
tupcontainer.d(12): Error: template
std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor does not match  
any

function template declaration
/usr/local/include/d2/std/typecons.d(406): Error: template
std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor cannot deduce  
template

function from argument types !()(ulong,_error_)
tupcontainer.d(51): Error: template instance
tupcontainer.Container!(ulong,real,value) error instantiating


I'm confused as to why the Container struct cannot take these template
parameters when the corresponding parameters work just fine for Tup.

Can anyone advise what the problem is and if it's possible to get the  
Container

working as envisioned?


std.typecons.Tuple does a bit of magic behind the scenes. This includes
ridding itself of non-type parameters.

Simply put, you can imagine inserting the type tuple directly into the
function definition:

void add(ID id, size_t arg0, real arg1, value arg2);

as you probably notice, the last argument looks weird.

Now, Phobos does not currently have a staticFilter template, nor does it
have an isType template, so here are implementations of those:


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;
}
}

unittest {
static struct S(T...){}

assert( is( S!(staticFilter!(isType, int, float)) == S!(int, float) )  
);
assert( is( S!(staticFilter!(isType, int, foo, float)) == S!(int,  
float) ) );

assert( is( S!(staticFilter!(isType, foo, bar)) == S!() ) );
}

template isType( T... ) if ( T.length == 1 ) {
enum isType = !is( typeof( T[0] ) );
}

unittest {
struct S {}
class C {}

assert( isType!int );
assert( isType!string );
assert( isType!S );
assert( isType!C );

assert( !isType!1 );
assert( !isType! );
assert( !isType!(S( )) );
}


add would then have this signature:

void add(ID id, staticFilter!(isType, Properties));

--
Simen


Re: SList of chars not possible?

2012-11-02 Thread Simen Kjaeraas

On 2012-18-01 23:11, They call me Mr. D khea...@eapl.org wrote:



auto i = SList!int(1, 2, 3, 4, 5, 6, 7);

auto f = SList!float(1.1, 2.234, 3.21, 4.3, 5.001, 6.2, 7.0);

auto s = SList!string([I, Hello, World]);

auto c = SList!char('a', 'b' ,'c');  // doesn't compile, get the  
following


C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(905): Error:  
template std.container.SList!(char).SList.insertFront does not match any  
function template

eclaration
C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(1096): Error:  
template std.container.SList!(char).SList.insertFront cannot deduce  
template function from

argument types !()(char[])
Container.d(19): Error: template instance  
std.container.SList!(char).SList.__ctor!(char) error instantiating


auto c = SList!char(['a', 'b' ,'c']); // doesn't compile either.


Seems to me a Slist of char nodes should be pretty innocuous.


Not sure of the exact reasons, but I think Ali is probably right.

A char cannot hold all possible values for a unicode character, so
having a range with that element type is not really a good idea.

--
Simen


Re: How to add n items to TypeTuple?

2012-11-01 Thread Simen Kjaeraas

On 2012-11-01, 19:52, Justin Whear wrote:


On Thu, 01 Nov 2012 19:42:07 +0100, denizzzka wrote:


For example, adding 3 strings to type tuple t:

foreach( i; 0..2 )
  alias TypeTuple!( t, string ) t; // this is wrong code

and result should be:

TypeTuple!( string, string, string );


Use a recursive template.  Here's one that repeats a given type N times:

template Repeat(Type, size_t Times)
{
static if (Times == 0)
alias TypeTuple!() Repeat;
else
alias TypeTuple!(Type, Repeat!(Type, Times - 1)) Repeat;
}

Invoke like so:
Repeat!(string, 3) threeStrings;


I've always preferred the opposite order of arguments, as that
allows repetition of more complex things:

template Repeat(size_t times, T...) {
static if ( times == 0 ) {
alias TypeTuple!() Repeat;
} else {
alias TypeTuple!( T, Repeat!( times - 1, T ) ) Repeat;
}
}

Invoke like so:

alias Repeat!(4, string, int, Hello, template world!)  
YeahThisIsGonnaBeUseful;


Or:

alias Repeat!(3, string) ThreeStrings;

--
Simen


Re: What is the proper way to handle pointers in variable arguments list?

2012-10-28 Thread Simen Kjaeraas

On 2012-08-28 22:10, Tyro[17] nos...@home.com wrote:


On 10/28/12 4:44 PM, Dmitry Olshansky wrote:

On 29-Oct-12 00:36, Tyro[17] wrote:

The following fails because the compiler assumes I am trying to
dereference non-pointer variables. Can this be done?

void main()
{
 int i;
 int* pi;
 double d;
 double* pd;
 char c;
 char* pc;

 scan(i, pi, d, pd, c, pc);
}

void scan(A...)(ref A data)
{
 import std.traits;
 foreach (element; data) {
 if(isPointer!(typeof(element)) 
isIntegral!(typeof(*element))) {
 *element = 10;
 }
 }
}

Thanks


Well, first things first:
if --- static if



Changing it to static allows compilation, however I get the following  
runtime error:


 Segmentation fault: 11

This happens whether I try to read from *element or modify it.


I assume you've actually initialized the pointers to something?

Given the above code, all the pointers point to null, and a segfault
would be a reasonable reaction.

--
Simen


Re: Narrow string is not a random access range

2012-10-24 Thread Simen Kjaeraas

On 2012-41-24 01:10, Adam D. Ruppe destructiona...@gmail.com wrote:


On Tuesday, 23 October 2012 at 23:07:28 UTC, Jonathan M Davis wrote:
I think that Andrei was arguing for changing how the compiler itself  
handles arrays of char and wchar so that they wouldn't


As I said last time this came up, we could actually do this today  
without changing the compiler. Since string is a user defined type  
anyway, we could just define it differently.


http://arsdnet.net/dcode/test99.d

I'm pretty sure that changes to Phobos are even required. (The reason I  
called it String there instead of string is simply so it doesn't  
conflict with the string in object.d)



As long as typeof() != String, this is not going t work:

auto s = ;

--
Simen


Re: Narrow string is not a random access range

2012-10-23 Thread Simen Kjaeraas

On 2012-10-23, 19:21, mist wrote:

Hm, and all phobos functions should operate on narrow strings as if they  
where not random-acessible? I am thinking about something like  
commonPrefix from std.algorithm, which operates on code points for  
strings.


Preferably, yes. If there are performance (or other) benefits from
operating on code units, and it's just as safe, then operating on code
units is ok.

--
Simen


Re: Reordered class fields?

2012-10-22 Thread Simen Kjaeraas

On 2012-36-22 01:10, bearophile bearophileh...@lycos.com wrote:

This benchmark shows that if you allocate the class instances on the  
heap one at a time the total amount of memory used is the same for the  
various Bar (maybe because of the GC), so that optimization is useful  
for emplace() only and similar in-place allocations


The current GC always allocates a power of two, with a minimum of 16
bytes. You should see an effect if you make a class that will be above
such a threshold without reordering, and below with.


So is such class field reordering worth an enhancement request in  
Bugzilla?


Nothing bad can come of it.

--
Simen


Re: opCast using in template struct

2012-10-18 Thread Simen Kjaeraas

On 2012-10-18, 17:45, Oleg wrote:


Sorry. My problem more complex and my simplification is not correct.
I want use mixin for math operations.

mixin template vectOp( string DataName, int DataLen, T, vecType )
{
 mixin( alias  ~ DataName ~  this; );

 auto opBinary(string op,E)( E[DataLen] b ) 
 auto opBinary(string op,E)( E[] b ) 
 auto opOpBinary(string op,E)( E[] b ) 
 auto opOpBinary(string op,E)( E[DataLen] b ) 

}

struct vec(string S,T=double)
{
 T[S.length] data;
 mixin vectOp( data, S.length, T, vec!(S,T) );
}

unittest{
vec!xyz a;
vec!xyz b;
a += b;
}

and it isn't work

Error: 'a += b' is not a scalar, it is a vec!(xyz)
Error: 'a._data' is not of arithmetic type, it is a double[3LU]
Error: 'b._data' is not of arithmetic type, it is a double[3LU]


I see you have opOpBinary there - should those be opOpAssign?

--
Simen


Re: Returning dynamic array from the function

2012-10-17 Thread Simen Kjaeraas

On 2012-10-17, 21:17, m0rph wrote:


I tryed to learn how arrays works and found another strange thing:

import std.stdio;

int[] create()
{
int[5] a1 = [ 10, 20, 30, 40, 50 ];
int[] b1 = a1;
writeln(b1: , b1);
return b1;
}

void main()
{
int[] a2 = create();
writeln(a2: , a2);
}

Result of execution:
b1: [10, 20, 30, 40, 50]
a2: [-142625792, 32767, 4358059, 0, 5]

Please explain what's wrong with this code? Why variable a2 contains  
crap? Is this another dmd/druntime bug or I missed something?


b1 points to the exact same data as does a1. This data is stack-
allocated, and thus a2 points to an overwritten stack frame.

--
Simen


Re: templated static array

2012-10-15 Thread Simen Kjaeraas

On 2012-05-15 16:10, Namespace rswhi...@googlemail.com wrote:


How can I do this?

I have this code: http://dpaste.dzfl.pl/d9165502

And as you can see, the templated function 'receive2' take automatically  
dynamic arrays. But how can I tell the compiler, that this function  
takes (preferably) static arrays?
My little hack function 'receive' take the type and the number of  
elements. So the compiler know: it's a static array. But is there no  
simpler trick to do this?

Maybe something like 'void receive(T)(static T vals) {'.


Nope. That's the way to do it.

--
Simen


Re: templated static array

2012-10-15 Thread Simen Kjaeraas

On 2012-23-15 16:10, Simen Kjaeraas simen.kja...@gmail.com wrote:


On 2012-05-15 16:10, Namespace rswhi...@googlemail.com wrote:


How can I do this?

I have this code: http://dpaste.dzfl.pl/d9165502

And as you can see, the templated function 'receive2' take  
automatically dynamic arrays. But how can I tell the compiler, that  
this function takes (preferably) static arrays?
My little hack function 'receive' take the type and the number of  
elements. So the compiler know: it's a static array. But is there no  
simpler trick to do this?

Maybe something like 'void receive(T)(static T vals) {'.


Nope. That's the way to do it.


No, wait, sorry. You don't need to specify those things when calling the
function. This works:

void bar(T, size_t n)(T[n] a) {}

void main(){
int[3] a;
bar(a);
}

--
Simen


Re: templated static array

2012-10-15 Thread Simen Kjaeraas

On 2012-35-15 17:10, Namespace rswhi...@googlemail.com wrote:

But bar([1, 2, 3]); not. The compiler does not realize that [1, 2, 3]  
means a static array in this context.
You have to write bar(cast(int[3]) [1, 2, 3]); but I think the compiler  
have to recognize this on it's own.


This is true. The problem is, as you say, that the compiler treats array
literals as dynamic rather than static arrays. I would argue this is the
correct default, but it's obviously not the default you want here.

bearophile has posted about this on numerous occasions, and it's among
his top thousand wanted features. :p

--
Simen


Re: What am I doing wrong here?

2012-10-14 Thread Simen Kjaeraas

On 2012-10-14, 14:28, Martin wrote:

Hey everyone, I'm new to D so bare with me please. I've been trying to  
figure out what's up with the strange forward refernce errors the  
compiler (DMD 2.060) is giving me. Here's a code snippet that's  
generating a forward reference error:


public class AliasTestClass(alias func)
{

static assert(__traits(isStaticFunction, func));

}

public class TestClass
{

private AliasTestClass!(randomFunction) test; // -

public static void randomFunction()
{
}

}

The strange part about it is that if I surround the randomFunction  
parameter with another pair of paranthesis like so


private AliasTestClass!((randomFunction)) test;

It works just fine. If I don't, however, I get a forward reference error:
Error: template instance main.AliasTestClass!(randomFunction) forward  
reference of randomFunction


Am I doing anything wrong or is this some kind of bug?


It's a bug. Maybe it's already in Bugzilla (there are some forward-ref
bugs there already). Please file:

http://d.puremagic.com/issues/enter_bug.cgi

--
Simen


Re: Detect if running 32 bit program on 64 bit Windows OS

2012-10-09 Thread Simen Kjaeraas

On 2012-01-10 02:10, Josh moonbur...@gmail.com wrote:

Is there a way to do that? I've tried getenv(PROCESSOR_ARCHITECTURE)  
and shell(echo %PROCESSOR_ARCHITECTURE%), and both of them return  
x86 instead of AMD64 like cmd. I want to use this to run a 64 bit  
version of an external program if the OS is 64 bit, and the 32 bit  
version if not.


http://msdn.microsoft.com/en-us/library/ms684139(v=vs.85).aspx

--
Simen


Re: enum of tuples

2012-09-27 Thread Simen Kjaeraas

On 2012-09-27, 00:02, Jonathan M Davis wrote:


Classes will not work for the same reason that you can never use a class
object as an enum with manifest constants.


Has a decision been made as to whether or not this will be possible in the
future?

--
Simen


Re: move object from heap to stack

2012-09-19 Thread Simen Kjaeraas
On Wed, 19 Sep 2012 15:45:21 +0200, Namespace rswhi...@googlemail.com  
wrote:



On Wednesday, 19 September 2012 at 13:32:42 UTC, Namespace wrote:

Is that possible?
I can initialize an object with scope or, in feature, with scoped,  
directly on the stack but is it also possible to move an existing  
object from the heap to the stack?


I tried this:
http://dpaste.dzfl.pl/2955ff41
But as you can see in line 25/26, after I destroyed the heap object, the  
stack object seems to be corrupted.


The problem here is that A.sizeof returns the size of the reference, not
the instance. Instead you should use __traits(classInstanceSize, A).

Also, do have a look at the internals of std.typecons.scoped, it likely
contains some good ideas.

--
Simen


Re: static init cycle detection problem

2012-09-19 Thread Simen Kjaeraas

On Wed, 19 Sep 2012 22:25:46 +0200, Øivind oivind@gmail.com wrote:

I am struggeling to get around the cycle detection kicking in when I  
have static init in modules that depend on eachother.


I have seen some threads on 'fixes' for this, e.g. adding a @standalone  
property to the module or similar. Has there been any progress on this?


If not would it be possible in e.g. main() to get a list of all  
compiled-in modules, and then iterate over them and call an init  
function where it exists? As long as there is a way to list the name of  
the modules at compile-time, this should be pretty easy..?


There's no way to get that list at compile-time, because object files may
be added at link-time. However, D has a ModuleInfo object, which contains
information on all modules in the program:

import std.stdio;
void main( ) {
foreach( m; ModuleInfo ) {
writeln( m.name );
}
}

For details on how this object works, have a look-see at
src/druntime/src/object_.d in your DMD installation folder.

I'm not sure what you're asking for is possible even given this object,
but it's probably the closest you'll (easily) get.

--
Simen


Re: Quick int pointer allocation question

2012-09-14 Thread Simen Kjaeraas
On Fri, 14 Sep 2012 16:27:55 +0200, monarch_dodra monarchdo...@gmail.com  
wrote:



On Friday, 14 September 2012 at 11:17:55 UTC, Jacob Carlborg wrote:

On 2012-09-14 12:52, monarch_dodra wrote:


int x = void;

http://dpaste.dzfl.pl/24c1baa9


Hum, but that is a stack allocated variable.


Perhaps using GC.malloc?


Hum, apparently, there is a second (default aka-hidden) argument that is  
a bitmask applied to the allocated memory. So not much gain there.


I'm allocating an array of 500_000 ulongs, and afterwards, I'm  
initializing them all by hand, making the default allocation useless.


I'm not going to lose any sleep over this, but there is no way in D to  
get (garbage collected) un-initialized memory/allocations?


What's wrong with GC.malloc? The bitmask is there to... well, many things.
Pass it BlkAttr.NO_SCAN to ensure memory is not initialized. I think that's
all what's needed.

--
Simen


Re: auto limitation?

2012-09-11 Thread Simen Kjaeraas

On Tue, 11 Sep 2012 20:48:25 +0200, Ali Çehreli acehr...@yahoo.com wrote:

Or you can write or find a template that produces the largest type among  
the members of a union.


std.traits.CommonType.

--
Simen


Re: How to have strongly typed numerical values?

2012-09-04 Thread Simen Kjaeraas
On Wed, 05 Sep 2012 02:55:45 +0200, Nicholas Londey lon...@gmail.com  
wrote:



Hello.
I am trying to work out if there is existing support for strongly typed  
numerical values for example degrees west and kilograms such that they  
cannot be accidentally mixed in an expression. I have vague recollection  
of seeing a presentation by Walter talking about this but I cannot seem  
to find it. I have looked at std.typecons.Typedef and Proxy but neither  
seem to do what I want or at least fail to compile for the expression n  
=  n + n;. I could easily implement my own as I have done in C++ in the  
past but assume there is a standard implementation which I would prefer.

Any help or links to examples much appreciated.

Regards,

Nicholas


Not mine, but this is the implementation I use:

https://github.com/klickverbot/phobos/tree/units/std

Files are units.d and si.d.

Documentation:
http://klickverbot.at/code/units/std_units.html
http://klickverbot.at/code/units/std_si.html

--
Simen


Re: popFront with input variables

2012-08-31 Thread Simen Kjaeraas
On Fri, 31 Aug 2012 16:56:32 +0200, Joseph Rushton Wakeling  
joseph.wakel...@webdrake.net wrote:



Hello all,

Is it considered legit in any circumstances for popFront to take an  
input variable (e.g. a random number generator)?  Or is it required  
always to have no input variables?


No parameters, or at least it should be callable with no parameters.

Might I ask why you'd want this?

--
Simen


Re: static struct definition

2012-08-28 Thread Simen Kjaeraas
On Tue, 28 Aug 2012 12:10:47 +0200, monarch_dodra monarchdo...@gmail.com  
wrote:



 From TDPL: 7.18:

Unlike classes nested within classes, nested structs and nested classes  
within
structs don’t contain any hidden member outer—there is no special code  
generated.
The main design goal of nesting such types is to enforce the desired  
access control.


I suppose this has become obsolete then?
...Or is it the other way around?


TDPL trumps most everything else, I believe.

--
Simen


Re: struct with @disable(d) default constructor doesn't work with arrays?

2012-08-22 Thread Simen Kjaeraas
On Wed, 22 Aug 2012 13:09:49 +0200, bearophile bearophileh...@lycos.com  
wrote:



Minas Mina:


I think it's a bug, what do you think?


Search for it in Bugzilla. Maybe it's there already.

Bye,
bearophile


It is. #7021/#8457

--
Simen


  1   2   3   4   5   >