blob: e9298618e8b741f04b14d6e65d0627ba19feb76d [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}
140} // namespace framework
141} // namespace test
142} // namespace arm_compute
143#endif /* ARM_COMPUTE_TEST_UTILS */