Re: [fpc-pascal] Compatibility of very similar generic types
Am 18.08.2016 15:09 schrieb "Felipe Monteiro de Carvalho" < felipemonteiro.carva...@gmail.com>: > > On Thu, Aug 18, 2016 at 2:44 PM, Sven Barth wrote: > > generic procedure WriteVector_To_DM(ADest: TDataManager; ASelf: > > specialize TVector); > > generic procedure ReadVector_From_DM(AFrom: TDataManager; var ASelf: > > specialize TVector); > > > > and use them like this: > > > > specialize WriteVector_To_DM(...); > > Aha, great, didn't know we had something in this direction. But > correct me if I am wrong, but this wouldn't work in my case, because > my function writes the class to a stream in the end of it, so it needs > to know which type T is. If the type is TSomeClass or a descendent, > then it will write each field of the class to the stream. > > But in a generic class/function there is no way to ask if T is an int, > or is an TSomeClass, or am I missing some way of writing code that is > different for various possible types? You can enforce that T needs to be a subclass of TSomeClass by declaring it as "T: TSomeClass"; like this: generic procedure WriteVector_To_DM(ADest: TDataManager; ASelf: specialize TVector); In that case the compiler knows that T will at least be a TSomeClass so you can use methods and fields of it without problems. Note: these generic constraints also work for generic types and is already in 3.0.0 for them. Additionally you can play around with TypeInfo() which works on variables of a generic type as well. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Compatibility of very similar generic types
On Thu, Aug 18, 2016 at 2:44 PM, Sven Barth wrote: > generic procedure WriteVector_To_DM(ADest: TDataManager; ASelf: > specialize TVector); > generic procedure ReadVector_From_DM(AFrom: TDataManager; var ASelf: > specialize TVector); > > and use them like this: > > specialize WriteVector_To_DM(...); Aha, great, didn't know we had something in this direction. But correct me if I am wrong, but this wouldn't work in my case, because my function writes the class to a stream in the end of it, so it needs to know which type T is. If the type is TSomeClass or a descendent, then it will write each field of the class to the stream. But in a generic class/function there is no way to ask if T is an int, or is an TSomeClass, or am I missing some way of writing code that is different for various possible types? thanks, -- Felipe Monteiro de Carvalho ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Compatibility of very similar generic types
Am 18.08.2016 10:57 schrieb "Felipe Monteiro de Carvalho" < felipemonteiro.carva...@gmail.com>: > > Hello, > > Consider this: > > TSubClass1 = class(TSomeClass)...; > TSubClass2 = class(TSomeClass)...; > > TSubClass1Vector = specialize TVector; > TSubClass2Vector = specialize TVector; > TSomeClassVector = specialize TVector; > > And I want to write a function like: > > procedure WriteVector_To_DM(ADest: TDataManager; ASelf: TSomeClassVector); > procedure ReadVector_From_DM(AFrom: TDataManager; var ASelf: TSomeClassVector); [snip] > > Now I understand that some people will scream: DON'T DO THIS. > > But my question is: Is there any real reason why I am wrong and will > fail in some future compiler version or something, or while not > recommended I am correct that there is no real reason why it could > possibly fail. Considering my points above? What you're looking for is a form of type coercion that we don't support (at least currently; dont know what the future will bring). Also your assumption is only correct as it is now, however it could be in the future that the compiler might generate different code for the different classes, cause of different optimization potential (unlikely, but I hope you get my point), thus you are relying on implementation details and thus it will be your own fault if things should stop working in the future. One of the cleaner solutions (aside from possible type coercion) is available on trunk: generic function. Declare your functions like this: generic procedure WriteVector_To_DM(ADest: TDataManager; ASelf: specialize TVector); generic procedure ReadVector_From_DM(AFrom: TDataManager; var ASelf: specialize TVector); and use them like this: specialize WriteVector_To_DM(...); Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Compatibility of very similar generic types
Hello, Consider this: TSubClass1 = class(TSomeClass)...; TSubClass2 = class(TSomeClass)...; TSubClass1Vector = specialize TVector; TSubClass2Vector = specialize TVector; TSomeClassVector = specialize TVector; And I want to write a function like: procedure WriteVector_To_DM(ADest: TDataManager; ASelf: TSomeClassVector); procedure ReadVector_From_DM(AFrom: TDataManager; var ASelf: TSomeClassVector); So according to the compiler warnings this is impossible, and I need to write 3 functions to cover the 3 specializations, even if those functions would be identical. Which sucks, because in the real case I have like 10 nearly identical specializations, then I need 10 identical copy+pasted functions... of course I could use TSomeClassVector everywhere, but this negates the advantages of using generics in the first place which was type safety and elegancy. Of course I am not satisfied to copy+paste 10 times and maintain the copy+pasted mirrors in every change, so I simply wrote only 1 function for the base class and I call it like this: var myobj: TSubClass1Vector; begin ReadVector_From_DM(MyDM, TSomeClassVector(myobj)); Yes, I could write the read/write functions in the vector itself, but then the vector would need to know about TDataManager, which it is not supposed to know really :( The rationale here is that I only use functions from TSubClass1 that are in TSomeClass, and I can't see how it could go wrong, I understand that the compiler will generate 3 copies of the same code: 1 time for TSubClass1Vector, 1 time for TSubClass2Vector and another for TSomeClassVector. But all those copies should be fully compatible, considering that: A> The generic class cannot use anything specific from TSubClass1 since it doesn't know even that we are talking about a class, it could be an int B> All classes are equal sized pointers My conclusion is that doing what I am doing will work, and it can't possibly fail. Now I understand that some people will scream: DON'T DO THIS. But my question is: Is there any real reason why I am wrong and will fail in some future compiler version or something, or while not recommended I am correct that there is no real reason why it could possibly fail. Considering my points above? thanks, -- Felipe Monteiro de Carvalho ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal