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