diff options
author | Bernard Normier <bernard@zeroc.com> | 2016-06-16 10:33:55 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2016-06-16 10:33:55 -0400 |
commit | 30fb2e0a6149d6607cc1e89e7d8013c273bd29fd (patch) | |
tree | 3799f140e7095dd1a8164a2d130ecda574d3aba6 /cpp/src | |
parent | Update cpp/test/IceGrid/admin/run.py print statement (diff) | |
download | ice-30fb2e0a6149d6607cc1e89e7d8013c273bd29fd.tar.bz2 ice-30fb2e0a6149d6607cc1e89e7d8013c273bd29fd.tar.xz ice-30fb2e0a6149d6607cc1e89e7d8013c273bd29fd.zip |
C++11 AMI custom mapping support
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/Proxy.cpp | 8 | ||||
-rw-r--r-- | cpp/src/IceUtil/OutputUtil.cpp | 10 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 101 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.h | 10 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 7 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.h | 2 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 541 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.h | 2 |
8 files changed, 373 insertions, 308 deletions
diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index fbf096dfd89..e2cc8a9b6e3 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -74,7 +74,7 @@ Ice::ObjectPrx::__ice_isA(const shared_ptr<IceInternal::OutgoingAsyncT<bool>>& o const string& typeId, const Context& ctx) { - __checkAsyncTwowayOnly("__ice_isA"); + __checkAsyncTwowayOnly(ice_isA_name); outAsync->invoke(ice_isA_name, OperationMode::Nonmutating, DefaultFormat, ctx, [&](Ice::OutputStream* os) { @@ -92,14 +92,14 @@ Ice::ObjectPrx::__ice_ping(const shared_ptr<IceInternal::OutgoingAsyncT<void>>& void Ice::ObjectPrx::__ice_ids(const shared_ptr<IceInternal::OutgoingAsyncT<vector<string>>>& outAsync, const Context& ctx) { - __checkAsyncTwowayOnly("__ice_ids"); + __checkAsyncTwowayOnly(ice_ids_name); outAsync->invoke(ice_ids_name, OperationMode::Nonmutating, DefaultFormat, ctx, nullptr, nullptr); } void Ice::ObjectPrx::__ice_id(const shared_ptr<IceInternal::OutgoingAsyncT<string>>& outAsync, const Context& ctx) { - __checkAsyncTwowayOnly("__ice_id"); + __checkAsyncTwowayOnly(ice_id_name); outAsync->invoke(ice_id_name, OperationMode::Nonmutating, DefaultFormat, ctx, nullptr, nullptr); } @@ -669,7 +669,7 @@ IceProxy::Ice::Object::__newInstance() const ConnectionPtr IceProxy::Ice::Object::ice_getConnection() { - InvocationObserver observer(this, "ice_getConnection", ::Ice::noExplicitContext); + InvocationObserver observer(this, ice_getConnection_name, ::Ice::noExplicitContext); int cnt = 0; while(true) { diff --git a/cpp/src/IceUtil/OutputUtil.cpp b/cpp/src/IceUtil/OutputUtil.cpp index 755e80d2c4b..3e21011e511 100644 --- a/cpp/src/IceUtil/OutputUtil.cpp +++ b/cpp/src/IceUtil/OutputUtil.cpp @@ -23,6 +23,8 @@ StartBlock sb; EndBlock eb; StartPar spar; EndPar epar; +StartAbrk sabrk; +EndAbrk eabrk; Separator sp; EndElement ee; StartEscapes startEscapes; @@ -302,17 +304,17 @@ IceUtilInternal::Output::eb() } void -IceUtilInternal::Output::spar() +IceUtilInternal::Output::spar(char c) { - _out << '('; + _out << c; _par = 0; } void -IceUtilInternal::Output::epar() +IceUtilInternal::Output::epar(char c) { _par = -1; - _out << ')'; + _out << c; } Output& diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp index dc0b9cdd4a5..d1688074dcb 100644 --- a/cpp/src/Slice/CPlusPlusUtil.cpp +++ b/cpp/src/Slice/CPlusPlusUtil.cpp @@ -141,7 +141,6 @@ dictionaryTypeToString(const DictionaryPtr& dict, const StringList& metaData, in } } - void writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData, int typeCtx, bool cpp11, bool endArg) @@ -198,8 +197,13 @@ writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const st } void -writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData) +writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData, + const string& obj = "") { + string objPrefix = obj.empty() ? obj : obj + "."; + string paramName = objPrefix + fixedName; + string escapedParamName = objPrefix + "___" + fixedName; + SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { @@ -220,14 +224,14 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << " = ___" << fixedName << "->second;"; - out << eb; + out << nl << paramName << " = " << escapedParamName << "->second;"; + out << eb; } else { - out << nl << fixedName << " = ___" << fixedName << ".second;"; + out << nl << paramName << " = " << escapedParamName << ".second;"; } } else if(!builtin || @@ -237,32 +241,30 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << ".__setIsSet();"; - out << nl << "if(!___" << fixedName << "->empty())"; + out << nl << paramName << ".__setIsSet();"; + out << nl << "if(!" << escapedParamName << "->empty())"; out << sb; - out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];"; - out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___" - << fixedName << "->size();"; + out << nl << paramName << "->first" << " = &(*" << escapedParamName << ")[0];"; + out << nl << paramName << "->second" << " = " << paramName << "->first + " << escapedParamName << "->size();"; out << eb; out << nl << "else"; out << sb; - out << nl << fixedName << "->first" << " = " << fixedName << "->second" << " = 0;"; + out << nl << paramName << "->first" << " = " << paramName << "->second" << " = 0;"; out << eb; out << eb; } else { - out << nl << "if(!___" << fixedName << ".empty())"; + out << nl << "if(!" << escapedParamName << ".empty())"; out << sb; - out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; - out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" - << fixedName << ".size();"; + out << nl << paramName << ".first" << " = &" << escapedParamName << "[0];"; + out << nl << paramName << ".second" << " = " << paramName << ".first + " << escapedParamName << ".size();"; out << eb; out << nl << "else"; out << sb; - out << nl << fixedName << ".first" << " = " << fixedName << ".second" << " = 0;"; + out << nl << paramName << ".first" << " = " << paramName << ".second" << " = 0;"; out << eb; } } @@ -271,17 +273,17 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << ".__setIsSet();"; - out << nl << fixedName << "->first = (*___" << fixedName << ").begin();"; - out << nl << fixedName << "->second = (*___" << fixedName << ").end();"; + out << nl << paramName << ".__setIsSet();"; + out << nl << paramName << "->first = (*" << escapedParamName << ").begin();"; + out << nl << paramName << "->second = (*" << escapedParamName << ").end();"; out << eb; } else { - out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; - out << nl << fixedName << ".second = ___" << fixedName << ".end();"; + out << nl << paramName << ".first = " << escapedParamName << ".begin();"; + out << nl << paramName << ".second = " << escapedParamName << ".end();"; } } } @@ -289,9 +291,10 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& void writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const OperationPtr& op, bool marshal, - bool prepend, int typeCtx) + bool prepend, int typeCtx, const string& retP = "", const string& obj = "") { string prefix = prepend ? paramPrefix : ""; + string returnValueS = retP.empty() ? string("__ret") : retP; // // Marshal non optional parameters. @@ -306,14 +309,15 @@ writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const Oper else { writeMarshalUnmarshalCode(out, (*p)->type(), false, 0, fixKwd(prefix + (*p)->name()), marshal, (*p)->getMetaData(), - typeCtx); + typeCtx, "", true, obj); } } if(op && op->returnType()) { if(!op->returnIsOptional()) { - writeMarshalUnmarshalCode(out, op->returnType(), false, 0, "__ret", marshal, op->getMetaData(), typeCtx); + writeMarshalUnmarshalCode(out, op->returnType(), false, 0, returnValueS, marshal, op->getMetaData(), typeCtx, + "", true, obj); } } @@ -338,17 +342,17 @@ writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const Oper { if(checkReturnType && op->returnTag() < (*p)->tag()) { - writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), "__ret", marshal, - op->getMetaData(), typeCtx); + writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), returnValueS, marshal, + op->getMetaData(), typeCtx, "", true, obj); checkReturnType = false; } writeMarshalUnmarshalCode(out, (*p)->type(), true, (*p)->tag(), fixKwd(prefix + (*p)->name()), marshal, - (*p)->getMetaData(), typeCtx); + (*p)->getMetaData(), typeCtx, "", true, obj); } if(checkReturnType) { - writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), "__ret", marshal, op->getMetaData(), - typeCtx); + writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), returnValueS, marshal, op->getMetaData(), + typeCtx, "", true, obj); } } @@ -1102,8 +1106,11 @@ Slice::fixKwd(const string& name) void Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, bool optional, int tag, const string& param, - bool marshal, const StringList& metaData, int typeCtx, const string& str, bool pointer) + bool marshal, const StringList& metaData, int typeCtx, const string& str, bool pointer, + const string& obj) { + string objPrefix = obj.empty() ? obj : obj + "."; + ostringstream os; if(str.empty()) { @@ -1150,24 +1157,24 @@ Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, bool optional BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); if(builtin && builtin->kind() == Builtin::KindByte) { - out << nl << func << param << ");"; + out << nl << func << objPrefix << param << ");"; return; } - out << nl << func << "___" << param << ");"; - writeParamEndCode(out, seq, optional, param, metaData); + out << nl << func << objPrefix << "___" << param << ");"; + writeParamEndCode(out, seq, optional, param, metaData, obj); return; } else if(seqType.find("%range") == 0) { - out << nl << func << "___" << param << ");"; - writeParamEndCode(out, seq, optional, param, metaData); + out << nl << func << objPrefix << "___" << param << ");"; + writeParamEndCode(out, seq, optional, param, metaData, obj); return; } } } - out << nl << func << param << ");"; + out << nl << func << objPrefix << param << ");"; } void @@ -1177,25 +1184,31 @@ Slice::writeMarshalCode(Output& out, const ParamDeclList& params, const Operatio } void -Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx) +Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, + const string& retP, const string& obj) { - writeMarshalUnmarshalParams(out, params, op, false, prepend, typeCtx); + writeMarshalUnmarshalParams(out, params, op, false, prepend, typeCtx, retP, obj); } void -Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, bool cpp11) +Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, + bool cpp11) { string prefix = prepend ? paramPrefix : ""; + string returnValueS = "__ret"; + for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { writeParamAllocateCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData(), typeCtx, cpp11, getEndArg((*p)->type(),(*p)->getMetaData(), (*p)->name()) != (*p)->name()); } + if(op && op->returnType()) { - writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData(), typeCtx, cpp11, - getEndArg(op->returnType(), op->getMetaData(), "__ret") != "__ret"); + writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), returnValueS, op->getMetaData(), typeCtx, cpp11, + getEndArg(op->returnType(), op->getMetaData(), returnValueS) != returnValueS); } + } string diff --git a/cpp/src/Slice/CPlusPlusUtil.h b/cpp/src/Slice/CPlusPlusUtil.h index f5f94acd365..b60d6036c2f 100644 --- a/cpp/src/Slice/CPlusPlusUtil.h +++ b/cpp/src/Slice/CPlusPlusUtil.h @@ -48,12 +48,14 @@ std::string opFormatTypeToString(const OperationPtr&); std::string fixKwd(const std::string&); void writeMarshalUnmarshalCode(::IceUtilInternal::Output&, const TypePtr&, bool, int, const std::string&, - bool, const StringList& = StringList(), int = 0, const std::string& = "", - bool = true); + bool, const StringList& = StringList(), int = 0, const std::string& = "", + bool = true, const std::string& = ""); void writeMarshalCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool, int = 0); -void writeUnmarshalCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool, int = 0); -void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool, int = 0, bool = false); +void writeUnmarshalCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool, int = 0, + const std::string& = "", const std::string& = ""); +void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool, int = 0, + bool = false); std::string getEndArg(const TypePtr&, const StringList&, const std::string&); void writeEndCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool = false); diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 4fedc671cfa..502d20677be 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -4108,13 +4108,8 @@ Slice::Exception::Exception(const ContainerPtr& container, const string& name, c DataMemberPtr Slice::Struct::createDataMember(const string& name, const TypePtr& type, bool optional, int tag, const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue, - const string& defaultLiteral, bool checkName) + const string& defaultLiteral) { - if(checkName) - { - checkIdentifier(name); - } - ContainedList matches = _unit->findContents(thisScope() + name); if(!matches.empty()) { diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h index def1bd40abe..ece0c696e02 100644 --- a/cpp/src/Slice/Parser.h +++ b/cpp/src/Slice/Parser.h @@ -750,7 +750,7 @@ class Struct : public virtual Container, public virtual Constructed public: DataMemberPtr createDataMember(const std::string&, const TypePtr&, bool, int, const SyntaxTreeBasePtr&, - const std::string&, const std::string&, bool = true); + const std::string&, const std::string&); DataMemberList dataMembers() const; DataMemberList classDataMembers() const; virtual ContainedType containedType() const; diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 2ca81cf9e91..c7eef696620 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -464,6 +464,18 @@ resultStructName(const string& name, const string& scope = "") return stName; } +string +condMove(bool moveIt, const string& str) +{ + return moveIt ? string("::std::move(") + str + ")" : str; +} + +string +condString(bool ok, const string& str) +{ + return ok ? str : ""; +} + } Slice::Gen::Gen(const string& base, const string& headerExtension, const string& sourceExtension, @@ -5598,8 +5610,8 @@ Slice::Gen::Cpp11DeclVisitor::visitOperation(const OperationPtr& p) } } -Slice::Gen::Cpp11TypesVisitor::Cpp11TypesVisitor(Output& h, Output& c, const string& dllExport, int useWstring) : - H(h), C(c), _dllExport(dllExport), _doneStaticSymbol(false), _useWstring(useWstring) +Slice::Gen::Cpp11TypesVisitor::Cpp11TypesVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _doneStaticSymbol(false), _useWstring(false) { } @@ -6186,7 +6198,7 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) TypePtr ret = p->returnType(); bool retIsOpt = p->returnIsOptional(); - string retS = returnTypeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextAMIEnd, true); + string retS = returnTypeToString(ret, retIsOpt, p->getMetaData(), _useWstring, true); ContainerPtr container = p->container(); ClassDefPtr cl = ClassDefPtr::dynamicCast(container); @@ -6194,93 +6206,81 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) vector<string> params; vector<string> paramsDecl; - vector<string> lambdaParams; - vector<string> lambdaParamsDecl; - - vector<string> futureParamsDecl; + vector<string> inParamsS; + vector<string> inParamsDecl; + vector<string> futureOutParams; vector<string> lambdaOutParams; - vector<string> lambdaOutParamsDecl; ParamDeclList paramList = p->parameters(); ParamDeclList inParams; ParamDeclList outParams; string returnValueS = "returnValue"; + bool outParamsHasOpt = false; - bool lambdaOutParamsHasOpt = false; if(ret) { - lambdaOutParams.push_back(retS); - lambdaOutParamsDecl.push_back(retS + " returnValue"); - lambdaOutParamsHasOpt |= p->returnIsOptional(); + futureOutParams.push_back(typeToString(ret, retIsOpt, p->getMetaData(), _useWstring, true)); + + lambdaOutParams.push_back( + typeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextInParam, true)); + + outParamsHasOpt |= p->returnIsOptional(); } for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { string paramName = fixKwd(paramPrefix + (*q)->name()); - StringList metaData = (*q)->getMetaData(); - string typeString; - string outputTypeString; - string typeStringEndAMI; - if((*q)->isOutParam()) - { - typeString = typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); - outputTypeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); - } - else - { - typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); - } - if(!(*q)->isOutParam()) + if((*q)->isOutParam()) { - params.push_back(typeString); - paramsDecl.push_back(typeString + ' ' + paramName); + futureOutParams.push_back(typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true)); + lambdaOutParams.push_back( + typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring | TypeContextInParam, true)); - lambdaParams.push_back(typeString); - lambdaParamsDecl.push_back(typeString + ' ' + paramName); + string outputTypeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); - futureParamsDecl.push_back(typeString + ' ' + paramName); - - inParams.push_back(*q); - } - else - { params.push_back(outputTypeString); paramsDecl.push_back(outputTypeString + ' ' + paramName); - lambdaOutParams.push_back(typeString); - lambdaOutParamsDecl.push_back(typeString + ' ' + paramName); - lambdaOutParamsHasOpt |= (*q)->optional(); - + outParamsHasOpt |= (*q)->optional(); outParams.push_back(*q); + if((*q)->name() == "returnValue") { returnValueS = "_returnValue"; } } + else + { + string typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); + + params.push_back(typeString); + paramsDecl.push_back(typeString + ' ' + paramName); + + inParamsS.push_back(typeString); + inParamsDecl.push_back(typeString + ' ' + paramName); + inParams.push_back(*q); + } } string scoped = fixKwd(cl->scope() + cl->name() + "Prx" + "::").substr(2); string futureT; - if(lambdaOutParams.empty()) + if(futureOutParams.empty()) { futureT = "void"; } - else if(lambdaOutParams.size() == 1) + else if(futureOutParams.size() == 1) { - futureT = lambdaOutParams[0]; + futureT = futureOutParams[0]; } else { - string resultScope = cl->scope() + cl->name(); - if(!cl->isInterface()) - { - resultScope += "Disp"; - } + string suffix = cl->isInterface() ? "" : "Disp"; + string resultScope = fixKwd(cl->scope() + cl->name() + suffix); futureT = resultStructName(name, resultScope); } @@ -6293,7 +6293,7 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; H << sb; H << nl; - if(lambdaOutParams.size() == 1) + if(futureOutParams.size() == 1) { if(ret) { @@ -6304,160 +6304,279 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) H << paramPrefix << (*outParams.begin())->name() << " = "; } } - else if(lambdaOutParams.size() > 1) + else if(futureOutParams.size() > 1) { H << "auto __result = "; } - if(futureT == "void") - { - H << "makePromiseOutgoing"; - } - else - { - H << "makePromiseOutgoing<" << futureT << ">"; - } + + H << "makePromiseOutgoing<" << futureT << ">"; + H << spar << "true, this" << string("&" + scoped + "__" + name); for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) { H << fixKwd(paramPrefix + (*q)->name()); } H << "__ctx" << epar << ".get();"; - if(lambdaOutParams.size() > 1) + if(futureOutParams.size() > 1) { for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) { H << nl << paramPrefix << (*q)->name() << " = "; - if(isMovable((*q)->type())) - { - H << "::std::move(__result." << fixKwd((*q)->name()) << ");"; - } - else - { - H << "__result." << fixKwd((*q)->name()) << ";"; - } + H << condMove(isMovable((*q)->type()), "__result." + fixKwd((*q)->name())) + ";"; } if(ret) { - if(isMovable(ret)) - { - H << nl << "return ::std::move(__result." << returnValueS << ");"; - } - else - { - H << nl << "return __result." << returnValueS << ";"; - } + H << nl << "return " + condMove(isMovable(ret), "__result." + returnValueS) + ";"; } } H << eb; // + // Promise based asynchronous operation + // + H << sp; + H << nl << "template<template<typename> class P = ::std::promise>"; + H << nl << deprecateSymbol << "auto " << name << "Async" << spar << inParamsDecl; + H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; + H.inc(); + H << nl << "-> decltype(::std::declval<P<" << futureT << ">>().get_future())"; + H.dec(); + H << sb; + + H << nl << "return makePromiseOutgoing<" << futureT << ", P>" << spar; + + H << "false, this" << string("&" + scoped + "__" + name); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()); + } + H << "__ctx" << epar << ";"; + H << eb; + + + // // Lambda based asynchronous operation // + bool lambdaCustomOut = (lambdaOutParams != futureOutParams); + H << sp; H << nl << "::std::function<void()>"; H << nl << name << "Async("; H.useCurrentPosAsIndent(); - if(!lambdaParamsDecl.empty()) + if(!inParamsDecl.empty()) { - for(vector<string>::const_iterator q = lambdaParamsDecl.begin(); q != lambdaParamsDecl.end(); ++q) + if(lambdaCustomOut) { - H << *q << ", "; + for(vector<string>::const_iterator q = inParamsS.begin(); q != inParamsS.end(); ++q) + { + H << *q << ", "; + } + } + else + { + for(vector<string>::const_iterator q = inParamsDecl.begin(); q != inParamsDecl.end(); ++q) + { + H << *q << ", "; + } } H << nl; } - H << "::std::function<void" << spar << lambdaOutParams << epar << "> __response,"; - H << nl << "::std::function<void(::std::exception_ptr)> __ex = nullptr,"; - H << nl << "::std::function<void(bool)> __sent = nullptr,"; - H << nl << "const ::Ice::Context& __ctx = Ice::noExplicitContext)"; + + H << "::std::function<void" << spar << lambdaOutParams << epar << ">" + + condString(!lambdaCustomOut, " __response") + ","; + H << nl << "::std::function<void(::std::exception_ptr)>" + + condString(!lambdaCustomOut, " __ex") + " = nullptr,"; + H << nl << "::std::function<void(bool)>" + + condString(!lambdaCustomOut," __sent") + " = nullptr,"; + H << nl << "const ::Ice::Context&" + + condString(!lambdaCustomOut, "__ctx") + " = Ice::noExplicitContext)" + condString(lambdaCustomOut, ";"); + H.restoreIndent(); - H << sb; - if(lambdaOutParams.size() > 1) + if(lambdaCustomOut) { - H << nl << "auto __responseCb = [__response](" << futureT << "&& result)"; - H << sb; - H << nl << "__response" << spar; - if(ret) + // + // "Custom" implementation in .cpp file + // + + C << sp; + C << nl << "::std::function<void()>"; + C << nl << scoped << name << "Async("; + C.useCurrentPosAsIndent(); + if(!inParamsDecl.empty()) { - if(isMovable(ret)) - { - H << "::std::move(result." + returnValueS + ")"; - } - else + for(vector<string>::const_iterator q = inParamsDecl.begin(); q != inParamsDecl.end(); ++q) { - H << "result." + returnValueS; + C << *q << ", "; } + C << nl; + } + C << "::std::function<void " << spar << lambdaOutParams << epar << "> __response,"; + C << nl << "::std::function<void(::std::exception_ptr)> __ex,"; + C << nl << "::std::function<void(bool)> __sent,"; + C << nl << "const ::Ice::Context& __ctx)"; + C.restoreIndent(); + C << sb; + if(p->returnsData()) + { + C << nl << "__checkAsyncTwowayOnly(" << flatName << ");"; + } + + C << nl << "::std::function<void(::Ice::InputStream*)> __read;"; + C << nl << "if(__response)"; + C << sb; + C << nl << "__read = [__response](::Ice::InputStream* __is)"; + C << sb; + C << nl << "__is->startEncapsulation();"; + writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextInParam, true); + writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextInParam); + + if(p->returnsClasses(false)) + { + C << nl << "__is->readPendingValues();"; + } + C << nl << "__is->endEncapsulation();"; + C << nl << "try" << sb; + C << nl << "__response" << spar; + if(ret) + { + C << "__ret"; } for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) { - if(isMovable((*q)->type())) + C << fixKwd(paramPrefix + (*q)->name()); + } + C << epar << ";"; + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "throw ::std::current_exception();"; + C << eb; + C << eb << ";"; + C << eb; + C << nl << "auto __outAsync = ::std::make_shared<::IceInternal::CustomLambdaOutgoing>("; + C << "shared_from_this(), __read, __ex, __sent);"; + C << sp; + + // TODO: fix duplication with "private implementation" code below + + C << nl << "__outAsync->invoke(" << flatName << ", "; + C << operationModeToString(p->sendMode(), true) << ", " << opFormatTypeToString(p) << ", __ctx, "; + C.inc(); + C << nl; + if(inParams.empty()) + { + C << "nullptr"; + } + else + { + C << "[&](::Ice::OutputStream* __os)"; + C << sb; + writeMarshalCode(C, inParams, 0, true, TypeContextInParam); + if(p->sendsClasses(false)) { - H << "::std::move(result." + fixKwd((*q)->name()) + ")"; + C << nl << "__os->writePendingValues();"; } - else + C << eb; + } + C << "," << nl; + + ExceptionList throws = p->throws(); + if(throws.empty()) + { + C << "nullptr"; + } + else + { + throws.sort(); + throws.unique(); + + // + // Arrange exceptions into most-derived to least-derived order. If we don't + // do this, a base exception handler can appear before a derived exception + // handler, causing compiler warnings and resulting in the base exception + // being marshaled instead of the derived exception. + // + throws.sort(Slice::DerivedToBaseCompare()); + + C << "[](const ::Ice::UserException& __ex)"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "__ex.ice_throw();"; + C << eb; + // + // Generate a catch block for each legal user exception. + // + for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i) { - H << "result." + fixKwd((*q)->name()); + string scoped = (*i)->scoped(); + C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)"; + C << sb; + C << nl << "throw;"; + C << eb; } + C << nl << "catch(const ::Ice::UserException&)"; + C << sb; + C << eb; + C << eb; } - H << epar << ";" << eb << ";"; - } - if(futureT == "void") - { - H << nl << "return makeLambdaOutgoing" << spar; + + C.dec(); + C << ");"; + C << nl << "return [__outAsync]() { __outAsync->cancel(); };"; + C << eb; } else { + // + // Simple implementation directly in header file + // + + H << sb; + if(futureOutParams.size() > 1) + { + H << nl << "auto __responseCb = [__response](" << futureT << "&& result)"; + H << sb; + H << nl << "__response" << spar; + + if(ret) + { + H << condMove(isMovable(ret), string("result.") + returnValueS); + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + H << condMove(isMovable((*q)->type()), "result." + fixKwd((*q)->name())); + } + H << epar << ";" << eb << ";"; + } + H << nl << "return makeLambdaOutgoing<" << futureT << ">" << spar; - } - H << (lambdaOutParams.size() > 1 ? "__responseCb" : "__response") << "__ex" << "__sent" << "this"; - H << string("&" + scoped + "__" + name); - for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) - { - H << fixKwd(paramPrefix + (*q)->name()); - } - H << "__ctx" << epar << ";"; - H << eb; - // - // Promise based asynchronous operation - // - H << sp; - H << nl << "template<template<typename> class P = ::std::promise>"; - H << nl << deprecateSymbol << "auto " << name << "Async" << spar << futureParamsDecl; - H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; - H.inc(); - H << nl << "-> decltype(::std::declval<P<" << futureT << ">>().get_future())"; - H.dec(); - H << sb; - if(futureT == "void") - { - H << nl << "return makePromiseOutgoing<P>" << spar; - } - else - { - H << nl << "return makePromiseOutgoing<" << futureT << ", P>" << spar; - } - H << "false, this" << string("&" + scoped + "__" + name); - for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) - { - H << fixKwd(paramPrefix + (*q)->name()); + H << (futureOutParams.size() > 1 ? "__responseCb" : "__response") << "__ex" << "__sent" << "this"; + H << string("&" + scoped + "__" + name); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()); + } + H << "__ctx" << epar << ";"; + H << eb; } - H << "__ctx" << epar << ";"; - H << eb; // // Private implementation // + H << sp; H << nl << "void __" << name << spar; H << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>&"; - H << lambdaParams; - H << "const ::Ice::Context& = Ice::noExplicitContext"; + H << inParamsS; + H << "const ::Ice::Context&"; H << epar << ";"; C << sp; C << nl << "void" << nl << scoped << "__" << name << spar; C << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>& __outAsync"; - C << lambdaParamsDecl << "const ::Ice::Context& __ctx"; + C << inParamsDecl << "const ::Ice::Context& __ctx"; C << epar; C << sb; if(p->returnsData()) @@ -6526,67 +6645,18 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) C << eb; } - if(lambdaOutParams.size() > 1) + if(futureOutParams.size() > 1) { // // Generate a read method if there are more than one ret/out parameter. If there's - // only one, we rely on the default read method from LambdaOutgoing. + // only one, we rely on the default read method from LambdaOutgoing + // except if the unique ret/out is optional or is an array/range. // - C << "," << nl << "[&](::Ice::InputStream* __is)"; + C << "," << nl << "[](::Ice::InputStream* __is)"; C << sb; C << nl << futureT << " v;"; - ParamDeclList optionals; - for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) - { - if((*q)->optional()) - { - optionals.push_back(*q); - } - else - { - string name = "v." + fixKwd((*q)->name()); - writeMarshalUnmarshalCode(C, (*q)->type(), false, 0, name, false, (*q)->getMetaData()); - } - } - if(ret && !retIsOpt) - { - string name = "v." + returnValueS; - writeMarshalUnmarshalCode(C, ret, false, 0, name, false, p->getMetaData()); - } + writeUnmarshalCode(C, outParams, p, false, _useWstring, returnValueS, "v"); - // - // Sort optional parameters by tag. - // - class SortFn - { - public: - static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) - { - return lhs->tag() < rhs->tag(); - } - }; - optionals.sort(SortFn::compare); - - // - // Marshal optional parameters. - // - bool checkReturnType = ret && retIsOpt; - for(ParamDeclList::const_iterator q = optionals.begin(); q != optionals.end(); ++q) - { - if(checkReturnType && p->returnTag() < (*q)->tag()) - { - string name = "v." + returnValueS; - writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), name, false, p->getMetaData()); - checkReturnType = false; - } - string name = "v." + fixKwd((*q)->name()); - writeMarshalUnmarshalCode(C, (*q)->type(), true, (*q)->tag(), name, false, (*q)->getMetaData()); - } - if(checkReturnType) - { - string name = "v." + returnValueS; - writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), name, false, p->getMetaData()); - } if(p->returnsClasses(false)) { C << nl << "__is->readPendingValues();"; @@ -6594,51 +6664,36 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) C << nl << "return v;"; C << eb; } - else if(lambdaOutParamsHasOpt) + else if(outParamsHasOpt || p->returnsClasses(false)) { // // If there's only one optional ret/out parameter, we still need to generate // a read method, we can't rely on the default read method which wouldn't // known which tag to use. // - C << "," << nl << "[&](::Ice::InputStream* __is)"; + C << "," << nl << "[](::Ice::InputStream* __is)"; C << sb; - C << nl << futureT << " v;"; - if(p->returnIsOptional()) - { - writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), "v", false, p->getMetaData()); - } - else + + writeAllocateCode(C, outParams, p, true, _useWstring, true); + writeUnmarshalCode(C, outParams, p, true, _useWstring); + + if(p->returnsClasses(false)) { - assert(outParams.size() == 1); - ParamDeclPtr q = (*outParams.begin()); - writeMarshalUnmarshalCode(C, q->type(), true, q->tag(), "v", false, q->getMetaData()); + C << nl << "__is->readPendingValues();"; } - C << nl << "return v;"; - C << eb; - } - else if(p->returnsClasses(false)) - { - C << "," << nl << "[&](::Ice::InputStream* __is)"; - C << sb; - C << nl << futureT << " v;"; + if(ret) { - writeMarshalUnmarshalCode(C, ret, false, 0, "v", false, p->getMetaData()); + C << nl << "return __ret;"; } else { - assert(outParams.size() == 1); - ParamDeclPtr q = (*outParams.begin()); - writeMarshalUnmarshalCode(C, q->type(), false, 0, "v", false, q->getMetaData()); + C << nl << "return " << fixKwd(paramPrefix + outParams.front()->name()) << ";"; } - C << nl << "__is->readPendingValues();"; - C << nl << "return v;"; C << eb; } C.dec(); - C << ");" << eb; } @@ -7363,45 +7418,43 @@ Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p) paramsDecl += typeString; paramsDecl += ' '; paramsDecl += paramName; - args += (isMovable(type) && !isOutParam) ? ("::std::move(" + paramName + ")") : paramName; + args += condMove(isMovable(type) && !isOutParam, paramName); } if((outParams.size() > 1) || (ret && outParams.size() > 0)) { // - // Generate OpNameResult struct + // Generate OpNameResult struct // - StructPtr st = cl->createStruct(resultStructName(name), false, Slice::Dummy); - st->setMetaData(cl->getMetaData()); + list<string> dataMembers; + string returnValueS = "returnValue"; - if(ret) + for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) { - string returnValue = "returnValue"; - for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) + string typeString + = typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + + dataMembers.push_back(typeString + " " + fixKwd((*q)->name())); + + if((*q)->name() == "returnValue") { - if((*q)->name() == returnValue) - { - returnValue = string("_") + returnValue; - break; - } + returnValueS = "_returnValue"; } - DataMemberPtr dm = - st->createDataMember(returnValue, ret, p->returnIsOptional(), p->returnTag(), 0, "", "", false); - dm->setMetaData(p->getMetaData()); } - for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) + if(ret) { - DataMemberPtr dm = - st->createDataMember((*q)->name(), (*q)->type(), (*q)->optional(), (*q)->tag(), 0, "", ""); - dm->setMetaData((*q)->getMetaData()); + dataMembers.push_front(retS + " " + returnValueS); } - // - // Generate C++ struct - // - Cpp11TypesVisitor typesVisitor(H, C, _dllExport, _useWstring); - st->visit(&typesVisitor, false); + H << sp; + H << nl << "struct " << resultStructName(name); + H << sb; + for(list<string>::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + H << nl << *q << ";"; + } + H << eb << ";"; } diff --git a/cpp/src/slice2cpp/Gen.h b/cpp/src/slice2cpp/Gen.h index e1d00e60976..114f13781c0 100644 --- a/cpp/src/slice2cpp/Gen.h +++ b/cpp/src/slice2cpp/Gen.h @@ -369,7 +369,7 @@ private: { public: - Cpp11TypesVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, int = 0); + Cpp11TypesVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); virtual bool visitModuleStart(const ModulePtr&); virtual void visitModuleEnd(const ModulePtr&); |