www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - setTypeInfo???

reply dsimcha <dsimcha yahoo.com> writes:
I've noticed something strange with the setTypeInfo() function in gc.d. Ran
into it trying to write some custom allocation functions for dynamic arrays.

writefln(typeid(uint).flags);  //Returns 0.
writefln(typeid(float).flags);  //Returns 0.
writefln(typeid(uint*).flags);  //Returns 1.
writefln(typeid(void*).flags);  //Returns 1.

Docs say that the above behavior is correct.

However, :

void setTypeInfo(TypeInfo ti, void* p)
{
    if (ti.flags() & 1)
	hasNoPointers(p);
    else
	hasPointers(p);
}

Is this really backwards in DMD 2.018?  If so, how can it possibly have taken
this long for someone to notice something this obvious?  I can't find anything
in Bugzilla about this.
Aug 30 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
dsimcha Wrote:

 I've noticed something strange with the setTypeInfo() function in gc.d. Ran
 into it trying to write some custom allocation functions for dynamic arrays.
 writefln(typeid(uint).flags);  //Returns 0.
 writefln(typeid(float).flags);  //Returns 0.
 writefln(typeid(uint*).flags);  //Returns 1.
 writefln(typeid(void*).flags);  //Returns 1.

Ah, for that purpose I have used the following monster (take a look at my last post too http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=75811 ): import std.traits: FieldTypeTuple; template IsType(T, Types...) { // Original idea by Burton Radons, modified static if (Types.length == 0) const bool IsType = false; else const bool IsType = is(T == Types[0]) || IsType!(T, Types[1 .. $]); } template ArrayType1(T: T[]) { alias T ArrayType1; } template IsReferenceType(Types...) { static if (Types.length == 0) { const bool IsReferenceType = false; } else static if (Types.length == 1) { static if (IsType!(Types[0], bool, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real, ifloat, idouble, ireal, cfloat, cdouble, creal, char, dchar, wchar) ) { const bool IsReferenceType = false; } else static if ( is(Types[0] == struct) ) { const bool IsReferenceType = IsReferenceType!(FieldTypeTuple!(Types[0])); } else static if (IsStaticArray!(Types[0])) { const bool IsReferenceType = IsReferenceType!(ArrayType1!(Types[0])); } else const bool IsReferenceType = true; } else const bool IsReferenceType = IsReferenceType!(Types[0]) | IsReferenceType!(Types[1 .. $]); } // end IsReferenceType!() template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } template IsDynamicArray(T) { // Adapted from the module tango.core.Traits, (C) 2005-2006 Sean Kelly, BSD style licence const bool IsDynamicArray = is( typeof(T.init[0])[] == T ); } template IsStaticArray(T) { const bool IsStaticArray = IsArray!(T) && (!IsDynamicArray!(T)); } Bye, bearophile
Aug 30 2008
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
They aren't the same thing, that template monster works at compile time, so
(beside not taking RAM at runtime) it can be used for static ifs.

Bye,
bearophile
Aug 30 2008
prev sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 31 Aug 2008 01:45:55 +0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 dsimcha Wrote:

 I've noticed something strange with the setTypeInfo() function in gc.d.  
 Ran
 into it trying to write some custom allocation functions for dynamic  
 arrays.
 writefln(typeid(uint).flags);  //Returns 0.
 writefln(typeid(float).flags);  //Returns 0.
 writefln(typeid(uint*).flags);  //Returns 1.
 writefln(typeid(void*).flags);  //Returns 1.

Ah, for that purpose I have used the following monster (take a look at my last post too http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=75811 ): import std.traits: FieldTypeTuple; template IsType(T, Types...) { // Original idea by Burton Radons, modified static if (Types.length == 0) const bool IsType = false; else const bool IsType = is(T == Types[0]) || IsType!(T, Types[1 .. $]); } template ArrayType1(T: T[]) { alias T ArrayType1; } template IsReferenceType(Types...) { static if (Types.length == 0) { const bool IsReferenceType = false; } else static if (Types.length == 1) { static if (IsType!(Types[0], bool, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real, ifloat, idouble, ireal, cfloat, cdouble, creal, char, dchar, wchar) ) { const bool IsReferenceType = false; } else static if ( is(Types[0] == struct) ) { const bool IsReferenceType = IsReferenceType!(FieldTypeTuple!(Types[0])); } else static if (IsStaticArray!(Types[0])) { const bool IsReferenceType = IsReferenceType!(ArrayType1!(Types[0])); } else const bool IsReferenceType = true; } else const bool IsReferenceType = IsReferenceType!(Types[0]) | IsReferenceType!(Types[1 .. $]); } // end IsReferenceType!() template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } template IsDynamicArray(T) { // Adapted from the module tango.core.Traits, (C) 2005-2006 Sean Kelly, BSD style licence const bool IsDynamicArray = is( typeof(T.init[0])[] == T ); } template IsStaticArray(T) { const bool IsStaticArray = IsArray!(T) && (!IsDynamicArray!(T)); } Bye, bearophile

Looks like my message class is a static array: class Message { this(char[] message) { this.message = message; } size_t length() { return message.length; } void sort() { message.sort(); } void reverse() { message.reverse(); } Message dup() { return new Message(message.dup()); } char[] toString() { return message; } private char[] message; } assert(IsStaticArray!(Message) == false); // fails
Aug 31 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Denis Koroskin:
 Looks like my message class is a static array:

Thank you, this fixes that uncommon bug, I have fixed another similar bug relative to AAs. template IsArray(T) { const bool IsArray = !is(T == class) && is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } Bye and thank you, bearophile
Aug 31 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
bearophile Wrote:

I try again :-)

template IsArray(T) {
    const bool IsArray = !is(T == class) && !is(T == struct) &&
                         is(typeof(T.length)) && is(typeof(T.sort))
                         && is(typeof(T.reverse)) && is(typeof(T.dup));
}
Aug 31 2008
parent bearophile <bearophileHUGS lycos.com> writes:
Sorry for spamming the newsgroup, I am not there yet. The original IsArray
template was correct, because is uses a kind of static duck typing :-) So to
solve your bug I have modified IsReferenceType!() like this:

