xref: /openbmc/telemetry/src/utils/transform.hpp (revision fdb06a141c6d9bbf1088fee974b815d1f35d3bcb)
1 #pragma once
2 
3 #include <algorithm>
4 #include <iterator>
5 
6 namespace utils
7 {
8 namespace detail
9 {
10 
11 template <class T>
12 concept has_member_reserve = requires(T t)
13 {
14     t.reserve(size_t{});
15 };
16 
17 } // namespace detail
18 
19 template <template <class, class...> class R, class Container, class Functor>
20 inline auto transform(const Container& container, Functor&& f)
21 {
22     auto result = R<decltype(f(*container.begin()))>{};
23 
24     if constexpr (detail::has_member_reserve<decltype(result)>)
25     {
26         result.reserve(container.size());
27     }
28 
29     std::transform(container.begin(), container.end(),
30                    std::inserter(result, result.end()),
31                    std::forward<Functor>(f));
32 
33     return result;
34 }
35 
36 template <template <class, class...> class Container, class Functor,
37           class... Args>
38 inline auto transform(const Container<Args...>& container, Functor&& f)
39 {
40     return transform<Container, Container<Args...>, Functor>(
41         container, std::forward<Functor>(f));
42 }
43 
44 } // namespace utils
45