blob: 7b3e33ae9a089d036ea25f55725f482843a3f2f0 [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>
Szymon Dompke7e114c02022-10-13 18:15:23 +020012concept has_member_reserve = requires(T t) { t.reserve(size_t{}); };
Wludzik, Jozefe2362792020-10-27 17:23:55 +010013
Wludzik, Jozefe2362792020-10-27 17:23:55 +010014} // namespace detail
15
Szymon Dompkefdb06a12022-02-11 11:04:44 +010016template <template <class, class...> class R, class Container, class Functor>
17inline auto transform(const Container& container, Functor&& f)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010018{
Szymon Dompkefdb06a12022-02-11 11:04:44 +010019 auto result = R<decltype(f(*container.begin()))>{};
Wludzik, Jozefe2362792020-10-27 17:23:55 +010020
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010021 if constexpr (detail::has_member_reserve<decltype(result)>)
Wludzik, Jozefe2362792020-10-27 17:23:55 +010022 {
23 result.reserve(container.size());
24 }
Szymon Dompkefdb06a12022-02-11 11:04:44 +010025
Wludzik, Jozefe2362792020-10-27 17:23:55 +010026 std::transform(container.begin(), container.end(),
27 std::inserter(result, result.end()),
Szymon Dompkefdb06a12022-02-11 11:04:44 +010028 std::forward<Functor>(f));
29
Wludzik, Jozefe2362792020-10-27 17:23:55 +010030 return result;
31}
32
Szymon Dompkefdb06a12022-02-11 11:04:44 +010033template <template <class, class...> class Container, class Functor,
34 class... Args>
35inline auto transform(const Container<Args...>& container, Functor&& f)
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010036{
Szymon Dompkefdb06a12022-02-11 11:04:44 +010037 return transform<Container, Container<Args...>, Functor>(
38 container, std::forward<Functor>(f));
Krzysztof Grobelny60fee072022-01-13 16:25:04 +010039}
40
Wludzik, Jozefe2362792020-10-27 17:23:55 +010041} // namespace utils