提升ICL,区间集的基数

时间:2014-12-01 09:05:50

标签: c++ boost boost-icl

在Boost ICL中,当我在间隔集上调用cardinality()或size()函数时,返回类型为size_t,与间隔类型无关。在32位机器上,这是一个32位无符号整数。但是,如果我的间隔是int64_t类型,则基数很容易溢出32位整数。我错过了一些明显的东西,或者这是这个库的严重缺陷吗?

编辑:添加了示例

以下代码在64位上编译并运行时没有错误,但在32位计算机上没有错误,它会抛出断言。

#include <boost/icl/interval_set.hpp>

int main()
{
    boost::icl::interval_set<int64_t> is;
    is.add(boost::icl::interval<int64_t>::closed(1, 4294967297LL));
    assert(boost::icl::cardinality(is) == 4294967297LL);
}

编辑:我在Ubuntu 13.10上使用boost :: icl版本1.49.0

编辑:

这不是特别是32/64位的问题,因为以下代码无法在64位上运行

#include <boost/icl/interval_set.hpp>
int main()
{
    boost::icl::interval_set<double> is;
    is.add(boost::icl::interval<double>::closed(1, 1.5));
    assert(boost::icl::cardinality(is) == 0.5);
}

1 个答案:

答案 0 :(得分:2)

在Ubuntu 14.04.1 LTS上用Boost 1_54转载

这确实是一个错误。要修复的专业是

template <class Type> 
struct get_size_type<Type, false, false, false>
{ 
    typedef std::size_t type; 
};

icl/type_traits/size_type_of.hpp。不知何故,ICL开发人员最近似乎没有使用-m32进行测试。

我已成功取代

// BEGIN SEHE WAS HERE
template <class Type> 
struct get_size_type<Type, std::enable_if<not boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{ 
    typedef std::size_t type; 
};

template <class Type> 
struct get_size_type<Type, std::enable_if<boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{ 
    typedef typename std::common_type<Type, std::size_t>::type type; 
};
// END SEHE WAS HERE

遗憾的是,这个特性并不是非常友好的SFINAE,因此使用SFINAE的第一个bool模板参数进行了破解。改进可能是:

  • 仅使用boost类型特征
  • 使用Boost Integer的积分值推导而不是整数类型的common_type<...>

我已经对interval_set<double>的DoTheRightThing(TM)以及g ++ -m32和-m64上的interval_set<uint64_t>进行了测试。


我会在邮件列表上报告此内容。