GCC Code Coverage Report


Directory: ./
File: include/hpp/pinocchio/util.hh
Date: 2025-05-04 12:09:19
Exec Total Coverage
Lines: 25 25 100.0%
Branches: 33 62 53.2%

Line Branch Exec Source
1 //
2 // Copyright (c) 2017-2018 CNRS
3 // Author: Joseph Mirabel
4 //
5 //
6
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // 1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //
14 // 2. Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30
31 #ifndef HPP_PINOCCHIO_UTIL_HH
32 #define HPP_PINOCCHIO_UTIL_HH
33
34 #include <hpp/pinocchio/config.hh>
35 #include <hpp/pinocchio/fwd.hh>
36 #include <hpp/util/indent.hh>
37
38 namespace hpp {
39 /// \addtogroup to_output_stream Printing to output stream
40 ///
41 /// Some tools to ease pretty printing of objects in HPP.
42 /// To print vectors, you have the following options:
43 /// \snippet tests/print.cc Example usage
44 /// which should output something like
45 /// \code
46 /// R = 1, 0, 0
47 /// 0, 1, 0
48 /// 0, 0, 1
49 /// p = 0, 0, 0
50 /// q = 0, 0, 0, 1
51 /// p = 0, 0, 0
52 /// q = 0, 0, 0, 1, p = 0, 0, 0
53 ///
54 /// R = ( (1, 0, 0,)
55 /// (0, 1, 0,)
56 /// (0, 0, 1,) )
57 /// p = (0, 0, 0,)
58 /// q = (0, 0, 0, 1,)
59 /// p = (0, 0, 0,)
60 /// q = (0, 0, 0, 1,), p = (0, 0, 0,)
61 ///
62 /// 1, 1
63 /// 1, 1
64 /// 1, 1
65 /// 1, 1
66 /// 1, 1
67 ///
68 /// ( (1, 0, 0,),
69 /// (0, 1, 0,),
70 /// (0, 0, 1,), )
71 /// ( (1, 0, 0,), (0, 1, 0,), (0, 0, 1,), )
72 /// ( (1, 0,), (0, 1,), )
73 /// \endcode
74 /// \{
75
76 /// This function must be specialized for the type you want to print.
77 template <typename T, int Option>
78 struct HPP_PINOCCHIO_DLLAPI prettyPrint {
79 static std::ostream& run(std::ostream& os, const T& pp);
80 };
81
82 /// The printing options, currently only contains the output format
83 enum {
84 OutputFormatBits = 3,
85
86 OneLineOutput = 0,
87 CondensedOutput = 1,
88 PrettyOutput = 2
89 };
90
91 /// \cond
92 HPP_PINOCCHIO_DLLAPI long& getpythonformat(std::ostream& o);
93
94 template <bool OneLine, bool PythonStyle, bool Vector>
95 struct HPP_PINOCCHIO_DLLAPI eigen_format {
96 static const Eigen::IOFormat run();
97 };
98
99 // Default implementation
100 template <bool OneLine, bool PythonStyle, bool Vector>
101 96 const Eigen::IOFormat eigen_format<OneLine, PythonStyle, Vector>::run() {
102
10/20
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 8 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 8 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 8 times.
✗ Branch 31 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
96 static const Eigen::IOFormat fmt(
103 (PythonStyle ? Eigen::FullPrecision : Eigen::StreamPrecision), 0,
104 ", ", // Coeff separator
105 (PythonStyle // Row separator
106 ? (OneLine ? ", " : ",\n")
107 : (OneLine ? "; " : "\n")),
108 (PythonStyle ? "(" : ""), // row prefix
109 (PythonStyle ? ",)" : ""), // row suffix
110 (PythonStyle && !Vector ? "( " : ""), // mat prefix
111 (PythonStyle && !Vector ? ", )" : "") // mat suffix
112 );
113 96 return fmt;
114 }
115
116 template <typename T, int Option>
117 struct PrettyPrint {
118 const T& value;
119 32 inline explicit PrettyPrint(const T& t) : value(t) {}
120 };
121
122 template <typename T, int Option>
123 32 std::ostream& operator<<(std::ostream& os, const PrettyPrint<T, Option> pp) {
124 32 return prettyPrint<T, Option>::run(os, pp.value);
125 }
126
127 /// Generic implementation for Eigen objects
128 template <typename Derived, int Option>
129 struct HPP_PINOCCHIO_DLLAPI prettyPrintEigen{
130 static inline std::ostream &
131 20 run(std::ostream & os, const Derived& M){
132 enum {Condensed = ((Option & OutputFormatBits) == OneLineOutput) ||
133 ((Option & OutputFormatBits) == CondensedOutput)};
134
4/8
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
20 static const Eigen::IOFormat mfmt_py =
135 eigen_format<Condensed, true, false>::run();
136
4/8
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
20 static const Eigen::IOFormat vfmt_py =
137 eigen_format<Condensed, true, true>::run();
138
4/8
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
20 static const Eigen::IOFormat mfmt_raw =
139 eigen_format<Condensed, false, false>::run();
140
4/8
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
20 static const Eigen::IOFormat vfmt_raw =
141 eigen_format<Condensed, false, true>::run();
142 20 bool use_py_fmt = (getpythonformat(os) != 0);
143
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
20 const Eigen::IOFormat& fmt =
144 (Derived::IsVectorAtCompileTime ? (use_py_fmt ? vfmt_py : vfmt_raw)
145 : (use_py_fmt ? mfmt_py : mfmt_raw));
146 20 bool transpose = (Derived::ColsAtCompileTime == 1);
147
148
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
20 if (transpose)
149
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
14 return os << M.transpose().format(fmt);
150 else
151
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 return os << M.format(fmt);
152 } // namespace hpp
153 }
154 ;
155 /// FIXME All eigen object must be manually specialized as follow...
156
157 /// Pretty printer for Eigen::Matrix
158 template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
159 int _MaxCols, int Option>
160 struct HPP_PINOCCHIO_DLLAPI prettyPrint<
161 Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Option>
162 : prettyPrintEigen<
163 Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>,
164 Option> {};
165
166 /// Pretty printer for Eigen::VectorBlock
167 template <typename OtherDerived, int Size, int Option>
168 struct HPP_PINOCCHIO_DLLAPI
169 prettyPrint<Eigen::VectorBlock<OtherDerived, Size>, Option>
170 : prettyPrintEigen<Eigen::VectorBlock<OtherDerived, Size>, Option> {};
171
172 /// Pretty printer for Eigen::Block
173 template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel,
174 int Option>
175 struct HPP_PINOCCHIO_DLLAPI
176 prettyPrint<Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>, Option>
177 : prettyPrintEigen<Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>,
178 Option> {};
179
180 /// Pretty printer for Eigen::Ref
181 template <typename _PlainObjectType, int _Options, typename _StrideType,
182 int Option>
183 struct HPP_PINOCCHIO_DLLAPI
184 prettyPrint<Eigen::Ref<_PlainObjectType, _Options, _StrideType>, Option>
185 : prettyPrintEigen<Eigen::Ref<_PlainObjectType, _Options, _StrideType>,
186 Option> {};
187
188 /// Pretty printer for Eigen::Transpose
189 template <typename _PlainObjectType, int Option>
190 struct HPP_PINOCCHIO_DLLAPI
191 prettyPrint<Eigen::Transpose<_PlainObjectType>, Option>
192 : prettyPrintEigen<Eigen::Transpose<_PlainObjectType>, Option> {};
193
194 /// Pretty printer for Eigen::Quaternion
195 template <typename _Scalar, int _Options, int Option>
196 struct HPP_PINOCCHIO_DLLAPI
197 prettyPrint<Eigen::Quaternion<_Scalar, _Options>, Option> {
198 typedef Eigen::Quaternion<_Scalar, _Options> Derived;
199 typedef typename Eigen::internal::traits<Derived>::Coefficients Coefficients;
200 4 static inline std::ostream& run(std::ostream& os, const Derived& M) {
201 4 return prettyPrint<Coefficients, Option>::run(os, M.coeffs());
202 }
203 };
204 /// \endcond
205
206 // Set python formatting of vector and matrices
207 HPP_PINOCCHIO_DLLAPI std::ostream& setpyformat(std::ostream& o);
208
209 // Unset python formatting of vector and matrices
210 HPP_PINOCCHIO_DLLAPI std::ostream& unsetpyformat(std::ostream& o);
211
212 /// Pretty printing
213 template <typename T>
214 10 inline PrettyPrint<T, PrettyOutput> pretty_print(const T& t) {
215 10 return PrettyPrint<T, PrettyOutput>(t);
216 }
217 /// Condensed printing
218 template <typename T>
219 10 inline PrettyPrint<T, CondensedOutput> condensed(const T& t) {
220 10 return PrettyPrint<T, CondensedOutput>(t);
221 }
222 /// Print on one line
223 template <typename T>
224 8 inline PrettyPrint<T, OneLineOutput> one_line(const T& t) {
225 8 return PrettyPrint<T, OneLineOutput>(t);
226 }
227
228 /// \}
229 } // namespace hpp
230 #endif // HPP_PINOCCHIO_UTIL_HH
231