digitalmars.D.learn - Fastest way to check if the bottom-class of a class reference is any
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (29/29) Dec 16 2019 What is the fastest way to check whether a class reference is an
- H. S. Teoh (20/38) Dec 16 2019 [...]
- Steven Schveighoffer (8/42) Dec 16 2019 I'd compare the typeid directly:
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (10/19) Dec 17 2019 Great. Thanks.
What is the fastest way to check whether a class reference is an instance of a bottom equal to any in a set of classes? My current try is something like class C {} class X : C {} class Y : C {} class Z : C {} ... bool pred(scope const Object object) { return (cast(const(X))object || cast(const(Y))object || cast(const(Z))object || ...); } or is it better to switch on the non-scoped (via some existing string-to-string function `unscoped`) part of the `typeid(object).name` like bool pred(scope const Object object) { const name = typeid(object).name.unscope; import std.algorithm.comparison : among; return name.among!(X.stringof, Y.stringof, Z.stringof, ...); } ?
Dec 16 2019
On Mon, Dec 16, 2019 at 02:38:59PM +0000, Per Nordlöw via Digitalmars-d-learn wrote:What is the fastest way to check whether a class reference is an instance of a bottom equal to any in a set of classes? My current try is something like class C {} class X : C {} class Y : C {} class Z : C {} ... bool pred(scope const Object object) { return (cast(const(X))object || cast(const(Y))object || cast(const(Z))object || ...); }[...] What about: class X {} class Y {} class Z {} bool pred(scope const Object object) { import std.meta : AliasSeq; // make this as long as you need alias MyClasses = AliasSeq!(X, Y, Z); static foreach (C; MyClasses) { if (cast(const(C)) object) return true; } return false; } T -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald Knuth
Dec 16 2019
On 12/16/19 9:38 AM, Per Nordlöw wrote:What is the fastest way to check whether a class reference is an instance of a bottom equal to any in a set of classes? My current try is something like class C {} class X : C {} class Y : C {} class Z : C {} .... bool pred(scope const Object object) {    return (cast(const(X))object ||            cast(const(Y))object ||            cast(const(Z))object ||            ...); } or is it better to switch on the non-scoped (via some existing string-to-string function `unscoped`) part of the `typeid(object).name` like bool pred(scope const Object object) {    const name = typeid(object).name.unscope;    import std.algorithm.comparison : among;    return name.among!(X.stringof,                       Y.stringof,                       Z.stringof,                       ...); } ?I'd compare the typeid directly: auto tid = typeid(object); return(tid is typeid(X) || tid is typeid(Y) || tid is typeid(Z) || ...) If you are doing a cast(const(X))object, what you are doing is each time traversing the linked-list of typeids anyway doing the same as the above, but doing extra work. So this should be faster. -Steve
Dec 16 2019
On Monday, 16 December 2019 at 18:01:06 UTC, Steven Schveighoffer wrote:I'd compare the typeid directly: auto tid = typeid(object); return(tid is typeid(X) || tid is typeid(Y) || tid is typeid(Z) || ...) If you are doing a cast(const(X))object, what you are doing is each time traversing the linked-list of typeids anyway doing the same as the above, but doing extra work. So this should be faster. -SteveGreat. Thanks. Because we're only interested in non-abstract classes I adjusted your code to static foreach (Type; AliasSeq!(...)) { static assert(!__traits(isAbstractClass, Type)); if (zingid is typeid(Type)) { return true; } }
Dec 17 2019