Create a new wxStringBase class, providing a STL-like API, using

the current wxString implementation.
  Derive wxString from one of wxStringBase, std::string, std::wstring
depending on wxUSE_STL/wxUSE_UNICODE settings. wxString provides
full compatibility with the old wxString in both wxUSE_STL=0 and
wxUSE_STL=1 modes (except for [Un]getWriteBuffer).
  Add some configure checks for std::string features.
  Add tests for STL API in console sample.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22280 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Mattia Barbon 2003-07-24 19:44:57 +00:00
parent 7918efb247
commit e87b783352
7 changed files with 1751 additions and 974 deletions

164
configure vendored
View File

@ -17656,6 +17656,170 @@ _ACEOF
fi
if test "$wxUSE_STL" = "yes"; then
ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
echo "$as_me:$LINENO: checking for basic STL functionality" >&5
echo $ECHO_N "checking for basic STL functionality... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
int
main ()
{
std::vector<int> moo;
std::list<int> foo;
std::vector<int>::iterator it =
std::find_if(moo.begin(), moo.end(),
std::bind2nd(std::less<int>(), 3));
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
{ { echo "$as_me:$LINENO: error: Basic STL functionality missing" >&5
echo "$as_me: error: Basic STL functionality missing" >&2;}
{ (exit 1); exit 1; }; }
fi
rm -f conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: checking for std::wstring in <string>" >&5
echo $ECHO_N "checking for std::wstring in <string>... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <string>
int
main ()
{
std::wstring foo;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_STD_WSTRING 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: checking for compliant std::string::compare" >&5
echo $ECHO_N "checking for compliant std::string::compare... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <string>
int
main ()
{
std::string foo, bar;
foo.compare(bar);
foo.compare(1, 1, bar);
foo.compare(1, 1, bar, 1, 1);
foo.compare("");
foo.compare(1, 1, "");
foo.compare(1, 1, "", 2);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_STD_STRING_COMPARE 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
SEARCH_INCLUDE="\
/usr/local/include \

View File

@ -1612,6 +1612,51 @@ WX_CPP_EXPLICIT
dnl check whether C++ compiler supports C++ casts
AC_CXX_CONST_CAST
dnl check various STL features
if test "$wxUSE_STL" = "yes"; then
AC_LANG_PUSH(C++)
dnl check for basic STL functionality
AC_MSG_CHECKING([for basic STL functionality])
AC_TRY_COMPILE([#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>],
[std::vector<int> moo;
std::list<int> foo;
std::vector<int>::iterator it =
std::find_if(moo.begin(), moo.end(),
std::bind2nd(std::less<int>(), 3));],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([Basic STL functionality missing])])
dnl check if <string> declares std::wstring
AC_MSG_CHECKING([for std::wstring in <string>])
AC_TRY_COMPILE([#include <string>],
[std::wstring foo;],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_STD_WSTRING)],
[AC_MSG_RESULT(no)])
dnl check for compliant std::string::compare
AC_MSG_CHECKING([for compliant std::string::compare])
AC_TRY_COMPILE([#include <string>],
[std::string foo, bar;
foo.compare(bar);
foo.compare(1, 1, bar);
foo.compare(1, 1, bar, 1, 1);
foo.compare("");
foo.compare(1, 1, "");
foo.compare(1, 1, "", 2);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_STD_STRING_COMPARE)],
[AC_MSG_RESULT(no)])
AC_LANG_POP
fi
dnl ---------------------------------------------------------------------------
dnl Define search path for includes and libraries: all headers and libs will be
dnl looked for in all directories of this path

View File

@ -230,7 +230,7 @@ typedef int wxWindowID;
// check for explicit keyword support
#ifndef HAVE_EXPLICIT
#if defined(__VISUALC__) && (__VISUALC__ >= 1100)
// VC++ 6.0 and 5.0 have explicit (what about the earlier versions?)
// VC++ 6.0 and 5.0 have explicit (what about earlier versions?)
#define HAVE_EXPLICIT
#elif ( defined(__MINGW32__) || defined(__CYGWIN32__) ) \
&& wxCHECK_GCC_VERSION(2, 95)
@ -256,7 +256,7 @@ typedef int wxWindowID;
// check for static/const/reinterpret_cast<>()
#ifndef HAVE_STATIC_CAST
#if defined(__VISUALC__) && (__VISUALC__ >= 1100)
// VC++ 6.0 and 5.0 have C++ casts (what about the earlier versions?)
// VC++ 6.0 and 5.0 have C++ casts (what about earlier versions?)
#define HAVE_CXX_CASTS
#elif ( defined(__MINGW32__) || defined(__CYGWIN32__) ) \
&& wxCHECK_GCC_VERSION(2, 95)
@ -271,6 +271,30 @@ typedef int wxWindowID;
#endif
#endif // HAVE_CXX_CASTS
#ifndef HAVE_STD_WSTRING
#if defined(__VISUALC__) && (__VISUALC__ >= 1100)
// VC++ 6.0 and 5.0 have std::wstring (what about earlier versions?)
#define HAVE_STD_WSTRING
#elif ( defined(__MINGW32__) || defined(__CYGWIN32__) ) \
&& wxCHECK_GCC_VERSION(3, 1)
// GCC 3.1 has std::wstring; 3.0 never was in MinGW, 2.95 hasn't it
#define HAVE_STD_WSTRING
#endif
#endif
#ifndef HAVE_STD_STRING_COMPARE
#if defined(__VISUALC__) && (__VISUALC__ >= 1100)
// VC++ 6.0 and 5.0 have std::string::compare
// (what about earlier versions?)
#define HAVE_STD_STRING_COMPARE
#elif ( defined(__MINGW32__) || defined(__CYGWIN32__) ) \
&& wxCHECK_GCC_VERSION(3, 1)
// GCC 3.1 has std::string::compare;
// 3.0 never was in MinGW, 2.95 hasn't it
#define HAVE_STD_STRING_COMPARE
#endif
#endif
// ----------------------------------------------------------------------------
// portable calling conventions macros
// ----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -96,10 +96,7 @@
#undef TEST_ALL
static const bool TEST_ALL = true;
#else
#define TEST_ARRAYS
#define TEST_HASH
#define TEST_LIST
#define TEST_SCOPEGUARD
#define TEST_HASHMAP
static const bool TEST_ALL = false;
#endif
@ -6071,14 +6068,14 @@ static void TestString()
for (int i = 0; i < 1000000; ++i)
{
a = "Hello";
b = " world";
c = "! How'ya doin'?";
a = _T("Hello");
b = _T(" world");
c = _T("! How'ya doin'?");
a += b;
a += c;
c = "Hello world! What's up?";
c = _T("Hello world! What's up?");
if (c != a)
c = "Doh!";
c = _T("Doh!");
}
wxPrintf(_T("TestString elapsed time: %ld\n"), sw.Time());
@ -6109,7 +6106,7 @@ static void TestPChar()
static void TestStringSub()
{
wxString s("Hello, world!");
wxString s(_T("Hello, world!"));
wxPuts(_T("*** Testing wxString substring extraction ***"));
@ -6406,6 +6403,180 @@ static void TestStringMatch()
wxPuts(_T(""));
}
// Sigh, I want Test::Simple, Test::More and Test::Harness...
void ok(int line, bool ok, const wxString& msg = wxEmptyString)
{
if( !ok )
wxPuts(_T("NOT OK: (") + wxString::Format(_T("%d"), line) +
_T(") ") + msg);
}
void is(int line, const wxString& got, const wxString& expected,
const wxString& msg = wxEmptyString)
{
bool isOk = got == expected;
ok(line, isOk, msg);
if( !isOk )
{
wxPuts(_T("Got: ") + got);
wxPuts(_T("Expected: ") + expected);
}
}
void is(int line, const wxChar& got, const wxChar& expected,
const wxString& msg = wxEmptyString)
{
bool isOk = got == expected;
ok(line, isOk, msg);
if( !isOk )
{
wxPuts("Got: " + got);
wxPuts("Expected: " + expected);
}
}
void TestStdString()
{
wxPuts(_T("*** Testing std::string operations ***\n"));
// test ctors
wxString s1(_T("abcdefgh")),
s2(_T("abcdefghijklm"), 8),
s3(_T("abcdefghijklm")),
s4(8, _T('a'));
wxString s5(s1),
s6(s3, 0, 8),
s7(s3.begin(), s3.begin() + 8);
wxString s8(s1, 4, 8), s9, s10, s11;
is( __LINE__, s1, _T("abcdefgh") );
is( __LINE__, s2, s1 );
is( __LINE__, s4, _T("aaaaaaaa") );
is( __LINE__, s5, _T("abcdefgh") );
is( __LINE__, s6, s1 );
is( __LINE__, s7, s1 );
is( __LINE__, s8, _T("efgh") );
// test append
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = _T("abc");
s1.append(_T("def"));
s2.append(_T("defgh"), 3);
s3.append(wxString(_T("abcdef")), 3, 6);
s4.append(s1);
s5.append(3, _T('a'));
s6.append(s1.begin() + 3, s1.end());
is( __LINE__, s1, _T("abcdef") );
is( __LINE__, s2, _T("abcdef") );
is( __LINE__, s3, _T("abcdef") );
is( __LINE__, s4, _T("abcabcdef") );
is( __LINE__, s5, _T("abcaaa") );
is( __LINE__, s6, _T("abcdef") );
// test assign
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = _T("abc");
s1.assign(_T("def"));
s2.assign(_T("defgh"), 3);
s3.assign(wxString(_T("abcdef")), 3, 6);
s4.assign(s1);
s5.assign(3, _T('a'));
s6.assign(s1.begin() + 1, s1.end());
is( __LINE__, s1, _T("def") );
is( __LINE__, s2, _T("def") );
is( __LINE__, s3, _T("def") );
is( __LINE__, s4, _T("def") );
is( __LINE__, s5, _T("aaa") );
is( __LINE__, s6, _T("ef") );
// test compare
s1 = _T("abcdefgh");
s2 = _T("abcdefgh");
s3 = _T("abc");
s4 = _T("abcdefghi");
s5 = _T("aaa");
s6 = _T("zzz");
s7 = _T("zabcdefg");
ok( __LINE__, s1.compare(s2) == 0 );
ok( __LINE__, s1.compare(s3) > 0 );
ok( __LINE__, s1.compare(s4) < 0 );
ok( __LINE__, s1.compare(s5) > 0 );
ok( __LINE__, s1.compare(s6) < 0 );
ok( __LINE__, s1.compare(1, 12, s1) > 0);
ok( __LINE__, s1.compare(_T("abcdefgh")) == 0);
ok( __LINE__, s1.compare(1, 7, _T("bcdefgh")) == 0);
ok( __LINE__, s1.compare(1, 7, _T("bcdefgh"), 7) == 0);
// test erase
s1.erase(1, 1);
s2.erase(4, 12);
wxString::iterator it = s3.erase(s3.begin() + 1);
wxString::iterator it2 = s4.erase(s4.begin() + 4, s4.begin() + 6);
wxString::iterator it3 = s7.erase(s7.begin() + 4, s7.begin() + 8);
is( __LINE__, s1, _T("acdefgh") );
is( __LINE__, s2, _T("abcd") );
is( __LINE__, s3, _T("ac") );
is( __LINE__, s4, _T("abcdghi") );
is( __LINE__, s7, _T("zabc") );
is( __LINE__, *it, _T('c') );
is( __LINE__, *it2, _T('g') );
ok( __LINE__, it3 == s7.end() );
// test insert
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = _T("aaaa");
s9 = s10 = _T("cdefg");
s1.insert(1, _T("cc") );
s2.insert(2, _T("cdef"), 3);
s3.insert(2, s10);
s4.insert(2, s10, 3, 7);
s5.insert(1, 2, _T('c'));
it = s6.insert(s6.begin() + 3, _T('X'));
s7.insert(s7.begin(), s9.begin(), s9.end() - 1);
s8.insert(s8.begin(), 2, _T('c'));
is( __LINE__, s1, _T("accaaa") );
is( __LINE__, s2, _T("aacdeaa") );
is( __LINE__, s3, _T("aacdefgaa") );
is( __LINE__, s4, _T("aafgaa") );
is( __LINE__, s5, _T("accaaa") );
is( __LINE__, s6, _T("aaaXa") );
is( __LINE__, s7, _T("cdefaaaa") );
is( __LINE__, s8, _T("ccaaaa") );
s1 = s2 = s3 = _T("aaaa");
s1.insert(0, _T("ccc"), 2);
s2.insert(4, _T("ccc"), 2);
is( __LINE__, s1, _T("ccaaaa") );
is( __LINE__, s2, _T("aaaacc") );
// test replace
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = _T("QWERTYUIOP");
s9 = s10 = _T("werty");
s1.replace(3, 4, _T("rtyu"));
s1.replace(8, 7, _T("opopop"));
s2.replace(10, 12, _T("WWWW"));
s3.replace(1, 5, s9);
s4.replace(1, 4, s9, 0, 4);
s5.replace(1, 2, s9, 1, 12);
s6.replace(0, 123, s9, 0, 123);
s7.replace(2, 7, s9);
is( __LINE__, s1, _T("QWErtyuIopopop") );
is( __LINE__, s2, _T("QWERTYUIOPWWWW") );
is( __LINE__, s3, _T("QwertyUIOP") );
is( __LINE__, s4, _T("QwertYUIOP") );
is( __LINE__, s5, _T("QertyRTYUIOP") );
is( __LINE__, s6, s9);
is( __LINE__, s7, _T("QWwertyP") );
wxPuts(_T("*** Testing std::string operations finished ***\n"));
}
#endif // TEST_STRINGS
// ----------------------------------------------------------------------------
@ -6416,16 +6587,6 @@ static void TestStringMatch()
#include "wx/snglinst.h"
#endif // TEST_SNGLINST
static int MyStringCompare(wxString* s1, wxString* s2)
{
return wxStrcmp(s1->c_str(), s2->c_str());
}
static int MyStringReverseCompare(wxString* s1, wxString* s2)
{
return -wxStrcmp(s1->c_str(), s2->c_str());
}
int main(int argc, char **argv)
{
wxApp::CheckBuildOptions(wxBuildOptions());
@ -6552,6 +6713,8 @@ int main(int argc, char **argv)
{
TestStringMatch();
}
TestStdString();
#endif // TEST_STRINGS
#ifdef TEST_ARRAYS
@ -6597,11 +6760,11 @@ int main(int argc, char **argv)
#endif
wxPuts(_T("*** After sorting a1"));
a1.Sort(&MyStringCompare);
a1.Sort(wxStringCompareAscending);
PrintArray(_T("a1"), a1);
wxPuts(_T("*** After sorting a1 in reverse order"));
a1.Sort(&MyStringReverseCompare);
a1.Sort(wxStringCompareDescending);
PrintArray(_T("a1"), a1);
#if !wxUSE_STL

View File

@ -157,6 +157,15 @@
*/
#undef HAVE_CONST_CAST
/*
* Define if your compiler has std::wstring
*/
#undef HAVE_STD_WSTRING
/*
* Define if your compiler has compilant std::string::compare
*/
#undef HAVE_STD_STRING_COMPARE
/*
* use STL for containers and wxString
*/

File diff suppressed because it is too large Load Diff