algorithm.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu)
20 * @date 2016
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#pragma once
25
26#include <algorithm>
27#include <map>
28#include <numeric>
29#include <unordered_map>
30#include <vector>
31
33
34namespace armarx
35{
36 /**
37 * @brief Uses the range of indices to copy values (accessed via src.at())from the given container into the output iterator.
38 *
39 * This function e.g. is useful if you have a map of joint values and need a specific subset 'idx' as vector of floats.
40 * \code
41 * std::vector<int> idx = {0,1,3};
42 *
43 * std::vector<long> srcV={0,10,20,30,40,50};
44 * std::vector<long> fromVec;
45 * copyValuesAt(srcV, idx.begin(), idx.end(), std::back_inserter(fromVec));
46 * //fromVec == {0, 10, 30}
47 *
48 * std::map<int, long> srcM={{0,0},{1,10},{2,20},{3,30},{4,40},{5,50}};
49 * std::vector<long> fromMap;
50 * copyValuesAt(srcM, idx.begin(), idx.end(), std::back_inserter(fromMap));
51 * //fromMap == {0, 10, 30}
52 * \endcode
53 */
54 template <class ContainerT,
55 class IndexIteratorT,
56 class OutputIteratorT,
57 class IndexT = typename std::iterator_traits<IndexIteratorT>::value_type>
58 void
59 copyValuesAt(const ContainerT& src,
60 IndexIteratorT fst,
61 IndexIteratorT lst,
62 OutputIteratorT dest)
63 {
64 std::transform(fst, lst, dest, [&src](const IndexT& i) { return src.at(i); });
65 }
66
67 /**
68 * @brief Uses the container of indices to copy values (accessed via src.at())from the given container into the output iterator.
69 *
70 * This function e.g. is useful if you have a map of joint values and need a specific subset 'idx' as vector of floats.
71 * \code
72 * std::vector<int> idx = {0,1,3};
73 *
74 * std::vector<long> srcV={0,10,20,30,40,50};
75 * std::vector<long> fromVec;
76 * copyValuesAt(srcV, idx, std::back_inserter(fromVec));
77 * //fromVec == {0, 10, 30}
78 *
79 * std::map<int, long> srcM={{0,0},{1,10},{2,20},{3,30},{4,40},{5,50}};
80 * std::vector<long> fromMap;
81 * copyValuesAt(srcM, idx, std::back_inserter(fromMap));
82 * //fromMap == {0, 10, 30}
83 * \endcode
84 */
85 template <class ContainerT,
86 class IndexContainerT,
87 class OutputIteratorT,
88 class IndexT = typename IndexContainerT::value_type>
89 void
90 copyValuesAt(const ContainerT& src, const IndexContainerT& idx, OutputIteratorT dest)
91 {
92 copyValuesAt(src, idx.begin(), idx.end(), dest);
93 }
94
95 /**
96 * @brief Uses the range of indices to copy values (accessed via src.at())from the given container into a vector and returns his vector.
97 *
98 * This function e.g. is useful if you have a map of joint values and need a specific subset 'idx' as vector of floats.
99 * \code
100 * std::vector<int> idx = {0,1,3};
101 *
102 * std::vector<long> srcV={0,10,20,30,40,50};
103 * std::vector<long> fromVec = copyValuesAt(srcV, idx.begin(), idx.end());
104 * //fromVec == {0, 10, 30}
105 *
106 * std::map<int, long> srcM={{0,0},{1,10},{2,20},{3,30},{4,40},{5,50}};
107 * std::vector<long> fromMap = copyValuesAt(srcM, idx.begin(), idx.end());
108 * //fromMap == {0, 10, 30}
109 * \endcode
110 */
111 template <class ContainerT,
112 class IndexIteratorT,
113 class IndexT = typename std::iterator_traits<IndexIteratorT>::value_type>
114 std::vector<typename ContainerT::value_type>
115 copyValuesAt(const ContainerT& src, IndexIteratorT fst, IndexIteratorT lst)
116 {
117 std::vector<typename ContainerT::value_type> result;
118 result.reserve(std::distance(fst, lst));
119 copyValuesAt(src, std::move(fst), std::move(lst), std::back_inserter(result));
120 return result;
121 }
122
123 /**
124 * @brief Uses the container of indices to copy values (accessed via src.at()) from the given container into a vector and returns his vector.
125 *
126 * This function e.g. is useful if you have a map of joint values and need a specific subset 'idx' as vector of floats.
127 * \code
128 * std::vector<int> idx = {0,1,3};
129 *
130 * std::vector<long> srcV={0,10,20,30,40,50};
131 * std::vector<long> fromVec = copyValuesAt(srcV, idx);
132 * //fromVec == {0, 10, 30}
133 *
134 * std::map<int, long> srcM={{0,0},{1,10},{2,20},{3,30},{4,40},{5,50}};
135 * std::vector<long> fromMap = copyValuesAt(srcM, idx);
136 * //fromMap == {0, 10, 30}
137 * \endcode
138 */
139 template <class ContainerT,
140 class IndexContainerT,
141 class IndexT = typename IndexContainerT::value_type>
142 std::vector<typename ContainerT::value_type>
143 copyValuesAt(const ContainerT& src, const IndexContainerT& idx)
144 {
145 return copyValuesAt(src, idx.begin(), idx.end());
146 }
147
148 /**
149 * @brief This function takes a container (e.g. a vector) of unique elements and returns a map mapping the elements to their corresponding index
150 * @param Container of unique elements (needs index access via at)
151 * @return index map
152 */
153 template <class T,
154 class MapType = std::unordered_map<typename T::value_type, typename T::size_type>>
155 MapType
156 toIndexMap(const T& vec)
157 {
158 MapType result;
159 result.reserve(vec.size());
160 for (typename T::size_type i = 0; i < vec.size(); ++i)
161 {
162 auto emplacement = result.emplace(vec.at(i), i).second;
163 if (!emplacement)
164 {
165 throw std::invalid_argument{"The given container did not contain unique elements!"};
166 }
167 }
168 return result;
169 }
170
171 template <class MapType, class OutputIteratorType>
172 void
173 getMapKeys(const MapType& map, OutputIteratorType it)
174 {
175 for (const auto& e : map)
176 {
177 *it = e.first;
178 ++it;
179 }
180 }
181
182 template <class MapType>
183 std::vector<typename MapType::key_type>
184 getMapKeys(const MapType& map)
185 {
186 std::vector<typename MapType::key_type> result;
187 result.reserve(map.size());
188 getMapKeys(map, std::back_inserter(result));
189 return result;
190 }
191
192 template <class MapType, class OutputIteratorType>
193 void
194 getMapValues(const MapType& map, OutputIteratorType it)
195 {
196 for (const auto& e : map)
197 {
198 *it = e.second;
199 ++it;
200 }
201 }
202
203 template <class MapType, template <class...> class ContainerT = std::vector>
204 ContainerT<typename MapType::mapped_type>
205 getMapValues(const MapType& map)
206 {
207 ContainerT<typename MapType::mapped_type> result;
208 getMapValues(map, std::inserter(result, result.end()));
209 return result;
210 }
211
212 template <class T>
213 T
215 {
216 return t < 0 ? -1 : 1;
217 }
218
219 /**
220 * @brief Increment all given parameter using the pre-increment operator.
221 */
222 inline void
224 {
225 }
226
227 template <typename It0, typename... It>
228 void
229 incrementAll(It0& it0, It&... it)
230 {
231 ++it0;
232 incrementAll(it...);
233 }
234
235
242
243 /**
244 * Inserts and overwrites the values from oldMap with the values from newMap.
245 * Template parameter T needs to be a map-container value like std::map.
246 */
247 template <typename T>
248 void
249 mergeMaps(T& oldMap,
250 const T& newMap,
252 {
253 //we can't annotate fallthrough as ok (we need a newer compiler)
254#pragma GCC diagnostic push
255#if __GNUC__ > 4
256#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
257#endif
258 switch (mergeMode)
259 {
261 for (auto& elem : newMap)
262 {
263 if (oldMap.count(elem.first))
264 {
265 throw std::invalid_argument{
266 "mergeMaps: newMap would override values from oldMap"};
267 }
268 }
269 //all ok -> fall through
271 for (auto& elem : newMap)
272 {
273 oldMap[elem.first] = elem.second;
274 }
275 break;
277 for (auto& elem : newMap)
278 {
279 oldMap.emplace(elem);
280 }
281 break;
282 }
283#pragma GCC diagnostic pop
284 }
285
286 template <class MapInT, class TransformT, class MapOutT = MapInT>
287 void
288 transformMapKeys(const MapInT& inMap, MapOutT& outMap, TransformT transform)
289 {
290 for (const auto& elem : inMap)
291 {
292 outMap[transform(elem.first)] = elem.second;
293 }
294 }
295
296 template <class MapInT, class TransformT, class MapOutT = MapInT>
297 MapOutT
298 transformMapKeys(const MapInT& inMap, TransformT transform)
299 {
300 MapOutT out;
301 transformMapKeys(inMap, out, transform);
302 return out;
303 }
304
305 template <class KeyT, class ValT>
306 std::vector<KeyT>
307 getIndices(const std::map<KeyT, ValT>& c)
308 {
309 return getMapKeys(c);
310 }
311
312 template <class KeyT, class ValT>
313 std::vector<KeyT>
314 getIndices(const std::unordered_map<KeyT, ValT>& c)
315 {
316 return getMapKeys(c);
317 }
318
319 template <class ValT>
320 std::vector<std::size_t>
321 getIndices(const std::vector<ValT>& c)
322 {
323 std::vector<std::size_t> r(c.size()); // don't use uniform initialization here!
324 std::iota(r.begin(), r.end(), 0);
325 return r;
326 }
327
328 template <class ContainerType, class ElementType>
329 bool
330 Contains(const ContainerType& container, const ElementType& searchElement)
331 {
332 return std::find(container.begin(), container.end(), searchElement) != container.end();
333 }
334
335 /**
336 * Convenience function (with less typing) to transform a container of type InputT into the same container type of type OutputT.
337 *
338 * Example usage:
339 * <code>
340 * std::vector<int> values = {1,2,3};
341 * auto stringValues = transform(values, +[](const int& v)
342 * {
343 * return std::to_string(v);
344 * };
345 * // stringValues == {"1","2","3"}
346 * </code>
347 * \note Do not forget the + in front of the lambda!
348 */
349 template <class OutputT, class InputT, typename Alloc, template <class, class> class Container>
350 auto
351 transform(const Container<InputT, Alloc>& in, OutputT (*func)(InputT const&))
352 -> Container<OutputT, typename std::allocator_traits<Alloc>::template rebind_alloc<OutputT>>
353 {
354 Container<OutputT, typename std::allocator_traits<Alloc>::template rebind_alloc<OutputT>>
355 result;
356 result.reserve(in.size());
357 std::transform(in.begin(), in.end(), std::back_inserter(result), func);
358 return result;
359 }
360} // namespace armarx
361
362namespace std
363{
364 template <class T, class... Ts>
365 bool
366 isfinite(const std::vector<T, Ts...>& v)
367 {
368 return std::all_of(v.begin(), v.end(), [](const T& t) { return isfinite(t); });
369 }
370} // namespace std
constexpr T c
This file offers overloads of toIce() and fromIce() functions for STL container types.
void transformMapKeys(const MapInT &inMap, MapOutT &outMap, TransformT transform)
Definition algorithm.h:288
MapType toIndexMap(const T &vec)
This function takes a container (e.g.
Definition algorithm.h:156
void copyValuesAt(const ContainerT &src, IndexIteratorT fst, IndexIteratorT lst, OutputIteratorT dest)
Uses the range of indices to copy values (accessed via src.at())from the given container into the out...
Definition algorithm.h:59
MergeMapsMode
Definition algorithm.h:237
std::vector< KeyT > getIndices(const std::map< KeyT, ValT > &c)
Definition algorithm.h:307
void incrementAll()
Increment all given parameter using the pre-increment operator.
Definition algorithm.h:223
void mergeMaps(T &oldMap, const T &newMap, MergeMapsMode mergeMode=MergeMapsMode::OverrideOldValues)
Inserts and overwrites the values from oldMap with the values from newMap.
Definition algorithm.h:249
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition algorithm.h:351
ElementTypes::ElementType ElementType
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition algorithm.h:173
T sign(T t)
Definition algorithm.h:214
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition algorithm.h:330
void getMapValues(const MapType &map, OutputIteratorType it)
Definition algorithm.h:194
bool isfinite(const std::vector< T, Ts... > &v)
Definition algorithm.h:366