Increase ICL, interval power

In Boost ICL, when I call cardinality () or size () on a given interval, the return type is size_t, regardless of the interval type. On 32-bit machines, this is an unsigned 32-bit integer. However, if my intervals are of type int64_t, the cardinality can easily overflow a 32-bit integer. Am I missing something obvious here or is this a major flaw in this library?

EDIT: example added

The following code compiles and runs without error on 64-bit, but not on 32-bit machines where it issues this assertion.

#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: I am using boost :: icl version 1.49.0 on Ubuntu 13.10

EDIT:

This is not a 32/64-bit issue as the following code will not work on 64-bit

#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


source to share


1 answer


Reproduced with Boost 1_54 on Ubuntu 14.04.1 LTS

It really seems like a bug. Specialization to fix

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

      

In icl/type_traits/size_type_of.hpp

. Somehow ICL devs don't seem to be tested with -m32 these days.

I had success replacing it with

// 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

      



This trait is unfortunately not very convenient for SFINAE, so hack the first template argument bool

for SFINAE. Improvements can be:

  • only use tags like boost

  • use integral subtraction value from Boost Integer as opposed to common_type<...>

    for integral types

I've tested this on DoTheRightThing (TM) for interval_set<double>

as well interval_set<uint64_t>

as g ++ -m32 and -m64.


I would post this on the mailing list.

+2


source







All Articles