From 27cbfef0269146eb296bbd2b810a6d331e5cb7d2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 19 Jul 2012 08:35:11 -0400 Subject: MAINT-1175: Use workaround for comparing std::type_info* on gcc < 4.4. We now specialize std::less to use std::type_info::before(), and on Windows and Mac that Just Works. It even works on Linux when using gcc 4.4+: more recent implementations of gcc's std::type_info::before() apparently do name()-string comparisons internally. It doesn't work so well on Linux with gcc 4.1, though, and that's the compiler we still use on our Linux build-farm machines. But rather than give up, perform explicit name()-string comparison in that case. --- indra/llcommon/llstl.h | 59 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 6109b21546..d3941e1bc9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -471,6 +471,27 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); } +/** + * Compare std::type_info* pointers a la std::less. We break this out as a + * separate function for use in two different std::less specializations. + */ +inline +bool before(const std::type_info* lhs, const std::type_info* rhs) +{ +#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + // If we're building on Linux with gcc, and it's either gcc 3.x or + // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on + // Mac too, and some people build with gcc on Windows (cygwin or mingw). + // On Linux, different load modules may produce different type_info* + // pointers for the same type. Have to compare name strings to get good + // results. + return strcmp(lhs->name(), rhs->name()) < 0; +#else // not Linux, or gcc 4.4+ + // Just use before(), as we normally would + return lhs->before(*rhs); +#endif +} + /** * Specialize std::less to use std::type_info::before(). * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* @@ -479,25 +500,25 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) */ namespace std { - template <> - struct less: - public std::binary_function - { - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } - }; - - template <> - struct less: - public std::binary_function - { - bool operator()(std::type_info* lhs, std::type_info* rhs) const - { - return lhs->before(*rhs); - } - }; + template <> + struct less: + public std::binary_function + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; + + template <> + struct less: + public std::binary_function + { + bool operator()(std::type_info* lhs, std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; } // std #endif // LL_LLSTL_H -- cgit v1.2.3