Add conversion to signed/unsigned int to wxString
Add wxString::ToInt() and ToUInt() for convenience and consistency with the existing ToLong() and ToULong(). Closes #22068.
This commit is contained in:
committed by
Vadim Zeitlin
parent
c10a70be67
commit
9dc7248b1d
@@ -2310,9 +2310,14 @@ public:
|
|||||||
// provided, the base is the numeric base in which the conversion should be
|
// provided, the base is the numeric base in which the conversion should be
|
||||||
// done and must be comprised between 2 and 36 or be 0 in which case the
|
// done and must be comprised between 2 and 36 or be 0 in which case the
|
||||||
// standard C rules apply (leading '0' => octal, "0x" => hex)
|
// standard C rules apply (leading '0' => octal, "0x" => hex)
|
||||||
|
|
||||||
// convert to a signed integer
|
// convert to a signed integer
|
||||||
bool ToLong(long *val, int base = 10) const;
|
bool ToInt(int *val, int base = 10) const;
|
||||||
// convert to an unsigned integer
|
// convert to an unsigned integer
|
||||||
|
bool ToUInt(unsigned int *val, int base = 10) const;
|
||||||
|
// convert to a signed long
|
||||||
|
bool ToLong(long *val, int base = 10) const;
|
||||||
|
// convert to an unsigned long
|
||||||
bool ToULong(unsigned long *val, int base = 10) const;
|
bool ToULong(unsigned long *val, int base = 10) const;
|
||||||
// convert to wxLongLong
|
// convert to wxLongLong
|
||||||
#if defined(wxLongLong_t)
|
#if defined(wxLongLong_t)
|
||||||
|
|||||||
@@ -1266,6 +1266,24 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool ToCDouble(double* val) const;
|
bool ToCDouble(double* val) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Works like ToLong() but for signed integers.
|
||||||
|
|
||||||
|
@see ToLong(), ToUInt(), ToDouble()
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
bool ToInt(int *val, int base = 10) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Works like ToULong() but for unsigned integers.
|
||||||
|
|
||||||
|
@see ToInt(), ToULong(), ToDouble()
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
bool ToUInt(unsigned int *val, int base = 10) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Attempts to convert the string to a signed integer in base @a base.
|
Attempts to convert the string to a signed integer in base @a base.
|
||||||
|
|
||||||
@@ -1294,7 +1312,7 @@ public:
|
|||||||
Please refer to the documentation of the standard function @c strtol()
|
Please refer to the documentation of the standard function @c strtol()
|
||||||
for more details about the supported syntax.
|
for more details about the supported syntax.
|
||||||
|
|
||||||
@see ToCDouble(), ToDouble(), ToULong()
|
@see ToCDouble(), ToDouble(), ToULong(), ToInt()
|
||||||
*/
|
*/
|
||||||
bool ToLong(long* val, int base = 10) const;
|
bool ToLong(long* val, int base = 10) const;
|
||||||
|
|
||||||
|
|||||||
@@ -1677,6 +1677,32 @@ int wxString::Find(wxUniChar ch, bool bFromEnd) const
|
|||||||
*pVal = val; \
|
*pVal = val; \
|
||||||
return !*end;
|
return !*end;
|
||||||
|
|
||||||
|
bool wxString::ToInt(int *pVal, int base) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(!base || (base > 1 && base <= 36), wxT("invalid base"));
|
||||||
|
|
||||||
|
WX_STRING_TO_X_TYPE_START
|
||||||
|
wxLongLong_t lval = wxStrtoll(start, &end, base);
|
||||||
|
|
||||||
|
if (lval < INT_MIN || lval > INT_MAX)
|
||||||
|
return false;
|
||||||
|
int val = (int)lval;
|
||||||
|
|
||||||
|
WX_STRING_TO_X_TYPE_END
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxString::ToUInt(unsigned int *pVal, int base) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(!base || (base > 1 && base <= 36), wxT("invalid base"));
|
||||||
|
|
||||||
|
WX_STRING_TO_X_TYPE_START
|
||||||
|
wxULongLong_t lval = wxStrtoull(start, &end, base);
|
||||||
|
if (lval > UINT_MAX)
|
||||||
|
return false;
|
||||||
|
unsigned int val = (unsigned int)lval;
|
||||||
|
WX_STRING_TO_X_TYPE_END
|
||||||
|
}
|
||||||
|
|
||||||
bool wxString::ToLong(long *pVal, int base) const
|
bool wxString::ToLong(long *pVal, int base) const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
|
wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ private:
|
|||||||
CPPUNIT_TEST( Compare );
|
CPPUNIT_TEST( Compare );
|
||||||
CPPUNIT_TEST( CompareNoCase );
|
CPPUNIT_TEST( CompareNoCase );
|
||||||
CPPUNIT_TEST( Contains );
|
CPPUNIT_TEST( Contains );
|
||||||
|
CPPUNIT_TEST( ToInt );
|
||||||
|
CPPUNIT_TEST( ToUInt );
|
||||||
CPPUNIT_TEST( ToLong );
|
CPPUNIT_TEST( ToLong );
|
||||||
CPPUNIT_TEST( ToULong );
|
CPPUNIT_TEST( ToULong );
|
||||||
#ifdef wxLongLong_t
|
#ifdef wxLongLong_t
|
||||||
@@ -78,6 +80,8 @@ private:
|
|||||||
void Compare();
|
void Compare();
|
||||||
void CompareNoCase();
|
void CompareNoCase();
|
||||||
void Contains();
|
void Contains();
|
||||||
|
void ToInt();
|
||||||
|
void ToUInt();
|
||||||
void ToLong();
|
void ToLong();
|
||||||
void ToULong();
|
void ToULong();
|
||||||
#ifdef wxLongLong_t
|
#ifdef wxLongLong_t
|
||||||
@@ -602,7 +606,8 @@ enum
|
|||||||
Number_Unsigned = 2, // if not specified, works for signed conversion
|
Number_Unsigned = 2, // if not specified, works for signed conversion
|
||||||
Number_Signed = 4, // if not specified, works for unsigned
|
Number_Signed = 4, // if not specified, works for unsigned
|
||||||
Number_LongLong = 8, // only for long long tests
|
Number_LongLong = 8, // only for long long tests
|
||||||
Number_Long = 16 // only for long tests
|
Number_Long = 16, // only for long tests
|
||||||
|
Number_Int = 32 // only for int tests
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef wxLongLong_t
|
#ifdef wxLongLong_t
|
||||||
@@ -613,6 +618,38 @@ typedef long TestValue_t;
|
|||||||
|
|
||||||
wxGCC_WARNING_SUPPRESS(missing-field-initializers)
|
wxGCC_WARNING_SUPPRESS(missing-field-initializers)
|
||||||
|
|
||||||
|
static const struct ToIntData
|
||||||
|
{
|
||||||
|
const wxChar *str;
|
||||||
|
TestValue_t value;
|
||||||
|
int flags;
|
||||||
|
int base;
|
||||||
|
|
||||||
|
int IValue() const { return value; }
|
||||||
|
unsigned int UIValue() const { return value; }
|
||||||
|
|
||||||
|
bool IsOk() const { return !(flags & Number_Invalid); }
|
||||||
|
} intData[] =
|
||||||
|
{
|
||||||
|
{ wxT("1"), 1, Number_Ok },
|
||||||
|
{ wxT("0"), 0, Number_Ok },
|
||||||
|
{ wxT("a"), 0, Number_Invalid },
|
||||||
|
{ wxT("12345"), 12345, Number_Ok },
|
||||||
|
{ wxT("--1"), 0, Number_Invalid },
|
||||||
|
|
||||||
|
{ wxT("-1"), -1, Number_Signed | Number_Int },
|
||||||
|
{ wxT("-1"), (TestValue_t)UINT_MAX, Number_Unsigned | Number_Int | Number_Invalid },
|
||||||
|
|
||||||
|
{ wxT("2147483647"), (TestValue_t)INT_MAX, Number_Int | Number_Signed },
|
||||||
|
{ wxT("2147483648"), (TestValue_t)INT_MAX, Number_Int | Number_Signed | Number_Invalid },
|
||||||
|
|
||||||
|
{ wxT("-2147483648"), (TestValue_t)INT_MIN, Number_Int | Number_Signed },
|
||||||
|
{ wxT("-2147483649"), (TestValue_t)INT_MIN, Number_Int | Number_Signed | Number_Invalid },
|
||||||
|
|
||||||
|
{ wxT("4294967295"), (TestValue_t)UINT_MAX, Number_Int | Number_Unsigned },
|
||||||
|
{ wxT("4294967296"), (TestValue_t)UINT_MAX, Number_Int | Number_Unsigned | Number_Invalid },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct ToLongData
|
static const struct ToLongData
|
||||||
{
|
{
|
||||||
const wxChar *str;
|
const wxChar *str;
|
||||||
@@ -670,6 +707,64 @@ static const struct ToLongData
|
|||||||
|
|
||||||
wxGCC_WARNING_RESTORE(missing-field-initializers)
|
wxGCC_WARNING_RESTORE(missing-field-initializers)
|
||||||
|
|
||||||
|
void StringTestCase::ToInt()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (size_t n = 0; n < WXSIZEOF(intData); n++)
|
||||||
|
{
|
||||||
|
const ToIntData &id = intData[n];
|
||||||
|
|
||||||
|
if (id.flags & (Number_Unsigned))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(id.IsOk(),
|
||||||
|
wxString(id.str).ToInt(&i, id.base));
|
||||||
|
|
||||||
|
if (id.IsOk())
|
||||||
|
CPPUNIT_ASSERT_EQUAL(id.IValue(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case: check that the output is not modified if the parsing
|
||||||
|
// failed completely
|
||||||
|
i = 17;
|
||||||
|
CPPUNIT_ASSERT(!wxString("foo").ToInt(&i));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(17, i);
|
||||||
|
|
||||||
|
// also check that it is modified if we did parse something successfully in
|
||||||
|
// the beginning of the string
|
||||||
|
CPPUNIT_ASSERT(!wxString("9 cats").ToInt(&i));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(9, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringTestCase::ToUInt()
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (size_t n = 0; n < WXSIZEOF(intData); n++)
|
||||||
|
{
|
||||||
|
const ToIntData &id = intData[n];
|
||||||
|
|
||||||
|
if (id.flags & (Number_Signed))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(id.IsOk(),
|
||||||
|
wxString(id.str).ToUInt(&i, id.base));
|
||||||
|
|
||||||
|
if (id.IsOk())
|
||||||
|
CPPUNIT_ASSERT_EQUAL(id.UIValue(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case: check that the output is not modified if the parsing
|
||||||
|
// failed completely
|
||||||
|
i = 17;
|
||||||
|
CPPUNIT_ASSERT(!wxString("foo").ToUInt(&i));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(17, i);
|
||||||
|
|
||||||
|
// also check that it is modified if we did parse something successfully in
|
||||||
|
// the beginning of the string
|
||||||
|
CPPUNIT_ASSERT(!wxString("9 cats").ToUInt(&i));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(9, i);
|
||||||
|
}
|
||||||
|
|
||||||
void StringTestCase::ToLong()
|
void StringTestCase::ToLong()
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
|
|||||||
Reference in New Issue
Block a user