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-4e9fcf61c3251129f7d36d00a2de88af6cedb465.tar.bz2 slicer-4e9fcf61c3251129f7d36d00a2de88af6cedb465.tar.xz slicer-4e9fcf61c3251129f7d36d00a2de88af6cedb465.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, ".", "::"));  | 
