This patch rewrites the C++03 __invoke and related meta-programming. There are a number of major changes.
__invoke in C++03 now has a fallback overload for when the invoke expression is ill-formed (similar to C++11). This means that the __invoke_return traits will return __nat when __invoke(...) is ill formed. This would previously cause a compile error.
Bullets 1-4 of __invoke have been rewritten. In the old version __invoke had 32 overloads for bullets 1 and 2,
one for each possible cv-qualified function signature with arities 0-3. 64 overloads would be needed to support member functions
with varargs. Currently these overloads were fundamentally broken. An example overload looked like:
template <class Rp, class Tp, class T1, class A0> Rp __invoke(Rp (Tp::*pm)(A0) const, T1&, A0&)
Because A0 appeared in two different deducible contexts it would have to deduce to be an exact match or the overload
would be rejected. This is made even worse because A0 appears without a reference qualifier in the member function signature
and with a reference qualifier as an __invoke parameter. This means that only member functions that took all
of their arguments by value could be matched.
One possible fix would be to make the second occurrence of A0 appear in a non-deducible context. This way
any type convertible to A0 could be passed as the first parameter. The benefit of this approach is that the
signature of the member function enforces the arity and types taken by the __invoke signature it generates. However
nothing in the INVOKE specification requires this behavior.
My solution is to use a __invoke_enable_if<PM_Type, Tp> metafunction to selectively enable the __invoke overloads for bullets 1, 2, 3 and 4. It uses __member_function_traits to inspect and extract the return type and class type of the pointer to member. Using __member_function_traits to inspect PM_Type also allows us to reduce the number of __invoke overloads from 32 to 8 and add
varargs support at the same time.
Because __invoke_enable_if knows the exact return type of __invoke for bullets 1-4 we no longer need to use decltype(__invoke(...)) to
compute the return type in the __invoke_return* traits. This will reduce the problems caused by #define decltype(X) __typeof__(X) in C++03.
Tests for this change have already been committed. All tests in test/std/utilities/function.objects now pass in C++03, previously there were 20 failures.
I know you didn't change this, but how did we get away with an && w/o a #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES ?