| /usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/libpanda.x/i/panda/cast.h | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 17 | 17 | 100.0 |
| branch | 194 | 438 | 44.2 |
| condition | n/a | ||
| subroutine | n/a | ||
| pod | n/a | ||
| total | 211 | 455 | 46.3 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | #pragma once | ||||||
| 2 | #include | ||||||
| 3 | #include |
||||||
| 4 | #include |
||||||
| 5 | #include |
||||||
| 6 | #include |
||||||
| 7 | |||||||
| 8 | namespace panda { | ||||||
| 9 | |||||||
| 10 | namespace detail { namespace cast { | ||||||
| 11 | typedef std::map |
||||||
| 12 | |||||||
| 13 | template |
||||||
| 14 | 292 | DynCastCacheMap& get_map () { | |||||
| 15 | thread_local DynCastCacheMap* map; | ||||||
| 16 | 292 | 50 | if (!map) { | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 100 | |||||||
| 100 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 100 | |||||||
| 100 | |||||||
| 17 | 185 | 50 | thread_local struct { DynCastCacheMap map; } wrp; | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 18 | 37 | map = &wrp.map; | |||||
| 19 | } | ||||||
| 20 | 292 | return *map; | |||||
| 21 | } | ||||||
| 22 | |||||||
| 23 | constexpr const ptrdiff_t INCORRECT_PTRDIFF = PTRDIFF_MAX; | ||||||
| 24 | }} | ||||||
| 25 | |||||||
| 26 | template |
||||||
| 27 | 1676 | DERIVED_PTR dyn_cast (BASE* obj) { | |||||
| 28 | using namespace detail::cast; | ||||||
| 29 | using DERIVED = typename std::remove_pointer |
||||||
| 30 | |||||||
| 31 | 1092 | if (std::is_same |
|||||
| 32 | 292 | 50 | if (!obj) return NULL; | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 33 | |||||||
| 34 | 292 | 50 | intptr_t key = (intptr_t)typeid(*obj).name(); | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 35 | 292 | auto& map = get_map |
|||||
| 36 | //auto& map = DynCastCache |
||||||
| 37 | 292 | 50 | DynCastCacheMap::iterator it = map.find(key); | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 38 | 292 | 50 | if (it != map.end()) | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 100 | |||||||
| 100 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 100 | |||||||
| 100 | |||||||
| 39 | 228 | 0 | return it->second != INCORRECT_PTRDIFF ? reinterpret_cast |
||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 50 | |||||||
| 50 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 50 | |||||||
| 100 | |||||||
| 40 | 61 | 50 | DERIVED* ret = dynamic_cast |
||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 41 | 64 | 50 | if (ret) map[key] = (char*)obj - (char*)ret; | ||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 50 | |||||||
| 100 | |||||||
| 50 | |||||||
| 42 | 15 | 0 | else map[key] = INCORRECT_PTRDIFF; | ||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 50 | |||||||
| 43 | 292 | return ret; | |||||
| 44 | } | ||||||
| 45 | |||||||
| 46 | template |
||||||
| 47 | DERIVED_REF dyn_cast (BASE& obj) { | ||||||
| 48 | using namespace detail::cast; | ||||||
| 49 | using DERIVED = typename std::remove_reference |
||||||
| 50 | |||||||
| 51 | if (std::is_same |
||||||
| 52 | |||||||
| 53 | intptr_t key = (intptr_t)typeid(obj).name(); | ||||||
| 54 | auto& map = get_map |
||||||
| 55 | DynCastCacheMap::iterator it = map.find(key); | ||||||
| 56 | if (it != map.end() && it->second != INCORRECT_PTRDIFF) | ||||||
| 57 | return *(reinterpret_cast |
||||||
| 58 | // dont cache fails, as exceptions are much slower than dynamic_cast, let it always fall here | ||||||
| 59 | DERIVED& ret = dynamic_cast |
||||||
| 60 | map[key] = (char*)&obj - (char*)&ret; | ||||||
| 61 | return ret; | ||||||
| 62 | } | ||||||
| 63 | |||||||
| 64 | } |