diff options
-rw-r--r-- | slicer/slicer/modelParts.h | 6 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.h | 3 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 39 | ||||
-rw-r--r-- | slicer/test/conversions.cpp | 8 | ||||
-rw-r--r-- | slicer/test/included/Jamfile.jam | 7 | ||||
-rw-r--r-- | slicer/test/preprocessor.cpp | 4 | ||||
-rw-r--r-- | slicer/test/serializers.cpp | 6 | ||||
-rw-r--r-- | slicer/test/types.ice | 3 | ||||
-rw-r--r-- | slicer/tool/parser.cpp | 26 |
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)); |