Compute Library
 23.05
Utility.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021, 2023 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_MISC_UTILITY_H
25 #define ARM_COMPUTE_MISC_UTILITY_H
26 
27 #include "arm_compute/core/Error.h"
28 
29 #include <algorithm>
30 #include <array>
31 #include <cstdint>
32 #include <limits>
33 #include <numeric>
34 #include <vector>
35 
36 namespace arm_compute
37 {
38 namespace utility
39 {
40 /** @cond */
41 template <std::size_t...>
42 struct index_sequence
43 {
44 };
45 
46 template <std::size_t N, std::size_t... S>
47 struct index_sequence_generator : index_sequence_generator < N - 1, N - 1, S... >
48 {
49 };
50 
51 template <std::size_t... S>
52 struct index_sequence_generator<0u, S...> : index_sequence<S...>
53 {
54  using type = index_sequence<S...>;
55 };
56 
57 template <std::size_t N>
58 using index_sequence_t = typename index_sequence_generator<N>::type;
59 
60 template <typename T, std::size_t N, T val, T... vals>
61 struct generate_array : generate_array < T, N - 1, val, val, vals... >
62 {
63 };
64 
65 template <typename T, T val, T... vals>
66 struct generate_array<T, 0, val, vals...>
67 {
68  static constexpr std::array<T, sizeof...(vals)> value{ vals... };
69 };
70 
71 template <typename T, T val, T... vals>
72 constexpr std::array<T, sizeof...(vals)> generate_array<T, 0, val, vals...>::value;
73 /** @endcond */
74 
75 namespace detail
76 {
77 template <std::size_t... S,
78  typename Iterator,
79  typename T = std::array<typename std::iterator_traits<Iterator>::value_type, sizeof...(S)>>
80 T make_array(Iterator first, index_sequence<S...>)
81 {
82  return T{ { first[S]... } };
83 }
84 } // namespace detail
85 
86 template <std::size_t N, typename Iterator>
87 std::array<typename std::iterator_traits<Iterator>::value_type, N> make_array(Iterator first, Iterator last)
88 {
89  ARM_COMPUTE_UNUSED(last);
90  return detail::make_array(first, index_sequence_t<N> {});
91 }
92 
93 /** Performs clamping among a lower and upper value.
94  *
95  * @param[in] n Value to clamp.
96  * @param[in] lower Lower threshold.
97  * @param[in] upper Upper threshold.
98  *
99  * @return Clamped value.
100  */
101 template <typename DataType, typename RangeType = DataType>
102 inline DataType clamp(const DataType &n,
104  const DataType &upper = std::numeric_limits<RangeType>::max())
105 {
106  return std::max(lower, std::min(n, upper));
107 }
108 
109 /** Base case of for_each. Does nothing. */
110 template <typename F>
111 inline void for_each(F &&)
112 {
113 }
114 
115 /** Call the function for each of the arguments
116  *
117  * @param[in] func Function to be called
118  * @param[in] arg Argument passed to the function
119  * @param[in] args Remaining arguments
120  */
121 template <typename F, typename T, typename... Ts>
122 inline void for_each(F &&func, T &&arg, Ts &&... args)
123 {
124  func(std::forward<T>(arg));
125  for_each(std::forward<F>(func), std::forward<Ts>(args)...);
126 }
127 
128 /** Base case of foldl.
129  *
130  * @return value.
131  */
132 template <typename F, typename T>
133 inline T &&foldl(F &&, T &&value)
134 {
135  return std::forward<T>(value);
136 }
137 
138 /** Fold left.
139  *
140  * @param[in] func Function to be called
141  * @param[in] initial Initial value
142  * @param[in] value Argument passed to the function
143  * @param[in] values Remaining arguments
144  */
145 template <typename F, typename T, typename U, typename... Us>
146 inline auto foldl(F &&func, T &&initial, U &&value, Us &&... values) -> decltype(func(std::forward<T>(initial), std::forward<U>(value)))
147 {
148  return foldl(std::forward<F>(func), func(std::forward<T>(initial), std::forward<U>(value)), std::forward<Us>(values)...);
149 }
150 
151 /** Perform an index sort of a given vector.
152  *
153  * @param[in] v Vector to sort
154  *
155  * @return Sorted index vector.
156  */
157 template <typename T>
158 std::vector<size_t> sort_indices(const std::vector<T> &v)
159 {
160  std::vector<size_t> idx(v.size());
161  std::iota(idx.begin(), idx.end(), 0);
162 
163  std::sort(idx.begin(), idx.end(),
164  [&v](size_t i1, size_t i2)
165  {
166  return v[i1] < v[i2];
167  });
168 
169  return idx;
170 }
171 
172 /** Checks if a string contains a given suffix
173  *
174  * @param[in] str Input string
175  * @param[in] suffix Suffix to check for
176  *
177  * @return True if the string ends with the given suffix else false
178  */
179 inline bool endswith(const std::string &str, const std::string &suffix)
180 {
181  if(str.size() < suffix.size())
182  {
183  return false;
184  }
185  return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
186 }
187 
188 /** Checks if a pointer complies with a given alignment
189  *
190  * @param[in] ptr Pointer to check
191  * @param[in] alignment Alignment value
192  *
193  * @return True if the pointer is aligned else false
194  */
195 inline bool check_aligned(void *ptr, const size_t alignment)
196 {
197  return (reinterpret_cast<std::uintptr_t>(ptr) % alignment) == 0;
198 }
199 
200 /** Convert string to lower case.
201  *
202  * @param[in] string To be converted string.
203  *
204  * @return Lower case string.
205  */
206 inline std::string tolower(std::string string)
207 {
208  std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c)
209  {
210  return std::tolower(c);
211  });
212  return string;
213 }
214 
215 /** Get environment variable as a string
216  *
217  * @note Return empty string on bare-metal
218  *
219  * @param[in] env_name Name of the Environment variable to retrieve
220  *
221  * @return Environment variable content, or empty string if the variable is undefined or on bare-metal
222  */
223 inline std::string getenv(const std::string &env_name)
224 {
225 #ifdef BARE_METAL
226  ARM_COMPUTE_UNUSED(env_name);
227  return std::string{};
228 #else // BARE_METAL
229  const auto env_chr = std::getenv(env_name.c_str());
230  return env_chr == nullptr ? std::string{} : std::string{ env_chr };
231 #endif // BARE_METAL
232 }
233 } // namespace utility
234 } // namespace arm_compute
235 #endif /* ARM_COMPUTE_MISC_UTILITY_H */
std::string getenv(const std::string &env_name)
Get environment variable as a string.
Definition: Utility.h:223
decltype(strategy::transforms) typedef type
Copyright (c) 2017-2023 Arm Limited.
DataType clamp(const DataType &n, const DataType &lower=std::numeric_limits< RangeType >::lowest(), const DataType &upper=std::numeric_limits< RangeType >::max())
Performs clamping among a lower and upper value.
Definition: Utility.h:102
bool endswith(const std::string &str, const std::string &suffix)
Checks if a string contains a given suffix.
Definition: Utility.h:179
std::string tolower(std::string string)
Convert string to lower case.
Definition: Utility.h:206
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
T && foldl(F &&, T &&value)
Base case of foldl.
Definition: Utility.h:133
unsigned int N
void end(TokenStream &in, bool &valid)
Definition: MLGOParser.cpp:290
void for_each(F &&)
Base case of for_each.
Definition: Utility.h:111
T make_array(Iterator first, index_sequence< S... >)
Definition: Utility.h:80
Iterator updated by execute_window_loop for each window element.
Definition: Helpers.h:46
DataType
Available data types.
Definition: Types.h:79
std::array< typename std::iterator_traits< Iterator >::value_type, N > make_array(Iterator first, Iterator last)
Definition: Utility.h:87
std::vector< size_t > sort_indices(const std::vector< T > &v)
Perform an index sort of a given vector.
Definition: Utility.h:158
bool check_aligned(void *ptr, const size_t alignment)
Checks if a pointer complies with a given alignment.
Definition: Utility.h:195