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);
}

3

Решение

Воспроизведено с 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 только тип черты
  • использовать вычет целочисленного значения из Boost Integer, а не common_type<...> для целочисленных типов

Я проверил это на DoTheRightThing (TM) для interval_set<double> так же как interval_set<uint64_t> на g ++ -m32 и -m64.


Я бы сообщил об этом в списке рассылки.

2

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector