summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-08-05 15:23:10 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-08-05 15:23:10 +0100
commit56fef50c0a7c0e3a604b8a9b68017ed265b9fa88 (patch)
treef0f2e28f7106fdd18f896b865ef02847cb51dfa5
parentConstref correctness for shared_ptr parameters (diff)
downloadslicer-56fef50c0a7c0e3a604b8a9b68017ed265b9fa88.tar.bz2
slicer-56fef50c0a7c0e3a604b8a9b68017ed265b9fa88.tar.xz
slicer-56fef50c0a7c0e3a604b8a9b68017ed265b9fa88.zip
Use faster std::from_chars over boost::lexical_cast for XML numeric parse
-rw-r--r--slicer/xml/serializer.cpp31
-rw-r--r--slicer/xml/testSpecifics.cpp6
-rw-r--r--slicer/xml/xmlExceptions.ice4
3 files changed, 32 insertions, 9 deletions
diff --git a/slicer/xml/serializer.cpp b/slicer/xml/serializer.cpp
index 27bf10b..56cdbaa 100644
--- a/slicer/xml/serializer.cpp
+++ b/slicer/xml/serializer.cpp
@@ -1,5 +1,6 @@
#include "serializer.h"
#include <boost/lexical_cast.hpp>
+#include <charconv>
#include <compileTimeFormatter.h>
#include <functional>
#pragma GCC diagnostic push
@@ -73,37 +74,37 @@ namespace Slicer {
void
set(Ice::Byte & v) const override
{
- v = boost::numeric_cast<Ice::Byte>(boost::lexical_cast<int>(value));
+ from_chars(v);
}
void
set(Ice::Short & v) const override
{
- v = boost::lexical_cast<Ice::Short>(value);
+ from_chars(v);
}
void
set(Ice::Int & v) const override
{
- v = boost::lexical_cast<Ice::Int>(value);
+ from_chars(v);
}
void
set(Ice::Long & v) const override
{
- v = boost::lexical_cast<Ice::Long>(value);
+ from_chars(v);
}
void
set(Ice::Float & v) const override
{
- v = boost::lexical_cast<Ice::Float>(value);
+ from_chars(v);
}
void
set(Ice::Double & v) const override
{
- v = boost::lexical_cast<Ice::Double>(value);
+ from_chars(v);
}
void
@@ -113,6 +114,16 @@ namespace Slicer {
}
private:
+ template<typename T>
+ void
+ from_chars(T & v) const
+ {
+ std::string_view raw {value.raw()};
+ if (std::from_chars(raw.begin(), raw.end(), v).ec != std::errc {}) {
+ throw BadNumericValue(value);
+ }
+ }
+
const Glib::ustring value;
};
@@ -489,4 +500,12 @@ namespace Slicer {
{
BadBooleanValueMsg::write(s, text);
}
+
+ AdHocFormatter(BadNumericValueMsg, "Bad numeric value [%?]");
+
+ void
+ BadNumericValue::ice_print(std::ostream & s) const
+ {
+ BadNumericValueMsg::write(s, text);
+ }
}
diff --git a/slicer/xml/testSpecifics.cpp b/slicer/xml/testSpecifics.cpp
index ec9fe11..24edf78 100644
--- a/slicer/xml/testSpecifics.cpp
+++ b/slicer/xml/testSpecifics.cpp
@@ -54,11 +54,11 @@ BOOST_AUTO_TEST_CASE(int_values)
doc.parse_memory("<Int>-4</Int>");
BOOST_REQUIRE_EQUAL(-4, BoostThrowWrapperHelper<Ice::Int>(doc.get_document()));
doc.parse_memory("<Int> </Int>");
- BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), std::bad_cast);
+ BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), Slicer::BadNumericValue);
doc.parse_memory("<Int>notanint</Int>");
- BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), std::bad_cast);
+ BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), Slicer::BadNumericValue);
doc.parse_memory("<Int></Int>");
- BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), std::bad_cast);
+ BOOST_REQUIRE_THROW(BoostThrowWrapperHelper<Ice::Int>(doc.get_document()), Slicer::BadNumericValue);
}
BOOST_AUTO_TEST_CASE(factories)
diff --git a/slicer/xml/xmlExceptions.ice b/slicer/xml/xmlExceptions.ice
index 390f458..26d8aa2 100644
--- a/slicer/xml/xmlExceptions.ice
+++ b/slicer/xml/xmlExceptions.ice
@@ -8,6 +8,10 @@ module Slicer {
exception BadBooleanValue extends DeserializerError {
string text;
};
+ ["cpp:ice_print"]
+ exception BadNumericValue extends DeserializerError {
+ string text;
+ };
};
#endif