Fix wxStringTokenizer copy ctor and assignment operator.

Implement copying of wxStringTokenizer correctly: compiler-generated versions
didn't work as the position of the tokenizer didn't point into the correct
string after making the copy.

Fix this by adjusting the position iterator to use the copy of the string.

Closes #16339.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78050 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-10-20 15:08:09 +00:00
parent 82a591c138
commit 069415c2a6
4 changed files with 78 additions and 0 deletions

View File

@ -47,6 +47,7 @@ All:
- Specialize std::hash<> for wxString when using C++11.
- Allow recursive calls to wxYield().
- Add wxART_FULL_SCREEN standard bitmap (Igor Korot).
- Fix wxStringTokenizer copy ctor and assignment operator.
Unix:

View File

@ -47,6 +47,9 @@ public:
wxStringTokenizer(const wxString& str,
const wxString& delims = wxDEFAULT_DELIMITERS,
wxStringTokenizerMode mode = wxTOKEN_DEFAULT);
// copy ctor and assignment operator
wxStringTokenizer(const wxStringTokenizer& src);
wxStringTokenizer& operator=(const wxStringTokenizer& src);
// args are same as for the non default ctor above
void SetString(const wxString& str,
@ -112,6 +115,8 @@ protected:
bool DoHasMoreTokens() const;
void DoCopyFrom(const wxStringTokenizer& src);
enum MoreTokensState
{
MoreTokens_Unknown,

View File

@ -84,6 +84,21 @@ wxStringTokenizer::wxStringTokenizer(const wxString& str,
SetString(str, delims, mode);
}
wxStringTokenizer::wxStringTokenizer(const wxStringTokenizer& src)
{
DoCopyFrom(src);
}
wxStringTokenizer& wxStringTokenizer::operator=(const wxStringTokenizer& src)
{
if (this != &src)
{
DoCopyFrom(src);
}
return *this;
}
void wxStringTokenizer::SetString(const wxString& str,
const wxString& delims,
wxStringTokenizerMode mode)
@ -136,6 +151,18 @@ void wxStringTokenizer::Reinit(const wxString& str)
m_hasMoreTokens = MoreTokens_Unknown;
}
void wxStringTokenizer::DoCopyFrom(const wxStringTokenizer& src)
{
m_string = src.m_string;
m_stringEnd = m_string.end();
m_pos = m_string.begin() + (src.m_pos - src.m_string.begin());
m_delims = src.m_delims;
m_delimsLen = src.m_delimsLen;
m_mode = src.m_mode;
m_lastDelim = src.m_lastDelim;
m_hasMoreTokens = src.m_hasMoreTokens;
}
// ----------------------------------------------------------------------------
// access to the tokens
// ----------------------------------------------------------------------------

View File

@ -38,6 +38,8 @@ private:
CPPUNIT_TEST( GetString );
CPPUNIT_TEST( LastDelimiter );
CPPUNIT_TEST( StrtokCompat );
CPPUNIT_TEST( CopyObj );
CPPUNIT_TEST( AssignObj );
CPPUNIT_TEST_SUITE_END();
void GetCount();
@ -45,6 +47,8 @@ private:
void GetString();
void LastDelimiter();
void StrtokCompat();
void CopyObj();
void AssignObj();
DECLARE_NO_COPY_CLASS(TokenizerTestCase)
};
@ -268,4 +272,45 @@ void TokenizerTestCase::StrtokCompat()
}
}
void TokenizerTestCase::CopyObj()
{
// Test copy ctor
wxStringTokenizer tkzSrc(wxT("first:second:third:fourth"), wxT(":"));
while ( tkzSrc.HasMoreTokens() )
{
wxString tokenSrc = tkzSrc.GetNextToken();
wxStringTokenizer tkz = tkzSrc;
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
// Change the state of both objects and compare again...
tokenSrc = tkzSrc.GetNextToken();
wxString token = tkz.GetNextToken();
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
}
}
void TokenizerTestCase::AssignObj()
{
// Test assignment
wxStringTokenizer tkzSrc(wxT("first:second:third:fourth"), wxT(":"));
wxStringTokenizer tkz;
while ( tkzSrc.HasMoreTokens() )
{
wxString tokenSrc = tkzSrc.GetNextToken();
tkz = tkzSrc;
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
// Change the state of both objects and compare again...
tokenSrc = tkzSrc.GetNextToken();
wxString token = tkz.GetNextToken();
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
}
}