2014-12-01 2 views
3

В Boost ICL, когда я вызываю функции cardinality() или size() на заданном интервале, тип возвращаемого значения - size_t, независимо от типа интервала. На 32-битных машинах это 32-разрядное целое число без знака. Однако, если мои интервалы имеют тип int64_t, мощность может легко переполнить 32-разрядное целое число. Я пропустил что-то очевидное здесь или это серьезный недостаток этой библиотеки?Boost ICL, мощность набора интервалов

EDIT: пример добавлена ​​

Следующий код компилируется и выполняется без ошибок на 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: Я использую повышение :: ICL версии 1.49.0 на Ubuntu 13,10

EDIT:

Это не особо 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); 
} 

ответ

2

Воспроизводится с усилением 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.


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

+1

Я уже создал ошибку # 10829: https://svn.boost.org/trac/boost/ticket/10829 – Konstantin

+0

Хорошая работа. Я обнаружил, что get'size_type не особенно приветствуется SFINAE, но если вы хотите добавить патч Proof-Of-Concept в качестве «идей» к этой проблеме, пожалуйста. – sehe

+0

Кстати, это не особенно проблема с 32-разрядной/64-разрядной версией, потому что вы получаете те же проблемы, если ваш тип интервала двойной, даже на 64-битной машине. С одной стороны, из-за переполнения (двойной диапазон больше, чем 64-разрядный целочисленный диапазон), с другой стороны, поскольку в этом случае число мощностей может быть числом с плавающей запятой. Они просто должны использовать тот же тип для мощности, что и в интервалах. – Konstantin