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