Skip to content

Commit

Permalink
Fix conversions to bool with leading zeros (refs #9659)
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin committed Mar 5, 2014
1 parent 1e65265 commit d1a51b8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 25 deletions.
46 changes: 24 additions & 22 deletions include/boost/lexical_cast.hpp
Expand Up @@ -1878,35 +1878,37 @@ namespace boost {
}
#endif

/*
* case "-0" || "0" || "+0" : output = false; return true;
* case "1" || "+1": output = true; return true;
* default: return false;
*/
bool operator>>(bool& output) BOOST_NOEXCEPT {
output = false; // Suppress warning about uninitalized variable

if (start == finish) return false;
CharT const zero = lcast_char_constants<CharT>::zero;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const minus = lcast_char_constants<CharT>::minus;

output = false; // Suppress warning about uninitalized variable
switch (finish - start) {
case 1:
output = Traits::eq(start[0], zero+1);
return output || Traits::eq(start[0], zero );

case 2:
if (Traits::eq(plus, *start)) {
++start;
output = Traits::eq(start[0], zero + 1);
return output || Traits::eq(start[0], zero );
} else {
return Traits::eq( minus, *start)
&& Traits::eq( zero, start[1]);
}
const CharT* const dec_finish = finish - 1;
output = Traits::eq(*dec_finish, zero + 1);
if (!output && !Traits::eq(*dec_finish, zero)) {
return false; // Does not ends on '0' or '1'
}

default:
return false;
if (start == dec_finish) return true;

// We may have sign at the beginning
if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
++ start;
}

// Skipping zeros
while (start != dec_finish) {
if (!Traits::eq(zero, *start)) {
return false; // Not a zero => error
}

++ start;
}

return true;
}

bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); }
Expand Down
27 changes: 24 additions & 3 deletions test/lexical_cast_test.cpp
Expand Up @@ -272,11 +272,32 @@ void test_conversion_to_bool()
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("Test")), bad_lexical_cast);

BOOST_CHECK(lexical_cast<bool>("+1") == true );
BOOST_CHECK(lexical_cast<bool>("+0") == false );
BOOST_CHECK(lexical_cast<bool>("-0") == false );
BOOST_CHECK(lexical_cast<bool>("+1") == true);
BOOST_CHECK(lexical_cast<bool>("+0") == false);
BOOST_CHECK(lexical_cast<bool>("-0") == false);
BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);

BOOST_CHECK(lexical_cast<bool>("0") == false);
BOOST_CHECK(lexical_cast<bool>("1") == true);
BOOST_CHECK(lexical_cast<bool>("00") == false);
BOOST_CHECK(lexical_cast<bool>("00000000000") == false);
BOOST_CHECK(lexical_cast<bool>("000000000001") == true);
BOOST_CHECK(lexical_cast<bool>("+00") == false );
BOOST_CHECK(lexical_cast<bool>("-00") == false );
BOOST_CHECK(lexical_cast<bool>("+00000000001") == true );

BOOST_CHECK_THROW(lexical_cast<bool>("020"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("00200"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-00200"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("+00200"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("000000000002"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-0000000001"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("00000000011"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("001001"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-00000000010"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-000000000100"), bad_lexical_cast);
}

void test_conversion_to_string()
Expand Down

0 comments on commit d1a51b8

Please sign in to comment.