C ++ Write Macro用于在给定另一个整数类型的情况下查找整数类型
C++ Write Macro for finding an integer type given another integer type
我有一个看起来像这样的函数:
template<class T, class E, class U = T> T function(T input1, E input2) {
// implementation here
}
我希望 U
的默认值是一个接受 T
作为输入的宏,而不是上面的声明。更具体地说,如果 T
是 boost::multiprecision::cpp_int
,我希望 U
的默认值是 boost::multiprecision::cpp_int
,并且我希望 U
的默认值是一个双精度整数T
的精度固定精度 T
.
我知道第二部分可以通过以下方式完成:
U = boost::uint_t<2 * std::numeric_limits<T>::digits>::fast
如何检查 T
是否为 cpp_int
(或 std 和 boost 中的任何其他任意精度整数),并将所有内容放在一个宏中?
编辑:
我发现可以通过以下方式测试任意精度:
std::numeric_limits<T>::is_bounded
我仍然不知道如何将这 2 个测试组合成 1 个宏。
如果 T
的两倍大小大于 int64_t
。
,则可以使用 boost::multiprecision::cpp_int
想法:
#include <boost/multiprecision/cpp_int.hpp>
#include <cstddef>
#include <type_traits>
// type trait to get an int of the requested size
template<size_t S>
struct int_size {
using type = std::conditional_t<S==1, int8_t,
std::conditional_t<S==2, int16_t,
std::conditional_t<S==4, int32_t,
std::conditional_t<S==8, int64_t,
boost::multiprecision::cpp_int>>>>;
};
template<size_t S>
using int_size_t = int_size<S>::type;
然后 U
是 T
或 boost::multiprecision::cpp_int
的两倍,如果它大于 int64_t
:
template<class T, class E, class U = int_size_t<sizeof(T) * 2>>
T function(T input1, E input2) {
// implementation here
}
使用宏定义了一个自定义的 boost 多精度 int,并将函数后端隐藏在另一个检查类型的函数后面。 U 是空的,因此用户可以选择自定义它。如果 T 是固定精度,则函数调用宏,否则将 cpp_int 作为模板参数传递。自定义 boost int 的类型推导是在编译时完成的,if 语句也可能在编译时进行评估。
#include <limits>
#include <type_traits>
#ifndef BOOST_UINT
#define BOOST_UINT(bit_count) boost::multiprecision::number<boost::multiprecision::cpp_int_backend<bit_count, bit_count, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>
#endif
template<class T, class E, class U = void> T function(T input1, E input2) {
if(std::is_same<U, void>::value) {
if(std::numeric_limits<T>::is_bounded) {
return function_backend<T, E, BOOST_UINT( ((std::numeric_limits<T>::digits + 1) >> 1) << 2)>(input1, input2);
} else {
return function_backend<T, E, cpp_int>(input1, input2);
}
} else {
return function_backend<T, E, U>(input, input2);
}
}
template<class T, class E, class U> T function_backend(T input1, E input2);
我有一个看起来像这样的函数:
template<class T, class E, class U = T> T function(T input1, E input2) {
// implementation here
}
我希望 U
的默认值是一个接受 T
作为输入的宏,而不是上面的声明。更具体地说,如果 T
是 boost::multiprecision::cpp_int
,我希望 U
的默认值是 boost::multiprecision::cpp_int
,并且我希望 U
的默认值是一个双精度整数T
的精度固定精度 T
.
我知道第二部分可以通过以下方式完成:
U = boost::uint_t<2 * std::numeric_limits<T>::digits>::fast
如何检查 T
是否为 cpp_int
(或 std 和 boost 中的任何其他任意精度整数),并将所有内容放在一个宏中?
编辑:
我发现可以通过以下方式测试任意精度:
std::numeric_limits<T>::is_bounded
我仍然不知道如何将这 2 个测试组合成 1 个宏。
如果 T
的两倍大小大于 int64_t
。
boost::multiprecision::cpp_int
想法:
#include <boost/multiprecision/cpp_int.hpp>
#include <cstddef>
#include <type_traits>
// type trait to get an int of the requested size
template<size_t S>
struct int_size {
using type = std::conditional_t<S==1, int8_t,
std::conditional_t<S==2, int16_t,
std::conditional_t<S==4, int32_t,
std::conditional_t<S==8, int64_t,
boost::multiprecision::cpp_int>>>>;
};
template<size_t S>
using int_size_t = int_size<S>::type;
然后 U
是 T
或 boost::multiprecision::cpp_int
的两倍,如果它大于 int64_t
:
template<class T, class E, class U = int_size_t<sizeof(T) * 2>>
T function(T input1, E input2) {
// implementation here
}
使用宏定义了一个自定义的 boost 多精度 int,并将函数后端隐藏在另一个检查类型的函数后面。 U 是空的,因此用户可以选择自定义它。如果 T 是固定精度,则函数调用宏,否则将 cpp_int 作为模板参数传递。自定义 boost int 的类型推导是在编译时完成的,if 语句也可能在编译时进行评估。
#include <limits>
#include <type_traits>
#ifndef BOOST_UINT
#define BOOST_UINT(bit_count) boost::multiprecision::number<boost::multiprecision::cpp_int_backend<bit_count, bit_count, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>
#endif
template<class T, class E, class U = void> T function(T input1, E input2) {
if(std::is_same<U, void>::value) {
if(std::numeric_limits<T>::is_bounded) {
return function_backend<T, E, BOOST_UINT( ((std::numeric_limits<T>::digits + 1) >> 1) << 2)>(input1, input2);
} else {
return function_backend<T, E, cpp_int>(input1, input2);
}
} else {
return function_backend<T, E, U>(input, input2);
}
}
template<class T, class E, class U> T function_backend(T input1, E input2);