Define std::swap() correctly for wxUniCharRef.

The default implementation doesn't work for this reference-like class, and
this breaks not only swap() itself (see #14694), but also any algorithms using
it, such as std::reverse().

Fix this by providing our own specialization which does work correctly.

Closes #16234.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76474 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-05-07 13:09:40 +00:00
parent 5b56498f88
commit b445166012

View File

@@ -14,6 +14,8 @@
#include "wx/chartype.h"
#include "wx/stringimpl.h"
#include <algorithm> // only for std::swap specialization below
class WXDLLIMPEXP_FWD_BASE wxUniCharRef;
class WXDLLIMPEXP_FWD_BASE wxString;
@@ -289,6 +291,33 @@ inline wxUniChar& wxUniChar::operator=(const wxUniCharRef& c)
return *this;
}
// wxUniCharRef doesn't behave quite like a reference, notably because template
// deduction from wxUniCharRef doesn't yield wxUniChar as would have been the
// case if it were a real reference. This results in a number of problems and
// we can't fix all of them but we can at least provide a working swap() for
// it, instead of the default version which doesn't work because a "wrong" type
// is deduced.
namespace std
{
template <>
void swap<wxUniCharRef>(wxUniCharRef& lhs, wxUniCharRef& rhs)
{
if ( &lhs != &rhs )
{
// The use of wxUniChar here is the crucial difference: in the default
// implementation, tmp would be wxUniCharRef and so assigning to lhs
// would modify it too. Here we make a real copy, not affected by
// changing lhs, instead.
wxUniChar tmp = lhs;
lhs = rhs;
rhs = tmp;
}
}
} // namespace std
// Comparison operators for the case when wxUniChar(Ref) is the second operand
// implemented in terms of member comparison functions