14
14
#include < pybind11/pybind11.h>
15
15
#include < pybind11/stl.h>
16
16
17
+ #include < any>
18
+ #include < cstdint>
19
+ #include < stdexcept>
17
20
#include < string>
21
+ #include < unordered_map>
18
22
19
23
namespace pyfiction
20
24
{
21
25
22
26
namespace detail
23
27
{
24
28
29
+ namespace py = pybind11;
30
+
31
+ // Helper function to convert std::any to Python objects
32
+ inline py::object convert_any_to_py (const std::any& value)
33
+ {
34
+ try
35
+ {
36
+ if (value.type () == typeid (int ))
37
+ {
38
+ return py::int_ (std::any_cast<int >(value));
39
+ }
40
+ else if (value.type () == typeid (double ))
41
+ {
42
+ return py::float_ (std::any_cast<double >(value));
43
+ }
44
+ else if (value.type () == typeid (bool ))
45
+ {
46
+ return py::bool_ (std::any_cast<bool >(value));
47
+ }
48
+ else if (value.type () == typeid (std::string))
49
+ {
50
+ return py::str (std::any_cast<std::string>(value));
51
+ }
52
+ else if (value.type () == typeid (uint64_t ))
53
+ {
54
+ return pybind11::int_ (std::any_cast<uint64_t >(value));
55
+ }
56
+ else
57
+ {
58
+ throw std::runtime_error (std::string (" Unsupported type in std::any: " ) + value.type ().name ());
59
+ }
60
+ }
61
+ catch (const std::exception & e)
62
+ {
63
+ throw std::runtime_error (std::string (" Error in convert_any_to_py: " ) + e.what ());
64
+ }
65
+ }
66
+
67
+ inline py::dict convert_map_to_py (const std::unordered_map<std::string, std::any>& map)
68
+ {
69
+ pybind11::dict result;
70
+ for (const auto & [key, value] : map)
71
+ {
72
+ try
73
+ {
74
+ result[key.c_str ()] = convert_any_to_py (value);
75
+ }
76
+ catch (const std::exception & e)
77
+ {
78
+ throw std::runtime_error (fmt::format (" Error converting key: {}" , e.what ()));
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+
25
84
template <typename Lyt>
26
85
void sidb_simulation_result (pybind11::module& m, const std::string& lattice = " " )
27
86
{
28
87
namespace py = pybind11;
29
- namespace py = pybind11;
30
88
31
89
py::class_<fiction::sidb_simulation_result<Lyt>>(m, fmt::format (" sidb_simulation_result{}" , lattice).c_str (),
32
90
DOC (fiction_sidb_simulation_result))
@@ -39,16 +97,17 @@ void sidb_simulation_result(pybind11::module& m, const std::string& lattice = ""
39
97
DOC (fiction_sidb_simulation_result_charge_distributions))
40
98
.def_readwrite (" simulation_parameters" , &fiction::sidb_simulation_result<Lyt>::simulation_parameters,
41
99
DOC (fiction_sidb_simulation_result_simulation_parameters))
42
- .def_readwrite (" additional_simulation_parameters" ,
43
- &fiction::sidb_simulation_result<Lyt>::additional_simulation_parameters,
44
- DOC (fiction_sidb_simulation_result_additional_simulation_parameters));
100
+ .def_property_readonly (
101
+ " additional_simulation_parameters" , [](const fiction::sidb_simulation_result<Lyt>& self)
102
+ { return convert_map_to_py (self.additional_simulation_parameters ); },
103
+ DOC (fiction_sidb_simulation_result_additional_simulation_parameters));
45
104
}
46
105
47
106
} // namespace detail
48
107
49
108
inline void sidb_simulation_result (pybind11::module& m)
50
109
{
51
- // NOTE be careful with the order of the following calls! Python will resolve the first matching overload!
110
+ // Define simulation result for specific lattices
52
111
detail::sidb_simulation_result<py_sidb_100_lattice>(m, " _100" );
53
112
detail::sidb_simulation_result<py_sidb_111_lattice>(m, " _111" );
54
113
}
0 commit comments