70 lines
1.7 KiB
C++
70 lines
1.7 KiB
C++
|
|
#pragma once
|
|
|
|
#if !defined(MIJIN_UTIL_MISC_HPP_INCLUDED)
|
|
#define MIJIN_UTIL_MISC_HPP_INCLUDED 1
|
|
|
|
#include <array>
|
|
#include <tuple>
|
|
#include <utility>
|
|
#include "./traits.hpp"
|
|
|
|
namespace mijin
|
|
{
|
|
|
|
//
|
|
// public functions
|
|
//
|
|
|
|
template<auto V, typename T>
|
|
constexpr decltype(auto) idValue(T&& value)
|
|
{
|
|
return std::forward<T>(value);
|
|
}
|
|
|
|
namespace impl
|
|
{
|
|
template<typename T, typename... TArgs>
|
|
struct ConstructArrayHelper
|
|
{
|
|
template<std::size_t... I>
|
|
static constexpr std::array<T, sizeof...(I)> construct(const TArgs&... args, std::index_sequence<I...>)
|
|
{
|
|
return {idValue<I>(T(args...))...};
|
|
}
|
|
};
|
|
}
|
|
|
|
template<typename T, std::size_t count, typename... TArgs>
|
|
constexpr std::array<T, count> constructArray(const TArgs&... args)
|
|
{
|
|
return impl::ConstructArrayHelper<T, TArgs...>::construct(args..., std::make_index_sequence<count>());
|
|
}
|
|
|
|
template<typename TFunction, typename... TArgs>
|
|
constexpr auto applyPack(TFunction&& function, TArgs&&... args)
|
|
{
|
|
auto doApply = [&]<std::size_t... Idx>(std::index_sequence<Idx...>)
|
|
{
|
|
if constexpr (!is_any_type_v<void, std::invoke_result_t<TFunction, std::size_t, TArgs>...>) {
|
|
return std::make_tuple(std::invoke(function, Idx, args) ...);
|
|
}
|
|
else {
|
|
(std::invoke(function, Idx, args), ...);
|
|
}
|
|
};
|
|
return doApply(std::index_sequence_for<TArgs...>());
|
|
}
|
|
|
|
template<typename TFunction, typename TTuple>
|
|
constexpr auto applyWithIndex(TFunction&& function, TTuple&& tuple)
|
|
{
|
|
auto doApply = [&]<typename... TArgs>(TArgs&&... args)
|
|
{
|
|
return applyPack(std::forward<TFunction>(function), std::forward<TArgs>(args)...);
|
|
};
|
|
return std::apply(doApply, std::forward<TTuple>(tuple));
|
|
}
|
|
}
|
|
#endif // !defined(MIJIN_UTIL_MISC_HPP_INCLUDED)
|