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 作为输入的宏,而不是上面的声明。更具体地说,如果 Tboost::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;

然后 UTboost::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
}

Demo

使用宏定义了一个自定义的 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);