summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2016-06-16 10:33:55 -0400
committerBernard Normier <bernard@zeroc.com>2016-06-16 10:33:55 -0400
commit30fb2e0a6149d6607cc1e89e7d8013c273bd29fd (patch)
tree3799f140e7095dd1a8164a2d130ecda574d3aba6 /cpp/src
parentUpdate cpp/test/IceGrid/admin/run.py print statement (diff)
downloadice-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.cpp8
-rw-r--r--cpp/src/IceUtil/OutputUtil.cpp10
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp101
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.h10
-rw-r--r--cpp/src/Slice/Parser.cpp7
-rw-r--r--cpp/src/Slice/Parser.h2
-rw-r--r--cpp/src/slice2cpp/Gen.cpp541
-rw-r--r--cpp/src/slice2cpp/Gen.h2
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&);