From 0a9dd0c7d31cbba2170fdfda4b747a1fe5ce665a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 31 Mar 2022 13:34:36 +0200 Subject: Use own type information instead of dynamic_cast in target::is_a() --- libbuild2/target-type.hxx | 9 +++++---- libbuild2/target.cxx | 15 +-------------- libbuild2/target.hxx | 35 +++++++++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 24 deletions(-) (limited to 'libbuild2') diff --git a/libbuild2/target-type.hxx b/libbuild2/target-type.hxx index 0e24e3a..ef3a3ed 100644 --- a/libbuild2/target-type.hxx +++ b/libbuild2/target-type.hxx @@ -102,14 +102,15 @@ namespace build2 bool is_a (const target_type& tt) const { - return this == &tt || (base != nullptr && is_a_base (tt)); + for (const target_type* b (this); b != nullptr; b = b->base) + if (b == &tt) + return true; + + return false; } bool is_a (const char*) const; // Defined in target.cxx - - bool - is_a_base (const target_type&) const; // Defined in target.cxx }; inline bool diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 5fa3c37..ba1454e 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -22,26 +22,13 @@ namespace build2 bool target_type:: is_a (const char* n) const { - if (strcmp (name, n) == 0) - return true; - - for (const target_type* b (base); b != nullptr; b = b->base) + for (const target_type* b (this); b != nullptr; b = b->base) if (strcmp (b->name, n) == 0) return true; return false; } - bool target_type:: - is_a_base (const target_type& tt) const - { - for (const target_type* b (base); b != nullptr; b = b->base) - if (*b == tt) - return true; - - return false; - } - // target_key // void target_key:: diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 6b79e1b..2820aa7 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -780,20 +780,43 @@ namespace build2 // public: const target* - is_a (const target_type& tt) const { - return type ().is_a (tt) ? this : nullptr;} + is_a (const target_type& tt) const + { + return type ().is_a (tt) ? this : nullptr; + } template T* - is_a () {return dynamic_cast (this);} + is_a () + { + // At least with GCC we see slightly better and more consistent + // performance with our own type information. + // +#if 0 + return dynamic_cast (this); +#else + // We can skip dynamically-derived type here (derived_type). + // + return dynamic_type ().is_a () ? static_cast (this) : nullptr; +#endif + } template const T* - is_a () const {return dynamic_cast (this);} + is_a () const + { +#if 0 + return dynamic_cast (this); +#else + return dynamic_type ().is_a () ? static_cast (this) : nullptr; +#endif + } const target* - is_a (const char* n) const { - return type ().is_a (n) ? this : nullptr;} + is_a (const char* n) const + { + return type ().is_a (n) ? this : nullptr; + } // Unchecked cast. // -- cgit v1.1