Skip to content
Snippets Groups Projects
Commit 27cbfef0 authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

MAINT-1175: Use workaround for comparing std::type_info* on gcc < 4.4.

We now specialize std::less<const std::type_info*> 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.
parent 2e83dfa2
No related branches found
No related tags found
No related merge requests found
...@@ -471,6 +471,27 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) ...@@ -471,6 +471,27 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
return llbinder2nd<_Operation>(__oper, _Arg2_type(__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<std::type_info*> to use std::type_info::before(). * Specialize std::less<std::type_info*> to use std::type_info::before().
* See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* * 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) ...@@ -479,25 +500,25 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
*/ */
namespace std namespace std
{ {
template <> template <>
struct less<const std::type_info*>: struct less<const std::type_info*>:
public std::binary_function<const std::type_info*, const std::type_info*, bool> public std::binary_function<const std::type_info*, const std::type_info*, bool>
{ {
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
{ {
return lhs->before(*rhs); return before(lhs, rhs);
} }
}; };
template <> template <>
struct less<std::type_info*>: struct less<std::type_info*>:
public std::binary_function<std::type_info*, std::type_info*, bool> public std::binary_function<std::type_info*, std::type_info*, bool>
{ {
bool operator()(std::type_info* lhs, std::type_info* rhs) const bool operator()(std::type_info* lhs, std::type_info* rhs) const
{ {
return lhs->before(*rhs); return before(lhs, rhs);
} }
}; };
} // std } // std
#endif // LL_LLSTL_H #endif // LL_LLSTL_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment