GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/utils/conversions.hpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 8 15 53.3%
Branches: 5 16 31.2%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2024-2025, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifndef CROCODDYL_UTILS_CONVERSIONS_HPP_
10 #define CROCODDYL_UTILS_CONVERSIONS_HPP_
11
12 #include <vector>
13
14 #include "crocoddyl/core/mathbase.hpp"
15
16 namespace crocoddyl {
17
18 template <typename Scalar>
19 struct ScalarSelector {
20 typedef typename std::conditional<std::is_floating_point<Scalar>::value,
21 Scalar, double>::type type;
22 };
23
24 // Casting between floating-point types
25 template <typename NewScalar, typename Scalar>
26 static typename std::enable_if<std::is_floating_point<NewScalar>::value &&
27 std::is_floating_point<Scalar>::value,
28 NewScalar>::type
29 423 scalar_cast(const Scalar& x) {
30 423 return static_cast<NewScalar>(x);
31 }
32
33 template <typename NewScalar, typename Scalar,
34 template <typename> class ItemTpl>
35 5 std::vector<ItemTpl<NewScalar>> vector_cast(
36 const std::vector<ItemTpl<Scalar>>& in) {
37 5 std::vector<ItemTpl<NewScalar>> out;
38
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 out.reserve(in.size()); // Optimize allocation
39
2/2
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 5 times.
25 for (const auto& obj : in) {
40
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
20 out.push_back(obj.template cast<NewScalar>());
41 }
42 5 return out;
43 }
44
45 template <typename NewScalar, typename Scalar,
46 template <typename> class ItemTpl>
47 std::vector<std::shared_ptr<ItemTpl<NewScalar>>> vector_cast(
48 const std::vector<std::shared_ptr<ItemTpl<Scalar>>>& in) {
49 std::vector<std::shared_ptr<ItemTpl<NewScalar>>> out;
50 out.reserve(in.size()); // Optimize allocation
51 for (const auto& obj : in) {
52 out.push_back(std::static_pointer_cast<ItemTpl<NewScalar>>(
53 obj->template cast<NewScalar>()));
54 }
55 return out;
56 }
57
58 } // namespace crocoddyl
59
60 #ifdef CROCODDYL_WITH_CODEGEN
61
62 // Specialize Eigen's internal cast_impl for your specific types
63 namespace Eigen {
64 namespace internal {
65
66 template <>
67 struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, float> {
68 EIGEN_DEVICE_FUNC static inline float run(
69 const CppAD::AD<CppAD::cg::CG<double>>& x) {
70 // Perform the conversion. This example extracts the value from the AD type.
71 // You might need to adjust this depending on the specific implementation of
72 // CppAD::cg::CG<double>.
73 return static_cast<float>(CppAD::Value(x).getValue());
74 }
75 };
76
77 template <>
78 struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>, double> {
79 EIGEN_DEVICE_FUNC static inline double run(
80 const CppAD::AD<CppAD::cg::CG<double>>& x) {
81 return CppAD::Value(x).getValue();
82 }
83 };
84
85 template <>
86 struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, float> {
87 EIGEN_DEVICE_FUNC static inline float run(
88 const CppAD::AD<CppAD::cg::CG<float>>& x) {
89 return CppAD::Value(x).getValue();
90 }
91 };
92
93 template <>
94 struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>, double> {
95 EIGEN_DEVICE_FUNC static inline double run(
96 const CppAD::AD<CppAD::cg::CG<float>>& x) {
97 // Perform the conversion. This example extracts the value from the AD type.
98 // You might need to adjust this depending on the specific implementation of
99 // CppAD::cg::CG<float>.
100 return static_cast<float>(CppAD::Value(x).getValue());
101 }
102 };
103
104 // Convert from CppAD::AD<CppAD::cg::CG<float>> to
105 // CppAD::AD<CppAD::cg::CG<double>>
106 template <>
107 struct cast_impl<CppAD::AD<CppAD::cg::CG<float>>,
108 CppAD::AD<CppAD::cg::CG<double>>> {
109 EIGEN_DEVICE_FUNC static inline CppAD::AD<CppAD::cg::CG<double>> run(
110 const CppAD::AD<CppAD::cg::CG<float>>& x) {
111 return CppAD::AD<CppAD::cg::CG<double>>(
112 CppAD::cg::CG<double>(CppAD::Value(x).getValue()));
113 }
114 };
115
116 // Convert from CppAD::AD<CppAD::cg::CG<double>> to
117 // CppAD::AD<CppAD::cg::CG<float>>
118 template <>
119 struct cast_impl<CppAD::AD<CppAD::cg::CG<double>>,
120 CppAD::AD<CppAD::cg::CG<float>>> {
121 EIGEN_DEVICE_FUNC static inline CppAD::AD<CppAD::cg::CG<float>> run(
122 const CppAD::AD<CppAD::cg::CG<double>>& x) {
123 return CppAD::AD<CppAD::cg::CG<float>>(
124 CppAD::cg::CG<float>(static_cast<float>(CppAD::Value(x).getValue())));
125 }
126 };
127
128 } // namespace internal
129 } // namespace Eigen
130
131 namespace crocoddyl {
132
133 // Casting to CppAD types from floating-point types
134 template <typename NewScalar, typename Scalar>
135 static typename std::enable_if<
136 std::is_floating_point<Scalar>::value &&
137 (std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<double>>>::value ||
138 std::is_same<NewScalar, CppAD::AD<CppAD::cg::CG<float>>>::value),
139 NewScalar>::type
140 scalar_cast(const Scalar& x) {
141 return static_cast<NewScalar>(x);
142 }
143
144 // Casting to floating-point types from CppAD types
145 template <typename NewScalar, typename Scalar>
146 static inline typename std::enable_if<std::is_floating_point<Scalar>::value,
147 NewScalar>::type
148 scalar_cast(const CppAD::AD<CppAD::cg::CG<Scalar>>& x) {
149 return static_cast<NewScalar>(CppAD::Value(x).getValue());
150 }
151
152 } // namespace crocoddyl
153
154 #endif
155
156 #endif // CROCODDYL_UTILS_CONVERSIONS_HPP_
157