summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2020-11-15 12:36:14 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2020-11-17 13:30:10 +0000
commit3242dc49ef311d7240d932cde93a5f1e32df82fd (patch)
tree2f35def608a64a41b0be3f60baa08ab2faf6105d
parentFix generated hook member expr (diff)
downloadslicer-3242dc49ef311d7240d932cde93a5f1e32df82fd.tar.bz2
slicer-3242dc49ef311d7240d932cde93a5f1e32df82fd.tar.xz
slicer-3242dc49ef311d7240d932cde93a5f1e32df82fd.zip
Fix cross library MP creation
-rw-r--r--slicer/slicer/modelParts.h6
-rw-r--r--slicer/slicer/modelPartsTypes.h3
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h39
-rw-r--r--slicer/test/conversions.cpp8
-rw-r--r--slicer/test/included/Jamfile.jam7
-rw-r--r--slicer/test/preprocessor.cpp4
-rw-r--r--slicer/test/serializers.cpp6
-rw-r--r--slicer/test/types.ice3
-rw-r--r--slicer/tool/parser.cpp26
9 files changed, 81 insertions, 21 deletions
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h
index 97b1623..b0de888 100644
--- a/slicer/slicer/modelParts.h
+++ b/slicer/slicer/modelParts.h
@@ -122,6 +122,9 @@ namespace Slicer {
const std::string * nameStr;
};
+ template<typename T> struct DLL_PUBLIC Default {
+ };
+
class DLL_PUBLIC ModelPart : public std::enable_shared_from_this<ModelPart> {
public:
ModelPart() = default;
@@ -133,8 +136,9 @@ namespace Slicer {
ModelPart & operator=(const ModelPart &) = delete;
ModelPart & operator=(ModelPart &&) = delete;
- template<typename T> static ModelPartPtr CreateFor();
+ template<typename MP> static ModelPartPtr Make(typename MP::element_type * t);
template<typename T> static ModelPartPtr CreateFor(T & t);
+ template<typename T> static ModelPartPtr CreateFor(Default<T> &&);
template<typename T> static ModelPartForRootPtr CreateRootFor(T & t);
virtual void OnEachChild(const ChildHandler &) = 0;
diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h
index 28054a8..de0bc29 100644
--- a/slicer/slicer/modelPartsTypes.h
+++ b/slicer/slicer/modelPartsTypes.h
@@ -114,7 +114,8 @@ namespace Slicer {
public ModelPartForOptionalBase,
protected ModelPartModel<Ice::optional<typename T::element_type>> {
public:
- explicit ModelPartForOptional(Ice::optional<typename T::element_type> * h);
+ using element_type = Ice::optional<typename T::element_type>;
+ explicit ModelPartForOptional(element_type * h);
void Create() override;
bool GetValue(ValueTarget && s) override;
ModelPartType GetType() const override;
diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h
index a008e02..be23e1f 100644
--- a/slicer/slicer/modelPartsTypes.impl.h
+++ b/slicer/slicer/modelPartsTypes.impl.h
@@ -12,13 +12,27 @@
#include <c++11Helpers.h>
#define CUSTOMMODELPARTFOR(Type, BaseModelPart, ModelPartType) \
- template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor<Type>() \
+ template<> DLL_PUBLIC ModelPartPtr ModelPart::Make<ModelPartType>(typename ModelPartType::element_type * t) \
{ \
- return std::make_shared<ModelPartType>(nullptr); \
+ return std::make_shared<ModelPartType>(t); \
+ } \
+ template<> \
+ DLL_PUBLIC ModelPartPtr ModelPart::Make<ModelPartForOptional<ModelPartType>>( \
+ Ice::optional<typename ModelPartType::element_type> * t) \
+ { \
+ return std::make_shared<ModelPartForOptional<ModelPartType>>(t); \
+ } \
+ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Default<Type> &&) \
+ { \
+ return Make<ModelPartType>(nullptr); \
+ } \
+ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Default<Ice::optional<Type>> &&) \
+ { \
+ return Make<ModelPartForOptional<ModelPartType>>(nullptr); \
} \
template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Type & s) \
{ \
- return std::make_shared<ModelPartType>(&s); \
+ return Make<ModelPartType>(&s); \
} \
template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(const Type & s) \
{ \
@@ -26,7 +40,7 @@
} \
template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Ice::optional<Type> & s) \
{ \
- return std::make_shared<ModelPartForOptional<ModelPartType>>(&s); \
+ return Make<ModelPartForOptional<ModelPartType>>(&s); \
} \
template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(const Ice::optional<Type> & s) \
{ \
@@ -375,12 +389,15 @@ namespace Slicer {
ModelPartPtr
Get(T * t) const override
{
- return std::make_shared<MP>(
- t ? const_cast<typename std::remove_const<MT>::type *>(&(t->*member)) : nullptr);
+ if (t) {
+ return Make<MP>(&(t->*member));
+ }
+ return Make<MP>(nullptr);
}
private:
- const MT T::*member;
+ using MemPtr = MT T::*;
+ const MemPtr member;
const MetaDataImpl<N> hookMetadata;
};
@@ -432,7 +449,7 @@ namespace Slicer {
ModelPartPtr
ModelPartForClass<T>::CreateModelPart(void * p)
{
- return std::make_shared<ModelPartForClass<T>>(static_cast<element_type *>(p));
+ return ::Slicer::ModelPart::CreateFor(*static_cast<element_type *>(p));
}
template<typename T>
@@ -591,7 +608,7 @@ namespace Slicer {
ModelPartPtr
ModelPartForSequence<T>::GetContainedModelPart()
{
- return ModelPart::CreateFor<typename T::value_type>();
+ return ModelPart::CreateFor(Default<typename T::value_type> {});
}
// ModelPartForDictionaryElementInserter
@@ -615,7 +632,7 @@ namespace Slicer {
{
BOOST_ASSERT(this->Model);
for (auto & pair : *this->Model) {
- ch(pairName, std::make_shared<ModelPartForStruct<typename T::value_type>>(&pair), NULL);
+ ch(pairName, std::make_shared<ModelPartForStruct<typename T::value_type>>(&pair), nullptr);
}
}
@@ -657,7 +674,7 @@ namespace Slicer {
ModelPartPtr
ModelPartForStream<T>::GetContainedModelPart()
{
- return ModelPart::CreateFor<T>();
+ return ModelPart::CreateFor(Default<T> {});
}
template<typename T>
diff --git a/slicer/test/conversions.cpp b/slicer/test/conversions.cpp
index 8b0f0ab..502975e 100644
--- a/slicer/test/conversions.cpp
+++ b/slicer/test/conversions.cpp
@@ -155,3 +155,11 @@ namespace TestModule {
completions += 1;
}
}
+namespace Slicer {
+ template<>
+ DLL_PUBLIC ModelPartPtr
+ ModelPart::Make<TestModule::MonthValidator>(::Ice::Short * m)
+ {
+ return std::make_shared<TestModule::MonthValidator>(m);
+ }
+}
diff --git a/slicer/test/included/Jamfile.jam b/slicer/test/included/Jamfile.jam
index 081810a..9871aeb 100644
--- a/slicer/test/included/Jamfile.jam
+++ b/slicer/test/included/Jamfile.jam
@@ -5,6 +5,13 @@ lib included :
:
<library>../..//Ice
<toolset>tidy:<checker>none
+ <toolset>gcc:<dependency>../../tool//slicer/<toolset>gcc
+ <toolset>clang:<dependency>../../tool//slicer/<toolset>clang
+ <toolset>tidy:<dependency>../../tool//slicer/<toolset>gcc
+ <slicer>yes
+ <toolset>gcc:<slicerbin>../../tool//slicer/<toolset>gcc
+ <toolset>clang:<slicerbin>../../tool//slicer/<toolset>clang
+ <toolset>tidy:<slicerbin>../../tool//slicer/<toolset>gcc
: :
<library>../..//Ice
<include>.
diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp
index 21ed5f1..72afa63 100644
--- a/slicer/test/preprocessor.cpp
+++ b/slicer/test/preprocessor.cpp
@@ -12,7 +12,7 @@
using ComponentsCount = std::map<std::string, unsigned int>;
ComponentsCount COMPONENTS_IN_TEST_ICE = {{"classtype.ice", 2}, {"classes.ice", 3}, {"collections.ice", 5},
{"enums.ice", 2}, {"inheritance.ice", 12}, {"interfaces.ice", 0}, {"json.ice", 2}, {"locals.ice", 7},
- {"optionals.ice", 2}, {"structs.ice", 5}, {"types.ice", 3}, {"xml.ice", 5}};
+ {"optionals.ice", 2}, {"structs.ice", 5}, {"types.ice", 4}, {"xml.ice", 5}};
unsigned int
total()
@@ -21,7 +21,7 @@ total()
COMPONENTS_IN_TEST_ICE.begin(), COMPONENTS_IN_TEST_ICE.end(), 0U, [](auto & t, auto && c) {
return t += c.second;
});
- BOOST_CHECK_EQUAL(48, t);
+ BOOST_CHECK_EQUAL(49, t);
return t;
}
diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp
index 26e4ad8..a22fd39 100644
--- a/slicer/test/serializers.cpp
+++ b/slicer/test/serializers.cpp
@@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(DeserializeXmlIncorrectSeqElementName)
BOOST_AUTO_TEST_CASE(customerModelPartCounters)
{
- BOOST_REQUIRE_EQUAL(21, TestModule::completions);
+ BOOST_REQUIRE_EQUAL(35, TestModule::completions);
}
BOOST_AUTO_TEST_CASE(enum_lookups)
@@ -738,6 +738,6 @@ BOOST_AUTO_TEST_CASE(enum_lookups)
BOOST_AUTO_TEST_CASE(sequence_element_in_same_slice_link_bug)
{
// Link error when sequence element type defined in same slice.
- // Slicer::ModelPartForSequence<TestModule::Classes> mpClasses(nullptr);
- // Slicer::ModelPartForSequence<TestModule::Dates> mpDates(nullptr);
+ BOOST_CHECK(Slicer::ModelPart::Make<Slicer::ModelPartForSequence<TestModule::Classes>>(nullptr));
+ BOOST_CHECK(Slicer::ModelPart::Make<Slicer::ModelPartForSequence<TestModule::Dates>>(nullptr));
}
diff --git a/slicer/test/types.ice b/slicer/test/types.ice
index ac050b4..ac3a706 100644
--- a/slicer/test/types.ice
+++ b/slicer/test/types.ice
@@ -19,6 +19,9 @@ module TestModule {
int someFunction();
DontCountMe otherFileReference();
};
+ class CrossLibrary {
+ DontCountMe otherFileReference;
+ };
};
module TestModule2 {
diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp
index 595cff4..797944d 100644
--- a/slicer/tool/parser.cpp
+++ b/slicer/tool/parser.cpp
@@ -190,6 +190,14 @@ namespace Slicer {
// Failed to convert
fprintbf(cpp, "\tconversion_fail(\"%s\");\n", Slice::typeToString(type));
fprintbf(cpp, "}\n\n");
+
+ fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<");
+ createModelPartForConverted(type, c->scoped(), dm);
+ fprintbf(cpp, ">(typename ");
+ createModelPartForConverted(type, c->scoped(), dm);
+ fprintbf(cpp, "::element_type * t) { return std::make_shared<");
+ createModelPartForConverted(type, c->scoped(), dm);
+ fprintbf(cpp, ">(t); } \n");
}
}
@@ -288,6 +296,9 @@ namespace Slicer {
if (definedTypes.count(type->typeId())) {
return;
}
+ if (Slice::ClassDeclPtr::dynamicCast(type)) {
+ fprintbf(cpp, "extern template class ModelPartForComplex< %s >;\n", type->typeId());
+ }
fprintbf(cpp, "extern template class %s< %s >;\n", getBasicModelPart(type),
Slice::ClassDeclPtr::dynamicCast(type) ? type->typeId() : Slice::typeToString(type));
}
@@ -349,6 +360,9 @@ namespace Slicer {
if (auto cmp = md.value("slicer:custommodelpart:")) {
fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", Slice::typeToString(decl),
getBasicModelPart(decl), c->scoped(), CppName {*cmp});
+ fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<%s<%s> >(%s * t)",
+ getBasicModelPart(decl), c->scoped(), Slice::typeToString(decl));
+ fprintbf(cpp, "{ return std::make_shared<%s>(t); } \n", CppName {*cmp});
}
else {
fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, ModelPartForClass<%s>, ModelPartForClass<%s>);\n\n",
@@ -529,10 +543,13 @@ namespace Slicer {
auto lname = std::string {name};
boost::algorithm::to_lower(lname);
fprintbf(cpp, "\tconst std::string hstr_C%d_%d { \"%s\" };\n", components, element, name);
- fprintbf(cpp, "\tconstexpr C%d::Hook< const %s, ", components, Slice::typeToString(t));
+ fprintbf(cpp, "\tconstexpr C%d::Hook< %s, ", components, Slice::typeToString(t));
createNewModelPartPtrFor(t);
- fprintbf(cpp, ", 0 > hook%d_%s {&%s::value_type::%s, \"%s\", \"%s\", &hstr_C%d_%s};\n", components, element,
- d->scoped(), element, name, lname, components, element);
+ fprintbf(cpp,
+ ", 0 > hook%d_%s {const_cast<%s (%s::value_type::*)>(&%s::value_type::%s), \"%s\", \"%s\", "
+ "&hstr_C%d_%s};\n",
+ components, element, Slice::typeToString(t), d->scoped(), d->scoped(), element, name, lname,
+ components, element);
};
addHook(md.value("slicer:key:").value_or("key"), "first", d->keyType());
addHook(md.value("slicer:value:").value_or("value"), "second", d->valueType());
@@ -662,6 +679,9 @@ namespace Slicer {
if (auto cmp = metadata.value("slicer:custommodelpart:")) {
fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", type, getBasicModelPart(stype), type,
CppName {*cmp});
+ fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<%s>(%s * t)", getBasicModelPart(stype),
+ type);
+ fprintbf(cpp, "{ return std::make_shared<%s>(t); } \n", CppName {*cmp});
}
else {
fprintbf(cpp, "MODELPARTFOR(%s, %s);\n\n", type, getBasicModelPart(stype));