diff --git a/src/disco/FixedWidthField.hpp b/src/disco/FixedWidthField.hpp index 34f4f02..09e7994 100644 --- a/src/disco/FixedWidthField.hpp +++ b/src/disco/FixedWidthField.hpp @@ -1,5 +1,6 @@ template< uint16_t w > struct FixedWidthField { + /* convenience typedefs */ template< typename T > using ArgumentType = @@ -8,11 +9,12 @@ struct FixedWidthField { T, std::add_const_t < std::add_lvalue_reference_t< T > > >; constexpr static bool - isSpace( const char c ){ return c == ' ' or c == '\t'; } + isSpace( const char c ) { return c == ' ' or c == '\t'; } template< typename Iterator > constexpr static bool - isNewline( const char c, Iterator& it ){ + isNewline( const char c, Iterator& it ) { + return c == '\n' or c == '\f' @@ -28,5 +30,4 @@ struct FixedWidthField { isEOF( const char c ){ return c == std::char_traits::eof(); } #include "disco/FixedWidthField/src/whiteSpace.hpp" - }; diff --git a/src/disco/FixedWidthField/Real.hpp b/src/disco/FixedWidthField/Real.hpp index f19769f..d0734fc 100644 --- a/src/disco/FixedWidthField/Real.hpp +++ b/src/disco/FixedWidthField/Real.hpp @@ -12,9 +12,6 @@ struct Real : public FixedWidthField< w >{ /* constants */ static constexpr uint16_t width = w; - /* convenience typedefs */ - using FixedWidthField_ = FixedWidthField< w >; - template< typename Iterator > static void write( Iterator& it ){ ColumnPosition< w >::write( it ); } diff --git a/src/disco/FixedWidthField/Real/ENDF/test/write.test.cpp b/src/disco/FixedWidthField/Real/ENDF/test/write.test.cpp index 6709607..14a86ea 100644 --- a/src/disco/FixedWidthField/Real/ENDF/test/write.test.cpp +++ b/src/disco/FixedWidthField/Real/ENDF/test/write.test.cpp @@ -1,8 +1,5 @@ #include #include -#include -#include -#include #include "disco.hpp" #include "catch.hpp" diff --git a/src/disco/FixedWidthField/Real/src/noDigits.hpp b/src/disco/FixedWidthField/Real/src/noDigits.hpp index 5afe2d1..0b489e8 100644 --- a/src/disco/FixedWidthField/Real/src/noDigits.hpp +++ b/src/disco/FixedWidthField/Real/src/noDigits.hpp @@ -1,6 +1,7 @@ template< typename UnsignedInteger > static uint16_t -noDigits( UnsignedInteger mantissa ){ +noDigits( UnsignedInteger mantissa ) { + if ( mantissa < 10ull ){ return 1; }; if ( mantissa < 100ull ){ return 2; }; if ( mantissa < 1000ull ){ return 3; }; diff --git a/src/disco/FixedWidthField/Real/src/parseBase.hpp b/src/disco/FixedWidthField/Real/src/parseBase.hpp index e7379b5..4d93e3b 100644 --- a/src/disco/FixedWidthField/Real/src/parseBase.hpp +++ b/src/disco/FixedWidthField/Real/src/parseBase.hpp @@ -1,13 +1,16 @@ template< typename Iterator > static uint64_t -parseBase( Iterator& it, uint16_t& position, bool& success ){ - uint64_t base = ( success = isdigit( *it ) ) ? (*it - 48) : 0; - if ( success ){ +parseBase( Iterator& it, uint16_t& position, bool& success ) { + + uint64_t base = ( success = isdigit( *it ) ) ? ( *it - 48 ) : 0; + if ( success ) { + ++position; ++it; while ( position < width ) { + if ( not isdigit( *it ) ) { break; } // TODO: overflow check - base = ( 10 * base ) + (*it - 48); + base = ( 10 * base ) + ( *it - 48 ); ++position; ++it; } } diff --git a/src/disco/FixedWidthField/Real/src/parseExponent.hpp b/src/disco/FixedWidthField/Real/src/parseExponent.hpp index 46e9572..bc82a35 100644 --- a/src/disco/FixedWidthField/Real/src/parseExponent.hpp +++ b/src/disco/FixedWidthField/Real/src/parseExponent.hpp @@ -1,49 +1,81 @@ template< typename Iterator > static int64_t -parseExponent( Iterator& it, uint16_t& position ){ +parseExponent( Iterator& it, uint16_t& position ) { + int16_t sign = 1; - auto boundCheck = []( auto p ){ - if ( unlikely( p == width ) ){ + auto boundCheck = [] ( auto p ) { + + if ( unlikely( p == width ) ) { + throw std::runtime_error ("illegal exponent format"); } }; const auto first = toupper(*it); - switch( first ) { - case 'E': - case 'D': - ++position; ++it; - boundCheck( position ); - switch( *it ){ - case '-': + + case 'E' : + case 'D' : { + + ++position; ++it; + boundCheck( position ); + switch( *it ) { + case '-' : { + + sign = -1; + // fall through + } + case '+' : { + + ++position; ++it; + boundCheck( position ); + } + default : break; + } + break; + } + case '-' : { + sign = -1; // fall through - case '+': + } + case '+' : { + ++position; ++it; boundCheck( position ); - default: break; + break; } - break; - case '-': - sign = -1; - // fall through - case '+': - ++position; ++it; - boundCheck( position ); - break; - default: - return 0; + default : return 0; } - if ( unlikely( not isdigit( *it ) ) ){ - throw std::runtime_error - ("illegal character encountered while parsing real number exponent"); + if ( unlikely( not isdigit( *it ) ) ) { + + if ( *it == ' ' ) { + + // older versions of fortran printed ' ' instead of '0' + do { + + ++position; ++it; + } while ( position < width and ( *it == ' ' ) ); + + boundCheck( position ); + if ( unlikely( not isdigit( *it ) ) ) { + + throw std::runtime_error + ("illegal character encountered while parsing real number exponent"); + } + } + else { + + throw std::runtime_error + ("illegal character encountered while parsing real number exponent"); + } } uint64_t exponent = 0; do { + exponent = 10 * exponent + ( *it - '0' ); ++position; ++it; } while ( position < width and isdigit( *it ) ); diff --git a/src/disco/FixedWidthField/Real/src/parseFraction.hpp b/src/disco/FixedWidthField/Real/src/parseFraction.hpp index 21db701..4365559 100644 --- a/src/disco/FixedWidthField/Real/src/parseFraction.hpp +++ b/src/disco/FixedWidthField/Real/src/parseFraction.hpp @@ -1,15 +1,18 @@ template< typename Iterator > static uint64_t -parseFraction( Iterator& it, uint16_t& position, bool& success ){ +parseFraction( Iterator& it, uint16_t& position, bool& success ) { + uint64_t fraction = 0; success = false; - if ( *it == '.' ){ + if ( *it == '.' ) { + const auto initialPosition = ++position; ++it; while ( position < width ) { + if ( not isdigit( *it ) ) { break; } //TODO: overflow check - fraction = 10 * fraction + (*it - 48); + fraction = 10 * fraction + ( *it - 48 ); ++position; ++it; } success = initialPosition != position; diff --git a/src/disco/FixedWidthField/Real/src/parseInfinity.hpp b/src/disco/FixedWidthField/Real/src/parseInfinity.hpp index e58a7e6..a05c02a 100644 --- a/src/disco/FixedWidthField/Real/src/parseInfinity.hpp +++ b/src/disco/FixedWidthField/Real/src/parseInfinity.hpp @@ -1,27 +1,31 @@ template< typename Iterator > static bool -parseInfinity( Iterator& it, uint16_t& position ){ - auto canProceed = [&it](){ - return not ( FixedWidthField_::isEOF(*it) - or FixedWidthField_::isNewline(*it, it)); +parseInfinity( Iterator& it, uint16_t& position ) { + + auto canProceed = [&it]() { + + return not ( FixedWidthField< w >::isEOF( *it ) + or FixedWidthField< w >::isNewline( *it, it ) ); }; - - const auto remainingWidth = int(w) - position; + + const auto remainingWidth = int( w ) - position; bool success = false; - if ( remainingWidth >= 3 ){ + if ( remainingWidth >= 3 ) { + position += 3; - success = + success = ( toupper( *it++ ) == 'I' ) and ( canProceed() and toupper( *it++ ) == 'N' ) - and ( canProceed() and toupper( *it++ ) == 'F' ); - if ( success and remainingWidth >= 8 and toupper(*it) == 'I' ){ + and ( canProceed() and toupper( *it++ ) == 'F' ); + if ( success and remainingWidth >= 8 and toupper( *it ) == 'I' ) { + position += 5; ++it; - success = + success = ( canProceed() and toupper( *it++ ) == 'N' ) - and ( canProceed() and toupper( *it++ ) == 'I' ) - and ( canProceed() and toupper( *it++ ) == 'T' ) - and ( canProceed() and toupper( *it++ ) == 'Y' ); + and ( canProceed() and toupper( *it++ ) == 'I' ) + and ( canProceed() and toupper( *it++ ) == 'T' ) + and ( canProceed() and toupper( *it++ ) == 'Y' ); } } return success; diff --git a/src/disco/FixedWidthField/Real/src/parseSign.hpp b/src/disco/FixedWidthField/Real/src/parseSign.hpp index 53719e3..251b781 100644 --- a/src/disco/FixedWidthField/Real/src/parseSign.hpp +++ b/src/disco/FixedWidthField/Real/src/parseSign.hpp @@ -1,8 +1,10 @@ template< typename Iterator > -static int16_t parseSign( Iterator& it, uint16_t& position ){ - switch ( *it ){ - case '+': ++it; ++position; return 1; - case '-': ++it; ++position; return -1; - default: return 1; +static int16_t parseSign( Iterator& it, uint16_t& position ) { + + switch ( *it ) { + + case '+': ++it; ++position; return 1; + case '-': ++it; ++position; return -1; + default: return 1; } } diff --git a/src/disco/FixedWidthField/Real/src/read.hpp b/src/disco/FixedWidthField/Real/src/read.hpp index 15be87e..6c48941 100644 --- a/src/disco/FixedWidthField/Real/src/read.hpp +++ b/src/disco/FixedWidthField/Real/src/read.hpp @@ -1,28 +1,34 @@ template< typename Representation, typename Iterator, bool trust = true > static Representation -read( Iterator& it, const Iterator& ){ - auto position = FixedWidthField_::whiteSpace( it ); +read( Iterator& it, const Iterator& ) { + + auto position = FixedWidthField< w >::whiteSpace( it ); + + if( FixedWidthField< w >::isNewline(*it, it) or FixedWidthField< w >::isEOF(*it) ) { - if( FixedWidthField_::isNewline(*it, it) or FixedWidthField_::isEOF(*it) ){ return Representation(0.0); } - if ( position == w ){ + if ( position == w ) { + ++it; return Representation(0.0); } - const auto value = [&]{ + const auto value = [&] { + const auto sign = Real::parseSign(it, position); - if ( unlikely( position == width ) ){ + if ( unlikely( position == width ) ) { + throw std::runtime_error("cannot parse invalid real number"); } bool baseSuccess = false; auto base = Real::parseBase(it, position, baseSuccess); - if ( position == width ){ + if ( position == width ) { + return Representation( sign * int64_t( base ) ); } @@ -31,47 +37,62 @@ read( Iterator& it, const Iterator& ){ const auto fraction = Real::parseFraction( it, position, fractionSuccess ); const auto foundDecimal = decimalPosition != position; - const auto noFractionDigits = + const auto numberFractionDigits = fractionSuccess * ( position - decimalPosition - (position != width - 1) ); - if ( position == width ){ - const auto factor = - realExponentiation< Representation >::cache( -noFractionDigits ); - return sign * ( base + fraction * Representation(factor) ); - } + // ensure that something like ' . ' always fails + if ( unlikely( not baseSuccess && not fractionSuccess ) ) { - if ( unlikely( not baseSuccess && not fractionSuccess ) ){ const bool succeeded = not foundDecimal and Real::parseInfinity( it, position ); - if ( unlikely( not succeeded ) ){ + if ( unlikely( not succeeded ) ) { + throw std::runtime_error("cannot parse invalid real number"); } return sign * std::numeric_limits< Representation >::infinity(); } + // read over possible trailing white space between the fraction and exponent + while( FixedWidthField< w >::isSpace( *it ) and position < w ) { + + ++position; + ++it; + } + + // no need to continue if we are at the end + if ( position == width ) { + + const auto factor = + realExponentiation< Representation >::cache( -numberFractionDigits ); + return sign * ( base + fraction * Representation(factor) ); + } + const auto exponent = - Real::parseExponent( it, position ) - noFractionDigits; + Real::parseExponent( it, position ) - numberFractionDigits; if ( unlikely( exponent - < std::numeric_limits< Representation >::min_exponent10 ) ){ + < std::numeric_limits< Representation >::min_exponent10 ) ) { + return sign * 0.0; } if ( unlikely( exponent - > std::numeric_limits< Representation >::max_exponent10 ) ){ + > std::numeric_limits< Representation >::max_exponent10 ) ) { + return sign * std::numeric_limits< Representation >::infinity(); } const auto factor = - integerExponentiation< int64_t >::cache( noFractionDigits ); + integerExponentiation< int64_t >::cache( numberFractionDigits ); return sign * int64_t( base * factor + fraction ) * realExponentiation< Representation >::cache( exponent ); }(); - if ( unlikely( not FixedWidthField_::whiteSpace(it, position) ) ){ + if ( unlikely( not FixedWidthField< w >::whiteSpace(it, position) ) ) { + throw std::runtime_error("cannot parse invalid real number"); } @@ -80,6 +101,7 @@ read( Iterator& it, const Iterator& ){ template< typename Iterator, bool trust = true > static double -read( Iterator& it, const Iterator& end ){ - return read( it, end ); +read( Iterator& it, const Iterator& end ) { + + return read< double >( it, end ); } diff --git a/src/disco/FixedWidthField/Real/test/parseBase.test.cpp b/src/disco/FixedWidthField/Real/test/parseBase.test.cpp index 2ef8392..1ec8620 100644 --- a/src/disco/FixedWidthField/Real/test/parseBase.test.cpp +++ b/src/disco/FixedWidthField/Real/test/parseBase.test.cpp @@ -1,26 +1,48 @@ #include -#include #include "disco.hpp" #include "catch.hpp" -SCENARIO("Real parse base", "[Real], [parseBase]"){ - std::vector< std::string > - test_strings{ {"123"}, {"123."}, {"123.000"} }; - uint16_t p; - bool success; - for (unsigned i = 0; i < test_strings.size(); ++i){ - p = 0; - auto si = test_strings[i].begin(); - REQUIRE( 123 == njoy::disco::Real<5>::parseBase( si, p, success ) ); - REQUIRE( success == true ); - REQUIRE( p == 3 ); +SCENARIO( "Real - parse base" ) { + + auto parse = [] ( const std::string string, + uint16_t& position, bool& success ) { + + position = 0; + success = false; + auto iter = string.begin(); + return njoy::disco::Real< 5 >::parseBase( iter, position, success ); + }; + + THEN( "valid base strings can be read up to the correct position" ) { + + uint16_t position = 0; + bool success = false; + + CHECK( 123 == parse( "123", position, success ) ); + CHECK( success == true ); + CHECK( position == 3 ); + CHECK( 123 == parse( "123.", position, success ) ); + CHECK( success == true ); + CHECK( position == 3 ); + CHECK( 123 == parse( "123.000", position, success ) ); + CHECK( success == true ); + CHECK( position == 3 ); + CHECK( 123 == parse( "123 ", position, success ) ); + CHECK( success == true ); + CHECK( position == 3 ); } - std::string baseless(".123"); - p = 0; - auto si = baseless.begin(); - njoy::disco::Real<5>::parseBase( si, p, success ); - REQUIRE( p == 0 ); - REQUIRE( success == false ); + THEN( "a base value cannot be read if the string has no base value" ) { + + uint16_t position = 0; + bool success = false; + + CHECK( 0 == parse( ".123", position, success ) ); + CHECK( success == false ); + CHECK( position == 0 ); + CHECK( 0 == parse( "a123", position, success ) ); + CHECK( success == false ); + CHECK( position == 0 ); + } } diff --git a/src/disco/FixedWidthField/Real/test/parseExponent.test.cpp b/src/disco/FixedWidthField/Real/test/parseExponent.test.cpp index f906a6c..d6e29a1 100644 --- a/src/disco/FixedWidthField/Real/test/parseExponent.test.cpp +++ b/src/disco/FixedWidthField/Real/test/parseExponent.test.cpp @@ -1,24 +1,104 @@ #include -#include #include "disco.hpp" #include "catch.hpp" -SCENARIO("Real parse exponent", "[Real], [parseExponent]"){ - std::vector< std::string > - test_strings{ {"+123"}, {"-123"}, - {"E123"}, {"E+123"}, {"E-123"}, - {"e123"}, {"e+123"}, {"e-123"}, - {"D123"}, {"D+123"}, {"D-123"}, - {"d123"}, {"d+123"}, {"d-123"} }; - uint16_t p = 0; - bool success; - for (unsigned i = 0; i < test_strings.size(); ++i){ - p = 0; auto si = test_strings[i].begin(); - if ( (i + 1) % 3 == 2 ){ - REQUIRE( -123 == njoy::disco::Real<5>::parseExponent( si, p ) ); - } else { - REQUIRE( 123 == njoy::disco::Real<5>::parseExponent( si, p ) ); - } +SCENARIO( "Real - parse exponent" ) { + + auto parse = [] ( const std::string string, uint16_t& position ) { + + auto iter = string.begin(); + position = 0; + return njoy::disco::Real< 6 >::parseExponent( iter, position ); + }; + + THEN( "valid exponent strings can be read up to the correct position" ) + { + uint16_t position = 0; + + CHECK( +123 == parse( "+123", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "+ 123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "E+123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "E+ 123", position ) ); + CHECK( 6 == position ); + CHECK( +123 == parse( "E123", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "E 123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "e+123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "e+ 123", position ) ); + CHECK( 6 == position ); + CHECK( +123 == parse( "e123", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "e 123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "D+123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "D+ 123", position ) ); + CHECK( 6 == position ); + CHECK( +123 == parse( "D123", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "D 123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "d+123", position ) ); + CHECK( 5 == position ); + CHECK( +123 == parse( "d+ 123", position ) ); + CHECK( 6 == position ); + CHECK( +123 == parse( "d123", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "d 123", position ) ); + CHECK( 5 == position ); + + CHECK( -123 == parse( "-123", position ) ); + CHECK( 4 == position ); + CHECK( -123 == parse( "- 123", position ) ); + CHECK( 5 == position ); + CHECK( -123 == parse( "E-123", position ) ); + CHECK( 5 == position ); + CHECK( -123 == parse( "E- 123", position ) ); + CHECK( 6 == position ); + CHECK( -123 == parse( "e-123", position ) ); + CHECK( 5 == position ); + CHECK( -123 == parse( "e- 123", position ) ); + CHECK( 6 == position ); + CHECK( -123 == parse( "D-123", position ) ); + CHECK( 5 == position ); + CHECK( -123 == parse( "D- 123", position ) ); + CHECK( 6 == position ); + CHECK( -123 == parse( "d-123", position ) ); + CHECK( 5 == position ); + CHECK( -123 == parse( "d- 123", position ) ); + CHECK( 6 == position ); + + // exponent is only read up to the first non-digit + CHECK( +123 == parse( "+123 ", position ) ); + CHECK( 4 == position ); + CHECK( +123 == parse( "+123a", position ) ); + CHECK( 4 == position ); + } + + THEN( "invalid exponent strings cause an exception" ) + { + uint16_t position = 0; + + CHECK_THROWS( parse( "-a123", position ) ); + CHECK_THROWS( parse( "+a123", position ) ); + CHECK_THROWS( parse( "E-a123", position ) ); + CHECK_THROWS( parse( "E+a123", position ) ); + CHECK_THROWS( parse( "D-a123", position ) ); + CHECK_THROWS( parse( "D+a123", position ) ); + CHECK_THROWS( parse( "E -123", position ) ); + CHECK_THROWS( parse( "E +123", position ) ); + CHECK_THROWS( parse( "D -123", position ) ); + CHECK_THROWS( parse( "D +123", position ) ); + + CHECK_THROWS( parse( "- a3", position ) ); + CHECK_THROWS( parse( "- ", position ) ); + CHECK_THROWS( parse( "+ a3", position ) ); + CHECK_THROWS( parse( "+ ", position ) ); } } diff --git a/src/disco/FixedWidthField/Real/test/parseFraction.test.cpp b/src/disco/FixedWidthField/Real/test/parseFraction.test.cpp index 72015c2..c62ee29 100644 --- a/src/disco/FixedWidthField/Real/test/parseFraction.test.cpp +++ b/src/disco/FixedWidthField/Real/test/parseFraction.test.cpp @@ -1,25 +1,52 @@ #include -#include #include "disco.hpp" #include "catch.hpp" -SCENARIO("Real parse fraction", "[Real], [parseFraction]"){ - std::vector< std::string > test_strings{ {".123"}, {".123E"} }; - uint16_t p = 0; - bool success; - for (unsigned i = 0; i < test_strings.size(); ++i){ - p = 0; auto si = test_strings[i].begin(); - REQUIRE( 123 == njoy::disco::Real<5>::parseFraction( si, p, success ) ); - REQUIRE( success == true ); +SCENARIO( "Real - parse fraction" ) { + + auto parse = [] ( const std::string string, + uint16_t& position, bool& success ) { + + position = 0; + success = false; + auto iter = string.begin(); + return njoy::disco::Real< 6 >::parseFraction( iter, position, success ); + }; + + THEN( "valid fraction strings can be read up to the correct position" ) { + + uint16_t position = 0; + bool success = false; + + CHECK( 123 == parse( ".123", position, success ) ); + CHECK( success == true ); + CHECK( position == 4 ); + CHECK( 123 == parse( ".123E", position, success ) ); + CHECK( success == true ); + CHECK( position == 4 ); + CHECK( 123 == parse( ".123 E", position, success ) ); + CHECK( success == true ); + CHECK( position == 4 ); } - REQUIRE( p == 4 ); - - std::string fractionless("123"); - p = 0; - auto si = fractionless.begin(); - njoy::disco::Real<5>::parseFraction( si, p, success ); - REQUIRE( p == 0 ); - REQUIRE( success == false ); -} + THEN( "a fraction value cannot be read if the string does not start with " + "a decimal point" ) { + + uint16_t position = 0; + bool success = false; + + CHECK( 0 == parse( " .123", position, success ) ); + CHECK( success == false ); + CHECK( position == 0 ); + CHECK( 0 == parse( "a123", position, success ) ); + CHECK( success == false ); + CHECK( position == 0 ); + CHECK( 0 == parse( "123", position, success ) ); + CHECK( success == false ); + CHECK( position == 0 ); + CHECK( 0 == parse( ". E", position, success ) ); + CHECK( success == false ); + CHECK( position == 1 ); + } +} diff --git a/src/disco/FixedWidthField/Real/test/parseSign.test.cpp b/src/disco/FixedWidthField/Real/test/parseSign.test.cpp index da3860b..b8a471f 100644 --- a/src/disco/FixedWidthField/Real/test/parseSign.test.cpp +++ b/src/disco/FixedWidthField/Real/test/parseSign.test.cpp @@ -1,17 +1,26 @@ #include -#include #include "disco.hpp" #include "catch.hpp" -SCENARIO("Real parse sign", "[Real], [parseSign]"){ - std::vector< std::string > - test_strings{ {" 123."}, {"+123."}, {"-123."} }; - std::vector< int > - signs = { 1, 1, -1 }; - for (unsigned i = 0; i < signs.size(); ++i){ - uint16_t p = 0u; - auto si = test_strings[i].begin(); - REQUIRE( signs[i] == njoy::disco::Real<5>::parseSign( si, p ) ); +SCENARIO( "Real - parse sign" ) { + + auto parse = [] ( const std::string string, uint16_t& position ) { + + position = 0; + auto iter = string.begin(); + return njoy::disco::Real< 5 >::parseSign( iter, position ); + }; + + THEN( "valid sign strings can be read up to the correct position" ) + { + uint16_t position = 0; + + CHECK( +1 == parse( "123", position ) ); + CHECK( 0 == position ); + CHECK( +1 == parse( "+123", position ) ); + CHECK( 1 == position ); + CHECK( -1 == parse( "-123", position ) ); + CHECK( 1 == position ); } } diff --git a/src/disco/FixedWidthField/Real/test/read.test.cpp b/src/disco/FixedWidthField/Real/test/read.test.cpp index adbb197..9bac54a 100644 --- a/src/disco/FixedWidthField/Real/test/read.test.cpp +++ b/src/disco/FixedWidthField/Real/test/read.test.cpp @@ -5,359 +5,873 @@ #include "disco.hpp" #include "catch.hpp" -SCENARIO("Real read", "[Real], [read]"){ - GIVEN("A collection of strings and corresponding double values"){ - std::vector< std::pair< double, std::string > > - testset{ { 123., {" +123"} }, - { 123., {" 123.0"} }, - { 123.123, {" 123.123"} }, - { -123, {" -123"} }, - { 1E99, {" 1E99"} }, - { 1.E99, {" 1.E+99"} }, - { 1.E-99, {" 1E-99"} }, - { 1.E-99, {" 1.0-99"} }, - { 123., {"+123 "} }, - { 123., {"123.0 "} }, - { 123.123, {"123.123 "} }, - { -123, {"-123 "} }, - { 1E99, {"1E99 "} }, - { 1.E99, {"1.E+99 "} }, - { 1.E-99, {"1E-99 "} }, - { 1.E-99, {"1.0-99 "} }, - { 123., {" +123 "} }, - { 123., {" 123.0 "} }, - { 123.123, {" 123.123 "} }, - { -123, {" -123 "} }, - { 1E99, {" 1E99 "} }, - { 1.E99, {" 1.E+99 "} }, - { 1.E-99, {" 1E-99 "} }, - { 1.E-99, {" 1.0-99 "} } }; - - THEN("the string will parse to the corresponding value"){ - for ( const auto& pair : testset ){ - const auto& reference = std::get<0>(pair); - const auto& string = std::get<1>(pair); - - auto begin = string.begin(); - auto end = string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - auto error = std::abs( ( result - reference ) / reference ); - REQUIRE( error < 1E-15 ); - REQUIRE( end - begin == 0 ); - } - } - } - - GIVEN("A collection of strings and corresponding double values with 11 digits"){ - std::vector< std::pair< double, std::string > > - testset{ { 123., {" +123"} }, - { 123., {" 123.0"} }, - { 123.123, {" 123.123"} }, - { -123, {" -123"} }, - { 1E99, {" 1E99"} }, - { 1.E99, {" 1.E+99"} }, - { 1.E-99, {" 1E-99"} }, - { 1.E-99, {" 1.0-99"} }, - { 100., {"10.000000+1"} }, - { 100., {" 1.000000+2"} }, - { 123., {"+123 "} }, - { 123., {"123.0 "} }, - { 123.123, {"123.123 "} }, - { -123, {"-123 "} }, - { 1E99, {"1E99 "} }, - { 1.E99, {"1.E+99 "} }, - { 1.E-99, {"1E-99 "} }, - { 1.E-99, {"1.0-99 "} }, - { 123., {" +123 "} }, - { 123., {" 123.0 "} }, - { 123.123, {" 123.123 "} }, - { -123, {" -123 "} }, - { 1E99, {" 1E99 "} }, - { 1.E99, {" 1.E+99 "} }, - { 1.E-99, {" 1E-99 "} }, - { 1.E-99, {" 1.0-99 "} } }; - - THEN("the string will parse to the corresponding value"){ - for ( const auto& pair : testset ){ - const auto& reference = std::get<0>(pair); - const auto& string = std::get<1>(pair); - - auto begin = string.begin(); - auto end = string.end(); - auto result = njoy::disco::Real<11>::read(begin, end); - auto error = std::abs( ( result - reference ) / reference ); - REQUIRE( error < 1E-15 ); - REQUIRE( end - begin == 0 ); - } - } - } - - GIVEN("a blank string"){ - std::string blank {" "}; - THEN("the string will be parsed to zero"){ - auto begin = blank.begin(); - auto end = blank.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - REQUIRE( result == 0 ); - REQUIRE( end - begin == 0 ); - } - } - - GIVEN("a strings truncated with newline or EOF characters"){ - std::string ten = " 10 "; - - std::vector truncatedStrings - { {ten + '\n'}, - {ten + char{std::char_traits::eof()}} }; - - THEN("parsing will terminate at the last character"){ - for( const auto& string : truncatedStrings ){ - auto begin = string.begin(); - auto end = string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - REQUIRE( result == 10.0 ); - REQUIRE( *begin == string.back() ); - REQUIRE( end - begin == 1 ); - } - } - } - - std::vector< std::string > - zero = { " 0", " 0E0", " 0E+0", " 0E-0", - " 0e0", " 0e+0", " 0e-0", " 0D0", - " 0D+0", " 0D-0", " 0d0", " 0d+0", - " 0d-0", " 0+0", " 0-0", " 0.", - " 0.E0", " 0.E+0", " 0.E-0", " 0.e0", - " 0.e+0", " 0.e-0", " 0.D0", " 0.D+0", - " 0.D-0", " 0.d0", " 0.d+0", " 0.d-0", - " 0.+0", " 0.-0", " 0.0", " 0.0E0", - " 0.0E+0", " 0.0E-0", " 0.0e0", " 0.0e+0", - " 0.0e-0", " 0.0D0", " 0.0D+0", " 0.0D-0", - " 0.0d0", " 0.0d+0", " 0.0d-0", " 0.0+0", - " 0.0-0", " +0", " +0E0", " +0E+0", - " +0E-0", " +0e0", " +0e+0", " +0e-0", - " +0D0", " +0D+0", " +0D-0", " +0d0", - " +0d+0", " +0d-0", " +0+0", " +0-0", - " +0.", " +0.E0", " +0.E+0", " +0.E-0", - " +0.e0", " +0.e+0", " +0.e-0", " +0.D0", - " +0.D+0", " +0.D-0", " +0.d0", " +0.d+0", - " +0.d-0", " +0.+0", " +0.-0", " +0.0", - " +0.0E0", " +0.0E+0", " +0.0E-0", " +0.0e0", - " +0.0e+0", " +0.0e-0", " +0.0D0", " +0.0D+0", - " +0.0D-0", " +0.0d0", " +0.0d+0", " +0.0d-0", - " +0.0+0", " +0.0-0", " -0", " -0E0", - " -0E+0", " -0E-0", " -0e0", " -0e+0", - " -0e-0", " -0D0", " -0D+0", " -0D-0", - " -0d0", " -0d+0", " -0d-0", " -0+0", - " -0-0", " -0.", " -0.E0", " -0.E+0", - " -0.E-0", " -0.e0", " -0.e+0", " -0.e-0", - " -0.D0", " -0.D+0", " -0.D-0", " -0.d0", - " -0.d+0", " -0.d-0", " -0.+0", " -0.-0", - " -0.0", " -0.0E0", " -0.0E+0", " -0.0E-0", - " -0.0e0", " -0.0e+0", " -0.0e-0", " -0.0D0", - " -0.0D+0", " -0.0D-0", " -0.0d0", " -0.0d+0", - " -0.0d-0", " -0.0+0", " -0.0-0", " 0E1", - " 0E+1", " 0e1", " 0e+1", " 0D1", - " 0D+1", " 0d1", " 0d+1", " 0+1", - " +0E1", " +0E+1", " +0e1", " +0e+1", - " +0D1", " +0D+1", " +0d1", " +0d+1", - " +0+1", " 0E-1", " 0e-1", " 0D-1", - " 0d-1", " 0-1", " +0E-1", " +0e-1", - " +0D-1", " +0d-1", " +0-1", " -0E1", - " -0E+1", " -0e1", " -0e+1", " -0D1", - " -0D+1", " -0d1", " -0d+1", " -0+1", - " -0E-1", " -0e-1", " -0D-1", " -0d-1", - " -0-1", " " }; - - for ( auto& test_string : zero ){ - auto begin = test_string.begin(); - auto end = test_string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - REQUIRE( result == 0 ); - REQUIRE( end - begin == 0 ); - } - - const std::unordered_map - < double, std::vector > valid = - {{ -0.5, { " -.5", " -.5E0", " -.5E+0", " -.5E-0", - " -.5e0", " -.5e+0", " -.5e-0", " -.5D0", - " -.5D+0", " -.5D-0", " -.5d0", " -.5d+0", - " -.5d-0", " -.5+0", " -.5-0", " -0.5", - " -0.5E0", " -0.5E+0", " -0.5E-0", " -0.5e0", - " -0.5e+0", " -0.5e-0", " -0.5D0", " -0.5D+0", - " -0.5D-0", " -0.5d0", " -0.5d+0", " -0.5d-0", - " -0.50", " -0.5-0", " -0.50", " -0.50E0", - " -0.50E+0", " -0.50E-0", " -0.50e0", " -0.50e+0", - " -0.50e-0", " -0.50D0", " -0.50D+0", " -0.50D-0", - " -0.50d0", " -0.50d+0", " -0.50d-0", " -0.50+0", - " -0.50-0", " -.50", " -.50E0", " -.50E+0", - " -.50E-0", " -.50e0", " -.50e+0", " -.50e-0", - " -.50D0", " -.50D+0", " -.50D-0", " -.50d0", - " -.50d+0", " -.50d-0", " -.50+0", " -.50-0", - " -0.05E1", " -0.05E+1", " -0.05e1", " -0.05e+1", - " -0.05D1", " -0.05D+1", " -0.05d1", " -0.05d+1", - " -0.05+1", " -5E-1", " -5e-1", " -5D-1", - " -5d-1", " -5-1"}}, - { 0.5, { " .5", " .5E0", " .5E+0", " .5E-0", - " .5e0", " .5e+0", " .5e-0", " .5D0", - " .5D+0", " .5D-0", " .5d0", " .5d+0", - " .5d-0", " .5+0", " .5-0", " 0.5", - " 0.5E0", " 0.5E+0", " 0.5E-0", " 0.5e0", - " 0.5e+0", " 0.5e-0", " 0.5D0", " 0.5D+0", - " 0.5D-0", " 0.5d0", " 0.5d+0", " 0.5d-0", - " 0.50", " 0.5-0", " 0.50", " 0.50E0", - " 0.50E+0", " 0.50E-0", " 0.50e0", " 0.50e+0", - " 0.50e-0", " 0.50D0", " 0.50D+0", " 0.50D-0", - " 0.50d0", " 0.50d+0", " 0.50d-0", " 0.50+0", - " 0.50-0", " .50", " .50E0", " .50E+0", - " .50E-0", " .50e0", " .50e+0", " .50e-0", - " .50D0", " .50D+0", " .50D-0", " .50d0", - " .50d+0", " .50d-0", " .50+0", " .50-0", - " +.5", " +.5E0", " +.5E+0", " +.5E-0", - " +.5e0", " +.5e+0", " +.5e-0", " +.5D0", - " +.5D+0", " +.5D-0", " +.5d0", " +.5d+0", - " +.5d-0", " +.5+0", " +.5-0", " +0.5", - " +0.5E0", " +0.5E+0", " +0.5E-0", " +0.5e0", - " +0.5e+0", " +0.5e-0", " +0.5D0", " +0.5D+0", - " +0.5D-0", " +0.5d0", " +0.5d+0", " +0.5d-0", - " +0.50", " +0.5-0", " +0.50", " +0.50E0", - " +0.50E+0", " +0.50E-0", " +0.50e0", " +0.50e+0", - " +0.50e-0", " +0.50D0", " +0.50D+0", " +0.50D-0", - " +0.50d0", " +0.50d+0", " +0.50d-0", " +0.50+0", - " +0.50-0", " +.50", " +.50E0", " +.50E+0", - " +.50E-0", " +.50e0", " +.50e+0", " +.50e-0", - " +.50D0", " +.50D+0", " +.50D-0", " +.50d0", - " +.50d+0", " +.50d-0", " +.50+0", " +.50-0", - " 0.05E1", " 0.05E+1", " 0.05e1", " 0.05e+1", - " 0.05D1", " 0.05D+1", " 0.05d1", " 0.05d+1", - " 0.05+1", " +0.05E1", " +0.05E+1", " +0.05e1", - " +0.05e+1", " +0.05D1", " +0.05D+1", " +0.05d1", - " +0.05d+1", " +0.05+1", " 5E-1", " 5e-1", - " 5D-1", " 5d-1", " 5-1", " +5E-1", - " +5e-1", " +5D-1", " +5d-1", " +5-1" }}, - { -10.0, { " -10", " -10E0", " -10E+0", " -10E-0", - " -10e0", " -10e+0", " -10e-0", " -10D0", - " -10D+0", " -10D-0", " -10d0", " -10d+0", - " -10d-0", " -10+0", " -10-0", " -10.", - " -10.E0", " -10.E+0", " -10.E-0", " -10.e0", - " -10.e+0", " -10.e-0", " -10.D0", " -10.D+0", - " -10.D-0", " -10.d0", " -10.d+0", " -10.d-0", - " -10.+0", " -10.-0", " -10.0", " -10.0E0", - " -10.0E+0", " -10.0E-0", " -10.0e0", " -10.0e+0", - " -10.0e-0", " -10.0D0", " -10.0D+0", " -10.0D-0", - " -10.0d0", " -10.0d+0", " -10.0d-0", " -10.0+0", - " -10.0-0", " -1E1", " -1E+1", " -1e1", - " -1e+1", " -1D1", " -1D+1", " -1d1", - " -1d+1", " -1+1", " -100E-1", " -100e-1", - " -100D-1", " -100d-1", " -100-1"}}, - { 10.0, { " 10", " 10E0", " 10E+0", " 10E-0", - " 10e0", " 10e+0", " 10e-0", " 10D0", - " 10D+0", " 10D-0", " 10d0", " 10d+0", - " 10d-0", " 10+0", " 10-0", " 10.", - " 10.E0", " 10.E+0", " 10.E-0", " 10.e0", - " 10.e+0", " 10.e-0", " 10.D0", " 10.D+0", - " 10.D-0", " 10.d0", " 10.d+0", " 10.d-0", - " 10.+0", " 10.-0", " 10.0", " 10.0E0", - " 10.0E+0", " 10.0E-0", " 10.0e0", " 10.0e+0", - " 10.0e-0", " 10.0D0", " 10.0D+0", " 10.0D-0", - " 10.0d0", " 10.0d+0", " 10.0d-0", " 10.0+0", - " 10.0-0", " +10", " +10E0", " +10E+0", - " +10E-0", " +10e0", " +10e+0", " +10e-0", - " +10D0", " +10D+0", " +10D-0", " +10d0", - " +10d+0", " +10d-0", " +10+0", " +10-0", - " +10.", " +10.E0", " +10.E+0", " +10.E-0", - " +10.e0", " +10.e+0", " +10.e-0", " +10.D0", - " +10.D+0", " +10.D-0", " +10.d0", " +10.d+0", - " +10.d-0", " +10.+0", " +10.-0", " +10.0", - " +10.0E0", " +10.0E+0", " +10.0E-0", " +10.0e0", - " +10.0e+0", " +10.0e-0", " +10.0D0", " +10.0D+0", - " +10.0D-0", " +10.0d0", " +10.0d+0", " +10.0d-0", - " +10.0+0", " +10.0-0", " 1E1", " 1E+1", - " 1e1", " 1e+1", " 1D1", " 1D+1", - " 1d1", " 1d+1", " 1+1", " +1E1", - " +1E+1", " +1e1", " +1e+1", " +1D1", - " +1D+1", " +1d1", " +1d+1", " +1+1", - " 100E-1", " 100e-1", " 100D-1", " 100d-1", - " 100-1", " +100E-1", " +100e-1", " +100D-1", - " +100d-1", " +100-1"}}, - { 3.14159, { " 3.14159", "3.14159 ", " 3.14159E0", "3.14159E0 ", - "3.14159E+0", "3.14159E-0", "3.14159e+0", "3.14159e0 ", - "3.14159e-0", " 3.14159D0", "3.14159D0 ", "3.14159D+0", - "3.14159D-0", " 3.14159d0", "3.14159d0 ", "3.14159d+0", - "3.14159d-0", " 3.14159+0", "3.14159+0 ", " 3.14159-0", - "3.14159-0 ", " .314159E1", ".314159E1 " , ".314159E+1", - " .314159e1", ".314159e1 ", ".314159e+1", " .314159D1", - ".314159D1 ", ".314159D+1", " .314159d1", ".314159d1 ", - ".314159d+1", " .314159+1", ".314159+1 ", "0.314159E1", - "0.314159E1", "0.314159e1", ".314159e+1", "0.314159D1", - ".314159D+1", "0.314159d1", ".314159d+1", "0.314159+1", - "31.4159E-1", "31.4159e-1", "31.4159D-1", "31.4159d-1", - " 31.4159-1", "31.4159-1 ", " +3.14159", "+3.14159 ", - "+3.14159E0", "+3.14159D0", "+3.14159e0", "+3.14159d0" }}}; - - for ( auto& number : valid ){ - for ( auto& string : number.second ){ - auto begin = string.begin(); - auto end = string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - auto error = std::abs( ( result - number.first ) / number.first ); - REQUIRE( error < 1E-15 ); - REQUIRE( end - begin == 0 ); - } - } - - std::vector< std::string > - infinityStrings = { " infinity", " Infinity", - " +infinity", " +Infinity", - " inf", " Inf", - " +inf", " +Inf", - "infinity ", "Infinity ", - "+infinity ", "+Infinity ", - "inf ", "Inf ", - "+inf ", "+Inf " }; - - for ( auto& string : infinityStrings ){ - auto begin = string.begin(); - auto end = string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - REQUIRE( result == std::numeric_limits::infinity() ); - REQUIRE( end - begin == 0 ); - } - - infinityStrings = { " -infinity", " -Infinity", - " -infinity", " -Infinity", - " -inf", " -Inf", - " -inf", " -Inf", - "-infinity ", "-Infinity ", - "-infinity ", "-Infinity ", - "-inf ", "-Inf ", - "-inf ", "-Inf " }; - for ( auto& string : infinityStrings ){ +SCENARIO( "Real - read") { + + auto eps = 1e-15; // ~ std::numeric_limits< double >::epsilon() * 10; + + auto parse = [] ( const std::string string, bool& consumed ) { + + consumed = false; auto begin = string.begin(); auto end = string.end(); - auto result = njoy::disco::Real<10>::read(begin, end); - REQUIRE( result == -std::numeric_limits::infinity() ); - REQUIRE( end - begin == 0 ); - } - - GIVEN("A collection of invalid strings"){ - std::vector< std::string > - testset{{" +"}, - {" + 1"}, - {" . "}, - {" .inf "}, - {" E3"}, - {" .E3 "}, - {" E"}, - {" 1.2E"}, - {" -123.0a "}, - {" -123.0 a "}}; - - for ( auto& string : testset ){ - std::cout << string << std::endl; + auto result = njoy::disco::Real< 11 >::read< double >( begin, end ); + consumed = ( end - begin == 0 ); + + return result; + }; + + GIVEN( "A collection of strings and corresponding double values" ) { + + THEN( "the strings will parse to the corresponding values and the " + "strings will be consumed entirely" ) { + + bool consumed = false; + + CHECK( 123. == Approx( parse( " +123", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123. == Approx( parse( " 123.0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123.123 == Approx( parse( " 123.123", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( -123. == Approx( parse( " -123", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1E99 == Approx( parse( " 1E99", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E99 == Approx( parse( " 1.E+99", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( " 1E-99", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( " 1.0-99", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123. == Approx( parse( "+123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123. == Approx( parse( "123.0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123.123 == Approx( parse( "123.123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( -123. == Approx( parse( "-123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1E99 == Approx( parse( "1E99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E99 == Approx( parse( "1.E+99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( "1E-99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( "1.0-99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123. == Approx( parse( " +123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123. == Approx( parse( " 123.0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 123.123 == Approx( parse( " 123.123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( -123. == Approx( parse( " -123 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1E99 == Approx( parse( " 1E99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E99 == Approx( parse( " 1.E+99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( " 1E-99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 1.E-99 == Approx( parse( " 1.0-99 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 100. == Approx( parse( "10.000000+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 100. == Approx( parse( " 1.000000+2", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + + CHECK( 0. == parse( " 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0E-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0e-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0D-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0d-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0E-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0e-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0D-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0d-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0+1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0E-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0e-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0D-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0d-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0-1", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " ", consumed ) ); CHECK( true == consumed ); + + CHECK( -0.5 == parse( " -.5", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5E0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5e0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5D0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5d0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.5-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5E0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5e0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5D0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5d0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.5-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50E0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50e0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50D0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50d0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.50-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50E0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50e0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50D0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50d0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50+0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -.50-0", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05E1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05E+1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05e1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05e+1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05D1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05D+1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05d1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05d+1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -0.05+1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -5E-1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -5e-1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -5D-1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -5d-1", consumed ) ); CHECK( true == consumed ); + CHECK( -0.5 == parse( " -5-1", consumed ) ); CHECK( true == consumed ); + + CHECK( +0.5 == parse( " .5", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .5-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.5-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.50-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " .50-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.5-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.5-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.50-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50E0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50e0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50D0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50d0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50+0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +.50-0", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05E1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05E+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05e1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05e+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05D1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05D+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05d1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05d+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 0.05+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05E1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05E+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05e1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05e+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05D1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05D+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05d1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05d+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +0.05+1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 5E-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 5e-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 5D-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 5d-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " 5-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +5E-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +5e-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +5D-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +5d-1", consumed ) ); CHECK( true == consumed ); + CHECK( +0.5 == parse( " +5-1", consumed ) ); CHECK( true == consumed ); + + CHECK( -10. == parse( " -10", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10E0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10e0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10D0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10d0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.E0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.e0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.D0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.d0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -10.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1E1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1E+1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1e1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1e+1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1D1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1D+1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1d1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1d+1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -1+1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -100E-1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -100e-1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -100D-1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -100d-1", consumed ) ); CHECK( true == consumed ); + CHECK( -10. == parse( " -100-1", consumed ) ); CHECK( true == consumed ); + + CHECK( +10. == parse( " 10", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 10.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0E0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0E+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0E-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0e0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0e+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0e-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0D0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0D+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0D-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0d0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0d+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0d-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0+0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10.0-0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1E1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1E+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1e1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1e+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1D1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1D+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1d1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1d+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 1+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1E1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1E+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1e1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1e+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1D1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1D+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1d1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1d+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +1+1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 100E-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 100e-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 100D-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 100d-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " 100-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +100E-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +100e-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +100D-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +100d-1", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +100-1", consumed ) ); CHECK( true == consumed ); + + CHECK( 3.14159 == Approx( parse( " 3.14159", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159E0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159E0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159E+0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159E-0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159e+0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159e0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159e-0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159D0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159D0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159D+0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159D-0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159d0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159d0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159d+0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159d-0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159+0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159+0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159-0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159-0 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159E1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159E1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159E+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159e1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159e1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159e+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159D1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159D1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159D+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159d1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159d1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159d+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159+1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159E1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159E1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159e1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159e+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159D1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159D+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159d1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " .314159d+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 0.314159+1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159E-1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159e-1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159D-1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159d-1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159-1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159-1 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159 ", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159E0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159D0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159e0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " +3.14159d0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + + CHECK( 0. == parse( " 0.0 E 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. + 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( "+0.0 E 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( "+0. + 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( "-0.0 E 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( "-0. + 0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. ", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. +0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " 0. -0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. ", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. +0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " +0. -0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. ", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. E0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. E+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. E-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. e0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. e+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. e-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. D0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. D+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. D-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. d0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. d+0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. d-0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. +0", consumed ) ); CHECK( true == consumed ); + CHECK( 0. == parse( " -0. -0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. E 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. E+ 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. E- 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. e 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. e+ 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. e- 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. D 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. D+ 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. D- 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. d 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. d+ 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. d- 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. + 0", consumed ) ); CHECK( true == consumed ); + CHECK( +10. == parse( " +10. - 0", consumed ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 31.4159 -1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "31.4159 - 1", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 +0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "3.14159 + 0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 E0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "3.14159 E 0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 e0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "3.14159 e 0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 D0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "3.14159 D 0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( " 3.14159 d0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + CHECK( 3.14159 == Approx( parse( "3.14159 d 0", consumed ) ).epsilon( eps ) ); CHECK( true == consumed ); + } // THEN + } // GIVEN + + GIVEN( "a blank string" ) { + + THEN( "the string will be parsed to zero and the string will be consumed " + "entirely" ) { + + bool consumed = false; + + CHECK( 0. == parse( " ", consumed ) ); CHECK( true == consumed ); + } // THEN + } // GIVEN + + GIVEN( "A collection of strings representing infinity" ) { + + THEN( "the strings will parse to the corresponding infinite value and the " + "strings will be consumed entirely" ) { + + bool consumed = false; + auto inf = std::numeric_limits< double >::infinity(); + + CHECK( inf == parse( " infinity", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " Infinity", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " +infinity", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " +Infinity", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " inf", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " Inf", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " +inf", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( " +Inf", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "Infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "+infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "+Infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "inf ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "Inf ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "+inf ", consumed ) ); CHECK( true == consumed ); + CHECK( inf == parse( "+Inf ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -infinity", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -Infinity", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -infinity", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -Infinity", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -inf", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -Inf", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -inf", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( " -Inf", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-Infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-Infinity ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-inf ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-Inf ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-inf ", consumed ) ); CHECK( true == consumed ); + CHECK( -inf == parse( "-Inf ", consumed ) ); CHECK( true == consumed ); + } // THEN + } // GIVEN + + GIVEN( "A collection of invalid strings" ) { + + THEN( "an exception is thrown" ) { + + bool consumed = false; + + CHECK_THROWS( parse( " +", consumed ) ); + CHECK_THROWS( parse( " + 1", consumed ) ); + CHECK_THROWS( parse( " . ", consumed ) ); + CHECK_THROWS( parse( " .inf ", consumed ) ); + CHECK_THROWS( parse( " E3", consumed ) ); + CHECK_THROWS( parse( " .E3 ", consumed ) ); + CHECK_THROWS( parse( " E", consumed ) ); + CHECK_THROWS( parse( " 1.2E", consumed ) ); + CHECK_THROWS( parse( " E ", consumed ) ); + CHECK_THROWS( parse( " 1.2E ", consumed ) ); + CHECK_THROWS( parse( " 1.2 E ", consumed ) ); + CHECK_THROWS( parse( " -123.0a ", consumed ) ); + CHECK_THROWS( parse( " -123.0 a ", consumed ) ); + } // THEN + } // GIVEN + + GIVEN( "a strings truncated with newline or EOF characters" ) { + + THEN( "the strings will parse to the corresponding values and the " + "strings will be consumed up to the last character" ) { + + std::string string = ""; auto begin = string.begin(); auto end = string.end(); - REQUIRE_THROWS( njoy::disco::Real<10>::read(begin, end) ); - } - } -} + + string = " 10 \n"; + begin = string.begin(); + end = string.end(); + CHECK( 10. == njoy::disco::Real< 10 >::read< double >( begin, end ) ); + CHECK( 1 == end - begin ); + CHECK( string.back() == *begin ); + + string = " 10 "; + string += char{ std::char_traits< char >::eof() }; + begin = string.begin(); + end = string.end(); + CHECK( 10. == njoy::disco::Real< 10 >::read< double >( begin, end ) ); + CHECK( 1 == end - begin ); + CHECK( string.back() == *begin ); + } // THEN + } // GIVEN +} // SCENARIO diff --git a/src/disco/FixedWidthField/noDigits.hpp b/src/disco/FixedWidthField/noDigits.hpp index 9163995..0cb7e05 100644 --- a/src/disco/FixedWidthField/noDigits.hpp +++ b/src/disco/FixedWidthField/noDigits.hpp @@ -1,4 +1,5 @@ template< typename Integer > -constexpr int noDigits( Integer i ){ +constexpr int noDigits( Integer i ) { + return ( i < 10 ) ? 1 : 1 + noDigits( i / 10 ); -} +} diff --git a/src/disco/FixedWidthField/src/whiteSpace.hpp b/src/disco/FixedWidthField/src/whiteSpace.hpp index 7dabe82..59985af 100644 --- a/src/disco/FixedWidthField/src/whiteSpace.hpp +++ b/src/disco/FixedWidthField/src/whiteSpace.hpp @@ -1,8 +1,10 @@ template< typename Iterator > static uint16_t -whiteSpace( Iterator& it ){ +whiteSpace( Iterator& it ) { + uint16_t position = 0; while( FixedWidthField::isSpace( *it ) and ++position != w ) { + ++it; } return position; @@ -10,11 +12,10 @@ whiteSpace( Iterator& it ){ template< typename Iterator > static bool -whiteSpace( Iterator& it, uint16_t position ){ +whiteSpace( Iterator& it, uint16_t position ) { + while( ++position <= w and FixedWidthField::isSpace( *it ) ) { ++it; } - return - position > w - or FixedWidthField::isNewline( *it, it ) - or FixedWidthField::isEOF( *it ); + return position > w + or FixedWidthField::isNewline( *it, it ) + or FixedWidthField::isEOF( *it ); } -