Boost logo

Boost :

Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2011-01-02 11:00:11

----- Original Message -----
From: "vicente.botet" <vicente.botet_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Tuesday, November 16, 2010 10:15 PM
Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
> ----- Original Message -----
> From: "John Maddock" <boost.regex_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Monday, November 15, 2010 10:17 AM
> Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
>>>This means that with the current implementation we can not use
>>>integral_constant with the max value of the type.
>>>Do you think this is a bug in integral_constant?
>> It's nasty, but we do need MPL support in type_traits, so I don't see what
>> we can really do about this?
>> Can mpl be fixed not to cause numeric overflow when the value is at the
>> limit of the range?
> I gues that it will be enough to overload the next and prior metafunctions on integral_c so the next and prior nestedtypes are no more nedeed, but I don't understand why the compiler is instantiating these types when not used yet. Could someone clarify if this instantiation is conforming to the standard?

I have made some modification on Boost.MPL to don't include the prior and next nested types. Instead I have added a 'clone' metafunction that will not be instantiated if not explictly requested and that returns the integral type with a different parameter.

    struct clone {

Of course I have needed to change the next and prior metafunctions to use tag dispatch.

While running the regression on Boost.MPL I have found a problem: most of the types (iterators) that are used as parameter of next/prior don't have a tag nested type :(. I've added an artificial nested tag type on these types.

In this way we are now able to instantiate integral constants with the max and min values without error.

boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFFLL>

Most of the modified code is protected with the macro BOOST_MPL_NEXT_PRIOR_EXT.

I'm not sure this is the best way to workaround this BUG. Please, could you check the attached patches, and let me know if this patch can be included in trunk with minor modifications?


PS. Next follows the error when compiling

    typedef boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFF> T;

with gcc 4.6

gcc.compile.c++ ..\..\..\bin.v2\libs\ratio\test\ratio_add_pass.test\gcc-mingw-4.6.0x\debug\ratio_add_pass.o
In file included from ..\..\../boost/mpl/integral_c.hpp:32:0,
                 from ..\..\../boost/mpl/abs.hpp:15,
                 from ..\..\../boost/ratio/ratio.hpp:36,
                 from ..\..\../boost/ratio.hpp:12,
                 from ratio_arithmetic\ratio_add_pass.cpp:16:
..\..\../boost/mpl/aux_/integral_wrapper.hpp: In instantiation of 'mpl_::integral_c<long long int, 0x7fffffffffffffffll>':
ratio_arithmetic\ratio_add_pass.cpp:69:5: instantiated from here
..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: warning: integer overflow in expression [-Woverflow]
..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: error: '-0x8000000000000000ll' is not a valid template argument for type 'long long int' because it is a non-constant expression
..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: error: '-0x8000000000000000ll' is not a constant expression

    "c:\cygwin\gcc-4.6.0\bin\g++.exe" -ftemplate-depth-128 -std=c++0x -O0 -fno-inline -Wall -pedantic -g -Wextra -Wno-long-long -DBOOST_ALL_NO_LIB=1 -DBOOST_ENABLE_WARNINGS -DBOOST_RATIO_USES_MPL_ASSERT -I"..\..\.." -c -o "..\..\..\bin.v2\libs\ratio\test\ratio_add_pass.test\gcc-mingw-4.6.0x\debug\ratio_add_pass.o" "ratio_arithmetic\ratio_add_pass.cpp"

Boost list run by bdawes at, gregod at, cpdaniel at, john at