February 09, 2013
On Saturday, 9 February 2013 at 12:10:57 UTC, Namespace wrote:

>> In particular, you can't pack classes in a table, for example.
> I don't understand.

I mean structs you can pack together in an array, eg:

S[10] s10; //10 structs S

You can't do that with classes. Sure, you can put 10 class *references* in an array, but the *instances* themselves need to be individually allocated.

This can be a problem if you want to represent an image, for example, and "S" is an RGB quad.
February 09, 2013
monarch_dodra:

> I mean structs you can pack together in an array, eg:
>
> S[10] s10; //10 structs S
>
> You can't do that with classes. Sure, you can put 10 class *references* in an array, but the *instances* themselves need to be individually allocated.

This kind of works, with some limitations (I'll ask to remove one limitation):


import std.stdio, std.conv, std.typecons;

class Foo {
    int x;
    this(int x_) { this.x = x_; }
    override string toString() { return text(x); }
}

void main() {
    // scoped!Foo[10] foos;
    typeof(scoped!Foo(1))[10] foos; // Not initialized.

    foreach (i, ref f; foos)
        // f = new Foo(i * 10);
        // f = scoped!Foo(i * 10);
        f.x = i * 10;

    // writeln(foos);
    foreach (ref f; foos)
        writeln(f.x);
}


Bye,
bearophile
February 09, 2013
> (I'll ask to remove one limitation):

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


>     typeof(scoped!Foo(1))[10] foos; // Not initialized.
>
>     foreach (i, ref f; foos)
>         // f = new Foo(i * 10);
>         // f = scoped!Foo(i * 10);
>         f.x = i * 10;

What's the right/good way to initialize a scoped class instance? Currently this doesn't work:


import std.typecons;

class Foo {
    int x;
    this(int x_) { initialize(x_); }
    void initialize(int x_) {
        this.x = x_;
    }
}

void main() {
    typeof(scoped!Foo(1))[10] foos;
    foreach (i, ref f; foos)
        f.initialize(i * 10);
}


Bye,
bearophile
February 09, 2013
Why isn't there 'const' in ParameterStorageClass?
How could I detect that my Parameter storage class is 'in'?
February 09, 2013
It seems your template has problems with this:

struct A { }

class B {
public:
	const int bar(ref A a) {
		return 42;
	}
	
	mixin(rvalue!(bar));
}

remove the 'const' and it works fine.
February 09, 2013
On Saturday, 9 February 2013 at 22:23:07 UTC, Namespace wrote:
> It seems your template has problems with this:
>
> struct A { }
>
> class B {
> public:
> 	const int bar(ref A a) {
> 		return 42;
> 	}
> 	
> 	mixin(rvalue!(bar));
> }
>
> remove the 'const' and it works fine.

It seems that D has no functionality, to detect if a method is const.
February 10, 2013
This works so far:

auto funcAttr = functionAttributes!(fun);
if (FunctionAttribute.pure_ & funcAttr) s ~= " pure";
if (FunctionAttribute.nothrow_ & funcAttr) s ~= " nothrow";
if (FunctionAttribute.ref_ & funcAttr) s ~= " ref";
if (!isMutable!(typeof(fun))) s ~= " const";

But it's curious that FunctionAttributes has no const, immutable, inout or shared...
February 10, 2013
On Saturday, 9 February 2013 at 22:14:45 UTC, Namespace wrote:
> Why isn't there 'const' in ParameterStorageClass?
> How could I detect that my Parameter storage class is 'in'?

It's an ambiguity in the term "StorageClass" in D, which is different from "TypeQualifier". Const is part of the type. "StorageClass" means modifiers when you pass to a function.

As for "in" (or inout):

Apparently, they aren't "true" StorageClass, because the compiler re-writes them to "const ref" or "scope" something anyways, that's why they don't appear in the list.

On Saturday, 9 February 2013 at 22:54:23 UTC, Namespace wrote:
> On Saturday, 9 February 2013 at 22:23:07 UTC, Namespace wrote:
>> It seems your template has problems with this:
>>
>> struct A { }
>>
>> class B {
>> public:
>> 	const int bar(ref A a) {
>> 		return 42;
>> 	}
>> 	
>> 	mixin(rvalue!(bar));
>> }
>>
>> remove the 'const' and it works fine.
>
> It seems that D has no functionality, to detect if a method is const.

Well, I did mention "Also, I didn't code the FunctionAttribute part, but that's just because it's late and I want to sleep". I even left a big "todo" in there :)

On Sunday, 10 February 2013 at 00:01:32 UTC, Namespace wrote:
> This works so far:
>
> auto funcAttr = functionAttributes!(fun);
> if (FunctionAttribute.pure_ & funcAttr) s ~= " pure";
> if (FunctionAttribute.nothrow_ & funcAttr) s ~= " nothrow";
> if (FunctionAttribute.ref_ & funcAttr) s ~= " ref";
> if (!isMutable!(typeof(fun))) s ~= " const";
>
> But it's curious that FunctionAttributes has no const, immutable, inout or shared...

I I have no idea. File a bug maybe?

Either it'll be valid, or you'll get the "it would be redundant" reply, in which case the docs would *need* to be upgraded.
February 10, 2013
> Well, I did mention "Also, I didn't code the FunctionAttribute part, but that's just because it's late and I want to sleep". I even left a big "todo" in there :)

