diff --git a/tests/test_parser.cpp b/tests/test_parser.cpp index 8669af8..ff8b243 100644 --- a/tests/test_parser.cpp +++ b/tests/test_parser.cpp @@ -31,6 +31,12 @@ BOOST_AUTO_TEST_CASE(test_parse_basic_inline_string) BOOST_CHECK_EQUAL(result.first.get(), expected); BOOST_CHECK(result.second == acceptor::invoke(source.begin())); } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } } BOOST_AUTO_TEST_CASE(test_parse_basic_multiline_string) @@ -62,6 +68,12 @@ BOOST_AUTO_TEST_CASE(test_parse_basic_multiline_string) BOOST_CHECK_EQUAL(result.first.get(), expected); BOOST_CHECK(result.second == acceptor::invoke(source.begin())); } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } } BOOST_AUTO_TEST_CASE(test_parse_literal_inline_string) @@ -100,6 +112,12 @@ BOOST_AUTO_TEST_CASE(test_parse_literal_inline_string) BOOST_CHECK_EQUAL(result.first.get(), expected); BOOST_CHECK(result.second == acceptor::invoke(source.begin())); } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } } BOOST_AUTO_TEST_CASE(test_parse_literal_multiline_string) @@ -122,6 +140,12 @@ BOOST_AUTO_TEST_CASE(test_parse_literal_multiline_string) BOOST_CHECK_EQUAL(result.first.get(), expected); BOOST_CHECK(result.second == acceptor::invoke(source.begin())); } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } } BOOST_AUTO_TEST_CASE(test_parse_string) @@ -160,8 +184,148 @@ BOOST_AUTO_TEST_CASE(test_parse_string) BOOST_CHECK_EQUAL(result.first.get(), expected); BOOST_CHECK(result.second == acceptor::invoke(source.begin())); } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } } +BOOST_AUTO_TEST_CASE(test_integer) +{ + typedef toml::parse_integer parser; + typedef toml::is_integer acceptor; + { + const std::string source("42"); + const toml::Integer expected(42); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("+42"); + const toml::Integer expected(42); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-42"); + const toml::Integer expected(-42); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-4_2"); + const toml::Integer expected(-42); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } +} + +BOOST_AUTO_TEST_CASE(test_float) +{ + typedef toml::parse_float parser; + typedef toml::is_float acceptor; + { + const std::string source("42.0"); + const toml::Float expected(42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("+42.0"); + const toml::Float expected(42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-42.0"); + const toml::Float expected(-42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-4_2.0"); + const toml::Float expected(-42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-42e0"); + const toml::Float expected(-42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("-42.0e0"); + const toml::Float expected(-42.0); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("dummy"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } +} + +BOOST_AUTO_TEST_CASE(test_parse_boolean) +{ + typedef toml::parse_boolean parser; + typedef toml::is_boolean acceptor; + { + const std::string source("true"); + const toml::Boolean expected(true); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("false"); + const toml::Boolean expected(false); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(result.first.ok()); + BOOST_CHECK_EQUAL(result.first.get(), expected); + BOOST_CHECK(result.second == acceptor::invoke(source.begin())); + } + { + const std::string source("T"); + const auto result = parser::invoke(source.cbegin()); + BOOST_CHECK(!result.first.ok()); + BOOST_CHECK(result.second == source.begin()); + } +} + + + // BOOST_AUTO_TEST_CASE(test_parse_local_time) // { // typedef toml::parse_local_time parser; diff --git a/toml/parser.hpp b/toml/parser.hpp index d9e7c5c..c2a2893 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -284,58 +284,62 @@ struct parse_string } }; -// -// template -// struct parse_integer -// { -// typedef charT value_type; -// typedef std::basic_string string_type; -// typedef toml::Integer result_type; -// -// template::value_type, -// value_type>::value>::type> -// static result_type invoke(Iterator iter, Iterator end) -// { -// string_type result; result.resize(std::distance(iter, end)); -// std::copy_if(iter, end, result.begin(), [](charT c){return c != '_';}); -// return std::stoi(result); -// } -// }; -// -// template -// struct parse_float -// { -// typedef charT value_type; -// typedef std::basic_string string_type; -// typedef toml::Float result_type; -// -// template::value_type, -// value_type>::value>::type> -// static result_type invoke(Iterator iter, Iterator end) -// { -// string_type result; result.resize(std::distance(iter, end)); -// std::copy_if(iter, end, result.begin(), [](charT c){return c != '_';}); -// return std::stod(result); -// } -// }; -// -// template -// struct parse_boolean -// { -// typedef charT value_type; -// typedef toml::Boolean result_type; -// -// template::value_type, -// value_type>::value>::type> -// static result_type invoke(Iterator iter, Iterator end) -// { -// return (std::distance(iter, end) == 4); -// } -// }; -// +struct parse_integer +{ + typedef toml::charactor value_type; + typedef std::basic_string string_type; + typedef detail::result result_type; + + template::value_type, + value_type>::value>::type> + static std::pair invoke(Iterator iter) + { + const Iterator end = is_integer::invoke(iter); + if(iter == end) return std::make_pair(result_type{}, iter); + + string_type result; result.resize(std::distance(iter, end)); + std::copy_if(iter, end, result.begin(), [](value_type c){return c != '_';}); + return std::make_pair(std::stoll(result), end); + } +}; + +struct parse_float +{ + typedef toml::charactor value_type; + typedef std::basic_string string_type; + typedef detail::result result_type; + + template::value_type, + value_type>::value>::type> + static std::pair invoke(Iterator iter) + { + const Iterator end = is_float::invoke(iter); + if(iter == end) return std::make_pair(result_type{}, iter); + + string_type result; result.resize(std::distance(iter, end)); + std::copy_if(iter, end, result.begin(), [](value_type c){return c != '_';}); + return std::make_pair(std::stod(result), end); + } +}; + +struct parse_boolean +{ + typedef toml::charactor value_type; + typedef detail::result result_type; + + template::value_type, + value_type>::value>::type> + static std::pair invoke(Iterator iter) + { + const Iterator end = is_boolean::invoke(iter); + if(iter == end) return std::make_pair(result_type{}, iter); + return std::make_pair((std::distance(iter, end) == 4), end); + } +}; + // template // struct parse_local_time // {