xref: /openbmc/telemetry/src/utils/transform.hpp (revision 60fee077c544402f133230c4d3dc85ad0ada9381)
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 <class R, class Container, class F>
20 auto transform(const Container& container, F&& functor)
21 {
22     auto result = R{};
23 
24     if constexpr (detail::has_member_reserve<decltype(result)>)
25     {
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 
34 template <template <class, class...> class Container, class T, class... Args,
35           class F>
36 auto 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 
42 } // namespace utils
43