提升多精度整数的类型特征

Type trait for boost multiprecision integers

我想编写一个类型特征来识别 boost 多精度整数类型。我可以为 uint256_t:

这样的具体类型执行此操作
template <typename T>
struct is_multiprecision_int : std::false_type {};

template <>
struct is_multiprecision_int<uint256_t> : std::true_type {};

但是我怎样才能对任何 boost 多精度整数(或至少对具有 cpp_int 后端的任何多精度数字)执行相同的操作?

好的,我来试试看。

根据 boost-multiprecision 的官方文档:https://www.boost.org/doc/libs/1_73_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html,这可能是一个可能的选项:

#include<type_traits>

using namespace boost::multiprecision;

//helper struct for checking if type is cpp_int_backend at compile time using function overloading
template<typename T>
struct is_cpp_int_backend{
    //this template will trigger for pointer to any 
    //  specialisation of cpp_int_backend. Pass by pointer instead
    //  of value, for more generic usage (passing by value will
    //  only work if cpp_int_backend has move constructor defined,
    //  whereas pass-by-pointer will work regardless). References
    //  are also acceptable, however, using pointers will result in
    //  compile error if value is passed, whereas references may give
    //  unexpected behaviour. For these reasons, prefer pointers. 
    template<uint A, uint B, cpp_integer_type CIT, cpp_int_check_type C, typename TT>
    constexpr static std::true_type test(cpp_int_backend<A,B,CIT,C,TT>*);

    //this overload has the lowest precedence during overload
    //  resolution, but will accept any argument.  
    constexpr static std::false_type test(...);

    //type will be std::true_type or std::false_type depending
    //  on which overload is selected. If T is a specialisation
    //  of cpp_int_backend, it will be true_type, else false_type
    using type = decltype(test(std::declval<T*>())); 
    constexpr static bool value = type::value;
};

//use similar technique to above, to create type trait for 
//  multiprecision type
template<typename T>
struct is_multiprecision{

    //enable this template, if T is a specialisation of 'number'
    //  in boost::multiprecision, and the nested template parameter
    //  is a cpp_int_backend. Use pointers for similar reason as 
    //  above
    template<typename TT, typename = std::enable_if_t<is_cpp_int_backend<TT>::value>>
    constexpr static std::true_type test(number<TT>*);

    //again, lowest order of precedence, but will trigger for
    //  anything the above function template does not trigger for
    constexpr static std::false_type test(...);

    //get type depending on T
    using type = decltype(test(std::declval<T*>()));
    constexpr static bool value = type::value; 
};

//variable template for convenience
template<typename T>
constexpr bool is_multiprecision_v = is_multiprecision<T>::value;

//example usage
static_assert(is_multiprecision_v<uint256_t>);

它在我的机器上工作。

请注意,已经存在这样一个特征 - 称为 is_number 并且对于 number<> class 的任何实例化计算结果为真。还有一个特征 is_number_expression 可以检测从 number<>.

上的操作派生的表达式模板