2 * Copyright (c) 2017-2018 ARM Limited.
4 * SPDX-License-Identifier: MIT
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:
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
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
24 #ifndef ARM_COMPUTE_TEST_TOOLCHAINSUPPORT
25 #define ARM_COMPUTE_TEST_TOOLCHAINSUPPORT
35 #include <type_traits>
37 #include "support/Half.h"
45 #if(__ANDROID__ || BARE_METAL)
46 /** Convert integer and float values to string.
48 * @note This function implements the same behaviour as std::to_string. The
49 * latter is missing in some Android toolchains.
51 * @param[in] value Value to be converted to string.
53 * @return String representation of @p value.
55 template <typename T, typename std::enable_if<std::is_arithmetic<typename std::decay<T>::type>::value, int>::type = 0>
56 inline std::string to_string(T && value)
58 std::stringstream stream;
59 stream << std::forward<T>(value);
63 /** Convert string values to integer.
65 * @note This function implements the same behaviour as std::stoi. The latter
66 * is missing in some Android toolchains.
68 * @param[in] str String to be converted to int.
70 * @return Integer representation of @p str.
72 inline int stoi(const std::string &str, std::size_t *pos = 0, int base = 10)
85 /** Convert string values to unsigned long.
87 * @note This function implements the same behaviour as std::stoul. The latter
88 * is missing in some Android toolchains.
90 * @param[in] str String to be converted to unsigned long.
92 * @return Unsigned long representation of @p str.
94 inline unsigned long stoul(const std::string &str, std::size_t *pos = 0, int base = 10)
96 std::stringstream stream;
97 unsigned long value = 0;
107 /** Convert string values to float.
109 * @note This function implements the same behaviour as std::stof. The latter
110 * is missing in some Android toolchains.
112 * @param[in] str String to be converted to float.
114 * @return Float representation of @p str.
116 inline float stof(const std::string &str)
118 std::stringstream stream(str);
124 /** Round floating-point value with half value rounding away from zero.
126 * @note This function implements the same behaviour as std::round except that it doesn't
127 * support Integral type. The latter is not in the namespace std in some Android toolchains.
129 * @param[in] value floating-point value to be rounded.
131 * @return Floating-point value of rounded @p value.
133 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
134 inline T round(T value)
136 return ::round(value);
139 /** Truncate floating-point value.
141 * @note This function implements the same behaviour as std::truncate except that it doesn't
142 * support Integral type. The latter is not in the namespace std in some Android toolchains.
144 * @param[in] value floating-point value to be truncated.
146 * @return Floating-point value of truncated @p value.
148 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
149 inline T trunc(T value)
151 return ::trunc(value);
154 /** Composes a floating point value with the magnitude of @p x and the sign of @p y.
156 * @note This function implements the same behaviour as std::copysign except that it doesn't
157 * support Integral type. The latter is not in the namespace std in some Android toolchains.
159 * @param[in] x value that contains the magnitude to be used in constructing the result.
160 * @param[in] y value that contains the sign to be used in construct in the result.
162 * @return Floating-point value with magnitude of @p x and sign of @p y.
164 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
165 inline T copysign(T x, T y)
167 return ::copysign(x, y);
170 /** Loads the data from the given location, converts them to character string equivalents
171 * and writes the result to a character string buffer.
173 * @param[in] s Pointer to a character string to write to
174 * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
175 * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
176 * @param[in] args Arguments forwarded to snprintf.
178 * @return Number of characters that would have been written for a sufficiently large buffer
179 * if successful (not including the terminating null character), or a negative value if an error occurred.
181 template <typename... Ts>
182 inline int snprintf(char *s, size_t n, const char *fmt, Ts &&... args)
184 return ::snprintf(s, n, fmt, std::forward<Ts>(args)...);
186 #else /* (__ANDROID__ || BARE_METAL) */
187 /** Convert integer and float values to string.
189 * @note This function acts as a convenience wrapper around std::to_string. The
190 * latter is missing in some Android toolchains.
192 * @param[in] value Value to be converted to string.
194 * @return String representation of @p value.
196 template <typename T>
197 inline std::string to_string(T &&value)
199 return ::std::to_string(std::forward<T>(value));
202 /** Convert string values to integer.
204 * @note This function acts as a convenience wrapper around std::stoi. The
205 * latter is missing in some Android toolchains.
207 * @param[in] args Arguments forwarded to std::stoi.
209 * @return Integer representation of input string.
211 template <typename... Ts>
212 int stoi(Ts &&... args)
214 return ::std::stoi(std::forward<Ts>(args)...);
217 /** Convert string values to unsigned long.
219 * @note This function acts as a convenience wrapper around std::stoul. The
220 * latter is missing in some Android toolchains.
222 * @param[in] args Arguments forwarded to std::stoul.
224 * @return Unsigned long representation of input string.
226 template <typename... Ts>
227 int stoul(Ts &&... args)
229 return ::std::stoul(std::forward<Ts>(args)...);
232 /** Convert string values to float.
234 * @note This function acts as a convenience wrapper around std::stof. The
235 * latter is missing in some Android toolchains.
237 * @param[in] args Arguments forwarded to std::stof.
239 * @return Float representation of input string.
241 template <typename... Ts>
242 int stof(Ts &&... args)
244 return ::std::stof(std::forward<Ts>(args)...);
247 /** Round floating-point value with half value rounding away from zero.
249 * @note This function implements the same behaviour as std::round except that it doesn't
250 * support Integral type. The latter is not in the namespace std in some Android toolchains.
252 * @param[in] value floating-point value to be rounded.
254 * @return Floating-point value of rounded @p value.
256 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
257 inline T round(T value)
259 //Workaround Valgrind's mismatches: when running from Valgrind the call to std::round(-4.500000) == -4.000000 instead of 5.00000
260 return (value < 0.f) ? static_cast<int>(value - 0.5f) : static_cast<int>(value + 0.5f);
263 /** Truncate floating-point value.
265 * @note This function implements the same behaviour as std::truncate except that it doesn't
266 * support Integral type. The latter is not in the namespace std in some Android toolchains.
268 * @param[in] value floating-point value to be truncated.
270 * @return Floating-point value of truncated @p value.
272 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
273 inline T trunc(T value)
275 return std::trunc(value);
278 /** Composes a floating point value with the magnitude of @p x and the sign of @p y.
280 * @note This function implements the same behaviour as std::copysign except that it doesn't
281 * support Integral type. The latter is not in the namespace std in some Android toolchains.
283 * @param[in] x value that contains the magnitude to be used in constructing the result.
284 * @param[in] y value that contains the sign to be used in construct in the result.
286 * @return Floating-point value with magnitude of @p x and sign of @p y.
288 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
289 inline T copysign(T x, T y)
291 return std::copysign(x, y);
294 /** Loads the data from the given location, converts them to character string equivalents
295 * and writes the result to a character string buffer.
297 * @param[in] s Pointer to a character string to write to
298 * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
299 * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
300 * @param[in] args Arguments forwarded to std::snprintf.
302 * @return Number of characters that would have been written for a sufficiently large buffer
303 * if successful (not including the terminating null character), or a negative value if an error occurred.
305 template <typename... Ts>
306 inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args)
308 return std::snprintf(s, n, fmt, std::forward<Ts>(args)...);
310 #endif /* (__ANDROID__ || BARE_METAL) */
312 inline std::string to_string(bool value)
314 std::stringstream str;
315 str << std::boolalpha << value;
319 // std::align is missing in GCC 4.9
320 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350
321 inline void *align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
323 std::uintptr_t pn = reinterpret_cast<std::uintptr_t>(ptr);
324 std::uintptr_t aligned = (pn + alignment - 1) & -alignment;
325 std::size_t padding = aligned - pn;
326 if(space < size + padding)
333 return ptr = reinterpret_cast<void *>(aligned);
337 template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
338 inline bool isfinite(T value)
340 return std::isfinite(value);
343 inline bool isfinite(half_float::half value)
345 return half_float::isfinite(value);
351 /** make_unique is missing in CPP11. Re-implement it according to the standard proposal. */
353 /**<Template for single object */
357 typedef std::unique_ptr<T> _Single_object; /**< Single object type */
360 /** Template for array */
362 struct _Unique_if<T[]>
364 typedef std::unique_ptr<T[]> _Unknown_bound; /**< Array type */
367 /** Template for array with known bounds (to throw an error).
369 * @note this is intended to never be hit.
371 template <class T, size_t N>
372 struct _Unique_if<T[N]>
374 typedef void _Known_bound; /**< Should never be used */
377 /** Construct a single object and return a unique pointer to it.
379 * @param[in] args Constructor arguments.
381 * @return a unique pointer to the new object.
383 template <class T, class... Args>
384 typename _Unique_if<T>::_Single_object
385 make_unique(Args &&... args)
387 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
390 /** Construct an array of objects and return a unique pointer to it.
392 * @param[in] n Array size
394 * @return a unique pointer to the new array.
397 typename _Unique_if<T>::_Unknown_bound
398 make_unique(size_t n)
400 typedef typename std::remove_extent<T>::type U;
401 return std::unique_ptr<T>(new U[n]());
404 /** It is invalid to attempt to make_unique an array with known bounds. */
405 template <class T, class... Args>
406 typename _Unique_if<T>::_Known_bound
407 make_unique(Args &&...) = delete;
409 } // namespace support
410 } // namespace arm_compute
411 #endif /* ARM_COMPUTE_TEST_TOOLCHAINSUPPORT */