corelib/tests/strings-builder.cc
Emmanuel BENOîT db215e4baf Strings - Fixed appendNumeric(INT64_MIN)
Couldn't work as it was trying to store the absolute value in a signed
64-bit integer.
2020-10-01 13:20:50 +02:00

1163 lines
34 KiB
C++

#include <ebcl/Strings.hh>
#include <limits>
#include <cppunit/extensions/HelperMacros.h>
using namespace ebcl;
class StringsBuilderTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( StringsBuilderTest );
CPPUNIT_TEST( testConsDefault );
CPPUNIT_TEST( testConsFromAsciiBuffer );
CPPUNIT_TEST( testConsFromUTF8Buffer );
CPPUNIT_TEST( testConsFromAsciiNTS );
CPPUNIT_TEST( testConsFromUTF8NTS );
CPPUNIT_TEST( testConsFromString );
CPPUNIT_TEST( testCopyCons );
CPPUNIT_TEST( testCopyAss );
CPPUNIT_TEST( testMoveCons );
CPPUNIT_TEST( testMoveAss );
CPPUNIT_TEST( testSwap );
CPPUNIT_TEST( testEnsureCapacityFactor );
CPPUNIT_TEST( testEnsureCapacityOther );
CPPUNIT_TEST( testEnsureCapacitySmaller );
CPPUNIT_TEST( testClear );
CPPUNIT_TEST( testFree );
CPPUNIT_TEST( testTruncate );
CPPUNIT_TEST( testTruncateLonger );
CPPUNIT_TEST( testAppendOther );
CPPUNIT_TEST( testAppendSwap );
CPPUNIT_TEST( testAppendStr );
CPPUNIT_TEST( testAppendBuf );
CPPUNIT_TEST( testAppendChar );
CPPUNIT_TEST( testAppendUnicode );
CPPUNIT_TEST( testAppendNumSignedZeroB10 );
CPPUNIT_TEST( testAppendNumSignedPositiveB10 );
CPPUNIT_TEST( testAppendNumSignedNegativeB10 );
CPPUNIT_TEST( testAppendNumSignedMinB10 );
CPPUNIT_TEST( testAppendNumSignedMaxB10 );
CPPUNIT_TEST( testAppendNumSignedRest );
CPPUNIT_TEST( testAppendNumUnsigned );
CPPUNIT_TEST( testAppendNumFloat );
CPPUNIT_TEST( testStringConsCopy );
CPPUNIT_TEST( testStringAssCopy );
CPPUNIT_TEST( testStringConsMove );
CPPUNIT_TEST( testStringAssMove );
CPPUNIT_TEST( testCmpOther );
CPPUNIT_TEST( testCmpCString );
CPPUNIT_TEST( testCmpTString );
CPPUNIT_TEST( testToUnsignedBasic );
CPPUNIT_TEST( testToUnsignedOkValue );
CPPUNIT_TEST( testToUnsignedInvalid );
CPPUNIT_TEST( testToUnsignedTooLarge );
CPPUNIT_TEST( testToUnsignedBaseOk );
CPPUNIT_TEST( testToUnsignedBaseInvalid );
CPPUNIT_TEST( testToUnsignedBaseAutoBinary );
CPPUNIT_TEST( testToUnsignedBaseAutoOctal );
CPPUNIT_TEST( testToUnsignedBaseAutoDecimal );
CPPUNIT_TEST( testToUnsignedBaseAutoHexa );
CPPUNIT_TEST( testToUnsignedBaseAutoZero );
CPPUNIT_TEST( testToUnsignedBaseAutoInvalid );
CPPUNIT_TEST( testToUnsignedBaseAutoCut );
CPPUNIT_TEST( testToUnsignedSeparator );
CPPUNIT_TEST( testToUnsignedSeparatorCustom );
CPPUNIT_TEST( testToUnsignedSeparatorCustomUTF8 );
CPPUNIT_TEST( testToUnsignedLeadingWhitespace );
CPPUNIT_TEST( testToUnsignedLeadingWhitespaceOnly );
CPPUNIT_TEST( testToSignedBasic );
CPPUNIT_TEST( testToSignedOkValue );
CPPUNIT_TEST( testToSignedPlus );
CPPUNIT_TEST( testToSignedPlusMultiple );
CPPUNIT_TEST( testToSignedMinus );
CPPUNIT_TEST( testToSignedMinusMultiple );
CPPUNIT_TEST( testToSignedInvalid );
CPPUNIT_TEST( testToSignedTooLarge );
CPPUNIT_TEST( testToSignedTooSmall );
CPPUNIT_TEST( testToSignedBaseOk );
CPPUNIT_TEST( testToSignedBaseInvalid );
CPPUNIT_TEST( testToSignedBaseAutoBinary );
CPPUNIT_TEST( testToSignedBaseAutoOctal );
CPPUNIT_TEST( testToSignedBaseAutoDecimal );
CPPUNIT_TEST( testToSignedBaseAutoHexa );
CPPUNIT_TEST( testToSignedBaseAutoZero );
CPPUNIT_TEST( testToSignedBaseAutoInvalid );
CPPUNIT_TEST( testToSignedBaseAutoCut );
CPPUNIT_TEST( testToSignedBaseAutoPlus );
CPPUNIT_TEST( testToSignedBaseAutoMinus );
CPPUNIT_TEST( testToSignedSeparator );
CPPUNIT_TEST( testToSignedSeparatorCustom );
CPPUNIT_TEST( testToSignedSeparatorCustomUTF8 );
CPPUNIT_TEST( testToSignedLeadingWhitespace );
CPPUNIT_TEST( testToSignedLeadingWhitespaceOnly );
CPPUNIT_TEST( testToDouble );
CPPUNIT_TEST_SUITE_END( );
public:
void testConsDefault( );
void testConsFromAsciiBuffer( );
void testConsFromUTF8Buffer( );
void testConsFromAsciiNTS( );
void testConsFromUTF8NTS( );
void testConsFromString( );
void testCopyCons( );
void testCopyAss( );
void testMoveCons( );
void testMoveAss( );
void testSwap( );
void testEnsureCapacityFactor( );
void testEnsureCapacityOther( );
void testEnsureCapacitySmaller( );
void testClear( );
void testFree( );
void testTruncate( );
void testTruncateLonger( );
void testAppendOther( );
void testAppendSwap( );
void testAppendStr( );
void testAppendBuf( );
void testAppendChar( );
void testAppendUnicode( );
void testAppendNumSignedZeroB10( );
void testAppendNumSignedPositiveB10( );
void testAppendNumSignedNegativeB10( );
void testAppendNumSignedMinB10( );
void testAppendNumSignedMaxB10( );
void testAppendNumSignedRest( );
void testAppendNumUnsigned( );
void testAppendNumFloat( );
void testStringConsCopy( );
void testStringAssCopy( );
void testStringConsMove( );
void testStringAssMove( );
void testCmpOther( );
void testCmpCString( );
void testCmpTString( );
void testToUnsignedBasic( );
void testToUnsignedOkValue( );
void testToUnsignedInvalid( );
void testToUnsignedTooLarge( );
void testToUnsignedBaseOk( );
void testToUnsignedBaseInvalid( );
void testToUnsignedBaseAutoBinary( );
void testToUnsignedBaseAutoOctal( );
void testToUnsignedBaseAutoDecimal( );
void testToUnsignedBaseAutoHexa( );
void testToUnsignedBaseAutoZero( );
void testToUnsignedBaseAutoInvalid( );
void testToUnsignedBaseAutoCut( );
void testToUnsignedSeparator( );
void testToUnsignedSeparatorCustom( );
void testToUnsignedSeparatorCustomUTF8( );
void testToUnsignedLeadingWhitespace( );
void testToUnsignedLeadingWhitespaceOnly( );
void testToSignedBasic( );
void testToSignedOkValue( );
void testToSignedPlus( );
void testToSignedPlusMultiple( );
void testToSignedMinus( );
void testToSignedMinusMultiple( );
void testToSignedInvalid( );
void testToSignedTooLarge( );
void testToSignedTooSmall( );
void testToSignedBaseOk( );
void testToSignedBaseInvalid( );
void testToSignedBaseAutoBinary( );
void testToSignedBaseAutoOctal( );
void testToSignedBaseAutoDecimal( );
void testToSignedBaseAutoHexa( );
void testToSignedBaseAutoZero( );
void testToSignedBaseAutoInvalid( );
void testToSignedBaseAutoCut( );
void testToSignedBaseAutoPlus( );
void testToSignedBaseAutoMinus( );
void testToSignedSeparator( );
void testToSignedSeparatorCustom( );
void testToSignedSeparatorCustomUTF8( );
void testToSignedLeadingWhitespace( );
void testToSignedLeadingWhitespaceOnly( );
void testToDouble( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( StringsBuilderTest );
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testConsDefault( )
{
T_StringBuilder sb;
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) == nullptr );
}
void StringsBuilderTest::testConsFromAsciiBuffer( )
{
T_StringBuilder sb( "test" , 4 );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , "test" , 4 ) );
}
void StringsBuilderTest::testConsFromUTF8Buffer( )
{
const char test[] = "t\xe2\x82\xacst";
const uint32_t sz = sizeof( test ) - 1;
T_StringBuilder sb( test , sz );
CPPUNIT_ASSERT_EQUAL( uint32_t( sz ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , test , sz ) );
}
void StringsBuilderTest::testConsFromAsciiNTS( )
{
const char test[] = "test";
const uint32_t sz = sizeof( test ) - 1;
T_StringBuilder sb( test );
CPPUNIT_ASSERT_EQUAL( uint32_t( sz ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , test , sz ) );
}
void StringsBuilderTest::testConsFromUTF8NTS( )
{
const char test[] = "t\xe2\x82\xacst";
const uint32_t sz = sizeof( test ) - 1;
T_StringBuilder sb( test );
CPPUNIT_ASSERT_EQUAL( uint32_t( sz ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , test , sz ) );
}
void StringsBuilderTest::testConsFromString( )
{
const T_String test( "t\xe2\x82\xacst" );
T_StringBuilder sb( test );
CPPUNIT_ASSERT_EQUAL( test.size( ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( test.length( ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , test.data( ) , test.size( ) ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testCopyCons( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder isb( str );
T_StringBuilder sb( isb );
CPPUNIT_ASSERT_EQUAL( sz , isb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , isb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , isb.capacity( ) );
CPPUNIT_ASSERT( isb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( isb.data( ) , str , sz ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
CPPUNIT_ASSERT( sb.data( ) != isb.data( ) );
}
void StringsBuilderTest::testCopyAss( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder isb( str );
T_StringBuilder sb;
sb = isb;
CPPUNIT_ASSERT_EQUAL( sz , isb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , isb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , isb.capacity( ) );
CPPUNIT_ASSERT( isb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( isb.data( ) , str , sz ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
CPPUNIT_ASSERT( sb.data( ) != isb.data( ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testMoveCons( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder isb( str );
T_StringBuilder sb( std::move( isb ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.capacity( ) );
CPPUNIT_ASSERT( isb.data( ) == nullptr );
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
}
void StringsBuilderTest::testMoveAss( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder isb( str );
T_StringBuilder sb( "huh" );
sb = std::move( isb );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , isb.capacity( ) );
CPPUNIT_ASSERT( isb.data( ) == nullptr );
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testSwap( )
{
const char test[] = "test";
const uint32_t sz = sizeof( test ) - 1;
T_StringBuilder sb1( test , sz ) , sb2;
swap( sb1 , sb2 );
CPPUNIT_ASSERT_EQUAL( sz , sb2.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb1.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb2.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb1.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) ,
sb2.capacity( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb1.capacity( ) );
CPPUNIT_ASSERT( sb1.data( ) == nullptr );
CPPUNIT_ASSERT( sb2.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb2.data( ) , test , sz ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testEnsureCapacityFactor( )
{
T_StringBuilder sb;
sb.ensureCapacity( 2 * sb.C_GROWTH );
CPPUNIT_ASSERT_EQUAL( 2 * sb.C_GROWTH , sb.capacity( ) );
}
void StringsBuilderTest::testEnsureCapacityOther( )
{
T_StringBuilder sb;
sb.ensureCapacity( 3 * sb.C_GROWTH / 2 );
CPPUNIT_ASSERT_EQUAL( 2 * sb.C_GROWTH , sb.capacity( ) );
}
void StringsBuilderTest::testEnsureCapacitySmaller( )
{
T_StringBuilder sb;
sb.ensureCapacity( 4 * sb.C_GROWTH );
sb.ensureCapacity( 2 * sb.C_GROWTH );
CPPUNIT_ASSERT_EQUAL( 4 * sb.C_GROWTH , sb.capacity( ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testClear( )
{
T_StringBuilder sb( "this is a test" );
sb.clear( );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( sb.C_GROWTH ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
}
void StringsBuilderTest::testFree( )
{
T_StringBuilder sb( "this is a test" );
sb.free( );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) == nullptr );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testTruncate( )
{
T_StringBuilder sb( "this is\uf1bb a test" );
sb.truncate( 8 );
CPPUNIT_ASSERT_EQUAL( uint32_t( 8 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 10 ) , sb.size( ) );
}
void StringsBuilderTest::testTruncateLonger( )
{
T_StringBuilder sb( "this is\uf1bb a test" );
sb.truncate( 20 );
CPPUNIT_ASSERT_EQUAL( uint32_t( 15 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 17 ) , sb.size( ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testAppendOther( )
{
T_StringBuilder sb1( "this is " ) , sb2( "a test!" );
T_StringBuilder sb3( sb1 );
sb3.append( sb2 );
CPPUNIT_ASSERT_EQUAL( sb1.size( ) + sb2.size( ) , sb3.size( ) );
CPPUNIT_ASSERT_EQUAL( sb1.length( ) + sb2.length( ) , sb3.length( ) );
CPPUNIT_ASSERT( !memcmp( sb3.data( ) , sb1.data( ) , sb1.size( ) ) );
CPPUNIT_ASSERT( !memcmp( sb3.data( ) + sb1.size( ) , sb2.data( ) ,
sb2.size( ) ) );
}
void StringsBuilderTest::testAppendSwap( )
{
const char test[] = "test";
const uint32_t sz = sizeof( test ) - 1;
T_StringBuilder sbi( test , sz ) , sbo;
sbo.append( std::move( sbi ) );
CPPUNIT_ASSERT_EQUAL( sz , sbo.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , sbo.length( ) );
CPPUNIT_ASSERT( sbo.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , test , sz ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sbi.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sbi.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sbi.capacity( ) );
CPPUNIT_ASSERT( sbi.data( ) == nullptr );
}
void StringsBuilderTest::testAppendStr( )
{
T_String str( "test\u20ac" );
T_StringBuilder sbo;
sbo.append( str ).append( str );
CPPUNIT_ASSERT_EQUAL( str.size( ) * 2 , sbo.size( ) );
CPPUNIT_ASSERT_EQUAL( str.length( ) * 2 , sbo.length( ) );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , str.data( ) , str.size( ) ) );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) + str.size( ) , str.data( ) ,
str.size( ) ) );
}
void StringsBuilderTest::testAppendBuf( )
{
T_String str( "test\u20ac" );
T_StringBuilder sbo;
sbo.append( str.data( ) , str.size( ) );
CPPUNIT_ASSERT_EQUAL( str.size( ) , sbo.size( ) );
CPPUNIT_ASSERT_EQUAL( str.length( ) , sbo.length( ) );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , str.data( ) , str.size( ) ) );
}
void StringsBuilderTest::testAppendChar( )
{
T_StringBuilder sbo;
sbo.append( 'a' ).append( 'b' );
CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , sbo.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , sbo.length( ) );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , "ab" , 2 ) );
}
void StringsBuilderTest::testAppendUnicode( )
{
const char expected[] = "a\u00e9\u20ac\U00010102";
const uint32_t sz = sizeof( expected ) - 1;
T_StringBuilder sbo;
sbo.append( T_Character( 'a' ) )
.append( T_Character( 0xe9u ) )
.append( T_Character( 0x20acu ) )
.append( T_Character( 0x10102u ) );
CPPUNIT_ASSERT_EQUAL( sz , sbo.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 4 ) , sbo.length( ) );
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , expected , sz ) );
}
/*----------------------------------------------------------------------------*/
#define M_CHECK_( STR ) \
{ \
const char t[] = STR; \
const uint32_t sz = sizeof( t ) - 1; \
if ( sz != sbo.size( ) || memcmp( sbo.data( ) , t , sz ) ) { \
char x[ sbo.size( ) + 1 ]; \
x[ sizeof( x ) - 1 ] = 0; \
memcpy( x , sbo.data( ) , sizeof( x ) - 1 ); \
printf( "'%s' | expected '%s'\n" , x , STR ); \
} \
CPPUNIT_ASSERT_EQUAL( sz , sbo.size( ) ); \
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , t , sz ) ); \
}
void StringsBuilderTest::testAppendNumSignedZeroB10( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( 0 ) ); M_CHECK_( "0" );
}
void StringsBuilderTest::testAppendNumSignedNegativeB10( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( -1234 ) ); M_CHECK_( "-1234" );
}
void StringsBuilderTest::testAppendNumSignedPositiveB10( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( 1234 ) ); M_CHECK_( "1234" );
}
void StringsBuilderTest::testAppendNumSignedMinB10( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( INT64_MIN ) ); M_CHECK_( "-9223372036854775808" );
}
void StringsBuilderTest::testAppendNumSignedMaxB10( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( INT64_MAX ) ); M_CHECK_( "9223372036854775807" );
}
void StringsBuilderTest::testAppendNumSignedRest( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( int64_t( 129 ) , 2 );
M_CHECK_( "10000001" );
sbo.clear( ).appendNumeric( int64_t( -129 ) , 2 );
M_CHECK_( "-10000001" );
sbo.clear( ).appendNumeric( int64_t( 129 ) , 16 ); M_CHECK_( "81" );
sbo.clear( ).appendNumeric( int64_t( -129 ) , 16 ); M_CHECK_( "-81" );
sbo.clear( ).appendNumeric( int64_t( 1234 ) , 10 , true );
M_CHECK_( "1 234" );
sbo.clear( ).appendNumeric( int64_t( -1234 ) , 10 , true );
M_CHECK_( "-1 234" );
sbo.clear( ).appendNumeric( int64_t( 1234 ) , 10 , true , ',' );
M_CHECK_( "1,234" );
sbo.clear( ).appendNumeric( int64_t( -1234 ) , 10 , true , ',' );
M_CHECK_( "-1,234" );
sbo.clear( ).appendNumeric( int64_t( 1234 ) , 10 , true ,
T_Character( 0x20acu ) );
M_CHECK_( "1\u20ac234" );
sbo.clear( ).appendNumeric( int64_t( -1234 ) , 10 , true , 0x20acu );
M_CHECK_( "-1\u20ac234" );
sbo.clear( ).appendNumeric( int64_t( 65535 ) , 2 , true , ' ' , 8 );
M_CHECK_( "11111111 11111111" );
sbo.clear( ).appendNumeric( int64_t( -65535 ) , 2 , true , ' ' , 8 );
M_CHECK_( "-11111111 11111111" );
sbo.clear( ).appendNumeric( int64_t( 15 ) , 2 , true , ' ' , 1 );
M_CHECK_( "1 1 1 1" );
}
void StringsBuilderTest::testAppendNumUnsigned( )
{
T_StringBuilder sbo;
sbo.clear( ).appendNumeric( uint64_t( 1 ) ); M_CHECK_( "1" );
sbo.clear( ).appendNumeric( uint64_t( 0 ) ); M_CHECK_( "0" );
sbo.clear( ).appendNumeric( uint64_t( 1234 ) ); M_CHECK_( "1234" );
sbo.clear( ).appendNumeric( uint64_t( 129 ) , 2 );
M_CHECK_( "10000001" );
sbo.clear( ).appendNumeric( uint64_t( 129 ) , 16 ); M_CHECK_( "81" );
sbo.clear( ).appendNumeric( uint64_t( 1234 ) , 10 , true );
M_CHECK_( "1 234" );
sbo.clear( ).appendNumeric( uint64_t( 1234 ) , 10 , true , ',' );
M_CHECK_( "1,234" );
sbo.clear( ).appendNumeric( uint64_t( 1234 ) , 10 , true ,
T_Character( 0x20acu ) );
M_CHECK_( "1\u20ac234" );
sbo.clear( ).appendNumeric( uint64_t( 65535 ) , 2 , true , ' ' , 8 );
M_CHECK_( "11111111 11111111" );
sbo.clear( ).appendNumeric( uint64_t( 15 ) , 2 , true , ' ' , 1 );
M_CHECK_( "1 1 1 1" );
}
void StringsBuilderTest::testAppendNumFloat( )
{
T_StringBuilder sbo;
sbo.clear( ).appendDouble( -1 ); M_CHECK_( "-1" );
sbo.clear( ).appendDouble( 0 ); M_CHECK_( "0" );
sbo.clear( ).appendDouble( 1234 ); M_CHECK_( "1234" );
sbo.clear( ).appendDouble( 1.234 ); M_CHECK_( "1.234" );
sbo.clear( ).appendDouble( 1.23456789 ); M_CHECK_( "1.23457" );
sbo.clear( ).appendDouble( 10.23456789 ); M_CHECK_( "10.2346" );
sbo.clear( ).appendDouble( -1e10 ); M_CHECK_( "-1e+10" );
sbo.clear( ).appendDouble( 1 , 2 ); M_CHECK_( "1" );
sbo.clear( ).appendDouble( 1.5 , 2 ); M_CHECK_( "1.5" );
sbo.clear( ).appendDouble( 1.5432 , 2 ); M_CHECK_( "1.5" );
sbo.clear( ).appendDouble( 1e20 , 2 ); M_CHECK_( "1e+20" );
sbo.clear( ).appendDouble( 1.234 , 6 , true ); M_CHECK_( "1.234000" );
sbo.clear( ).appendDouble( 1.23456789 , 6 , true ); M_CHECK_( "1.234568" );
sbo.clear( ).appendDouble( 1 , 6 , true ); M_CHECK_( "1.000000" );
sbo.clear( ).appendDouble( -1 , 6 , true ); M_CHECK_( "-1.000000" );
sbo.clear( ).appendDouble( 1e10 , 6 , true ); M_CHECK_( "10000000000.000000" );
}
#undef M_CHECK_
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testStringConsCopy( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder sb( str );
T_String tstr( sb );
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
CPPUNIT_ASSERT( tstr == str );
CPPUNIT_ASSERT( tstr.data( ) != sb.data( ) );
}
void StringsBuilderTest::testStringAssCopy( )
{
const char str[] = "this is a test";
const uint32_t sz = sizeof( str ) - 1;
T_StringBuilder sb( str );
T_String tstr;
tstr = sb;
CPPUNIT_ASSERT_EQUAL( sz , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( sz , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( T_StringBuilder::C_GROWTH ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) != nullptr );
CPPUNIT_ASSERT( !memcmp( sb.data( ) , str , sz ) );
CPPUNIT_ASSERT( tstr == str );
CPPUNIT_ASSERT( tstr.data( ) != sb.data( ) );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testStringConsMove( )
{
const char str[] = "this is a test";
T_StringBuilder sb( str );
T_String tstr( std::move( sb ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) == nullptr );
CPPUNIT_ASSERT( tstr == str );
}
void StringsBuilderTest::testStringAssMove( )
{
const char str[] = "this is a test";
T_StringBuilder sb( str );
T_String tstr;
tstr = std::move( sb );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.length( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , sb.capacity( ) );
CPPUNIT_ASSERT( sb.data( ) == nullptr );
CPPUNIT_ASSERT( tstr == str );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testCmpOther( )
{
T_StringBuilder sb1( "this" ) , sb2( "that" ) , sb3( "this" );
CPPUNIT_ASSERT( sb1 == sb3 );
CPPUNIT_ASSERT( sb1 != sb2 );
}
void StringsBuilderTest::testCmpCString( )
{
T_StringBuilder sb( "this" );
CPPUNIT_ASSERT( sb == "this" );
CPPUNIT_ASSERT( sb != "that" );
}
void StringsBuilderTest::testCmpTString( )
{
T_StringBuilder sb( "this" );
T_String s1( "this" ) , s2( "that" );
CPPUNIT_ASSERT( sb == s1 );
CPPUNIT_ASSERT( sb != s2 );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testToUnsignedBasic( )
{
T_StringBuilder sb( "123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( ) );
}
void StringsBuilderTest::testToUnsignedOkValue( )
{
bool ok;
T_StringBuilder sb( "123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedInvalid( )
{
bool ok;
T_StringBuilder sb( "123lol" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToUnsignedTooLarge( )
{
bool ok;
T_StringBuilder sb( "18446744073709551616" );
CPPUNIT_ASSERT_EQUAL( uint64_t( UINT64_MAX ) , sb.toUnsignedInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToUnsignedBaseOk( )
{
bool ok;
T_StringBuilder sb( "1a23" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 6691 ) , sb.toUnsignedInteger( &ok , 16 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseInvalid( )
{
bool ok;
T_StringBuilder sb( "12g3" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 18 ) , sb.toUnsignedInteger( &ok , 16 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoBinary( )
{
bool ok;
T_StringBuilder sb( "0b1111" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 15 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoOctal( )
{
bool ok;
T_StringBuilder sb( "0123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 83 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoDecimal( )
{
bool ok;
T_StringBuilder sb( "123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoHexa( )
{
bool ok;
T_StringBuilder sb( "0x123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 291 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoZero( )
{
bool ok;
T_StringBuilder sb( "0" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 0 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoInvalid( )
{
bool ok;
T_StringBuilder sb( "0z123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 0 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToUnsignedBaseAutoCut( )
{
bool ok;
T_StringBuilder sb( "0x" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 0 ) , sb.toUnsignedInteger( &ok , 0 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToUnsignedSeparator( )
{
bool ok;
T_StringBuilder sb( "1 2 3" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok , 10 , true ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedSeparatorCustom( )
{
bool ok;
T_StringBuilder sb( "1.2.3" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok , 10 , true , '.' ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedSeparatorCustomUTF8( )
{
bool ok;
T_StringBuilder sb( "1""\xe2\x82\xac""23" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok , 10 , true , T_Character( 0x20ac ) ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedLeadingWhitespace( )
{
bool ok;
T_StringBuilder sb( " 123" );
CPPUNIT_ASSERT_EQUAL( uint64_t( 123 ) , sb.toUnsignedInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToUnsignedLeadingWhitespaceOnly( )
{
bool ok;
T_StringBuilder sb( " " );
CPPUNIT_ASSERT_EQUAL( uint64_t( 0 ) , sb.toUnsignedInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
/*----------------------------------------------------------------------------*/
void StringsBuilderTest::testToSignedBasic( )
{
T_StringBuilder sb( "123" );
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , sb.toInteger( ) );
}
void StringsBuilderTest::testToSignedOkValue( )
{
bool ok;
T_StringBuilder sb( "123" );
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedPlus( )
{
bool ok;
T_StringBuilder sb( "+123" );
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedPlusMultiple( )
{
bool ok;
T_StringBuilder sb( "++123" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedMinus( )
{
bool ok;
T_StringBuilder sb( "-123" );
CPPUNIT_ASSERT_EQUAL( int64_t( -123 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedMinusMultiple( )
{
bool ok;
T_StringBuilder sb( "--123" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedInvalid( )
{
bool ok;
T_StringBuilder sb( "1lol23wut" );
CPPUNIT_ASSERT_EQUAL( int64_t( 1 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedTooLarge( )
{
bool ok;
T_StringBuilder sb( "18446744073709551616" );
CPPUNIT_ASSERT_EQUAL( INT64_MAX , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedTooSmall( )
{
bool ok;
T_StringBuilder sb( "-18446744073709551616" );
CPPUNIT_ASSERT_EQUAL( INT64_MIN , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedBaseOk( )
{
bool ok;
T_StringBuilder sb( "1a2" );
CPPUNIT_ASSERT_EQUAL( int64_t( 418 ) , sb.toInteger( &ok , 16 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseInvalid( )
{
bool ok;
T_StringBuilder sb( "g12" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok , 16 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedBaseAutoBinary( )
{
bool ok;
T_StringBuilder sb( "0b11" );
CPPUNIT_ASSERT_EQUAL( int64_t( 3 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoOctal( )
{
bool ok;
T_StringBuilder sb( "011" );
CPPUNIT_ASSERT_EQUAL( int64_t( 9 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoDecimal( )
{
bool ok;
T_StringBuilder sb( "11" );
CPPUNIT_ASSERT_EQUAL( int64_t( 11 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoHexa( )
{
bool ok;
T_StringBuilder sb( "0x12" );
CPPUNIT_ASSERT_EQUAL( int64_t( 18 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoZero( )
{
bool ok;
T_StringBuilder sb( "0" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoInvalid( )
{
bool ok;
T_StringBuilder sb( "0z12" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedBaseAutoCut( )
{
bool ok;
T_StringBuilder sb( "0x" );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( !ok );
}
void StringsBuilderTest::testToSignedBaseAutoPlus( )
{
bool ok;
T_StringBuilder sb( "+0b11" );
CPPUNIT_ASSERT_EQUAL( int64_t( 3 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedBaseAutoMinus( )
{
bool ok;
T_StringBuilder sb( "-0b11" );
CPPUNIT_ASSERT_EQUAL( int64_t( -3 ) , sb.toInteger( &ok , 0 ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedSeparator( )
{
bool ok;
T_StringBuilder sb( "-1 1" );
CPPUNIT_ASSERT_EQUAL( int64_t( -11 ) , sb.toInteger( &ok , 10 , true ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedSeparatorCustom( )
{
bool ok;
T_StringBuilder sb( "-1x1" );
CPPUNIT_ASSERT_EQUAL( int64_t( -11 ) , sb.toInteger( &ok , 10 , true , 'x' ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedSeparatorCustomUTF8( )
{
bool ok;
T_StringBuilder sb( "1""\xe2\x82\xac""23" );
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , sb.toInteger( &ok , 10 , true , T_Character( 0x20ac ) ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedLeadingWhitespace( )
{
bool ok;
T_StringBuilder sb( " - 123" );
CPPUNIT_ASSERT_EQUAL( int64_t( -123 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( ok );
}
void StringsBuilderTest::testToSignedLeadingWhitespaceOnly( )
{
bool ok;
T_StringBuilder sb( " " );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , sb.toInteger( &ok ) );
CPPUNIT_ASSERT( !ok );
}
/*----------------------------------------------------------------------------*/
#define M_CHECK_( STR , VAL , OK ) \
do { \
bool ok; \
double v( T_StringBuilder( STR ).toDouble( &ok , '.' , true , ',' ) ); \
CPPUNIT_ASSERT_EQUAL( double( VAL ) , v ); \
CPPUNIT_ASSERT_EQUAL( bool( OK ) , ok ); \
} while ( 0 )
void StringsBuilderTest::testToDouble( )
{
M_CHECK_( " " , 0 , false );
M_CHECK_( " 0" , 0 , true );
M_CHECK_( " ,,0" , 0 , false );
M_CHECK_( "+" , 0 , false );
M_CHECK_( "-" , 0 , false );
M_CHECK_( "123" , 123 , true );
M_CHECK_( ",123" , 0 , false );
M_CHECK_( "1,2,3" , 123 , true );
M_CHECK_( "1,2," , 0 , false );
M_CHECK_( ",-123" , 0 , false );
M_CHECK_( "-123" , -123 , true );
M_CHECK_( "+123" , +123 , true );
M_CHECK_( "+,123" , 0 , false );
M_CHECK_( ".12" , .12 , true );
M_CHECK_( "-.12" , -.12 , true );
M_CHECK_( "+.12" , .12 , true );
M_CHECK_( "." , 0 , true );
M_CHECK_( "12." , 12 , true );
M_CHECK_( "12e" , 0 , false );
M_CHECK_( "12e2" , 12e2 , true );
M_CHECK_( "12e+" , 0 , false );
M_CHECK_( "12e-" , 0 , false );
M_CHECK_( "12e+2" , 12e2 , true );
M_CHECK_( "12e-2" , 12e-2 , true );
M_CHECK_( "1.2e2" , 120 , true );
M_CHECK_( "1.2e+2" , 120 , true );
M_CHECK_( "1.2e-2" , 1.2e-2 , true );
M_CHECK_( "1e3000" , std::numeric_limits< double >::infinity( ) , false );
M_CHECK_( "-1e3000" , -std::numeric_limits< double >::infinity( ) , false );
M_CHECK_( "1e-3000" , 0 , false );
}
#undef M_CHECK_