Conflict between Boost.Integer and boost/detail/numeric_traits.hpp

Hello everyone, There seems to be a problem with using Boost.Integer in combination with anything that uses boost/detail/numeric_traits.hpp (development). The latter also defines a struct with name integer_traits that is not compatible with the one declared in Boost.Integer. The problem can be reproduced by including boost/graph/adjacency_list.hpp first and boost/integer.hpp as in: #include <boost/graph/adjacency_list.hpp> #include <boost/integer.hpp> int main() { return 0; } Swapping the include directives avoids the problem. Regards, Jeroen van der Wulp

On Jul 14, 2008, at 11:31 AM, J. van der Wulp wrote:
There seems to be a problem with using Boost.Integer in combination with anything that uses boost/detail/numeric_traits.hpp (development). The latter also defines a struct with name integer_traits that is not compatible with the one declared in Boost.Integer.
The problem can be reproduced by including boost/graph/ adjacency_list.hpp first and boost/integer.hpp as in:
#include <boost/graph/adjacency_list.hpp> #include <boost/integer.hpp>
int main() { return 0; }
Swapping the include directives avoids the problem.
Does it have to be <boost/integer.hpp>, or will using <boost/ integer_traits.hpp> directly (without also including integer.hpp) also cause the error? (Check both relative orders, of course.) I wonder if changing numeric_traits to: //========================================= template <class Number> struct numeric_traits { typedef typename ::boost::detail::integer_traits<Number>::difference_type difference_type; }; //========================================= will make a difference. The extra qualification should specify exactly which "integer_traits" is used. (It was unqualified before, so maybe the compiler grabs boost::integer_traits if it doesn't know about boost::detail::integer_traits.) -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

Hello Daryle, Thanks for the quick response.
There seems to be a problem with using Boost.Integer in combination with anything that uses boost/detail/numeric_traits.hpp (development). The latter also defines a struct with name integer_traits that is not compatible with the one declared in Boost.Integer.
The problem can be reproduced by including boost/graph/adjacency_list.hpp first and boost/integer.hpp as in:
#include <boost/graph/adjacency_list.hpp> #include <boost/integer.hpp>
int main() { return 0; }
Swapping the include directives avoids the problem.
Does it have to be <boost/integer.hpp>, or will using <boost/integer_traits.hpp> directly (without also including integer.hpp) also cause the error? (Check both relative orders, of course.)
It only compiles when <boost/integer.hpp> is either not included or included after adjacency_list.hpp. Adding <boost/integer_traits.hpp> either before or after adjacency_list makes no difference in combination with <boost/integer.hpp>. Everything compiles fine without including the latter (only including integer_traits.hpp and boost/detail/numeric_traits.hpp indirectly).
I wonder if changing numeric_traits to:
//========================================= template <class Number> struct numeric_traits { typedef typename ::boost::detail::integer_traits<Number>::difference_type difference_type; }; //=========================================
will make a difference. The extra qualification should specify exactly which "integer_traits" is used. (It was unqualified before, so maybe the compiler grabs boost::integer_traits if it doesn't know about boost::detail::integer_traits.)
It is a good idea anyway, but it makes no difference. The problem is that integer.hpp also defines things in the boost::detail namespace and there the boost::detail::integer_traits structure is favoured over boost::integer_traits. But only when the boost::detail::integer_traits definition is in scope, such as when boost/detail/numeric_traits.hpp is included. The attached patch fixes the problem. Regards, Jeroen van der Wulp Index: boost/integer.hpp =================================================================== --- boost/integer.hpp (revision 4855) +++ boost/integer.hpp (working copy) @@ -122,16 +122,16 @@ { BOOST_STATIC_CONSTANT( int, rank = #ifdef BOOST_HAS_LONG_LONG - (MaxValue <= integer_traits< long_long_type >::const_max) + + (MaxValue <= boost::integer_traits< long_long_type >::const_max) + #elif defined(BOOST_HAS_MS_INT64) - (MaxValue <= integer_traits< __int64 >::const_max) + + (MaxValue <= boost::integer_traits< __int64 >::const_max) + #else 1 + #endif - (MaxValue <= integer_traits< long >::const_max) + - (MaxValue <= integer_traits< int >::const_max) + - (MaxValue <= integer_traits< short >::const_max) + - (MaxValue <= integer_traits< signed char >::const_max) ); + (MaxValue <= boost::integer_traits< long >::const_max) + + (MaxValue <= boost::integer_traits< int >::const_max) + + (MaxValue <= boost::integer_traits< short >::const_max) + + (MaxValue <= boost::integer_traits< signed char >::const_max) ); }; template < intmax_t MinValue > @@ -139,16 +139,16 @@ { BOOST_STATIC_CONSTANT( int, rank = #ifdef BOOST_HAS_LONG_LONG - (MinValue >= integer_traits< long_long_type >::const_min) + + (MinValue >= boost::integer_traits< long_long_type >::const_min) + #elif defined(BOOST_HAS_MS_INT64) - (MinValue >= integer_traits< __int64 >::const_min) + + (MinValue >= boost::integer_traits< __int64 >::const_min) + #else 1 + #endif - (MinValue >= integer_traits< long >::const_min) + - (MinValue >= integer_traits< int >::const_min) + - (MinValue >= integer_traits< short >::const_min) + - (MinValue >= integer_traits< signed char >::const_min) ); + (MinValue >= boost::integer_traits< long >::const_min) + + (MinValue >= boost::integer_traits< int >::const_min) + + (MinValue >= boost::integer_traits< short >::const_min) + + (MinValue >= boost::integer_traits< signed char >::const_min) ); }; template < uintmax_t Value > @@ -156,16 +156,16 @@ { BOOST_STATIC_CONSTANT( int, rank = #ifdef BOOST_HAS_LONG_LONG - (Value <= integer_traits< ulong_long_type >::const_max) + + (Value <= boost::integer_traits< ulong_long_type >::const_max) + #elif defined(BOOST_HAS_MS_INT64) - (Value <= integer_traits< unsigned __int64 >::const_max) + + (Value <= boost::integer_traits< unsigned __int64 >::const_max) + #else 1 + #endif - (Value <= integer_traits< unsigned long >::const_max) + - (Value <= integer_traits< unsigned int >::const_max) + - (Value <= integer_traits< unsigned short >::const_max) + - (Value <= integer_traits< unsigned char >::const_max) ); + (Value <= boost::integer_traits< unsigned long >::const_max) + + (Value <= boost::integer_traits< unsigned int >::const_max) + + (Value <= boost::integer_traits< unsigned short >::const_max) + + (Value <= boost::integer_traits< unsigned char >::const_max) ); }; } // namespace detail

On Jul 18, 2008, at 10:35 AM, J. van der Wulp wrote:
Thanks for the quick response.
[TRUNCATE description of problem and solution] Added as ticket #2134, <http://svn.boost.org/trac/boost/ticket/2134>. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (2)
-
Daryle Walker
-
J. van der Wulp