TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
36 / 70
51.4%
Branches:
3 / 26
11.5%
Functions:
14 / 18
77.8%

python/src/casters.h
Line Branch Exec Source
1 /// @file
2 /// @brief `Vec2d`, `Vec3d` and `Bounds2d` as Python tuples of floats.
3 #pragma once
4
5 #include "terraingen/util/geometry.h"
6
7 #include <nanobind/nanobind.h>
8 #include <nanobind/stl/array.h>
9
10 #include <array>
11 #include <cstddef>
12
13 namespace terraingen::python {
14
15 /// The components of a value, in the order Python sees them.
16 239 inline std::array<double, 2> Doubles(const Vec2d& v) {
17 239 return {v.x, v.y};
18 }
19
20 1192 inline std::array<double, 3> Doubles(const Vec3d& v) {
21 1192 return {v.x, v.y, v.z};
22 }
23
24 10 inline std::array<double, 4> Doubles(const Bounds2d& b) {
25 10 return {b.minX, b.minY, b.maxX, b.maxY};
26 }
27
28 /// The value whose `Doubles` are `a`.
29 531 template <typename T, std::size_t N> T FromDoubles(const std::array<double, N>& a) {
30 if constexpr (N == 2) {
31 322 return T{a[0], a[1]};
32 } else if constexpr (N == 3) {
33 169 return T{a[0], a[1], a[2]};
34 } else {
35 40 return T{a[0], a[1], a[2], a[3]};
36 }
37 }
38
39 } // namespace terraingen::python
40
41 namespace nanobind::detail {
42
43 /// Converts `T` from any sequence of numbers and to a tuple of floats.
44 template <typename T> struct doubles_caster {
45 681 NB_TYPE_CASTER(T, const_name("tuple"))
46
47 using Array = decltype(terraingen::python::Doubles(T{}));
48
49 531 bool from_python(handle src, uint32_t flags, cleanup_list* cleanup) noexcept {
50 make_caster<Array> caster;
51
3/6
nanobind::detail::doubles_caster<terraingen::Bounds2d>::from_python(nanobind::handle, unsigned int, nanobind::detail::cleanup_list*):
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
nanobind::detail::doubles_caster<terraingen::Vec2d>::from_python(nanobind::handle, unsigned int, nanobind::detail::cleanup_list*):
✗ Branch 1 not taken.
✓ Branch 2 taken 322 times.
nanobind::detail::doubles_caster<terraingen::Vec3d>::from_python(nanobind::handle, unsigned int, nanobind::detail::cleanup_list*):
✗ Branch 1 not taken.
✓ Branch 2 taken 169 times.
531 if (!caster.from_python(src, flags, cleanup)) {
52 ✗ return false;
53 }
54 531 value = terraingen::python::FromDoubles<T>(caster.operator cast_t<Array>());
55 531 return true;
56 }
57
58 1441 static handle from_cpp(const T& v, rv_policy /*policy*/, cleanup_list* /*cleanup*/) noexcept {
59 1441 const Array values = terraingen::python::Doubles(v);
60 1441 PyObject* tuple = PyTuple_New(static_cast<Py_ssize_t>(values.size()));
61
0/8
nanobind::detail::doubles_caster<terraingen::Vec2d>::from_cpp(terraingen::Vec2d const&, nanobind::rv_policy, nanobind::detail::cleanup_list*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
nanobind::detail::doubles_caster<terraingen::Vec3d>::from_cpp(terraingen::Vec3d const&, nanobind::rv_policy, nanobind::detail::cleanup_list*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11070 for (std::size_t i = 0; tuple != nullptr && i < values.size(); ++i) {
62 4094 PyObject* item = PyFloat_FromDouble(values[i]);
63
0/12
nanobind::detail::doubles_caster<terraingen::Vec2d>::from_cpp(terraingen::Vec2d const&, nanobind::rv_policy, nanobind::detail::cleanup_list*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
nanobind::detail::doubles_caster<terraingen::Vec3d>::from_cpp(terraingen::Vec3d const&, nanobind::rv_policy, nanobind::detail::cleanup_list*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4094 if (item == nullptr || PyTuple_SetItem(tuple, static_cast<Py_ssize_t>(i), item) != 0) {
64 ✗ Py_DECREF(tuple);
65 ✗ return {};
66 }
67 }
68 1441 return tuple;
69 }
70 };
71
72 template <> struct type_caster<terraingen::Vec2d> : doubles_caster<terraingen::Vec2d> {
73 static constexpr auto Name = const_name("tuple[float, float]");
74 };
75
76 template <> struct type_caster<terraingen::Vec3d> : doubles_caster<terraingen::Vec3d> {
77 static constexpr auto Name = const_name("tuple[float, float, float]");
78 };
79
80 template <> struct type_caster<terraingen::Bounds2d> : doubles_caster<terraingen::Bounds2d> {
81 static constexpr auto Name = const_name("tuple[float, float, float, float]");
82 };
83
84 } // namespace nanobind::detail
85