Files
Simple-Protocol-Lib/include/sp/common/Templates.h
2025-02-08 19:39:37 +01:00

54 lines
1.5 KiB
C++

#pragma once
#include <cstdint>
namespace sp {
/// @brief Concat multiple tuples in one big tuple
/// @tparam ...input_t Multiple std::tuple types to concat
template <typename... input_t>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<input_t>()...));
namespace details {
template <std::size_t TRem>
class TupleForEachHelper {
public:
template <typename TTuple, typename TFunc>
static void Exec(TTuple&& tuple, TFunc&& func) {
using Tuple = typename std::decay<TTuple>::type;
static const std::size_t TupleSize = std::tuple_size<Tuple>::value;
static_assert(TRem <= TupleSize, "Incorrect parameters");
// Invoke function with current element
static const std::size_t Idx = TupleSize - TRem;
func(std::get<Idx>(std::forward<TTuple>(tuple)));
// Compile time recursion - invoke function with the remaining elements
TupleForEachHelper<TRem - 1>::Exec(std::forward<TTuple>(tuple), std::forward<TFunc>(func));
}
};
template <>
class TupleForEachHelper<0> {
public:
// Stop compile time recursion
template <typename TTuple, typename TFunc>
static void Exec(TTuple&& tuple, TFunc&& func) {
static_cast<void>(tuple);
static_cast<void>(func);
}
};
} // namespace details
template <typename TFunc, typename TTuple>
void TupleForEach(TFunc&& func, TTuple&& tuple) {
using Tuple = typename std::decay<TTuple>::type;
static const std::size_t TupleSize = std::tuple_size<Tuple>::value;
details::TupleForEachHelper<TupleSize>::Exec(std::forward<TTuple>(tuple), std::forward<TFunc>(func));
}
} // namespace sp