Opened 8 years ago

Last modified 8 years ago

#10829 new Bugs

cardinality() of an interval_set is std::size_t independent of interval type, causing overflow

Reported by: konstantin.miller@… Owned by: Joachim Faulhaber
Milestone: To Be Determined Component: ICL
Version: Boost 1.49.0 Severity: Problem
Keywords: ICL Cc:

Description

For an interval_set boost::icl::interval_set<int64_t>, the cardinality function boost::icl::cardinality() returns std::size_t, which is 32-bit on 32-bit machines. This makes the result wrong, due to overflow, whenever the cardinality of the interval_set does not fit into 32-bit.

The following code works on 64-bit but not on 32-bit:

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

Change History (1)

comment:1 by bugs@…, 8 years ago

Out of curiosity, SFINAE-ing the get_size_type trait for arithmetic or integral types does seem to do what's expected.

I'm aware of the fact that following code is not up to coding standards and Boost guides. I'm just contributing it in case it saves anyone else time during analysis:

Replace

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

with

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; 
};
Note: See TracTickets for help on using tickets.