blob: b354b0f63f9bbe3b70c237f42f764134b117e34e [file] [log] [blame]
#pragma once
#include <algorithm>
#include <iterator>
namespace utils
{
namespace detail
{
template <class T>
struct has_member_reserve
{
template <class U>
static U& ref();
template <class U>
static std::true_type check(decltype(ref<U>().reserve(size_t{}))*);
template <class>
static std::false_type check(...);
static constexpr bool value =
decltype(check<std::decay_t<T>>(nullptr))::value;
};
template <class T>
constexpr bool has_member_reserve_v = has_member_reserve<T>::value;
} // namespace detail
template <template <class, class...> class Container, class T, class... Args,
class F>
auto transform(const Container<T, Args...>& container, F&& functor)
{
using R = decltype(functor(*container.begin()));
Container<R> result;
if constexpr (detail::has_member_reserve_v<Container<T, Args...>>)
{
result.reserve(container.size());
}
std::transform(container.begin(), container.end(),
std::inserter(result, result.end()),
std::forward<F>(functor));
return result;
}
} // namespace utils