blob: b354b0f63f9bbe3b70c237f42f764134b117e34e [file] [log] [blame]
Wludzik, Jozefe2362792020-10-27 17:23:55 +01001#pragma once
2
3#include <algorithm>
4#include <iterator>
5
6namespace utils
7{
8namespace detail
9{
10
11template <class T>
12struct has_member_reserve
13{
14 template <class U>
15 static U& ref();
16
17 template <class U>
18 static std::true_type check(decltype(ref<U>().reserve(size_t{}))*);
19
20 template <class>
21 static std::false_type check(...);
22
23 static constexpr bool value =
24 decltype(check<std::decay_t<T>>(nullptr))::value;
25};
26
27template <class T>
28constexpr bool has_member_reserve_v = has_member_reserve<T>::value;
29
30} // namespace detail
31
32template <template <class, class...> class Container, class T, class... Args,
33 class F>
34auto transform(const Container<T, Args...>& container, F&& functor)
35{
36 using R = decltype(functor(*container.begin()));
37
38 Container<R> result;
39 if constexpr (detail::has_member_reserve_v<Container<T, Args...>>)
40 {
41 result.reserve(container.size());
42 }
43 std::transform(container.begin(), container.end(),
44 std::inserter(result, result.end()),
45 std::forward<F>(functor));
46 return result;
47}
48
49} // namespace utils