blob: c0442cf9afad38c4610d71123111117913eaa46f [file] [log] [blame]
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +01001/*
2 * Copyright (c) 2017 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/ToolchainSupport.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
39namespace arm_compute
40{
41namespace test
42{
43namespace framework
44{
45/** @cond */
46namespace detail
47{
48template <int...>
49struct sequence
50{
51};
52
53template <int N, int... Ns>
54struct sequence_generator;
55
56template <int... Ns>
57struct sequence_generator<0, Ns...>
58{
59 using type = sequence<Ns...>;
60};
61
62template <int N, int... Ns>
63struct sequence_generator : sequence_generator < N - 1, N - 1, Ns... >
64{
65};
66
67template <int N>
68using sequence_t = typename sequence_generator<N>::type;
69/** @endcond */
70
71template <typename O, typename F, typename... As, int... S>
72void 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
78template <typename O, typename F, typename... As>
79void 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 */
92template <typename T, typename std::enable_if<std::is_same<typename T::value_type, std::string>::value, int>::type = 0>
93std::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 */
116template <typename T, typename UnaryOp>
117std::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 */
135template <typename T, typename std::enable_if<std::is_arithmetic<typename T::value_type>::value, int>::type = 0>
136std::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}
Moritz Pflanzer52800712017-08-30 16:27:14 +0100140
141/** Convert string to lower case.
142 *
143 * @param[in] string To be converted string.
144 *
145 * @return Lower case string.
146 */
147inline 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}
Anthony Barbierab14c152017-11-09 10:29:59 +0000155
156/** Create a string with the arithmetic value in full precision.
157 *
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000158 * @param val Arithmetic value
159 * @param decimal_places How many decimal places to show
Anthony Barbierab14c152017-11-09 10:29:59 +0000160 *
161 * @return String with the arithmetic value.
162 */
163template <typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000164inline std::string arithmetic_to_string(T val, int decimal_places = 0)
Anthony Barbierab14c152017-11-09 10:29:59 +0000165{
166 std::stringstream ss;
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000167 ss << std::fixed;
168 ss.precision((decimal_places) ? decimal_places : std::numeric_limits<T>::digits10 + 1);
Anthony Barbierab14c152017-11-09 10:29:59 +0000169 ss << val;
170 return ss.str();
171}
172
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100173} // namespace framework
174} // namespace test
175} // namespace arm_compute
176#endif /* ARM_COMPUTE_TEST_UTILS */