diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-08-30 13:19:23 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-08-30 13:26:50 +0100 |
commit | 4e9fcf61c3251129f7d36d00a2de88af6cedb465 (patch) | |
tree | e79de827bd34ac0c2951418044720bd3522cebe7 | |
parent | Fix scope of test suite (diff) | |
download | slicer-1.10.4.tar.bz2 slicer-1.10.4.tar.xz slicer-1.10.4.zip |
Support model parts that are abstract classes with functionsslicer-1.10.4
-rw-r--r-- | Jamroot.jam | 1 | ||||
-rw-r--r-- | slicer/json/serializer.cpp | 1 | ||||
-rw-r--r-- | slicer/slicer/common.ice | 4 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 7 | ||||
-rw-r--r-- | slicer/slicer/slicer.cpp | 7 | ||||
-rw-r--r-- | slicer/test/Jamfile.jam | 1 | ||||
-rw-r--r-- | slicer/test/functions.ice | 19 | ||||
-rw-r--r-- | slicer/test/functionsImpl.cpp | 6 | ||||
-rw-r--r-- | slicer/test/functionsImpl.h | 13 | ||||
-rw-r--r-- | slicer/test/serializers.cpp | 54 | ||||
-rw-r--r-- | slicer/tool/parser.cpp | 7 |
11 files changed, 118 insertions, 2 deletions
diff --git a/Jamroot.jam b/Jamroot.jam index b350916..b878832 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -38,6 +38,7 @@ project <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/classtype.h <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/collections.h <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/enums.h + <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/functions.h <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/inheritance.h <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/interfaces.h <toolset>tidy:<exclude>test/bin/tidy/debug/checker-none/cxxstd-17-iso/json.h diff --git a/slicer/json/serializer.cpp b/slicer/json/serializer.cpp index b94ae2e..0fa736c 100644 --- a/slicer/json/serializer.cpp +++ b/slicer/json/serializer.cpp @@ -181,7 +181,6 @@ namespace Slicer { for (const auto & element : o) { auto emp = modelPart->GetChild(element.first); if (emp) { - emp->Create(); std::visit(DocumentTreeIterate(emp), element.second); emp->Complete(); } diff --git a/slicer/slicer/common.ice b/slicer/slicer/common.ice index 9198aaa..60a4f92 100644 --- a/slicer/slicer/common.ice +++ b/slicer/slicer/common.ice @@ -42,6 +42,10 @@ module Slicer { exception InvalidStreamOperation extends SerializerError { string method; }; + ["cpp:ice_print"] + exception AbstractClassException extends DeserializerError { + string type; + }; }; #endif diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index b821d06..7efc02d 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -544,7 +544,12 @@ namespace Slicer { ModelPartForClass<T>::Create() { BOOST_ASSERT(this->Model); - *this->Model = std::make_shared<T>(); + if constexpr (std::is_abstract_v<T>) { + throw AbstractClassException(ModelPartForComplexBase::demangle(typeid(T).name())); + } + else { + *this->Model = std::make_shared<T>(); + } } template<typename T> diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp index af55977..f6d6fa6 100644 --- a/slicer/slicer/slicer.cpp +++ b/slicer/slicer/slicer.cpp @@ -104,4 +104,11 @@ namespace Slicer { { InvalidStreamOperationMsg::write(s, method); } + + AdHocFormatter(AbstractClassExceptionMsg, "%? is an abstract class"); + void + AbstractClassException::ice_print(std::ostream & s) const + { + AbstractClassExceptionMsg::write(s, type); + } } diff --git a/slicer/test/Jamfile.jam b/slicer/test/Jamfile.jam index d0eecdb..6801a77 100644 --- a/slicer/test/Jamfile.jam +++ b/slicer/test/Jamfile.jam @@ -20,6 +20,7 @@ lib icetypes : lib types : [ glob *.ice ] conversions.cpp + functionsImpl.cpp : <toolset>gcc:<dependency>../tool//slicer/<toolset>gcc <toolset>clang:<dependency>../tool//slicer/<toolset>clang diff --git a/slicer/test/functions.ice b/slicer/test/functions.ice new file mode 100644 index 0000000..baedc6d --- /dev/null +++ b/slicer/test/functions.ice @@ -0,0 +1,19 @@ +#ifndef SLICER_TEST_FUNCTIONS +#define SLICER_TEST_FUNCTIONS + +["slicer:include:functionsImpl.h"] +module Functions { + local class Funcs { + void func(); + }; + ["slicer:implementation:Functions.FuncsSubImpl"] + local class FuncsSub extends Funcs { + string testVal; + }; + local struct SFuncs { + Funcs obj; + }; +}; + +#endif + diff --git a/slicer/test/functionsImpl.cpp b/slicer/test/functionsImpl.cpp new file mode 100644 index 0000000..f57211d --- /dev/null +++ b/slicer/test/functionsImpl.cpp @@ -0,0 +1,6 @@ +#include "functionsImpl.h" + +void +Functions::FuncsSubImpl::func() +{ +} diff --git a/slicer/test/functionsImpl.h b/slicer/test/functionsImpl.h new file mode 100644 index 0000000..e46f28e --- /dev/null +++ b/slicer/test/functionsImpl.h @@ -0,0 +1,13 @@ +#ifndef SLICER_TEST_FUNCITONSIMPL_H +#define SLICER_TEST_FUNCITONSIMPL_H + +#include <functions.h> + +namespace Functions { + class FuncsSubImpl : public FuncsSub { + public: + void func() override; + }; +} + +#endif diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index d63651d..6b4393b 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -8,6 +8,7 @@ #include <definedDirs.h> #include <fstream> #include <functional> +#include <functionsImpl.h> #include <json.h> #include <json/serializer.h> #include <libxml2/libxml/parser.h> @@ -660,6 +661,59 @@ BOOST_AUTO_TEST_CASE(conversion) BOOST_REQUIRE_EQUAL("2016-06-30 12:34:56", std::get<json::String>(std::get<json::Object>(v)["conv"])); } +BOOST_AUTO_TEST_CASE(DeserializeJsonAbstractEmpty) +{ + auto in = json::parseValue(R"J({ "obj": null })J"); + auto obj = Slicer::DeserializeAny<Slicer::JsonValueDeserializer, Functions::SFuncs>(in); + BOOST_REQUIRE(!obj.obj); +} + +BOOST_AUTO_TEST_CASE(DeserializeJsonAbstractDefault) +{ + auto in = json::parseValue(R"J({ "obj": {} })J"); + BOOST_CHECK_THROW((Slicer::DeserializeAny<Slicer::JsonValueDeserializer, Functions::SFuncs>(in)), + Slicer::AbstractClassException); +} + +BOOST_AUTO_TEST_CASE(DeserializeJsonAbstractImpl) +{ + auto in = json::parseValue(R"J({ "obj": {"slicer-typeid": "::Functions::FuncsSub", "testVal": "value"} })J"); + auto obj = Slicer::DeserializeAny<Slicer::JsonValueDeserializer, Functions::SFuncs>(in); + BOOST_REQUIRE(obj.obj); + auto impl = std::dynamic_pointer_cast<Functions::FuncsSub>(obj.obj); + BOOST_REQUIRE(impl); + BOOST_CHECK_EQUAL("value", impl->testVal); +} + +BOOST_AUTO_TEST_CASE(DeserializeXmlAbstractEmpty) +{ + std::stringstream in("<SFuncs/>"); + auto obj = Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, Functions::SFuncs>(in); + BOOST_REQUIRE(!obj.obj); +} + +BOOST_AUTO_TEST_CASE(DeserializeXmlAbstractDefault) +{ + std::stringstream in("<SFuncs><obj/></SFuncs>"); + BOOST_CHECK_THROW((Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, Functions::SFuncs>(in)), + Slicer::AbstractClassException); +} + +BOOST_AUTO_TEST_CASE(DeserializeXmlAbstractImpl) +{ + std::stringstream in(R"X( + <SFuncs> + <obj slicer-typeid="::Functions::FuncsSub"> + <testVal>value</testVal> + </obj> + </SFuncs>)X"); + auto obj = Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, Functions::SFuncs>(in); + BOOST_REQUIRE(obj.obj); + auto impl = std::dynamic_pointer_cast<Functions::FuncsSub>(obj.obj); + BOOST_REQUIRE(impl); + BOOST_CHECK_EQUAL("value", impl->testVal); +} + BOOST_AUTO_TEST_CASE(customerModelPartCounters) { BOOST_REQUIRE_EQUAL(21, TestModule::completions); diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp index 33f003b..5a1d626 100644 --- a/slicer/tool/parser.cpp +++ b/slicer/tool/parser.cpp @@ -309,6 +309,13 @@ namespace Slicer { copyMetadata(c->getMetaData()); fprintbf(cpp, ";\n\n"); + if (auto implementation = metaDataValue("slicer:implementation:", c->getMetaData())) { + fprintbf(cpp, "\ttemplate<> void ModelPartForClass<%s>::Create() {\n", c->scoped()); + fprintf(cpp, "\t\tBOOST_ASSERT(this->Model);\n"); + fprintbf(cpp, "\t\t*this->Model = std::make_shared<%s>();\n}\n\n", + boost::algorithm::replace_all_copy(*implementation, ".", "::")); + } + if (auto cmp = metaDataValue("slicer:custommodelpart:", c->getMetaData())) { fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", Slice::typeToString(decl), getBasicModelPart(decl), c->scoped(), boost::algorithm::replace_all_copy(*cmp, ".", "::")); |