Skip to content

Commit 65c7096

Browse files
committed
Archiving godbolt code.
1 parent ad24dcc commit 65c7096

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

godbolt/jorg_black_box.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// https://godbolt.org/z/eTEvG3
2+
3+
#include <iostream>
4+
#include <memory>
5+
#include <typeindex>
6+
7+
#define DUMP(expr) #expr " = " << (expr)
8+
9+
struct base {
10+
base() : base_id{100} {}
11+
virtual ~base() = default;
12+
virtual int const id() { return base_id; }
13+
int base_id;
14+
};
15+
struct monkeywrench {
16+
virtual int const monkey_id() { return 150; }
17+
virtual ~monkeywrench() = default;
18+
};
19+
struct drvd : monkeywrench, base {
20+
int const id() override { return 2 * base_id; }
21+
};
22+
23+
struct BlackBox {
24+
std::shared_ptr<void> magicptr;
25+
std::type_index magictype;
26+
27+
BlackBox() : magictype(typeid(void)) {}
28+
template <typename T>
29+
BlackBox(std::shared_ptr<T> in) //
30+
: magicptr(std::static_pointer_cast<void>(in)), //
31+
magictype(typeid(T)) {}
32+
33+
template <typename T>
34+
std::shared_ptr<T> get() const {
35+
if (magictype == std::type_index(typeid(T))) {
36+
return std::static_pointer_cast<T>(magicptr);
37+
} else
38+
return {};
39+
}
40+
};
41+
42+
void drvd_void_base() {
43+
std::cout << "hello drvd_void_base" << '\n';
44+
BlackBox b;
45+
46+
// pybind11-wrapped C++ function returns shared_ptr<base> up-cast from drvd.
47+
{
48+
std::shared_ptr<base> shared_base_uc(new base);
49+
std::cout << "In: " << DUMP(shared_base_uc->id()) << '\n';
50+
b = shared_base_uc;
51+
52+
std::shared_ptr<base> shared_base_dc = b.get<base>();
53+
std::cout << "Out: " << DUMP(shared_base_dc->id()) << '\n';
54+
}
55+
{
56+
std::shared_ptr<base> shared_base_uc(new drvd);
57+
std::cout << "In: " << DUMP(shared_base_uc->id()) << '\n';
58+
b = shared_base_uc;
59+
60+
std::shared_ptr<base> shared_base_dc = b.get<base>();
61+
std::cout << "Out: " << DUMP(shared_base_dc->id()) << '\n';
62+
}
63+
{
64+
std::shared_ptr<drvd> shared_drvd_uc(new drvd);
65+
std::cout << "In: " << DUMP(shared_drvd_uc->id()) << '\n';
66+
b = shared_drvd_uc;
67+
68+
std::shared_ptr<drvd> shared_drvd_dc = b.get<drvd>();
69+
std::cout << "Out: " << DUMP(shared_drvd_dc->id()) << '\n';
70+
}
71+
}
72+
73+
void bad_cast() {
74+
std::cout << "uh-oh bad_cast" << '\n';
75+
BlackBox b;
76+
77+
// pybind11-wrapped C++ function returns shared_ptr<base> up-cast from drvd.
78+
79+
{
80+
std::shared_ptr<base> shared_base_uc(new drvd);
81+
std::cout << "In: " << DUMP(shared_base_uc->id()) << '\n';
82+
b = shared_base_uc;
83+
84+
std::cout << std::flush;
85+
86+
std::shared_ptr<drvd> shared_drvd_dc = b.get<drvd>();
87+
if (shared_drvd_dc) {
88+
std::cout << "Out: " << DUMP(shared_drvd_dc->id()) << '\n';
89+
} else {
90+
std::cout << "Out: nullptr, sorry!\n";
91+
}
92+
}
93+
}
94+
95+
int main() {
96+
std::cout << "hello main" << '\n';
97+
drvd_void_base();
98+
bad_cast();
99+
return 0;
100+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// https://godbolt.org/z/8873Wd
2+
3+
#include <iostream>
4+
#include <memory>
5+
6+
#define DUMP(expr) #expr " = " << (expr)
7+
8+
struct base {
9+
base() : base_id{100} {}
10+
virtual ~base() = default;
11+
virtual int const id() { return base_id; }
12+
int base_id;
13+
};
14+
struct monkeywrench {
15+
virtual int const monkey_id() { return 150; }
16+
virtual ~monkeywrench() = default;
17+
};
18+
struct drvd : monkeywrench, base {
19+
int const id() override { return 2 * base_id; }
20+
};
21+
22+
void drvd_void_base() {
23+
// pybind11-wrapped C++ function returns shared_ptr<base> up-cast from drvd.
24+
std::shared_ptr<base> shared_drvd_uc(new drvd);
25+
std::shared_ptr<void> ivp = std::dynamic_pointer_cast<void>(shared_drvd_uc);
26+
std::shared_ptr<drvd> shared_drvd_dc = std::static_pointer_cast<drvd>(ivp);
27+
// SEGFAULT:
28+
// std::shared_ptr<base> shared_drvd_dc_uc = std::static_pointer_cast<base>(ivp);
29+
// Can upcast only from std::shared_ptr<drvd>:
30+
std::shared_ptr<base> shared_drvd_dc_uc = shared_drvd_dc;
31+
std::cout << DUMP(shared_drvd_dc_uc->id()) << '\n';
32+
}
33+
34+
int main() {
35+
drvd_void_base();
36+
return 0;
37+
}

0 commit comments

Comments
 (0)