blob: ad09c6535ab1fc0f4bd090cfa159c709a65eff06 [file] [log] [blame]
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +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_TOOLCHAINSUPPORT
25#define ARM_COMPUTE_TEST_TOOLCHAINSUPPORT
26
27#include <algorithm>
28#include <cmath>
29#include <cstddef>
30#include <limits>
31#include <memory>
32#include <numeric>
33#include <sstream>
34#include <string>
35#include <type_traits>
36
Ioan-Cristian Szabo33fd07b2017-10-26 15:42:24 +010037#include "support/Half.h"
38
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +010039namespace arm_compute
40{
41namespace support
42{
43namespace cpp11
44{
Michalis Spyrou07781ac2017-08-31 15:11:41 +010045#if(__ANDROID__ || BARE_METAL)
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +010046/** Convert integer and float values to string.
47 *
48 * @note This function implements the same behaviour as std::to_string. The
49 * latter is missing in some Android toolchains.
50 *
51 * @param[in] value Value to be converted to string.
52 *
53 * @return String representation of @p value.
54 */
55template <typename T, typename std::enable_if<std::is_arithmetic<typename std::decay<T>::type>::value, int>::type = 0>
Moritz Pflanzer572ade72017-07-21 17:36:33 +010056inline std::string to_string(T && value)
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +010057{
58 std::stringstream stream;
59 stream << std::forward<T>(value);
60 return stream.str();
61}
62
63/** Convert string values to integer.
64 *
65 * @note This function implements the same behaviour as std::stoi. The latter
66 * is missing in some Android toolchains.
67 *
68 * @param[in] str String to be converted to int.
69 *
70 * @return Integer representation of @p str.
71 */
72inline int stoi(const std::string &str)
73{
74 std::stringstream stream(str);
75 int value = 0;
76 stream >> value;
77 return value;
78}
79
80/** Convert string values to unsigned long.
81 *
82 * @note This function implements the same behaviour as std::stoul. The latter
83 * is missing in some Android toolchains.
84 *
85 * @param[in] str String to be converted to unsigned long.
86 *
87 * @return Unsigned long representation of @p str.
88 */
89inline unsigned long stoul(const std::string &str)
90{
91 std::stringstream stream(str);
92 unsigned long value = 0;
93 stream >> value;
94 return value;
95}
96
97/** Convert string values to float.
98 *
99 * @note This function implements the same behaviour as std::stof. The latter
100 * is missing in some Android toolchains.
101 *
102 * @param[in] str String to be converted to float.
103 *
104 * @return Float representation of @p str.
105 */
106inline float stof(const std::string &str)
107{
108 std::stringstream stream(str);
109 float value = 0.f;
110 stream >> value;
111 return value;
112}
113
114/** Round floating-point value with half value rounding away from zero.
115 *
116 * @note This function implements the same behaviour as std::round except that it doesn't
117 * support Integral type. The latter is not in the namespace std in some Android toolchains.
118 *
119 * @param[in] value floating-point value to be rounded.
120 *
121 * @return Floating-point value of rounded @p value.
122 */
123template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
124inline T round(T value)
125{
126 return ::round(value);
127}
128
129/** Truncate floating-point value.
130 *
131 * @note This function implements the same behaviour as std::truncate except that it doesn't
132 * support Integral type. The latter is not in the namespace std in some Android toolchains.
133 *
134 * @param[in] value floating-point value to be truncated.
135 *
136 * @return Floating-point value of truncated @p value.
137 */
138template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
139inline T trunc(T value)
140{
141 return ::trunc(value);
142}
143
144/** Composes a floating point value with the magnitude of @p x and the sign of @p y.
145 *
146 * @note This function implements the same behaviour as std::copysign except that it doesn't
147 * support Integral type. The latter is not in the namespace std in some Android toolchains.
148 *
Georgios Pinitas7d3d1b92017-10-12 17:34:20 +0100149 * @param[in] x value that contains the magnitude to be used in constructing the result.
150 * @param[in] y value that contains the sign to be used in construct in the result.
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +0100151 *
152 * @return Floating-point value with magnitude of @p x and sign of @p y.
153 */
154template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
155inline T copysign(T x, T y)
156{
157 return ::copysign(x, y);
158}
Georgios Pinitas7d3d1b92017-10-12 17:34:20 +0100159
160/** Loads the data from the given location, converts them to character string equivalents
161 * and writes the result to a character string buffer.
162 *
163 * @param[in] s Pointer to a character string to write to
164 * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
165 * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
166 * @param[in] args Arguments forwarded to snprintf.
167 *
168 * @return Number of characters that would have been written for a sufficiently large buffer
169 * if successful (not including the terminating null character), or a negative value if an error occurred.
170 */
171template <typename... Ts>
172inline int snprintf(char *s, size_t n, const char *fmt, Ts &&... args)
173{
174 return ::snprintf(s, n, fmt, std::forward<Ts>(args)...);
175}
Michalis Spyrou07781ac2017-08-31 15:11:41 +0100176#else /* (__ANDROID__ || BARE_METAL) */
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +0100177/** Convert integer and float values to string.
178 *
179 * @note This function acts as a convenience wrapper around std::to_string. The
180 * latter is missing in some Android toolchains.
181 *
182 * @param[in] value Value to be converted to string.
183 *
184 * @return String representation of @p value.
185 */
186template <typename T>
Moritz Pflanzer572ade72017-07-21 17:36:33 +0100187inline std::string to_string(T &&value)
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +0100188{
189 return ::std::to_string(std::forward<T>(value));
190}
191
192/** Convert string values to integer.
193 *
194 * @note This function acts as a convenience wrapper around std::stoi. The
195 * latter is missing in some Android toolchains.
196 *
197 * @param[in] args Arguments forwarded to std::stoi.
198 *
199 * @return Integer representation of input string.
200 */
201template <typename... Ts>
202int stoi(Ts &&... args)
203{
204 return ::std::stoi(std::forward<Ts>(args)...);
205}
206
207/** Convert string values to unsigned long.
208 *
209 * @note This function acts as a convenience wrapper around std::stoul. The
210 * latter is missing in some Android toolchains.
211 *
212 * @param[in] args Arguments forwarded to std::stoul.
213 *
214 * @return Unsigned long representation of input string.
215 */
216template <typename... Ts>
217int stoul(Ts &&... args)
218{
219 return ::std::stoul(std::forward<Ts>(args)...);
220}
221
222/** Convert string values to float.
223 *
224 * @note This function acts as a convenience wrapper around std::stof. The
225 * latter is missing in some Android toolchains.
226 *
227 * @param[in] args Arguments forwarded to std::stof.
228 *
229 * @return Float representation of input string.
230 */
231template <typename... Ts>
232int stof(Ts &&... args)
233{
234 return ::std::stof(std::forward<Ts>(args)...);
235}
236
237/** Round floating-point value with half value rounding away from zero.
238 *
239 * @note This function implements the same behaviour as std::round except that it doesn't
240 * support Integral type. The latter is not in the namespace std in some Android toolchains.
241 *
242 * @param[in] value floating-point value to be rounded.
243 *
244 * @return Floating-point value of rounded @p value.
245 */
246template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
247inline T round(T value)
248{
249 return std::round(value);
250}
251
252/** Truncate floating-point value.
253 *
254 * @note This function implements the same behaviour as std::truncate except that it doesn't
255 * support Integral type. The latter is not in the namespace std in some Android toolchains.
256 *
257 * @param[in] value floating-point value to be truncated.
258 *
259 * @return Floating-point value of truncated @p value.
260 */
261template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
262inline T trunc(T value)
263{
264 return std::trunc(value);
265}
266
267/** Composes a floating point value with the magnitude of @p x and the sign of @p y.
268 *
269 * @note This function implements the same behaviour as std::copysign except that it doesn't
270 * support Integral type. The latter is not in the namespace std in some Android toolchains.
271 *
Georgios Pinitas7d3d1b92017-10-12 17:34:20 +0100272 * @param[in] x value that contains the magnitude to be used in constructing the result.
273 * @param[in] y value that contains the sign to be used in construct in the result.
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +0100274 *
275 * @return Floating-point value with magnitude of @p x and sign of @p y.
276 */
277template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
278inline T copysign(T x, T y)
279{
280 return std::copysign(x, y);
281}
Georgios Pinitas7d3d1b92017-10-12 17:34:20 +0100282
283/** Loads the data from the given location, converts them to character string equivalents
284 * and writes the result to a character string buffer.
285 *
286 * @param[in] s Pointer to a character string to write to
287 * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
288 * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
289 * @param[in] args Arguments forwarded to std::snprintf.
290 *
291 * @return Number of characters that would have been written for a sufficiently large buffer
292 * if successful (not including the terminating null character), or a negative value if an error occurred.
293 */
294template <typename... Ts>
295inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args)
296{
297 return std::snprintf(s, n, fmt, std::forward<Ts>(args)...);
298}
Michalis Spyrou07781ac2017-08-31 15:11:41 +0100299#endif /* (__ANDROID__ || BARE_METAL) */
Moritz Pflanzer572ade72017-07-21 17:36:33 +0100300
301inline std::string to_string(bool value)
302{
303 std::stringstream str;
304 str << std::boolalpha << value;
305 return str.str();
306}
Moritz Pflanzerbeabe3b2017-08-31 14:56:32 +0100307
308// std::align is missing in GCC 4.9
309// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350
310inline void *align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
311{
312 std::uintptr_t pn = reinterpret_cast<std::uintptr_t>(ptr);
313 std::uintptr_t aligned = (pn + alignment - 1) & -alignment;
314 std::size_t padding = aligned - pn;
315 if(space < size + padding)
316 {
317 return nullptr;
318 }
319
320 space -= padding;
321
322 return ptr = reinterpret_cast<void *>(aligned);
323}
Ioan-Cristian Szabo33fd07b2017-10-26 15:42:24 +0100324
325// std::isfinite
326template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
327inline bool isfinite(T value)
328{
329 return std::isfinite(value);
330}
331
332inline bool isfinite(half_float::half value)
333{
334 return half_float::isfinite(value);
335}
Moritz Pflanzerd0ae8b82017-06-29 14:51:57 +0100336} // namespace cpp11
337
338namespace cpp14
339{
340/** make_unqiue is missing in CPP11. Reimplement it according to the standard
341 * proposal.
342 */
343template <class T>
344struct _Unique_if
345{
346 typedef std::unique_ptr<T> _Single_object;
347};
348
349template <class T>
350struct _Unique_if<T[]>
351{
352 typedef std::unique_ptr<T[]> _Unknown_bound;
353};
354
355template <class T, size_t N>
356struct _Unique_if<T[N]>
357{
358 typedef void _Known_bound;
359};
360
361template <class T, class... Args>
362typename _Unique_if<T>::_Single_object
363make_unique(Args &&... args)
364{
365 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
366}
367
368template <class T>
369typename _Unique_if<T>::_Unknown_bound
370make_unique(size_t n)
371{
372 typedef typename std::remove_extent<T>::type U;
373 return std::unique_ptr<T>(new U[n]());
374}
375
376template <class T, class... Args>
377typename _Unique_if<T>::_Known_bound
378make_unique(Args &&...) = delete;
379} // namespace cpp14
380} // namespace support
381} // namespace arm_compute
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100382#endif /* ARM_COMPUTE_TEST_TOOLCHAINSUPPORT */