I've overlooked that. :)

Here is the complete code. If you have to improve something, say it please.
One last question: why 'ss' as function name? :o

[code]
template rvalue(alias fun) {
    private string ss() {
		enum Func = __traits(identifier, fun);
        enum Ret  = ReturnType!(fun).stringof;
		
        alias Args = ParameterTypeTuple!(fun);
        alias ParameterStorageClassTuple!(fun) pstc;
        enum names = [ParameterIdentifierTuple!(fun)];

        string s;
        s ~= Ret ~ " " ~ Func ~ "(";
        foreach(i, Type; Args[0 .. $]) {
            if (pstc[i] & ParameterStorageClass.scope_) s ~= "scope ";
            if (pstc[i] & ParameterStorageClass.out_) s ~= "out ";
            if (pstc[i] & ParameterStorageClass.lazy_) s ~= "lazy ";
			
            s ~= Args[i].stringof ~ " ";
            s ~= names[i];
			
            if (i + 1 != Args.length) s ~= ", ";
        }
        s ~= ")";
		
		auto funcAttr = functionAttributes!(fun);
		if (funcAttr & FunctionAttribute.pure_) s ~= " pure";
		if (funcAttr & FunctionAttribute.nothrow_) s ~= " nothrow";
		if (funcAttr & FunctionAttribute.ref_) s ~= " ref";
		if (!isMutable!(typeof(fun))) s ~= " const"; // no idea why FunctionAttribute has no const...

        s ~= " {\n\treturn " ~ Func ~ "(";
        if (Args.length) {
            s ~= names[0];
            foreach(i, Type; Args[1 .. $]) {
                s ~= ", " ~ names[i + 1];
            }
        }
        s ~= ");\n}\n";
        return s;
    }
	
    enum rvalue = ss();
}
[/code]
February 10, 2013
On Sunday, 10 February 2013 at 08:38:23 UTC, monarch_dodra wrote:
> On Saturday, 9 February 2013 at 22:14:45 UTC, Namespace wrote:
>> Why isn't there 'const' in ParameterStorageClass?
>> How could I detect that my Parameter storage class is 'in'?
>
> It's an ambiguity in the term "StorageClass" in D, which is different from "TypeQualifier". Const is part of the type. "StorageClass" means modifiers when you pass to a function.

Parameter storage classes are in, out, ref, lazy, const, immutable, shared, inout or scope.
http://dlang.org/function.html