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 struct 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 27 template <class T> 28 constexpr bool has_member_reserve_v = has_member_reserve<T>::value; 29 30 } // namespace detail 31 32 template <template <class, class...> class Container, class T, class... Args, 33 class F> 34 auto 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 50