From 7b439ff591777e8ea58045ce3fe082098d802b49 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 29 Jul 2023 12:34:05 +0100 Subject: Use faster std::from_chars over boost::lexical_cast if possible --- icespider/core/ihttpRequest.h | 12 +++++++++++- icespider/core/xwwwFormUrlEncoded.cpp | 6 ++++-- icespider/unittests/testFcgi.cpp | 2 ++ icespider/unittests/testPerf.cpp | 9 +++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index d1633b3..6cce145 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ namespace IceSpider { virtual std::ostream & dump(std::ostream & s) const = 0; static_assert(std::is_constructible_v); + static_assert(std::is_convertible_v); template [[nodiscard]] inline std::optional @@ -70,7 +72,15 @@ namespace IceSpider { return *v; } else if constexpr (std::is_constructible::value) { - return T(*v); + return std::optional {std::in_place, *v}; + } + else if constexpr (requires(T out) { std::from_chars(v->begin(), v->end(), out); }) { + if (T out {}; std::from_chars(v->begin(), v->end(), out).ec == std::errc {}) { + return out; + } + else { + throw Http400_BadRequest(); + } } else { try { diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp index 7bbf144..73f77b8 100644 --- a/icespider/core/xwwwFormUrlEncoded.cpp +++ b/icespider/core/xwwwFormUrlEncoded.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -181,7 +181,9 @@ namespace IceSpider { /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \ void set(T & t) const override \ { \ - t = boost::lexical_cast(s); \ + if (const auto v = s.value(); std::from_chars(v.begin(), v.end(), t).ec != std::errc {}) { \ + throw Http400_BadRequest(); \ + } \ } SET(Ice::Byte); diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp index e6508b3..b3ea6e2 100644 --- a/icespider/unittests/testFcgi.cpp +++ b/icespider/unittests/testFcgi.cpp @@ -316,6 +316,8 @@ BOOST_AUTO_TEST_CASE(cookies) }}); BOOST_REQUIRE_EQUAL(1234, *r.IceSpider::IHttpRequest::getCookieParam("valueA")); BOOST_REQUIRE_EQUAL("Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam("value B")); + BOOST_REQUIRE_EQUAL( + "Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam("value B")); BOOST_REQUIRE(!r.IceSpider::IHttpRequest::getCookieParam("notAThing")); r.setCookie("some int?[0]", 1234, "www.com"s, "/dir"s, true, 1476142378); BOOST_REQUIRE_EQUAL("Set-Cookie: some+int%3f%5b0%5d=1234; expires=Mon, 10 Oct 2016 23:32:58 GMT; domain=www.com; " diff --git a/icespider/unittests/testPerf.cpp b/icespider/unittests/testPerf.cpp index b23f436..04e5deb 100644 --- a/icespider/unittests/testPerf.cpp +++ b/icespider/unittests/testPerf.cpp @@ -93,6 +93,15 @@ BENCHMARK_F(CoreFixture, get_query_string_param)(benchmark::State & state) } } +BENCHMARK_F(CoreFixture, get_query_string_param_int)(benchmark::State & state) +{ + CharPtrPtrArray env(rootDir / "fixtures/env1"); + TestRequest r(this, env); + for (auto _ : state) { + benchmark::DoNotOptimize(r.getQueryStringParam("m")); + } +} + BENCHMARK_F(CoreFixture, get_cookie_param)(benchmark::State & state) { CharPtrPtrArray env(rootDir / "fixtures/env1"); -- cgit v1.2.3