/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 | } |