aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/target.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-03-31 13:34:36 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-03-31 13:34:36 +0200
commit0a9dd0c7d31cbba2170fdfda4b747a1fe5ce665a (patch)
tree08aaf5b0c9fa06ca2352f1775f2c470841653a93 /libbuild2/target.hxx
parenteed93abebc20e59f861c7e8b6322f7ef3681c59e (diff)
Use own type information instead of dynamic_cast in target::is_a()
Diffstat (limited to 'libbuild2/target.hxx')
-rw-r--r--libbuild2/target.hxx35
1 files changed, 29 insertions, 6 deletions
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 <typename T>
T*
- is_a () {return dynamic_cast<T*> (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<T*> (this);
+#else
+ // We can skip dynamically-derived type here (derived_type).
+ //
+ return dynamic_type ().is_a<T> () ? static_cast<T*> (this) : nullptr;
+#endif
+ }
template <typename T>
const T*
- is_a () const {return dynamic_cast<const T*> (this);}
+ is_a () const
+ {
+#if 0
+ return dynamic_cast<const T*> (this);
+#else
+ return dynamic_type ().is_a<T> () ? static_cast<const T*> (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.
//