HumanRender/human_render/Ipc/libipc/utility/utility.h
2024-12-22 23:24:02 +08:00

65 lines
2.1 KiB
C++

#pragma once
#include <utility> // std::forward, std::integer_sequence
#include <cstddef> // std::size_t
#include <new> // std::hardware_destructive_interference_size
#include <type_traits> // std::is_trivially_copyable
#include "libipc/platform/detail.h"
namespace ipc {
template <typename F, typename D>
constexpr decltype(auto) static_switch(std::size_t /*i*/, std::index_sequence<>, F&& /*f*/, D&& def) {
return std::forward<D>(def)();
}
template <typename F, typename D, std::size_t N, std::size_t...I>
constexpr decltype(auto) static_switch(std::size_t i, std::index_sequence<N, I...>, F&& f, D&& def) {
return (i == N) ? std::forward<F>(f)(std::integral_constant<std::size_t, N>{}) :
static_switch(i, std::index_sequence<I...>{}, std::forward<F>(f), std::forward<D>(def));
}
template <std::size_t N, typename F, typename D>
constexpr decltype(auto) static_switch(std::size_t i, F&& f, D&& def) {
return static_switch(i, std::make_index_sequence<N>{}, std::forward<F>(f), std::forward<D>(def));
}
template <typename F, std::size_t...I>
IPC_CONSTEXPR_ void static_for(std::index_sequence<I...>, F&& f) {
IPC_UNUSED_ auto expand = { (std::forward<F>(f)(std::integral_constant<std::size_t, I>{}), 0)... };
}
template <std::size_t N, typename F>
IPC_CONSTEXPR_ void static_for(F&& f) {
static_for(std::make_index_sequence<N>{}, std::forward<F>(f));
}
// Minimum offset between two objects to avoid false sharing.
enum {
// #if __cplusplus >= 201703L
// cache_line_size = std::hardware_destructive_interference_size
// #else /*__cplusplus < 201703L*/
cache_line_size = 64
// #endif/*__cplusplus < 201703L*/
};
template <typename T, typename U>
auto horrible_cast(U rhs) noexcept
-> typename std::enable_if<std::is_trivially_copyable<T>::value
&& std::is_trivially_copyable<U>::value, T>::type {
union {
T t;
U u;
} r = {};
r.u = rhs;
return r.t;
}
IPC_CONSTEXPR_ std::size_t make_align(std::size_t align, std::size_t size) {
// align must be 2^n
return (size + align - 1) & ~(align - 1);
}
} // namespace ipc