summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--slicer/slicer/common.ice5
-rw-r--r--slicer/slicer/modelPartsTypes.cpp6
-rw-r--r--slicer/slicer/modelPartsTypes.h1
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h9
-rw-r--r--slicer/slicer/slicer.cpp8
-rw-r--r--slicer/test/initial/inherit-base.xml4
-rw-r--r--slicer/test/initial/inherit-nosuchtype.xml5
-rw-r--r--slicer/test/initial/inherit-same.xml4
-rw-r--r--slicer/test/initial/inherit-wronghier.xml5
-rw-r--r--slicer/test/serializers.cpp34
10 files changed, 76 insertions, 5 deletions
diff --git a/slicer/slicer/common.ice b/slicer/slicer/common.ice
index 60a4f92..ad3ff1f 100644
--- a/slicer/slicer/common.ice
+++ b/slicer/slicer/common.ice
@@ -29,6 +29,11 @@ module Slicer {
string type;
};
["cpp:ice_print"]
+ exception IncorrectType extends DeserializerError {
+ string type;
+ string target;
+ };
+ ["cpp:ice_print"]
exception InvalidEnumerationValue extends SerializerError {
int value;
string type;
diff --git a/slicer/slicer/modelPartsTypes.cpp b/slicer/slicer/modelPartsTypes.cpp
index c57d987..ffaec04 100644
--- a/slicer/slicer/modelPartsTypes.cpp
+++ b/slicer/slicer/modelPartsTypes.cpp
@@ -74,6 +74,12 @@ namespace Slicer {
return name;
}
+ [[noreturn]] void
+ ModelPartForComplexBase::throwIncorrectType(const std::string & name, const std::type_info & target)
+ {
+ throw IncorrectType(name, demangle(target.name()));
+ }
+
#define Roots(Type, Name, NameLen) \
template<> CONSTSTR(NameLen) Slicer::ModelPartForRoot<Type>::rootName {#Name}; \
template<> \
diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h
index 6b6f852..f581c49 100644
--- a/slicer/slicer/modelPartsTypes.h
+++ b/slicer/slicer/modelPartsTypes.h
@@ -147,6 +147,7 @@ namespace Slicer {
static const std::string & ToExchangeTypeName(const std::string &);
static std::string_view ToModelTypeName(const std::string &);
+ [[noreturn]] static void throwIncorrectType(const std::string & name, const std::type_info & target);
};
template<typename T> class Hooks;
diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h
index 3d1d2be..60f221d 100644
--- a/slicer/slicer/modelPartsTypes.impl.h
+++ b/slicer/slicer/modelPartsTypes.impl.h
@@ -448,12 +448,13 @@ namespace Slicer {
ModelPartForClass<T>::OnSubclass(const ModelPartHandler & h, const std::string & name)
{
BOOST_ASSERT(this->Model);
- const ClassRefBase * refbase = ModelPartForComplexBase::getSubclassRef(name);
- BOOST_ASSERT(refbase);
- BOOST_ASSERT(dynamic_cast<const ClassRef<T> *>(refbase));
- if (auto ref = dynamic_cast<const ClassRef<T> *>(refbase)) {
+ if (const ClassRefBase * refbase = ModelPartForComplexBase::getSubclassRef(name);
+ auto ref = dynamic_cast<const ClassRef<T> *>(refbase)) [[likely]] {
ref->onSubClass(*this->Model, h);
}
+ else {
+ ModelPartForComplexBase::throwIncorrectType(name, typeid(T));
+ }
}
template<typename T>
diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp
index ff9a948..5a253b0 100644
--- a/slicer/slicer/slicer.cpp
+++ b/slicer/slicer/slicer.cpp
@@ -13,6 +13,14 @@ namespace Slicer {
InvalidEnumerationSymbolMsg::write(s, symbol, type);
}
+ AdHocFormatter(IncorrectTypeMsg, "Type [%?] cannot be used as a [%?]");
+
+ void
+ IncorrectType::ice_print(std::ostream & s) const
+ {
+ IncorrectTypeMsg::write(s, type, target);
+ }
+
AdHocFormatter(InvalidEnumerationValueMsg, "Invalid enumeration symbol [%?] for type [%?]");
void
diff --git a/slicer/test/initial/inherit-base.xml b/slicer/test/initial/inherit-base.xml
new file mode 100644
index 0000000..45456e2
--- /dev/null
+++ b/slicer/test/initial/inherit-base.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<D12 slicer-typeid="::TestModule::Base2">
+ <a>3</a>
+</D12>
diff --git a/slicer/test/initial/inherit-nosuchtype.xml b/slicer/test/initial/inherit-nosuchtype.xml
new file mode 100644
index 0000000..057bea5
--- /dev/null
+++ b/slicer/test/initial/inherit-nosuchtype.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<D12 slicer-typeid="::TestModule::NoSuchType">
+ <a>3</a>
+ <b>3</b>
+</D12>
diff --git a/slicer/test/initial/inherit-same.xml b/slicer/test/initial/inherit-same.xml
new file mode 100644
index 0000000..77a22ec
--- /dev/null
+++ b/slicer/test/initial/inherit-same.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<D1 slicer-typeid="::TestModule::D1">
+ <a>3</a>
+</D1>
diff --git a/slicer/test/initial/inherit-wronghier.xml b/slicer/test/initial/inherit-wronghier.xml
new file mode 100644
index 0000000..d1ce693
--- /dev/null
+++ b/slicer/test/initial/inherit-wronghier.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<D12 slicer-typeid="::TestModule::D3">
+ <a>3</a>
+ <b>3</b>
+</D12>
diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp
index 57779be..ae9a30e 100644
--- a/slicer/test/serializers.cpp
+++ b/slicer/test/serializers.cpp
@@ -1,4 +1,5 @@
#define BOOST_TEST_MODULE execute_serializers
+#include <boost/test/data/test_case.hpp>
#include <boost/test/unit_test.hpp>
#include "classes.h"
@@ -36,7 +37,6 @@
#include <string>
#include <types.h>
#include <utility>
-#include <variant>
#include <vector>
#include <xml.h>
// IWYU pragma: no_forward_declare Slicer::InvalidEnumerationSymbol
@@ -677,3 +677,35 @@ BOOST_AUTO_TEST_CASE(sequence_element_in_same_slice_link_bug)
BOOST_CHECK_NO_THROW(
Slicer::ModelPart::Make<Slicer::ModelPartForSequence<TestModule::Dates>>(nullptr, [](auto &&) {}));
}
+
+BOOST_AUTO_TEST_CASE(typeid_specifies_same)
+{
+ std::ifstream in {rootDir / "initial/inherit-same.xml"};
+ auto d1 = Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, TestModule::D1Ptr>(in);
+ BOOST_REQUIRE(d1);
+ BOOST_CHECK_EQUAL(d1->a, 3);
+ BOOST_CHECK_EQUAL(typeid(*d1).name(), typeid(TestModule::D1).name());
+}
+
+BOOST_DATA_TEST_CASE(typeid_specifies_bad,
+ boost::unit_test::data::make<std::filesystem::path>({
+ "inherit-base.xml",
+ "inherit-wronghier.xml",
+ }),
+ path)
+{
+ std::ifstream in {rootDir / "initial" / path};
+ BOOST_CHECK_THROW(std::ignore = (Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, TestModule::D12Ptr>(in)),
+ Slicer::IncorrectType);
+}
+
+BOOST_DATA_TEST_CASE(typeid_specifies_no_such_type,
+ boost::unit_test::data::make<std::filesystem::path>({
+ "inherit-nosuchtype.xml",
+ }),
+ path)
+{
+ std::ifstream in {rootDir / "initial" / path};
+ BOOST_CHECK_THROW(std::ignore = (Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, TestModule::D12Ptr>(in)),
+ Slicer::UnknownType);
+}