cpp-utils/include/transmute.hpp
2022-07-05 13:32:35 +01:00

65 lines
2 KiB
C++

#pragma once
#include <utility>
namespace util {
template <typename T1, typename T2>
struct copy_const : std::type_identity<T2> {};
template <typename T1, typename T2>
struct copy_const<const T1, T2> : std::type_identity<const T2> {};
template <typename T1, typename T2>
using copy_const_t = typename copy_const<T1, T2>::type;
template <typename T1, typename T2>
struct copy_volatile : std::type_identity<T2> {};
template <typename T1, typename T2>
struct copy_volatile<volatile T1, T2> : std::type_identity<volatile T2> {};
template <typename T1, typename T2>
using copy_volatile_t = typename copy_volatile<T1, T2>::type;
template <typename T1, typename T2>
struct copy_cv : std::type_identity<copy_const_t<T1, copy_volatile_t<T1, T2>>> {
};
template <typename T1, typename T2>
using copy_cv_t = typename copy_cv<T1, T2>::type;
template <typename T1, typename T2>
struct copy_reference : std::type_identity<T2> {};
template <typename T1, typename T2>
struct copy_reference<T1 &, T2>
: std::type_identity<std::add_lvalue_reference_t<T2>> {};
template <typename T1, typename T2>
struct copy_reference<T1 &&, T2>
: std::type_identity<std::add_rvalue_reference_t<T2>> {};
template <typename T1, typename T2>
using copy_reference_t = typename copy_reference<T1, T2>::type;
template <typename T1, typename T2>
using copy_cvref_t = copy_reference_t<
T1, copy_reference_t<T2, copy_cv_t<std::remove_reference_t<T1>, T2>>>;
template <typename T2>
constexpr inline auto transmute(auto &&t1) -> copy_cvref_t<decltype(t1), T2> {
return std::forward<copy_cvref_t<decltype(t1), T2>>(
reinterpret_cast<copy_cvref_t<decltype(t1), T2>>(t1));
}
template <typename T2>
constexpr inline auto transmute(auto &t1) -> copy_cvref_t<decltype(t1), T2> {
return std::forward<copy_cvref_t<decltype(t1), T2>>(
reinterpret_cast<copy_cvref_t<decltype(t1), T2>>(t1));
}
template <typename T1, typename T2>
constexpr inline auto transmute(T1 t1) -> T2 {
return std::forward<T2>(reinterpret_cast<T2>(t1));
}
} // namespace util