xref: /aosp_15_r20/external/ComputeLibrary/tests/framework/Utils.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2017-2020 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef ARM_COMPUTE_TEST_UTILS
25 #define ARM_COMPUTE_TEST_UTILS
26 
27 #include "support/StringSupport.h"
28 
29 #include <algorithm>
30 #include <cmath>
31 #include <cstddef>
32 #include <limits>
33 #include <memory>
34 #include <numeric>
35 #include <sstream>
36 #include <string>
37 #include <type_traits>
38 
39 namespace arm_compute
40 {
41 namespace test
42 {
43 namespace framework
44 {
45 /** @cond */
46 namespace detail
47 {
48 template <int...>
49 struct sequence
50 {
51 };
52 
53 template <int N, int... Ns>
54 struct sequence_generator;
55 
56 template <int... Ns>
57 struct sequence_generator<0, Ns...>
58 {
59     using type = sequence<Ns...>;
60 };
61 
62 template <int N, int... Ns>
63 struct sequence_generator : sequence_generator < N - 1, N - 1, Ns... >
64 {
65 };
66 
67 template <int N>
68 using sequence_t = typename sequence_generator<N>::type;
69 /** @endcond */
70 
71 template <typename O, typename F, typename... As, int... S>
72 void apply_impl(O *obj, F &&func, const std::tuple<As...> &args, detail::sequence<S...>)
73 {
74     (obj->*func)(std::get<S>(args)...);
75 }
76 } // namespace
77 
78 template <typename O, typename F, typename... As>
79 void apply(O *obj, F &&func, const std::tuple<As...> &args)
80 {
81     detail::apply_impl(obj, std::forward<F>(func), args, detail::sequence_t<sizeof...(As)>());
82 }
83 
84 /** Helper function to concatenate multiple strings.
85  *
86  * @param[in] first     Iterator pointing to the first element to be concatenated.
87  * @param[in] last      Iterator pointing behind the last element to be concatenated.
88  * @param[in] separator String used to join the elements.
89  *
90  * @return String containing all elements joined by @p separator.
91  */
92 template <typename T, typename std::enable_if<std::is_same<typename T::value_type, std::string>::value, int>::type = 0>
93 std::string join(T first, T last, const std::string &separator)
94 {
95     return std::accumulate(std::next(first), last, *first, [&separator](const std::string & base, const std::string & suffix)
96     {
97         return base + separator + suffix;
98     });
99 }
100 
101 /** Helper function to concatenate multiple values.
102  *
103  * All values are converted to std::string using the provided operation before
104  * being joined.
105  *
106  * The signature of op has to be equivalent to
107  * std::string op(const T::value_type &val).
108  *
109  * @param[in] first     Iterator pointing to the first element to be concatenated.
110  * @param[in] last      Iterator pointing behind the last element to be concatenated.
111  * @param[in] separator String used to join the elements.
112  * @param[in] op        Conversion function.
113  *
114  * @return String containing all elements joined by @p separator.
115  */
116 template <typename T, typename UnaryOp>
117 std::string join(T &&first, T &&last, const std::string &separator, UnaryOp &&op)
118 {
119     return std::accumulate(std::next(first), last, op(*first), [&separator, &op](const std::string & base, const typename T::value_type & suffix)
120     {
121         return base + separator + op(suffix);
122     });
123 }
124 
125 /** Helper function to concatenate multiple values.
126  *
127  * All values are converted to std::string using std::to_string before being joined.
128  *
129  * @param[in] first     Iterator pointing to the first element to be concatenated.
130  * @param[in] last      Iterator pointing behind the last element to be concatenated.
131  * @param[in] separator String used to join the elements.
132  *
133  * @return String containing all elements joined by @p separator.
134  */
135 template <typename T, typename std::enable_if<std::is_arithmetic<typename T::value_type>::value, int>::type = 0>
136 std::string join(T && first, T && last, const std::string &separator)
137 {
138     return join(std::forward<T>(first), std::forward<T>(last), separator, support::cpp11::to_string);
139 }
140 
141 /** Convert string to lower case.
142  *
143  * @param[in] string To be converted string.
144  *
145  * @return Lower case string.
146  */
147 inline std::string tolower(std::string string)
148 {
149     std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c)
150     {
151         return std::tolower(c);
152     });
153     return string;
154 }
155 
156 /** Create a string with the arithmetic value in full precision.
157  *
158  * @param val            Arithmetic value
159  * @param decimal_places How many decimal places to show
160  *
161  * @return String with the arithmetic value.
162  */
163 template <typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
164 inline std::string arithmetic_to_string(T val, int decimal_places = 0)
165 {
166     std::stringstream ss;
167     ss << std::fixed;
168     ss.precision((decimal_places) ? decimal_places : std::numeric_limits<T>::digits10 + 1);
169     ss << val;
170     return ss.str();
171 }
172 
173 /**  Makes the calling thread to sleep for a specified number of seconds
174  *
175  * @param[in] seconds Amount of seconds to sleep. Will return immediately if less or equal to zero.
176  */
177 void sleep_in_seconds(float seconds);
178 } // namespace framework
179 } // namespace test
180 } // namespace arm_compute
181 #endif /* ARM_COMPUTE_TEST_UTILS */
182