From 6d93e28adf4824a4e6a485e72b1fa64a4698403d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 31 Jul 2012 16:49:36 +0000 Subject: [PATCH] Fix comparisons of char and wchar_t with wxUniChar[Ref]. Comparisons didn't work correctly in the other direction as they were not reversed as needed. Fix this by adding wxDEFINE_COMPARISON_REV() macro which defines comparisons in terms of the reverse operations and use it for both wxUniChar and wxUniCharRef. Closes #14547. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72268 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 19 +++++++++++++++++-- include/wx/unichar.h | 14 +++++--------- tests/strings/unichar.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index 9f56272..2f58fef 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -673,9 +673,13 @@ typedef short int WXTYPE; m(==,x,y,z) m(!=,x,y,z) m(>=,x,y,z) m(<=,x,y,z) m(>,x,y,z) m(<,x,y,z) /* - This is only used with wxDEFINE_COMPARISON_REV: it passes both the normal - and the reversed comparison operators to the macro. + These are only used with wxDEFINE_COMPARISON_[BY_]REV: they pass both the + normal and the reversed comparison operators to the macro. */ +#define wxFOR_ALL_COMPARISONS_2_REV(m, x, y) \ + m(==,x,y,==) m(!=,x,y,!=) m(>=,x,y,<=) \ + m(<=,x,y,>=) m(>,x,y,<) m(<,x,y,>) + #define wxFOR_ALL_COMPARISONS_3_REV(m, x, y, z) \ m(==,x,y,z,==) m(!=,x,y,z,!=) m(>=,x,y,z,<=) \ m(<=,x,y,z,>=) m(>,x,y,z,<) m(<,x,y,z,>) @@ -687,6 +691,9 @@ typedef short int WXTYPE; #define wxDEFINE_COMPARISON_REV(op, T1, T2, cmp, oprev) \ inline bool operator op(T2 y, T1 x) { return cmp(x, y, oprev); } +#define wxDEFINE_COMPARISON_BY_REV(op, T1, T2, oprev) \ + inline bool operator op(T1 x, T2 y) { return y oprev x; } + /* Define all 6 comparison operators (==, !=, <, <=, >, >=) for the given types in the specified order. The implementation is provided by the cmp @@ -697,6 +704,14 @@ typedef short int WXTYPE; wxFOR_ALL_COMPARISONS_3(wxDEFINE_COMPARISON, T1, T2, cmp) /* + Define all 6 comparison operators (==, !=, <, <=, >, >=) for the given + types in the specified order, implemented in terms of existing operators + for the reverse order. + */ +#define wxDEFINE_COMPARISONS_BY_REV(T1, T2) \ + wxFOR_ALL_COMPARISONS_2_REV(wxDEFINE_COMPARISON_BY_REV, T1, T2) + +/* This macro allows to define all 12 comparison operators (6 operators for both orders of arguments) for the given types using the provided "cmp" macro to implement the actual comparison: the macro is called with the 2 diff --git a/include/wx/unichar.h b/include/wx/unichar.h index 5d019f5..fe99644 100644 --- a/include/wx/unichar.h +++ b/include/wx/unichar.h @@ -329,17 +329,13 @@ inline wxUniChar& wxUniChar::operator=(const wxUniCharRef& c) // Comparison operators for the case when wxUniChar(Ref) is the second operand // implemented in terms of member comparison functions -#define wxCMP_REVERSE(c1, c2, op) c2 op c1 +wxDEFINE_COMPARISONS_BY_REV(char, const wxUniChar&) +wxDEFINE_COMPARISONS_BY_REV(char, const wxUniCharRef&) -wxDEFINE_COMPARISONS(char, const wxUniChar&, wxCMP_REVERSE) -wxDEFINE_COMPARISONS(char, const wxUniCharRef&, wxCMP_REVERSE) +wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniChar&) +wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniCharRef&) -wxDEFINE_COMPARISONS(wchar_t, const wxUniChar&, wxCMP_REVERSE) -wxDEFINE_COMPARISONS(wchar_t, const wxUniCharRef&, wxCMP_REVERSE) - -wxDEFINE_COMPARISONS(const wxUniChar&, const wxUniCharRef&, wxCMP_REVERSE) - -#undef wxCMP_REVERSE +wxDEFINE_COMPARISONS_BY_REV(const wxUniChar&, const wxUniCharRef&) // for expressions like c-'A': inline int operator-(char c1, const wxUniCharRef& c2) { return -(c2 - c1); } diff --git a/tests/strings/unichar.cpp b/tests/strings/unichar.cpp index 4bd9dfd..e955aa0 100644 --- a/tests/strings/unichar.cpp +++ b/tests/strings/unichar.cpp @@ -68,48 +68,96 @@ void UniCharTestCase::CharCompare() CPPUNIT_ASSERT( a == wxUniChar('a') ); CPPUNIT_ASSERT( a == wxUniChar(wxT('a')) ); + CPPUNIT_ASSERT( a == a ); + CPPUNIT_ASSERT( 'a' == a ); + CPPUNIT_ASSERT( wxT('a') == a ); + CPPUNIT_ASSERT( wxUniChar('a') == a ); + CPPUNIT_ASSERT( wxUniChar(wxT('a')) == a ); + CPPUNIT_ASSERT( a != b ); CPPUNIT_ASSERT( a != 'b' ); CPPUNIT_ASSERT( a != wxT('b') ); CPPUNIT_ASSERT( a != wxUniChar('b') ); CPPUNIT_ASSERT( a != wxUniChar(wxT('b')) ); + CPPUNIT_ASSERT( b != a ); + CPPUNIT_ASSERT( 'b' != a ); + CPPUNIT_ASSERT( wxT('b') != a ); + CPPUNIT_ASSERT( wxUniChar('b') != a ); + CPPUNIT_ASSERT( wxUniChar(wxT('b')) != a ); + CPPUNIT_ASSERT( a < b ); CPPUNIT_ASSERT( a < 'b' ); CPPUNIT_ASSERT( a < wxT('b') ); CPPUNIT_ASSERT( a < wxUniChar('b') ); CPPUNIT_ASSERT( a < wxUniChar(wxT('b')) ); + CPPUNIT_ASSERT( b > a ); + CPPUNIT_ASSERT( 'b' > a ); + CPPUNIT_ASSERT( wxT('b') > a ); + CPPUNIT_ASSERT( wxUniChar('b') > a ); + CPPUNIT_ASSERT( wxUniChar(wxT('b')) > a ); + CPPUNIT_ASSERT( a <= b ); CPPUNIT_ASSERT( a <= 'b' ); CPPUNIT_ASSERT( a <= wxT('b') ); CPPUNIT_ASSERT( a <= wxUniChar('b') ); CPPUNIT_ASSERT( a <= wxUniChar(wxT('b')) ); + CPPUNIT_ASSERT( b >= a ); + CPPUNIT_ASSERT( 'b' >= a ); + CPPUNIT_ASSERT( wxT('b') >= a ); + CPPUNIT_ASSERT( wxUniChar('b') >= a ); + CPPUNIT_ASSERT( wxUniChar(wxT('b')) >= a ); + CPPUNIT_ASSERT( a <= a ); CPPUNIT_ASSERT( a <= 'a' ); CPPUNIT_ASSERT( a <= wxT('a') ); CPPUNIT_ASSERT( a <= wxUniChar('a') ); CPPUNIT_ASSERT( a <= wxUniChar(wxT('a')) ); + CPPUNIT_ASSERT( a >= a ); + CPPUNIT_ASSERT( 'a' >= a ); + CPPUNIT_ASSERT( wxT('a') >= a ); + CPPUNIT_ASSERT( wxUniChar('a') >= a ); + CPPUNIT_ASSERT( wxUniChar(wxT('a')) >= a ); + CPPUNIT_ASSERT( b > a ); CPPUNIT_ASSERT( b > 'a' ); CPPUNIT_ASSERT( b > wxT('a') ); CPPUNIT_ASSERT( b > wxUniChar('a') ); CPPUNIT_ASSERT( b > wxUniChar(wxT('a')) ); + CPPUNIT_ASSERT( a < b ); + CPPUNIT_ASSERT( 'a' < b ); + CPPUNIT_ASSERT( wxT('a') < b ); + CPPUNIT_ASSERT( wxUniChar('a') < b ); + CPPUNIT_ASSERT( wxUniChar(wxT('a')) < b ); + CPPUNIT_ASSERT( b >= a ); CPPUNIT_ASSERT( b >= 'a' ); CPPUNIT_ASSERT( b >= wxT('a') ); CPPUNIT_ASSERT( b >= wxUniChar('a') ); CPPUNIT_ASSERT( b >= wxUniChar(wxT('a')) ); + CPPUNIT_ASSERT( a <= b ); + CPPUNIT_ASSERT( 'a' <= b ); + CPPUNIT_ASSERT( wxT('a') <= b ); + CPPUNIT_ASSERT( wxUniChar('a') <= b ); + CPPUNIT_ASSERT( wxUniChar(wxT('a')) <= b ); + CPPUNIT_ASSERT( b >= b ); CPPUNIT_ASSERT( b >= 'b' ); CPPUNIT_ASSERT( b >= wxT('b') ); CPPUNIT_ASSERT( b >= wxUniChar('b') ); CPPUNIT_ASSERT( b >= wxUniChar(wxT('b')) ); + CPPUNIT_ASSERT( b <= b ); + CPPUNIT_ASSERT( 'b' <= b ); + CPPUNIT_ASSERT( wxT('b') <= b ); + CPPUNIT_ASSERT( wxUniChar('b') <= b ); + CPPUNIT_ASSERT( wxUniChar(wxT('b')) <= b ); + CPPUNIT_ASSERT( b - a == 1 ); CPPUNIT_ASSERT( a - b == -1 ); } -- 2.7.4