www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Fastest way to check if the bottom-class of a class reference is any

reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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.

 -Steve
Great. 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