Compute Library
 19.08
ToolchainSupport.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2019 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 <cassert>
29 #include <cmath>
30 #include <cstddef>
31 #include <limits>
32 #include <memory>
33 #include <numeric>
34 #include <sstream>
35 #include <string>
36 #include <type_traits>
37 
38 #include "support/Half.h"
39 
40 namespace arm_compute
41 {
42 namespace support
43 {
44 namespace cpp11
45 {
46 enum class NumericBase
47 {
48  BASE_10,
49  BASE_16
50 };
51 
63 inline int stoi(const std::string &str, std::size_t *pos = 0, NumericBase base = NumericBase::BASE_10)
64 {
65  assert(base == NumericBase::BASE_10 || base == NumericBase::BASE_16);
66  unsigned int x;
67  std::stringstream ss;
68  if(base == NumericBase::BASE_16)
69  {
70  ss << std::hex;
71  }
72  ss << str;
73  ss >> x;
74  return x;
75 }
76 
88 inline unsigned long stoul(const std::string &str, std::size_t *pos = 0, NumericBase base = NumericBase::BASE_10)
89 {
90  assert(base == NumericBase::BASE_10 || base == NumericBase::BASE_16);
91  std::stringstream stream;
92  unsigned long value = 0;
93  if(base == NumericBase::BASE_16)
94  {
95  stream << std::hex;
96  }
97  stream << str;
98  stream >> value;
99  return value;
100 }
101 
102 #if(__ANDROID__ || BARE_METAL)
103 
112 template <typename T, typename std::enable_if<std::is_arithmetic<typename std::decay<T>::type>::value, int>::type = 0>
113 inline std::string to_string(T && value)
114 {
115  std::stringstream stream;
116  stream << std::forward<T>(value);
117  return stream.str();
118 }
119 
129 template <typename T>
130 inline T nearbyint(T value)
131 {
132  return ::nearbyint(value);
133 }
134 
144 inline float stof(const std::string &str)
145 {
146  std::stringstream stream(str);
147  float value = 0.f;
148  stream >> value;
149  return value;
150 }
151 
161 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
162 inline T round(T value)
163 {
164  return ::round(value);
165 }
166 
176 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
177 inline T trunc(T value)
178 {
179  return ::trunc(value);
180 }
181 
192 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
193 inline T copysign(T x, T y)
194 {
195  return ::copysign(x, y);
196 }
197 
209 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
210 inline T fma(T x, T y, T z)
211 {
212  return ::fma(x, y, z);
213 }
214 
226 template <typename... Ts>
227 inline int snprintf(char *s, size_t n, const char *fmt, Ts &&... args)
228 {
229  return ::snprintf(s, n, fmt, std::forward<Ts>(args)...);
230 }
231 #else /* (__ANDROID__ || BARE_METAL) */
232 
241 template <typename T>
242 inline std::string to_string(T &&value)
243 {
244  return ::std::to_string(std::forward<T>(value));
245 }
246 
256 template <typename T>
257 inline T nearbyint(T value)
258 {
259  return std::nearbyint(value);
260 }
261 
271 template <typename... Ts>
272 int stof(Ts &&... args)
273 {
274  return ::std::stof(std::forward<Ts>(args)...);
275 }
276 
286 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
287 inline T round(T value)
288 {
289  //Workaround Valgrind's mismatches: when running from Valgrind the call to std::round(-4.500000) == -4.000000 instead of 5.00000
290  return (value < 0.f) ? static_cast<int>(value - 0.5f) : static_cast<int>(value + 0.5f);
291 }
292 
302 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
303 inline T trunc(T value)
304 {
305  return std::trunc(value);
306 }
307 
318 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
319 inline T copysign(T x, T y)
320 {
321  return std::copysign(x, y);
322 }
323 
335 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
336 inline T fma(T x, T y, T z)
337 {
338  return std::fma(x, y, z);
339 }
340 
352 template <typename... Ts>
353 inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args)
354 {
355  return std::snprintf(s, n, fmt, std::forward<Ts>(args)...);
356 }
357 #endif /* (__ANDROID__ || BARE_METAL) */
358 
359 inline std::string to_string(bool value)
360 {
361  std::stringstream str;
362  str << std::boolalpha << value;
363  return str.str();
364 }
365 
366 // std::align is missing in GCC 4.9
367 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350
368 inline void *align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
369 {
370  std::uintptr_t pn = reinterpret_cast<std::uintptr_t>(ptr);
371  std::uintptr_t aligned = (pn + alignment - 1) & -alignment;
372  std::size_t padding = aligned - pn;
373  if(space < size + padding)
374  {
375  return nullptr;
376  }
377 
378  space -= padding;
379 
380  return ptr = reinterpret_cast<void *>(aligned);
381 }
382 // std::numeric_limits<T>::lowest
383 template <typename T>
384 inline T lowest()
385 {
387 }
388 
389 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
390 template <>
391 inline __fp16 lowest<__fp16>()
392 {
394 }
395 #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
396 
397 // std::isfinite
398 template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
399 inline bool isfinite(T value)
400 {
401  return std::isfinite(value);
402 }
403 
404 inline bool isfinite(half_float::half value)
405 {
406  return half_float::isfinite(value);
407 }
408 } // namespace cpp11
409 
410 namespace cpp14
411 {
415 template <class T>
417 {
418  typedef std::unique_ptr<T> _Single_object;
419 };
420 
422 template <class T>
423 struct _Unique_if<T[]>
424 {
425  typedef std::unique_ptr<T[]> _Unknown_bound;
426 };
427 
432 template <class T, size_t N>
433 struct _Unique_if<T[N]>
434 {
435  typedef void _Known_bound;
436 };
437 
444 template <class T, class... Args>
446 make_unique(Args &&... args)
447 {
448  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
449 }
450 
457 template <class T>
458 typename _Unique_if<T>::_Unknown_bound
459 make_unique(size_t n)
460 {
461  typedef typename std::remove_extent<T>::type U;
462  return std::unique_ptr<T>(new U[n]());
463 }
464 
466 template <class T, class... Args>
467 typename _Unique_if<T>::_Known_bound
468 make_unique(Args &&...) = delete;
469 } // namespace cpp14
470 } // namespace support
471 } // namespace arm_compute
472 #endif /* ARM_COMPUTE_TEST_TOOLCHAINSUPPORT */
unsigned long stoul(const std::string &str, std::size_t *pos=0, NumericBase base=NumericBase::BASE_10)
Convert string values to unsigned long.
std::string to_string(bool value)
T trunc(T value)
Truncate floating-point value.
T copysign(T x, T y)
Composes a floating point value with the magnitude of x and the sign of y.
T nearbyint(T value)
Rounds the floating-point argument arg to an integer value in floating-point format,...
std::string to_string(T &&value)
Convert integer and float values to string.
half_float::half half
16-bit floating point type
Definition: Types.h:44
make_unique is missing in CPP11.
Copyright (c) 2017-2018 ARM Limited.
std::unique_ptr< T > _Single_object
Single object type.
_Unique_if< T >::_Single_object make_unique(Args &&... args)
Construct a single object and return a unique pointer to it.
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
int stoi(const std::string &str, std::size_t *pos=0, NumericBase base=NumericBase::BASE_10)
Convert string values to integer.
T fma(T x, T y, T z)
Computes (x*y) + z as if to infinite precision and rounded only once to fit the result type.
T round(T value)
Round floating-point value with half value rounding away from zero.
int stof(Ts &&... args)
Convert string values to float.
std::unique_ptr< T[]> _Unknown_bound
Array type.
bool isfinite(half_float::half value)
int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args)
Loads the data from the given location, converts them to character string equivalents and writes the ...