Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-09

[Feature Request] get nested type from a generic class

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

ZAN DoYe

I wanna make a generic class that can generates all six relational operators with the passed in class T which has only one lessThan operator. But fpc can't recognize blow code:

     generic tLess<T>= class
         public type
             tT= T;
         public
             class function lessThan(const a, b: T): boolean;
     end;
     generic tCompOps<C>= class
         public type
             T= C.tT;                        //// Error: Error in type definition ////
         public
             class function equal(const a, b: T): boolean;
             class function notEqual(const a, b: T): boolean;
             class function lessThan(const a, b: T): boolean;
             class function lessThanOrEqual(const a, b: T): boolean;
             class function greaterThan(const a, b: T): boolean;
             class function greaterThanOrEqual(const a, b: T): boolean;
     end;

I hope this feature could be implemented if it's possible.

Reply by email

Sven Barth
to ZAN DoYe
ZAN DoYe wrote 25 lines
I wanna make a generic class that can generates all six relational operators with the passed in class T which has only one lessThan operator. But fpc can't recognize blow code: generic tLess<T>= class public type tT= T; public class function lessThan(const a, b: T): boolean; end; generic tCompOps<C>= class public type T= C.tT; //// Error: Error in type definition //// public class function equal(const a, b: T): boolean; class function notEqual(const a, b: T): boolean; class function lessThan(const a, b: T): boolean; class function lessThanOrEqual(const a, b: T): boolean; class function greaterThan(const a, b: T): boolean; class function greaterThanOrEqual(const a, b: T): boolean; end; I hope this feature could be implemented if it's possible.

If you already expect that "C" is a "tLess<Something>" then you should write it the following way:

=== source begin ===

// tLess<T> as in your example
generic tCompOps<T> = class
   public type
     TLessT = specialize tLess<T>;
   public
     // the remaining methods are like in your example with the
exception that in the implementation you don't use type "C", but "TLessT"
end;

=== source end ===

Regards,
Sven

Reply by email

ZAN DoYe
to Sven Barth
Sven Barth wrote 14 lines
If you already expect that "C" is a "tLess<Something>" then you should write it the following way: === source begin === // tLess<T> as in your example generic tCompOps<T> = class public type TLessT = specialize tLess<T>; public // the remaining methods are like in your example with the exception that in the implementation you don't use type "C", but "TLessT" end; === source end ===

Thanks for your suggestion.
But what *tCompOps<C>* expects is a user-defined class which has a public function `lessThan(const a, b: keyType): boolean', a public type `keyType'. These tLess(_obj|_rec)? classes are just helper class to wrap some simple specific type.

Users may wanna compare a record contains strings. In this case, binaryCompare is different from a user-defined class that compare two record with `if rec1.str < rec2.str'. As the previous method essentially compare two pointers, not two strings.

Though we can manually specify the keyType, i.e. define tCompOps as generic tCompOps<T, C>. But define all thing in one class is more convenient(for later use, pass it to other generator, etc.).

Reply by email

Sven Barth
to ZAN DoYe
ZAN DoYe wrote 32 lines
On 2012-09-21 15:49, Sven Barth wrote: > If you already expect that "C" is a "tLess<Something>" then you should > write it the following way: > > === source begin === > > // tLess<T> as in your example > > generic tCompOps<T> = class > public type > TLessT = specialize tLess<T>; > public > // the remaining methods are like in your example with the > exception that in the implementation you don't use type "C", but "TLessT" > end; > > === source end === Thanks for your suggestion. But what *tCompOps<C>* expects is a user-defined class which has a public function `lessThan(const a, b: keyType): boolean', a public type `keyType'. These tLess(_obj|_rec)? classes are just helper class to wrap some simple specific type. Users may wanna compare a record contains strings. In this case, binaryCompare is different from a user-defined class that compare two record with `if rec1.str < rec2.str'. As the previous method essentially compare two pointers, not two strings. Though we can manually specify the keyType, i.e. define tCompOps as generic tCompOps<T, C>. But define all thing in one class is more convenient(for later use, pass it to other generator, etc.).

In that case you must always pass the type ("keyType" in your example) to tCompOps as well. Anything else does not work. Even generic constraints would not work here.

Regards,
Sven

Reply by email

ZAN DoYe
to Sven Barth
Sven Barth wrote
In that case you must always pass the type ("keyType" in your example) to tCompOps as well. Anything else does not work. Even generic constraints would not work here.

Eh? Fpc can specializes C.lessThan, then why can't C.keyType? Hense I request this feature :)

Reply by email

ZAN DoYe
to ZAN DoYe
ZAN DoYe wrote
On 2012-09-21 17:25, Sven Barth wrote: > In that case you must always pass the type ("keyType" in your example) to tCompOps as well. Anything else does not work. Even generic constraints would not work here. Eh? Fpc can specializes C.lessThan, then why can't C.keyType? Hense I request this feature :)

And, for example:

Show quoted text 24 lines
#include <iostream> using namespace std; template<typename T> class tn { public: typedef T nt; }; template<typename C> class to { public: void sayHi(typename C::nt w) { // prefix a `typename' keyword before the nested type which is in a generic class C. It works in cpp. cout << w << endl; }; }; int main(int argc, char * argv[]) { to< tn<int> > o; o.sayHi(3); return 0; }

could someone add this handy feature into fpc

Reply by email