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
|
||||
// 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)
|
||||
|
||||
// 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
|
||||
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;
|
||||
// convert to wxLongLong
|
||||
#if defined(wxLongLong_t)
|
||||
|
||||
@@ -1266,6 +1266,24 @@ public:
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -1294,7 +1312,7 @@ public:
|
||||
Please refer to the documentation of the standard function @c strtol()
|
||||
for more details about the supported syntax.
|
||||
|
||||
@see ToCDouble(), ToDouble(), ToULong()
|
||||
@see ToCDouble(), ToDouble(), ToULong(), ToInt()
|
||||
*/
|
||||
bool ToLong(long* val, int base = 10) const;
|
||||
|
||||
|
||||
@@ -1677,6 +1677,32 @@ int wxString::Find(wxUniChar ch, bool bFromEnd) const
|
||||
*pVal = val; \
|
||||
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
|
||||
{
|
||||
wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
|
||||
|
||||
@@ -43,6 +43,8 @@ private:
|
||||
CPPUNIT_TEST( Compare );
|
||||
CPPUNIT_TEST( CompareNoCase );
|
||||
CPPUNIT_TEST( Contains );
|
||||
CPPUNIT_TEST( ToInt );
|
||||
CPPUNIT_TEST( ToUInt );
|
||||
CPPUNIT_TEST( ToLong );
|
||||
CPPUNIT_TEST( ToULong );
|
||||
#ifdef wxLongLong_t
|
||||
@@ -78,6 +80,8 @@ private:
|
||||
void Compare();
|
||||
void CompareNoCase();
|
||||
void Contains();
|
||||
void ToInt();
|
||||
void ToUInt();
|
||||
void ToLong();
|
||||
void ToULong();
|
||||
#ifdef wxLongLong_t
|
||||
@@ -602,7 +606,8 @@ enum
|
||||
Number_Unsigned = 2, // if not specified, works for signed conversion
|
||||
Number_Signed = 4, // if not specified, works for unsigned
|
||||
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
|
||||
@@ -613,6 +618,38 @@ typedef long TestValue_t;
|
||||
|
||||
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
|
||||
{
|
||||
const wxChar *str;
|
||||
@@ -670,6 +707,64 @@ static const struct ToLongData
|
||||
|
||||
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()
|
||||
{
|
||||
long l;
|
||||
|
||||
Reference in New Issue
Block a user