blob: 4a2895088192dea39895ccf3b0e106a425c3ecca [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>
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010012concept has_member_reserve = requires(T t)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010013{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010014 t.reserve(size_t{});
Wludzik, Jozefe2362792020-10-27 17:23:55 +010015};
16
Wludzik, Jozefe2362792020-10-27 17:23:55 +010017} // namespace detail
18
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010019template <class R, class Container, class F>
20auto transform(const Container& container, F&& functor)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010021{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010022 auto result = R{};
Wludzik, Jozefe2362792020-10-27 17:23:55 +010023
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010024 if constexpr (detail::has_member_reserve<decltype(result)>)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010025 {
26 result.reserve(container.size());
27 }
28 std::transform(container.begin(), container.end(),
29 std::inserter(result, result.end()),
30 std::forward<F>(functor));
31 return result;
32}
33
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010034template <template <class, class...> class Container, class T, class... Args,
35 class F>
36auto transform(const Container<T, Args...>& container, F&& functor)
37{
38 using R = Container<decltype(functor(*container.begin()))>;
39 return transform<R>(container, std::forward<F>(functor));
40}
41
Wludzik, Jozefe2362792020-10-27 17:23:55 +010042} // namespace utils