template IsReferenceType(Types...) {
    static if (Types.length == 0) {
        const bool IsReferenceType = false;
    } else static if (Types.length == 1) {
        // dsimcha suggests to replace the following line with
        // static if (IsType!(Mutable!(Types[0]), bool, byte, ...
        // to make this template work with const/immutable types on D 2.x.
        static if (IsType!(Types[0], bool, byte, ubyte, short, ushort, int,
uint,
                           long, ulong, float, double, real, ifloat, idouble,
                           ireal, cfloat, cdouble, creal, char, dchar, wchar) )
{
            const bool IsReferenceType = false;
        } else static if ( is(Types[0] == class) ) {
            const bool IsReferenceType = true;
        } else static if ( is(Types[0] == struct) ) {
            const bool IsReferenceType =
IsReferenceType!(FieldTypeTuple!(Types[0]));
        } else static if (IsStaticArray!(Types[0])) {
            const bool IsReferenceType =
IsReferenceType!(ArrayType1!(Types[0]));
        } else
            const bool IsReferenceType = true;
    } else
        const bool IsReferenceType = IsReferenceType!(Types[0]) |
                                     IsReferenceType!(Types[1 .. $]);
} // end IsReferenceType!()


Bye,
bearophile
Aug 31 2008
prev sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from bearophile (bearophileHUGS lycos.com)'s article
 Denis Koroskin:
 Looks like my message class is a static array:


 template IsArray(T) {
     const bool IsArray = !is(T == class) && is(typeof(T.length)) &&
                          is(typeof(T.sort)) && is(typeof(T.reverse))
                          && is(typeof(T.dup));
 }
 Bye and thank you,
 bearophile

Or, if you're using D2 Phobos or (I think) D1 Tango, just port to the std lib implementations of isArray, etc. That's what I did, rather than re-invent/maintain/debug the wheel.
Aug 31 2008