В 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);
}
РЕДАКТИРОВАТЬ: я использую Boost :: ICL версии 1.49.0 на Ubuntu 13.10
РЕДАКТИРОВАТЬ:
Это не особенно 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);
}
Воспроизведено с Boost 1_54 в Ubuntu 14.04.1 LTS
Это действительно кажется ошибкой. Специализация, чтобы исправить это
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, поэтому взломать, чтобы использовать первый bool
шаблонный аргумент для SFINAE. Улучшения могут быть:
boost
только тип чертыcommon_type<...>
для целочисленных типовЯ проверил это на DoTheRightThing (TM) для interval_set<double>
так же как interval_set<uint64_t>
на g ++ -m32 и -m64.
Я бы сообщил об этом в списке рассылки.