GCC Code Coverage Report


Directory: ./
File: include/hpp/pinocchio/serialization.hh
Date: 2025-05-04 12:09:19
Exec Total Coverage
Lines: 79 86 91.9%
Branches: 49 106 46.2%

Line Branch Exec Source
1 //
2 // Copyright (c) 2020 CNRS
3 // Author: Joseph Mirabel
4 //
5
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //
13 // 2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 // DAMAGE.
29
30 #ifndef HPP_PINOCCHIO_SERIALIZATION_HH
31 #define HPP_PINOCCHIO_SERIALIZATION_HH
32
33 #include <boost/serialization/shared_ptr.hpp>
34 #include <boost/serialization/split_free.hpp>
35 #include <boost/serialization/weak_ptr.hpp>
36 #include <hpp/pinocchio/device.hh>
37 #include <hpp/pinocchio/fwd.hh>
38 #include <hpp/pinocchio/humanoid-robot.hh>
39 #include <hpp/util/serialization.hh>
40 #include <pinocchio/fwd.hpp>
41 #include <pinocchio/serialization/eigen.hpp>
42 #include <set>
43 #include <type_traits>
44
45 36 BOOST_SERIALIZATION_SPLIT_FREE(hpp::pinocchio::DevicePtr_t)
46 16 BOOST_SERIALIZATION_SPLIT_FREE(hpp::pinocchio::DeviceWkPtr_t)
47
48 namespace boost {
49 namespace serialization {
50 template <class Archive>
51 9 inline void load(Archive& ar, hpp::pinocchio::DevicePtr_t& d,
52 const unsigned int version) {
53 9 load<Archive, hpp::pinocchio::Device>(ar, d, version);
54 9 auto* har = hpp::serialization::cast(&ar);
55
4/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
9 if (d && har && har->contains(d->name()))
56 9 d = har->template get<hpp::pinocchio::Device>(d->name(), true)->self();
57 9 }
58 template <class Archive>
59 16 inline void load(Archive& ar, hpp::pinocchio::DeviceWkPtr_t& d,
60 const unsigned int version) {
61
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 load<Archive, hpp::pinocchio::Device>(ar, d, version);
62 16 auto* har = hpp::serialization::cast(&ar);
63
1/2
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
16 std::string name(d.lock()->name());
64
6/14
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
16 if (d.lock() && har && har->contains(name))
65
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 d = har->template get<hpp::pinocchio::Device>(name, true)->self();
66 }
67 template <class Archive>
68 2 inline void load(Archive& ar, hpp::pinocchio::HumanoidRobotPtr_t& d,
69 const unsigned int version) {
70 2 load<Archive, hpp::pinocchio::HumanoidRobot>(ar, d, version);
71 2 auto* har = hpp::serialization::cast(&ar);
72
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
2 if (d && har && har->contains(d->name()))
73 2 d = har->template getChildClass<hpp::pinocchio::Device,
74 2 hpp::pinocchio::HumanoidRobot>(d->name(),
75 true)
76 ->self();
77 }
78 template <class Archive>
79 2 inline void load(Archive& ar, hpp::pinocchio::HumanoidRobotWkPtr_t& d,
80 const unsigned int version) {
81
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 load<Archive, hpp::pinocchio::HumanoidRobot>(ar, d, version);
82 2 auto* har = hpp::serialization::cast(&ar);
83
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 std::string name(d.lock()->name());
84
6/14
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 if (d.lock() && har && har->contains(name))
85
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 d = har->template getChildClass<hpp::pinocchio::Device,
86 hpp::pinocchio::HumanoidRobot>(name, true)
87 ->self();
88 }
89
90 template <class Archive, typename _Scalar, int _Rows, int _Cols, int _Options,
91 int _MaxRows, int _MaxCols>
92 4 inline void serialize(
93 Archive& ar,
94 Eigen::Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& m,
95 const unsigned int version) {
96 (void)version;
97 4 Eigen::DenseIndex rows(m.rows()), cols(m.cols());
98
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 ar& BOOST_SERIALIZATION_NVP(rows);
99
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 ar& BOOST_SERIALIZATION_NVP(cols);
100
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 if (!Archive::is_saving::value) m.resize(rows, cols);
101
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
4 if (m.size() > 0)
102 ar& make_nvp("data", make_array(m.data(), (size_t)m.size()));
103 4 }
104
105 } // namespace serialization
106 } // namespace boost
107
108 namespace hpp {
109 namespace serialization {
110 namespace remove_duplicate {
111 template <typename Key, typename Compare = std::less<Key>>
112 struct ptr_less : Compare {
113 2 inline bool operator()(Key const* t1, Key const* t2) const {
114 2 return Compare::operator()(*t1, *t2);
115 }
116 };
117
118 template <typename Derived>
119 struct eigen_compare {
120 22 bool operator()(const Eigen::PlainObjectBase<Derived>& a,
121 const Eigen::PlainObjectBase<Derived>& b) const {
122
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
22 if (a.size() < b.size()) return true;
123
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
22 if (a.size() > b.size()) return false;
124
2/2
✓ Branch 1 taken 110 times.
✓ Branch 2 taken 22 times.
132 for (Eigen::Index i = 0; i < a.size(); ++i) {
125
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 110 times.
110 if (a.derived().data()[i] < b.derived().data()[i]) return true;
126
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 110 times.
110 if (a.derived().data()[i] > b.derived().data()[i]) return false;
127 }
128 22 return false;
129 }
130 };
131
132 template <typename Key, typename Compare = std::less<Key>>
133 struct archive {
134 typedef Compare compare_type;
135 typedef ptr_less<Key, Compare> ptr_compare_type;
136 std::set<Key const*, ptr_compare_type> datas;
137 int hitcount;
138
139 13 archive() : hitcount(0) {}
140 };
141
142 typedef archive<::hpp::pinocchio::vector_t,
143 eigen_compare<::hpp::pinocchio::vector_t>>
144 vector_archive;
145
146 template <class Archive, typename Key>
147 36 inline void load_or_save_no_remove_duplicate_check(Archive& ar,
148 const char* name, Key& key,
149 const unsigned int version) {
150 (void)version;
151 36 Key* value = &key;
152
1/2
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
36 ar& boost::serialization::make_nvp(name, value);
153
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
32 if (!Archive::is_saving::value) key = *value;
154 36 }
155
156 template <class Archive, typename Key>
157 inline void save_impl(Archive& ar, const char* name, const Key& key,
158 const unsigned int version) {
159 (void)version;
160 Key const* value = &key;
161 ar << boost::serialization::make_nvp(name, value);
162 }
163
164 template <class Archive, typename Key, typename Compare = std::less<Key>>
165 28 inline void save_impl(Archive& ar,
166 std::set<Key const*, ptr_less<Key, Compare>>& set,
167 int& hitcount, const char* name, const Key& key,
168 const unsigned int version) {
169 (void)version;
170 if (!Archive::is_saving::value)
171 throw std::logic_error(
172 "HPP serialization: cannot load into a const element. This should "
173 "never happen.");
174
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 auto result = set.insert(&key);
175 28 bool inserted = result.second;
176
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
28 Key const* k = (inserted ? &key : *result.first);
177
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 ar& boost::serialization::make_nvp(name, k);
178
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
28 if (!inserted) hitcount++;
179 }
180
181 template <class Archive, typename Key, typename Compare = std::less<Key>>
182 4 inline void serialize(Archive& ar,
183 std::set<Key const*, ptr_less<Key, Compare>>& set,
184 int& hitcount, const char* name, Key& key,
185 const unsigned int version) {
186 if (Archive::is_saving::value) {
187 4 save_impl(ar, set, hitcount, name, key, version);
188 } else {
189 load_or_save_no_remove_duplicate_check(ar, name, key, version);
190 }
191 }
192
193 template <bool is_base>
194 struct serialiaze_impl {
195 template <typename Archive, typename Key, typename Compare = std::less<Key>>
196 4 static inline void run(Archive& ar, const char* name, Key& key,
197 const unsigned int version) {
198
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
4 archive<Key, Compare>& rda = dynamic_cast<archive<Key, Compare>&>(ar);
199 4 serialize(ar, rda.datas, rda.hitcount, name, key, version);
200 }
201 template <typename Archive, typename Key, typename Compare = std::less<Key>>
202 24 static inline void save(Archive& ar, const char* name, const Key& key,
203 const unsigned int version) {
204
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 archive<Key, Compare>& rda = dynamic_cast<archive<Key, Compare>&>(ar);
205 24 save_impl(ar, rda.datas, rda.hitcount, name, key, version);
206 }
207 };
208
209 template <>
210 struct serialiaze_impl<false> {
211 template <typename Archive, typename Key, typename Compare = std::less<Key>>
212 36 static inline void run(Archive& ar, const char* name, Key& key,
213 const unsigned int version) {
214
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
36 if (dynamic_cast<archive<Key, Compare>*>(&ar) != NULL)
215 serialiaze_impl<true>::run<Archive, Key, Compare>(ar, name, key, version);
216 else
217 36 load_or_save_no_remove_duplicate_check(ar, name, key, version);
218 36 }
219 template <typename Archive, typename Key, typename Compare = std::less<Key>>
220 24 static inline void save(Archive& ar, const char* name, const Key& key,
221 const unsigned int version) {
222
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 if (dynamic_cast<archive<Key, Compare>*>(&ar) != NULL)
223 24 serialiaze_impl<true>::save<Archive, Key, Compare>(ar, name, key,
224 version);
225 else
226 save_impl(ar, name, key, version);
227 }
228 };
229
230 template <typename Archive, typename Key, typename Compare = std::less<Key>,
231 bool is_base = std::is_base_of<archive<Key, Compare>, Archive>::value>
232 40 inline void serialize(Archive& ar, const char* name, Key& key,
233 const unsigned int version) {
234 40 serialiaze_impl<is_base>::template run<Archive, Key, Compare>(ar, name, key,
235 version);
236 40 }
237
238 template <typename Archive, typename Key, typename Compare = std::less<Key>,
239 bool is_base = std::is_base_of<archive<Key, Compare>, Archive>::value>
240 24 inline void save(Archive& ar, const char* name, const Key& key,
241 const unsigned int version) {
242 24 serialiaze_impl<is_base>::template save<Archive, Key, Compare>(ar, name, key,
243 version);
244 }
245
246 template <typename Archive>
247 40 inline void serialize_vector(Archive& ar, const char* name,
248 ::hpp::pinocchio::vector_t& key,
249 const unsigned int version) {
250 40 serialize<Archive, ::hpp::pinocchio::vector_t, vector_archive::compare_type>(
251 ar, name, key, version);
252 40 }
253
254 template <typename Archive>
255 24 inline void save_vector(Archive& ar, const char* name,
256 const ::hpp::pinocchio::vector_t& key,
257 const unsigned int version) {
258 24 save<Archive, ::hpp::pinocchio::vector_t, vector_archive::compare_type>(
259 ar, name, key, version);
260 }
261
262 } // namespace remove_duplicate
263 } // namespace serialization
264 } // namespace hpp
265
266 #endif // HPP_PINOCCHIO_SERIALIZATION_HH
267