简体   繁体   English

提升ICL,区间集的基数

[英]Boost ICL, cardinality of an interval set

In Boost ICL, when I call cardinality() or size() functions on an interval set, the return type is size_t, independent of the type of interval. 在Boost ICL中,当我在间隔集上调用cardinality()或size()函数时,返回类型是size_t,与间隔类型无关。 On 32-bit machines this is a 32-bit unsigned integer. 在32位机器上,这是一个32位无符号整数。 If my intervals, however, are of type int64_t, the cardinality can easily overflow the 32-bit integer. 但是,如果我的间隔是int64_t类型,则基数很容易溢出32位整数。 Am I missing something obvious here or is this a serious flaw of this library? 我错过了一些明显的东西,或者这是这个图书馆的一个严重缺陷?

EDIT: example added 编辑:示例添加

The following code compiles and runs without error on 64-bit but not on 32-bit machines, where it throws the assertion. 以下代码在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);
}

EDIT: I'm using boost::icl version 1.49.0 on Ubuntu 13.10 编辑:我在Ubuntu 13.10上使用boost :: icl版本1.49.0

EDIT: 编辑:

This is not particularly a 32/64-bit problem, as the following code wouldn't work on 64-bit either 这不是特别是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);
}

Reproduced with Boost 1_54 on Ubuntu 14.04.1 LTS 在Ubuntu 14.04.1 LTS上使用Boost 1_54重现

This indeed seems to be a bug. 这确实是一个错误。 The specialization to fix is 修复的专业是

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

In icl/type_traits/size_type_of.hpp . icl/type_traits/size_type_of.hpp Somehow the ICL devs appear not to be testing with -m32 these days. 不知何故,这些天ICL开发人员似乎没有使用-m32进行测试。

I've had success replacing it by 我已成功取代它

// 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

The trait is sadly not very SFINAE friendly, hence the hack to use the first bool template argument for SFINAE. 可悲的是,这个特性并不是非常友好的SFINAE,因此使用SFINAE的第一个bool模板参数的黑客。 Improvements could be: 改进可能是:

  • use boost type traits only 仅使用boost类型特征
  • use integral value deduction from Boost Integer as opposed to common_type<...> for integral types 使用Boost Integer的积分值推导而不是整数类型的common_type<...>

I've tested this to DoTheRightThing(TM) for interval_set<double> as well as interval_set<uint64_t> on g++ -m32 and -m64. 我已经在for ++设置了对于interval_set<double> DoTheRightThing(TM)以及对g ++ -m32和-m64的interval_set<uint64_t>


I'd report this on the mailing list. 我会在邮件列表上报告这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM