Utilities.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <boost/iterator/iterator_adaptor.hpp>
5 #include <boost/type_traits/remove_cv.hpp>
6 #include <boost/variant/get.hpp>
7 #include <memory>
8 #include <numeric>
9 #include <type_traits>
10 #include <vector>
11 
12 #include "lanelet2_core/Forward.h"
14 
15 namespace lanelet {
16 
17 namespace utils {
22 template <typename Range, typename Func>
23 auto sum(Range&& r, Func f);
24 
25 namespace detail {
26 template <bool Move>
27 struct MoveIf {};
28 
29 template <>
30 struct MoveIf<true> {
31  template <typename Iter>
32  auto operator()(Iter it) {
33  return std::make_move_iterator(it);
34  }
35 };
36 
37 template <>
38 struct MoveIf<false> {
39  template <typename Iter>
40  auto operator()(Iter it) {
41  return it;
42  }
43 };
44 
45 template <typename ContainerT>
47  void operator()(ContainerT& /*c*/, size_t /*size*/) const {}
48 };
49 
50 template <typename T>
51 struct ReserveIfNecessary<std::vector<T>> {
52  void operator()(std::vector<T>& c, size_t size) const { c.reserve(size); }
53 };
54 
55 template <typename VectorT>
56 inline VectorT createReserved(size_t size) {
57  VectorT vector;
58  ReserveIfNecessary<VectorT>()(vector, size);
59  return vector;
60 }
61 
62 template <typename VectorT, typename ContainerT>
63 VectorT concatenate(ContainerT&& c) {
64  VectorT conced;
65  const auto size = sum(c, [](auto& elem) { return elem.size(); });
66  ReserveIfNecessary<VectorT>()(conced, size);
68  for (auto& elem : c) {
69  conced.insert(conced.end(), move(elem.begin()), move(elem.end()));
70  }
71  return conced;
72 }
73 
74 template <typename VectorT, typename ContainerT, typename Func>
75 VectorT concatenate(ContainerT&& c, Func f) {
76  VectorT conced;
77  MoveIf<true> move;
78  for (auto& elem : c) {
79  auto value = f(elem);
80  conced.insert(conced.end(), move(value.begin()), move(value.end()));
81  }
82  return conced;
83 }
84 
85 template <typename ContainerT, typename Func>
86 auto concatenateRange(ContainerT&& c, Func f) {
87  auto size = sum(c, [f](auto&& elem) {
88  auto range = f(elem);
89  return std::distance(range.first, range.second);
90  });
91  using RetT = typename decltype(f(*c.begin()).first)::value_type;
92  std::vector<RetT> ret;
93  ret.reserve(size);
95  for (auto&& elem : c) {
96  auto range = f(elem);
97  ret.insert(ret.end(), move(range.first), move(range.second));
98  }
99  return ret;
100 }
101 
102 template <typename ContainerT, typename Func, typename AllocatorT>
103 auto concatenateRange(ContainerT&& c, Func f, const AllocatorT& alloc) {
104  auto size = sum(c, [f](auto&& elem) {
105  auto range = f(elem);
106  return std::distance(range.first, range.second);
107  });
108  using RetT = typename decltype(f(*c.begin()).first)::value_type;
109  std::vector<RetT, AllocatorT> ret(alloc);
110  ret.reserve(size);
112  for (auto&& elem : c) {
113  auto range = f(elem);
114  ret.insert(ret.end(), move(range.first), move(range.second));
115  }
116  return ret;
117 }
118 
119 template <typename Container, typename Func>
120 auto transform(Container&& c, Func f) {
121  using RetT = std::decay_t<decltype(f(*c.begin()))>;
122  std::vector<RetT> transformed;
123  transformed.reserve(c.size());
124  std::transform(c.begin(), c.end(), std::back_inserter(transformed), f);
125  return transformed;
126 }
127 } // namespace detail
128 
130 
132 template <typename PrimitiveT>
133 constexpr bool idLess(const PrimitiveT& p1, const PrimitiveT& p2) {
134  return p1.id() < p2.id();
135 }
136 
138 template <typename T>
139 struct IdLess {
140  constexpr bool operator()(const T& a, const T& b) { return idLess(a, b); }
141 };
142 
143 template <typename T1, typename T2>
144 inline auto orderedPair(T1& first, T2& second) {
145  return (first.id() < second.id()) ? std::make_pair(first, second) : std::make_pair(second, first);
146 }
147 
148 template <class T>
149 const T& addConst(T& t) {
150  return t;
151 }
152 
153 template <class T>
154 std::shared_ptr<const T> addConst(std::shared_ptr<T> t) {
155  return std::const_pointer_cast<const T>(t);
156 }
157 
158 template <class T>
159 std::shared_ptr<T> removeConst(std::shared_ptr<const T> t) {
160  return std::const_pointer_cast<T>(t);
161 }
162 
163 template <class T>
164 T& removeConst(const T& t) {
165  return const_cast<T&>(t); // NOLINT
166 }
167 
168 template <typename Container>
169 Container invert(const Container& cont) {
170  Container cOut;
171  std::reverse_copy(cont.begin(), cont.end(), std::back_inserter(cOut));
172  return cOut;
173 }
174 
175 template <typename Iterator, typename Func>
176 auto transform(Iterator begin, Iterator end, const Func f) {
177  using ValueT = decltype(*begin);
178  using RetT = std::decay_t<decltype(f(*begin))>;
179  std::vector<RetT> transformed;
180  transformed.reserve(std::distance(begin, end));
181  std::transform(begin, end, std::back_inserter(transformed), [&f](ValueT elem) { return f(elem); });
182  return transformed;
183 }
184 
185 template <typename ContainerT, typename ValueT>
186 auto find(ContainerT&& c, const ValueT& val) {
188  auto it = std::find(std::begin(c), std::end(c), val);
189  if (it != std::end(c)) {
190  return RetT(*it);
191  }
192  return RetT();
193 }
194 
195 template <typename ContainerT, typename Func>
196 auto findIf(ContainerT&& c, Func f) {
198  auto it = std::find_if(std::begin(c), std::end(c), f);
199  if (it != std::end(c)) {
200  return RetT(*it);
201  }
202  return RetT();
203 }
204 
205 template <typename Container, typename Func>
206 auto transform(Container&& c, Func f) {
207  return detail::transform(std::forward<Container>(c), f);
208 }
209 
210 template <typename T, typename Func>
211 auto transform(std::initializer_list<T>&& c, Func f) {
212  return detail::transform(std::move(c), f);
213 }
214 
215 template <typename Container, typename Predicate>
216 bool anyOf(const Container& c, Predicate&& p) {
217  return std::any_of(c.begin(), c.end(), p);
218 }
219 
220 template <typename Container, typename Value>
221 bool contains(const Container& c, const Value& v) {
222  return std::find(c.begin(), c.end(), v) != c.end();
223 }
224 
225 template <typename Container, typename Func>
226 void forEach(Container&& c, Func&& f) {
227  std::for_each(c.begin(), c.end(), std::forward<Func>(f));
228 }
229 
230 template <typename OutT, typename InT>
231 auto transformSharedPtr(const std::vector<std::shared_ptr<InT>>& v) {
232  std::vector<std::shared_ptr<OutT>> transformed;
233  transformed.reserve(v.size());
234  for (const auto& elem : v) {
235  auto cast = std::dynamic_pointer_cast<OutT>(elem);
236  if (cast) {
237  transformed.push_back(std::move(cast));
238  }
239  }
240  return transformed;
241 }
242 
247 template <typename Range, typename Func>
248 auto sum(Range&& r, Func f) {
249  using ValT = decltype(f(*std::begin(r)));
250  return std::accumulate(std::begin(r), std::end(r), ValT(), [&f](auto v, auto&& elem) { return v + f(elem); });
251 }
252 
259 template <typename ContainerT>
260 auto concatenate(ContainerT&& c) {
261  using VectorT = std::decay_t<decltype(*std::begin(c))>;
262  return detail::concatenate<VectorT>(std::forward<ContainerT>(c));
263 }
264 
265 template <typename T>
266 auto concatenate(std::initializer_list<T>&& c) {
267  using VectorT = std::decay_t<decltype(*std::begin(c))>;
268  return detail::concatenate<VectorT>(std::move(c));
269 }
270 
275 template <typename ContainerT, typename Func>
276 auto concatenate(ContainerT&& c, Func f) {
277  using VectorT = std::decay_t<decltype(f(*c.begin()))>;
278  return detail::concatenate<VectorT>(std::forward<ContainerT>(c), f);
279 }
280 
281 template <typename T, typename Func>
282 auto concatenate(std::initializer_list<T>&& c, Func f) {
283  using VectorT = std::decay_t<decltype(f(*c.begin()))>;
284  return detail::concatenate<VectorT>(std::move(c), f);
285 }
286 
294 template <typename ContainerT, typename Func>
295 auto concatenateRange(ContainerT&& c, Func f) {
296  return detail::concatenateRange(std::forward<ContainerT>(c), f);
297 }
298 
299 template <typename T, typename Func>
300 auto concatenateRange(std::initializer_list<T>&& c, Func f) {
301  return detail::concatenateRange(std::move(c), f);
302 }
303 
305 template <typename ContainerT, typename Func, typename AllocatorT>
306 auto concatenateRange(ContainerT&& c, Func f, const AllocatorT& alloc) {
307  return detail::concatenateRange(std::forward<ContainerT>(c), f, alloc);
308 }
309 
310 template <typename T, typename Func, typename AllocatorT>
311 auto concatenateRange(std::initializer_list<T>&& c, Func f, const AllocatorT& alloc) {
312  return detail::concatenateRange(std::move(c), f, alloc);
313 }
314 
315 template <typename T, typename Variant>
316 std::vector<T> getVariant(const std::vector<Variant>& v) {
317  std::vector<T> s;
318  s.reserve(v.size());
319  for (const auto& e : v) {
320  const auto* t = boost::get<typename T::MutableType>(&e);
321  if (t) {
322  s.push_back(*t);
323  }
324  }
325  return s;
326 }
327 
332 constexpr bool strequal(char const* lhs, char const* rhs) {
333  while (*lhs != 0 && *rhs != 0) {
334  if (*lhs++ != *rhs++) { // NOLINT
335  return false;
336  }
337  }
338  return *lhs == 0 && *rhs == 0;
339 }
340 
346 template <typename WeakT>
347 auto strong(std::vector<WeakT> v) {
348  std::vector<decltype(v.front().lock())> s;
349  s.reserve(v.size());
350  for (const auto& e : v) {
351  if (!e.expired()) {
352  s.push_back(e.lock());
353  }
354  }
355  return s;
356 }
357 
359 inline bool nearZero(double d) { return std::abs(d) < 1e-8; }
360 
361 } // namespace utils
362 
363 namespace internal {
364 // See
365 // https://stackoverflow.com/questions/765148/how-to-remove-constness-of-const-iterator
366 template <typename Container, typename ConstIterator>
367 typename Container::iterator removeConst(Container& c, ConstIterator it) {
368  return c.erase(it, it);
369 }
370 } // namespace internal
371 } // namespace lanelet
BasicPoint p
VectorT createReserved(size_t size)
Definition: Utilities.h:56
auto find(ContainerT &&c, const ValueT &val)
Definition: Utilities.h:186
auto orderedPair(T1 &first, T2 &second)
Definition: Utilities.h:144
constexpr bool strequal(char const *lhs, char const *rhs)
compares two c-strings at compile time. Do not use this for run time.
Definition: Utilities.h:332
VectorT concatenate(ContainerT &&c)
Definition: Utilities.h:63
auto concatenateRange(ContainerT &&c, Func f)
Definition: Utilities.h:86
auto strong(std::vector< WeakT > v)
transforms a vector of weak_ptrs to a vector of shared_ptrs
Definition: Utilities.h:347
Compares ids of primitives. Can be used for some sorted stl containers.
Definition: Utilities.h:139
auto transformSharedPtr(const std::vector< std::shared_ptr< InT >> &v)
Definition: Utilities.h:231
BasicPoint p2
auto transform(std::initializer_list< T > &&c, Func f)
Definition: Utilities.h:211
void forEach(Container &&c, Func &&f)
Definition: Utilities.h:226
std::vector< T > getVariant(const std::vector< Variant > &v)
Definition: Utilities.h:316
boost::optional< T > Optional
Definition: Optional.h:7
constexpr bool operator()(const T &a, const T &b)
Definition: Utilities.h:140
void operator()(ContainerT &, size_t) const
Definition: Utilities.h:47
std::shared_ptr< T > removeConst(std::shared_ptr< const T > t)
Definition: Utilities.h:159
Optional< double > distance
const T & addConst(T &t)
Definition: Utilities.h:149
auto transform(Container &&c, Func f)
Definition: Utilities.h:120
BasicPoint p1
constexpr bool idLess(const PrimitiveT &p1, const PrimitiveT &p2)
Compares ids of primitives. Can be used for some stl algorithms.
Definition: Utilities.h:133
bool contains(const Container &c, const Value &v)
Definition: Utilities.h:221
auto findIf(ContainerT &&c, Func f)
Definition: Utilities.h:196
auto sum(Range &&r, Func f)
Wrapper around std::accumulate for summing up the result of Func over a range.
Definition: Utilities.h:248
void operator()(std::vector< T > &c, size_t size) const
Definition: Utilities.h:52
bool anyOf(const Container &c, Predicate &&p)
Definition: Utilities.h:216
bool nearZero(double d)
Tests if a double is close to zero within a small margin.
Definition: Utilities.h:359
Container invert(const Container &cont)
Definition: Utilities.h:169


lanelet2_core
Author(s): Fabian Poggenhans
autogenerated on Tue Jun 6 2023 02:23:32