diff options
-rw-r--r-- | cpp/include/Ice/Object.h | 6 | ||||
-rw-r--r-- | cpp/include/Ice/OutgoingAsync.h | 104 | ||||
-rw-r--r-- | cpp/include/Ice/Proxy.h | 118 | ||||
-rw-r--r-- | cpp/include/IceUtil/OutputUtil.h | 30 | ||||
-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 | ||||
-rw-r--r-- | cpp/test/Ice/custom/AllTests.cpp | 1108 | ||||
-rw-r--r-- | cpp/test/Ice/custom/CustomMap.h | 7 | ||||
-rw-r--r-- | cpp/test/Ice/invoke/AllTests.cpp | 62 |
15 files changed, 1640 insertions, 476 deletions
diff --git a/cpp/include/Ice/Object.h b/cpp/include/Ice/Object.h index b97dd0b6107..74db6c878a9 100644 --- a/cpp/include/Ice/Object.h +++ b/cpp/include/Ice/Object.h @@ -96,6 +96,12 @@ public: virtual DispatchStatus ice_dispatch(Ice::Request&, const DispatchInterceptorAsyncCallbackPtr& = 0); virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + struct Ice_invokeResult + { + bool returnValue; + std::vector<::Ice::Byte> outParams; + }; + protected: static void __checkMode(OperationMode, OperationMode); diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h index aac2b242698..f08ccfc8b17 100644 --- a/cpp/include/Ice/OutgoingAsync.h +++ b/cpp/include/Ice/OutgoingAsync.h @@ -542,27 +542,24 @@ public: { _response = [this, response](bool ok) { - if(ok) + if(!ok) + { + this->throwUserException(); + } + else if(response) { assert(this->_read); this->_is.startEncapsulation(); R v = this->_read(&this->_is); this->_is.endEncapsulation(); - if(response) + try { - try - { - response(std::move(v)); - } - catch(...) - { - throw std::current_exception(); - } + response(std::move(v)); + } + catch(...) + { + throw std::current_exception(); } - } - else - { - this->throwUserException(); } }; } @@ -581,46 +578,67 @@ public: { _response = [this, response](bool ok) { - if(this->_is.b.empty()) + if(!ok) { - // - // If there's no response (oneway, batch-oneway proxies), we just set the promise - // on completion without reading anything from the input stream. This is required for - // batch invocations. - // - if(response) - { - try - { - response(); - } - catch(...) - { - throw std::current_exception(); - } - } + this->throwUserException(); } - else if(ok) + else if(response) { - this->_is.skipEmptyEncapsulation(); - if(response) + if(!this->_is.b.empty()) + { + this->_is.skipEmptyEncapsulation(); + } + + try + { + response(); + } + catch(...) { - try - { - response(); - } - catch(...) - { - throw std::current_exception(); - } + throw std::current_exception(); } } - else + }; + } +}; + +class ICE_API CustomLambdaOutgoing : public OutgoingAsync, public LambdaInvoke +{ +public: + + CustomLambdaOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, + std::function<void(Ice::InputStream*)> read, + std::function<void(::std::exception_ptr)>& ex, + std::function<void(bool)>& sent) : + OutgoingAsync(proxy), LambdaInvoke(std::move(ex), std::move(sent)) + { + _response = [this, read](bool ok) + { + if(!ok) { this->throwUserException(); } + else if(read) + { + // + // Read and respond + // + read(&this->_is); + } }; } + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& ctx, + std::function<void(Ice::OutputStream*)>&& write, + std::function<void(const Ice::UserException&)>&& userException) + { + _userException = std::move(userException); + OutgoingAsync::invoke(operation, mode, format, ctx, write); + } }; template<typename P, typename R> diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h index 7b29ef98781..e3edf70b1e0 100644 --- a/cpp/include/Ice/Proxy.h +++ b/cpp/include/Ice/Proxy.h @@ -63,7 +63,7 @@ makePair(const Ice::ByteSeq& seq) } else { - return { &seq[0], &seq[0] + seq.size() }; + return { seq.data(), seq.data() + seq.size() }; } } @@ -289,7 +289,7 @@ public: void ice_ping(const ::Ice::Context& ctx = ::Ice::noExplicitContext) { - makePromiseOutgoing(true, this, &ObjectPrx::__ice_ping, ctx).get(); + makePromiseOutgoing<void>(true, this, &ObjectPrx::__ice_ping, ctx).get(); } ::std::function<void()> @@ -298,14 +298,14 @@ public: ::std::function<void(bool)> sent = nullptr, const ::Ice::Context& ctx = ::Ice::noExplicitContext) { - return makeLambdaOutgoing(response, ex, sent, this, &ObjectPrx::__ice_ping, ctx); + return makeLambdaOutgoing<void>(response, ex, sent, this, &ObjectPrx::__ice_ping, ctx); } template<template<typename> class P = std::promise> auto ice_pingAsync(const ::Ice::Context& ctx = ::Ice::noExplicitContext) -> decltype(std::declval<P<void>>().get_future()) { - return makePromiseOutgoing<P>(false, this, &ObjectPrx::__ice_ping, ctx); + return makePromiseOutgoing<void, P>(false, this, &ObjectPrx::__ice_ping, ctx); } void @@ -366,36 +366,29 @@ public: return ::Ice::Object::ice_staticId(); } - struct Result_ice_invoke - { - bool ok; - std::vector<::Ice::Byte> outParams; - }; - // Returns true if ok, false if user exception. + // + // ice_invoke with default vector mapping for byte-sequence parameters + // + bool ice_invoke(const ::std::string& operation, ::Ice::OperationMode mode, - const ::std::vector< ::Ice::Byte>& inP, + const ::std::vector<Byte>& inP, ::std::vector<::Ice::Byte>& outParams, const ::Ice::Context& ctx = ::Ice::noExplicitContext) { return ice_invoke(operation, mode, ::IceInternal::makePair(inP), outParams, ctx); } - bool - ice_invoke(const ::std::string& operation, - ::Ice::OperationMode mode, - const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inP, - ::std::vector<::Ice::Byte>& outParams, - const ::Ice::Context& ctx = ::Ice::noExplicitContext) + template<template<typename> class P = std::promise> auto + ice_invokeAsync(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector<Byte>& inP, + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + -> decltype(std::declval<P<::Ice::Object::Ice_invokeResult>>().get_future()) { - using Outgoing = ::IceInternal::InvokePromiseOutgoing<::std::promise<Result_ice_invoke>, Result_ice_invoke>; - auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), true); - outAsync->invoke(operation, mode, inP, ctx); - auto result = outAsync->getFuture().get(); - outParams.swap(result.outParams); - return result.ok; + return ice_invokeAsync<P>(operation, mode, ::IceInternal::makePair(inP), ctx); } ::std::function<void()> @@ -407,13 +400,13 @@ public: ::std::function<void(bool)> sent = nullptr, const ::Ice::Context& ctx = ::Ice::noExplicitContext) { - using Outgoing = ::IceInternal::InvokeLambdaOutgoing<Result_ice_invoke>; - ::std::function<void(Result_ice_invoke&&)> r; + using Outgoing = ::IceInternal::InvokeLambdaOutgoing<::Ice::Object::Ice_invokeResult>; + ::std::function<void(::Ice::Object::Ice_invokeResult&&)> r; if(response) { - r = [response](Result_ice_invoke&& result) + r = [response](::Ice::Object::Ice_invokeResult&& result) { - response(result.ok, std::move(result.outParams)); + response(result.returnValue, std::move(result.outParams)); }; } auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent); @@ -421,14 +414,25 @@ public: return [outAsync]() { outAsync->cancel(); }; } - template<template<typename> class P = std::promise> auto - ice_invokeAsync(const ::std::string& operation, - ::Ice::OperationMode mode, - const ::std::vector<::Ice::Byte>& inP, - const ::Ice::Context& ctx = ::Ice::noExplicitContext) - -> decltype(std::declval<P<Result_ice_invoke>>().get_future()) + + // + // ice_invoke with cpp:array mapping for byte sequence parameters + // + + bool + ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inP, + ::std::vector<::Ice::Byte>& outParams, + const ::Ice::Context& ctx = ::Ice::noExplicitContext) { - return ice_invokeAsync(operation, mode, ::IceInternal::makePair(inP), ctx); + using Outgoing = ::IceInternal::InvokePromiseOutgoing< + ::std::promise<::Ice::Object::Ice_invokeResult>, ::Ice::Object::Ice_invokeResult>; + auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), true); + outAsync->invoke(operation, mode, inP, ctx); + auto result = outAsync->getFuture().get(); + outParams.swap(result.outParams); + return result.returnValue; } template<template<typename> class P = std::promise> auto @@ -436,20 +440,15 @@ public: ::Ice::OperationMode mode, const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inP, const ::Ice::Context& ctx = ::Ice::noExplicitContext) - -> decltype(std::declval<P<Result_ice_invoke>>().get_future()) + -> decltype(std::declval<P<::Ice::Object::Ice_invokeResult>>().get_future()) { - using Outgoing = ::IceInternal::InvokePromiseOutgoing<P<Result_ice_invoke>, Result_ice_invoke>; + using Outgoing = + ::IceInternal::InvokePromiseOutgoing<P<::Ice::Object::Ice_invokeResult>, ::Ice::Object::Ice_invokeResult>; auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), false); outAsync->invoke(operation, mode, inP, ctx); return outAsync->getFuture(); } - struct Result_ice_invoke_zerocopy - { - bool ok; - std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outParams; - }; - ::std::function<void()> ice_invokeAsync(const ::std::string& operation, ::Ice::OperationMode mode, @@ -459,13 +458,15 @@ public: ::std::function<void(bool)> sent = nullptr, const ::Ice::Context& ctx = ::Ice::noExplicitContext) { - using Outgoing = ::IceInternal::InvokeLambdaOutgoing<Result_ice_invoke_zerocopy>; - ::std::function<void(Result_ice_invoke_zerocopy&&)> r; + using Result = ::std::tuple<bool, ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>>; + using Outgoing = ::IceInternal::InvokeLambdaOutgoing<Result>; + + ::std::function<void(Result&&)> r; if(response) { - r = [response](Result_ice_invoke_zerocopy&& result) + r = [response](Result&& result) { - response(result.ok, std::move(result.outParams)); + response(::std::get<0>(result), ::std::move(::std::get<1>(result))); }; } auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent); @@ -473,6 +474,7 @@ public: return [outAsync]() { outAsync->cancel(); }; } + ::Ice::Identity ice_getIdentity() const; ::std::shared_ptr<::Ice::ObjectPrx> ice_identity(const ::Ice::Identity&) const; @@ -620,8 +622,9 @@ public: protected: - template<typename R, template<typename> class P = ::std::promise, typename Obj, typename Fn, typename... Args> auto - makePromiseOutgoing(bool sync, Obj obj, Fn fn, Args&&... args) -> decltype(std::declval<P<R>>().get_future()) + template<typename R, template<typename> class P = ::std::promise, typename Obj, typename Fn, typename... Args> + auto makePromiseOutgoing(bool sync, Obj obj, Fn fn, Args&&... args) + -> decltype(std::declval<P<R>>().get_future()) { auto outAsync = ::std::make_shared<::IceInternal::PromiseOutgoing<P<R>, R>>(shared_from_this(), sync); (obj->*fn)(outAsync, std::forward<Args>(args)...); @@ -636,25 +639,6 @@ protected: return [outAsync]() { outAsync->cancel(); }; } - // - // Specializations for invocation which can be invoked with oneway/batch-oneway. - // - template<template<typename> class P = ::std::promise, typename Obj, typename Fn, typename... Args> auto - makePromiseOutgoing(bool sync, Obj obj, Fn fn, Args&&... args) -> decltype(std::declval<P<void>>().get_future()) - { - auto outAsync = ::std::make_shared<::IceInternal::PromiseOutgoing<P<void>, void>>(shared_from_this(), sync); - (obj->*fn)(outAsync, std::forward<Args>(args)...); - return outAsync->getFuture(); - } - - template<typename Re, typename E, typename S, typename Obj, typename Fn, typename... Args> - ::std::function<void()> makeLambdaOutgoing(Re r, E e, S s, Obj obj, Fn fn, Args&&... args) - { - auto outAsync = ::std::make_shared<::IceInternal::LambdaOutgoing<void>>(shared_from_this(), r, e, s); - (obj->*fn)(outAsync, std::forward<Args>(args)...); - return [outAsync]() { outAsync->cancel(); }; - } - virtual ::std::shared_ptr<ObjectPrx> __newInstance() const; ObjectPrx() = default; friend ::std::shared_ptr<ObjectPrx> IceInternal::createProxy<ObjectPrx>(); diff --git a/cpp/include/IceUtil/OutputUtil.h b/cpp/include/IceUtil/OutputUtil.h index a3a251b28ce..e7bc5f9b5c1 100644 --- a/cpp/include/IceUtil/OutputUtil.h +++ b/cpp/include/IceUtil/OutputUtil.h @@ -101,8 +101,8 @@ public: void sb(); // Start a block. void eb(); // End a block. - void spar(); // Start a paramater list. - void epar(); // End a paramater list. + void spar(char = '('); // Start a paramater list. + void epar(char = ')'); // End a paramater list. private: @@ -200,6 +200,32 @@ operator<<(Output& o, const EndPar&) return o; } +class ICE_API StartAbrk +{ +}; +extern ICE_API StartAbrk sabrk; + +template<> +inline Output& +operator<<(Output& o, const StartAbrk&) +{ + o.spar('<'); + return o; +} + +class ICE_API EndAbrk +{ +}; +extern ICE_API EndAbrk eabrk; + +template<> +inline Output& +operator<<(Output& o, const EndAbrk&) +{ + o.epar('>'); + return o; +} + ICE_API Output& operator<<(Output&, std::ios_base& (*)(std::ios_base&)); // ---------------------------------------------------------------------- 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&); diff --git a/cpp/test/Ice/custom/AllTests.cpp b/cpp/test/Ice/custom/AllTests.cpp index 28e35794cbd..a674024fde4 100644 --- a/cpp/test/Ice/custom/AllTests.cpp +++ b/cpp/test/Ice/custom/AllTests.cpp @@ -78,6 +78,8 @@ arrayRangeEquals(pair<const T*, const T*> lhs, pair<const T*, const T*> rhs) } +#ifndef ICE_CPP11_MAPPING + class CallbackBase : public IceUtil::Monitor<IceUtil::Mutex> { public: @@ -529,7 +531,6 @@ public: called(); } -#ifndef ICE_CPP11_MAPPING void throwExcept1(const Ice::AsyncResultPtr& result) { const wstring& in = getIn<wstring>(InParamPtr::dynamicCast(result->getCookie())); @@ -548,7 +549,6 @@ public: test(false); } } -#endif void throwExcept1(const Ice::Exception& ex, const wstring& in) { @@ -567,7 +567,6 @@ public: } } -#ifndef ICE_CPP11_MAPPING void throwExcept2(const Ice::AsyncResultPtr& result) { const wstring& in = getIn<wstring>(InParamPtr::dynamicCast(result->getCookie())); @@ -586,7 +585,6 @@ public: test(false); } } -#endif void throwExcept2(const Ice::Exception& ex, const wstring& in) { @@ -614,6 +612,9 @@ public: }; typedef IceUtil::Handle<Callback> CallbackPtr; +#endif + + Test::TestIntfPrxPtr allTests(const Ice::CommunicatorPtr& communicator) { @@ -1254,18 +1255,25 @@ allTests(const Ice::CommunicatorPtr& communicator) } cout << "ok" << endl; -#ifndef ICE_CPP11_MAPPING cout << "testing alternate strings with AMI... " << flush; { Util::string_view in = "Hello World!"; +#ifdef ICE_CPP11_MAPPING + + auto r = t->opStringAsync(in).get(); + test(r.returnValue == r.outString); + test(r.returnValue.size() == in.size()); + +#else Ice::AsyncResultPtr r = t->begin_opString(in); string out; string ret = t->end_opString(out, r); test(ret == out); test(ret.size() == in.size()); +#endif } cout << "ok" << endl; @@ -1285,11 +1293,17 @@ allTests(const Ice::CommunicatorPtr& communicator) } pair<const Ice::Double*, const Ice::Double*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + auto r = t->opDoubleArrayAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::DoubleSeq out; Ice::AsyncResultPtr r = t->begin_opDoubleArray(inPair); Test::DoubleSeq ret = t->end_opDoubleArray(out, r); test(out == in); test(ret == in); +#endif } { @@ -1306,11 +1320,18 @@ allTests(const Ice::CommunicatorPtr& communicator) } pair<const bool*, const bool*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + auto r = t->opBoolArrayAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else + Test::BoolSeq out; Ice::AsyncResultPtr r = t->begin_opBoolArray(inPair); Test::BoolSeq ret = t->end_opBoolArray(out, r); test(out == in); test(ret == in); +#endif } { @@ -1328,11 +1349,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(inArray[4]); pair<const Ice::Byte*, const Ice::Byte*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + auto r = t->opByteArrayAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::ByteList out; Ice::AsyncResultPtr r = t->begin_opByteArray(inPair); Test::ByteList ret = t->end_opByteArray(out, r); test(out == in); test(ret == in); +#endif } { @@ -1350,11 +1377,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(inArray[4]); pair<const Test::Variable*, const Test::Variable*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + auto r = t->opVariableArrayAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::VariableList out; Ice::AsyncResultPtr r = t->begin_opVariableArray(inPair); Test::VariableList ret = t->end_opVariableArray(out, r); test(out == in); test(ret == in); +#endif } { @@ -1366,11 +1399,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[4] = true; pair<Test::BoolSeq::const_iterator, Test::BoolSeq::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + auto r = t->opBoolRangeAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::BoolSeq out; Ice::AsyncResultPtr r = t->begin_opBoolRange(inPair); Test::BoolSeq ret = t->end_opBoolRange(out, r); test(out == in); test(ret == in); +#endif } { @@ -1382,11 +1421,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('5'); pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + auto r = t->opByteRangeAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::ByteList out; Ice::AsyncResultPtr r = t->begin_opByteRange(inPair); Test::ByteList ret = t->end_opByteRange(out, r); test(out == in); test(ret == in); +#endif } { @@ -1404,11 +1449,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(v); pair<Test::VariableList::const_iterator, Test::VariableList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + auto r = t->opVariableRangeAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::VariableList out; Ice::AsyncResultPtr r = t->begin_opVariableRange(inPair); Test::VariableList ret = t->end_opVariableRange(out, r); test(out == in); test(ret == in); +#endif } { @@ -1420,11 +1471,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('5'); pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + auto r = t->opByteRangeTypeAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::ByteList out; Ice::AsyncResultPtr r = t->begin_opByteRangeType(inPair); Test::ByteList ret = t->end_opByteRangeType(out, r); test(out == in); test(ret == in); +#endif } { @@ -1449,11 +1506,17 @@ allTests(const Ice::CommunicatorPtr& communicator) pair<deque<Test::Variable>::const_iterator, deque<Test::Variable>::const_iterator> inPair(inSeq.begin(), inSeq.end()); +#ifdef ICE_CPP11_MAPPING + auto r = t->opVariableRangeTypeAsync(inPair).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else Test::VariableList out; Ice::AsyncResultPtr r = t->begin_opVariableRangeType(inPair); Test::VariableList ret = t->end_opVariableRangeType(out, r); test(out == in); test(ret == in); +#endif } { @@ -1464,11 +1527,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = false; in[4] = true; +#ifdef ICE_CPP11_MAPPING + auto r = t->opBoolSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<bool> out; Ice::AsyncResultPtr r = t->begin_opBoolSeq(in); deque<bool> ret = t->end_opBoolSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1479,11 +1548,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(false); in.push_back(true); +#ifdef ICE_CPP11_MAPPING + auto r = t->opBoolListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<bool> out; Ice::AsyncResultPtr r = t->begin_opBoolList(in); list<bool> ret = t->end_opBoolList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1494,11 +1569,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = '4'; in[4] = '5'; +#ifdef ICE_CPP11_MAPPING + auto r = t->opByteSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque< ::Ice::Byte> out; Ice::AsyncResultPtr r = t->begin_opByteSeq(in); deque< ::Ice::Byte> ret = t->end_opByteSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1509,11 +1590,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('4'); in.push_back('5'); +#ifdef ICE_CPP11_MAPPING + auto r = t->opByteListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list< ::Ice::Byte> out; Ice::AsyncResultPtr r = t->begin_opByteList(in); list< ::Ice::Byte> ret = t->end_opByteList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1524,11 +1611,17 @@ allTests(const Ice::CommunicatorPtr& communicator) *p = '1' + i++; } +#ifdef ICE_CPP11_MAPPING + auto r = t->opMyByteSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else MyByteSeq out; Ice::AsyncResultPtr r = t->begin_opMyByteSeq(in); MyByteSeq ret = t->end_opMyByteSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1539,11 +1632,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = "short"; in[4] = "strings."; +#ifdef ICE_CPP11_MAPPING + auto r = t->opStringSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<string> out; Ice::AsyncResultPtr r = t->begin_opStringSeq(in); deque<string> ret = t->end_opStringSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1554,11 +1653,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back("short"); in.push_back("strings."); +#ifdef ICE_CPP11_MAPPING + auto r = t->opStringListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<string> out; Ice::AsyncResultPtr r = t->begin_opStringList(in); list<string> ret = t->end_opStringList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1569,11 +1674,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3].s = 4; in[4].s = 5; +#ifdef ICE_CPP11_MAPPING + auto r = t->opFixedSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<Test::Fixed> out; Ice::AsyncResultPtr r = t->begin_opFixedSeq(in); deque<Test::Fixed> ret = t->end_opFixedSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1584,11 +1695,17 @@ allTests(const Ice::CommunicatorPtr& communicator) (*p).s = num++; } +#ifdef ICE_CPP11_MAPPING + auto r = t->opFixedListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<Test::Fixed> out; Ice::AsyncResultPtr r = t->begin_opFixedList(in); list<Test::Fixed> ret = t->end_opFixedList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1599,11 +1716,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3].s = "short"; in[4].s = "strings."; +#ifdef ICE_CPP11_MAPPING + auto r = t->opVariableSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<Test::Variable> out; Ice::AsyncResultPtr r = t->begin_opVariableSeq(in); deque<Test::Variable> ret = t->end_opVariableSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1620,11 +1743,17 @@ allTests(const Ice::CommunicatorPtr& communicator) v.s = "strings."; in.push_back(v); +#ifdef ICE_CPP11_MAPPING + auto r = t->opVariableListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<Test::Variable> out; Ice::AsyncResultPtr r = t->begin_opVariableList(in); list<Test::Variable> ret = t->end_opVariableList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1635,11 +1764,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3]["D"] = "d"; in[4]["E"] = "e"; +#ifdef ICE_CPP11_MAPPING + auto r = t->opStringStringDictSeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<Test::StringStringDict> out; Ice::AsyncResultPtr r = t->begin_opStringStringDictSeq(in); deque<Test::StringStringDict> ret = t->end_opStringStringDictSeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1656,11 +1791,17 @@ allTests(const Ice::CommunicatorPtr& communicator) ssd["E"] = "e"; in.push_back(ssd); +#ifdef ICE_CPP11_MAPPING + auto r = t->opStringStringDictListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<Test::StringStringDict> out; Ice::AsyncResultPtr r = t->begin_opStringStringDictList(in); list<Test::StringStringDict> ret = t->end_opStringStringDictList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1671,11 +1812,17 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = Test:: ICE_ENUM(E, E1); in[4] = Test:: ICE_ENUM(E, E3); +#ifdef ICE_CPP11_MAPPING + auto r = t->opESeqAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else deque<Test::E> out; Ice::AsyncResultPtr r = t->begin_opESeq(in); deque<Test::E> ret = t->end_opESeq(out, r); test(out == in); test(ret == in); +#endif } { @@ -1686,41 +1833,79 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(Test:: ICE_ENUM(E, E1)); in.push_back(Test:: ICE_ENUM(E, E3)); +#ifdef ICE_CPP11_MAPPING + auto r = t->opEListAsync(in).get(); + test(r.outSeq == in); + test(r.returnValue == in); +#else list<Test::E> out; Ice::AsyncResultPtr r = t->begin_opEList(in); list<Test::E> ret = t->end_opEList(out, r); test(out == in); test(ret == in); +#endif } { - deque<Test::CPrx> in(5); + deque<Test::CPrxPtr> in(5); in[0] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C1:" + endp + " -t 10000")); in[1] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C2:" + endp + " -t 10001")); in[2] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C3:" + endp + " -t 10002")); in[3] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C4:" + endp + " -t 10003")); in[4] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C5:" + endp + " -t 10004")); +#ifdef ICE_CPP11_MAPPING + auto r = t->opCPrxSeqAsync(in).get(); + + test(r.outSeq.size() == in.size()); + test(r.returnValue.size() == in.size()); + + auto op = r.outSeq.begin(); + auto rp = r.returnValue.begin(); + + for(auto i: in) + { + test(Ice::targetEquals(*op++, i)); + test(Ice::targetEquals(*rp++, i)); + } +#else deque<Test::CPrx> out; Ice::AsyncResultPtr r = t->begin_opCPrxSeq(in); deque<Test::CPrx> ret = t->end_opCPrxSeq(out, r); test(out == in); test(ret == in); +#endif } { - list<Test::CPrx> in; + list<Test::CPrxPtr> in; in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C1:" + endp + " -t 10000"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C2:" + endp + " -t 10001"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C3:" + endp + " -t 10002"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C4:" + endp + " -t 10003"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C5:" + endp + " -t 10004"))); +#ifdef ICE_CPP11_MAPPING + auto r = t->opCPrxListAsync(in).get(); + + test(r.outSeq.size() == in.size()); + test(r.returnValue.size() == in.size()); + + auto op = r.outSeq.begin(); + auto rp = r.returnValue.begin(); + + for(auto i: in) + { + test(Ice::targetEquals(*op++, i)); + test(Ice::targetEquals(*rp++, i)); + } +#else list<Test::CPrx> out; Ice::AsyncResultPtr r = t->begin_opCPrxList(in); list<Test::CPrx> ret = t->end_opCPrxList(out, r); test(out == in); test(ret == in); +#endif } { @@ -1731,6 +1916,18 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = in[0]; in[4] = in[0]; +#ifdef ICE_CPP11_MAPPING + auto r = t->opCSeqAsync(in).get(); + test(r.outSeq.size() == in.size()); + test(r.returnValue.size() == in.size()); + + auto rp = r.returnValue.begin(); + for(auto o: r.outSeq) + { + test(o == r.outSeq[0]); + test(*rp++ == o); + } +#else deque<Test::CPtr> out; Ice::AsyncResultPtr r = t->begin_opCSeq(in); deque<Test::CPtr> ret = t->end_opCSeq(out, r); @@ -1741,6 +1938,7 @@ allTests(const Ice::CommunicatorPtr& communicator) test(out[i] == out[0]); test(ret[i] == out[i]); } +#endif } { @@ -1751,6 +1949,12 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(ICE_MAKE_SHARED(Test::C)); in.push_back(ICE_MAKE_SHARED(Test::C)); +#ifdef ICE_CPP11_MAPPING + auto r = t->opCListAsync(in).get(); + test(r.outSeq.size() == in.size()); + test(r.returnValue.size() == in.size()); + test(r.outSeq == r.returnValue); +#else list<Test::CPtr> out; Ice::AsyncResultPtr r = t->begin_opCList(in); list<Test::CPtr> ret = t->end_opCList(out, r); @@ -1762,6 +1966,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(*p1 == *p2); } +#endif } @@ -1772,6 +1977,11 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('3'); in.push_back('4'); +#ifdef ICE_CPP11_MAPPING + auto r = t->opOutArrayByteSeqAsync(in).get(); + test(r.size() == in.size()); + test(r == in); +#else Ice::AsyncResultPtr r = t->begin_opOutArrayByteSeq(in); Test::ByteSeq out; @@ -1785,6 +1995,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(*p1 == *p2); } +#endif } { @@ -1794,6 +2005,11 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('3'); in.push_back('4'); +#ifdef ICE_CPP11_MAPPING + auto r = t->opOutRangeByteSeqAsync(in).get(); + test(r.size() == in.size()); + test(r == in); +#else Ice::AsyncResultPtr r = t->begin_opOutRangeByteSeq(in); Test::ByteSeq out; @@ -1807,23 +2023,44 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(*p1 == *p2); } +#endif } } cout << "ok" << endl; - cout << "testing alternate strings with new AMI callbacks... " << flush; + cout << "testing alternate strings with AMI callbacks... " << flush; { Util::string_view in = "Hello World!"; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opStringAsync(in, + [&](Util::string_view ret, Util::string_view out) + { + test(out == ret); + test(in.size() == out.size()); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); + Test::Callback_TestIntf_opStringPtr callback = Test::newCallback_TestIntf_opString(cb, &Callback::opString, &Callback::noEx); t->begin_opString(in, callback, newInParam(in)); cb->check(); +#endif } cout << "ok" << endl; - cout << "testing alternate sequences with new AMI callbacks... " << flush; + cout << "testing alternate sequences with AMI callbacks... " << flush; { Test::DoubleSeq in(5); @@ -1839,13 +2076,34 @@ allTests(const Ice::CommunicatorPtr& communicator) } pair<const Ice::Double*, const Ice::Double*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opDoubleArrayAsync(inPair, + [&](pair<const Ice::Double*, const Ice::Double*> ret, + pair<const Ice::Double*, const Ice::Double*> out) + { + test(arrayRangeEquals<double>(out, inPair)); + test(arrayRangeEquals<double>(ret, inPair)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opDoubleArrayPtr callback = Test::newCallback_TestIntf_opDoubleArray(cb, &Callback::opDoubleArray, &Callback::noEx); t->begin_opDoubleArray(inPair, callback, newInParam(inPair)); cb->check(); +#endif } + { Test::BoolSeq in(5); in[0] = false; @@ -1860,11 +2118,31 @@ allTests(const Ice::CommunicatorPtr& communicator) } pair<const bool*, const bool*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opBoolArrayAsync(inPair, + [&](pair<const bool*, const bool*> ret, + pair<const bool*, const bool*> out) + { + test(arrayRangeEquals<bool>(out, inPair)); + test(arrayRangeEquals<bool>(ret, inPair)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opBoolArrayPtr callback = Test::newCallback_TestIntf_opBoolArray(cb, &Callback::opBoolArray, &Callback::noEx); t->begin_opBoolArray(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1876,11 +2154,32 @@ allTests(const Ice::CommunicatorPtr& communicator) in[4] = '5'; pair<const Ice::Byte*, const Ice::Byte*> inPair(in, in + 5); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opByteArrayAsync(inPair, + [&](pair<const Ice::Byte*, const Ice::Byte*> ret, + pair<const Ice::Byte*, const Ice::Byte*> out) + { + test(arrayRangeEquals<Ice::Byte>(out, inPair)); + test(arrayRangeEquals<Ice::Byte>(ret, inPair)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opByteArrayPtr callback = Test::newCallback_TestIntf_opByteArray(cb, &Callback::opByteArray, &Callback::noEx); t->begin_opByteArray(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1898,11 +2197,31 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(inArray[4]); pair<const Test::Variable*, const Test::Variable*> inPair(inArray, inArray + 5); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opVariableArrayAsync(inPair, + [&](pair<const Test::Variable*, const Test::Variable*> ret, + pair<const Test::Variable*, const Test::Variable*> out) + { + test(arrayRangeEquals<Test::Variable>(out, inPair)); + test(arrayRangeEquals<Test::Variable>(ret, inPair)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVariableArrayPtr callback = Test::newCallback_TestIntf_opVariableArray(cb, &Callback::opVariableArray, &Callback::noEx); t->begin_opVariableArray(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1914,13 +2233,35 @@ allTests(const Ice::CommunicatorPtr& communicator) in[4] = true; pair<Test::BoolSeq::const_iterator, Test::BoolSeq::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opBoolRangeAsync(inPair, + [&](pair<Test::BoolSeq::const_iterator, Test::BoolSeq::const_iterator> ret, + pair<Test::BoolSeq::const_iterator, Test::BoolSeq::const_iterator> out) + { + test(equal(out.first, out.second, inPair.first)); + test(equal(ret.first, ret.second, inPair.first)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opBoolRangePtr callback = Test::newCallback_TestIntf_opBoolRange(cb, &Callback::opBoolRange, &Callback::noEx); t->begin_opBoolRange(inPair, callback, newInParam(inPair)); cb->check(); +#endif } + { Test::ByteList in; in.push_back('1'); @@ -1930,11 +2271,32 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('5'); pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opByteRangeAsync(inPair, + [&](pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> ret, + pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> out) + { + test(equal(out.first, out.second, inPair.first)); + test(equal(ret.first, ret.second, inPair.first)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opByteRangePtr callback = Test::newCallback_TestIntf_opByteRange(cb, &Callback::opByteRange, &Callback::noEx); t->begin_opByteRange(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1952,11 +2314,32 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(v); pair<Test::VariableList::const_iterator, Test::VariableList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opVariableRangeAsync(inPair, + [&](pair<Test::VariableList::const_iterator, Test::VariableList::const_iterator> ret, + pair<Test::VariableList::const_iterator, Test::VariableList::const_iterator> out) + { + test(equal(out.first, out.second, inPair.first)); + test(equal(ret.first, ret.second, inPair.first)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVariableRangePtr callback = Test::newCallback_TestIntf_opVariableRange(cb, &Callback::opVariableRange, &Callback::noEx); t->begin_opVariableRange(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1968,11 +2351,32 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('5'); pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> inPair(in.begin(), in.end()); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opByteRangeTypeAsync(inPair, + [&](pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> ret, + pair<Test::ByteList::const_iterator, Test::ByteList::const_iterator> out) + { + test(equal(out.first, out.second, inPair.first)); + test(equal(ret.first, ret.second, inPair.first)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opByteRangeTypePtr callback = Test::newCallback_TestIntf_opByteRangeType(cb, &Callback::opByteRangeType, &Callback::noEx); t->begin_opByteRangeType(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -1997,11 +2401,32 @@ allTests(const Ice::CommunicatorPtr& communicator) pair<deque<Test::Variable>::const_iterator, deque<Test::Variable>::const_iterator> inPair(inSeq.begin(), inSeq.end()); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opVariableRangeTypeAsync(inPair, + [&](pair<deque<Test::Variable>::const_iterator, deque<Test::Variable>::const_iterator> ret, + pair<deque<Test::Variable>::const_iterator, deque<Test::Variable>::const_iterator> out) + { + test(equal(out.first, out.second, inPair.first)); + test(equal(ret.first, ret.second, inPair.first)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVariableRangeTypePtr callback = Test::newCallback_TestIntf_opVariableRangeType(cb, &Callback::opVariableRangeType, &Callback::noEx); t->begin_opVariableRangeType(inPair, callback, newInParam(inPair)); cb->check(); +#endif } { @@ -2012,11 +2437,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = false; in[4] = true; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opBoolSeqAsync(in, + [&](deque<bool>ret, deque<bool> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opBoolSeqPtr callback = Test::newCallback_TestIntf_opBoolSeq(cb, &Callback::opBoolSeq, &Callback::noEx); t->begin_opBoolSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2027,11 +2471,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(false); in.push_back(true); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opBoolListAsync(in, + [&](list<bool>ret, list<bool> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opBoolListPtr callback = Test::newCallback_TestIntf_opBoolList(cb, &Callback::opBoolList, &Callback::noEx); t->begin_opBoolList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2042,11 +2505,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = '4'; in[4] = '5'; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opByteSeqAsync(in, + [&](deque<Ice::Byte> ret, deque<Ice::Byte> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opByteSeqPtr callback = Test::newCallback_TestIntf_opByteSeq(cb, &Callback::opByteSeq, &Callback::noEx); t->begin_opByteSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2057,11 +2539,31 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('4'); in.push_back('5'); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opByteListAsync(in, + [&](list<Ice::Byte> ret, list<Ice::Byte> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opByteListPtr callback = Test::newCallback_TestIntf_opByteList(cb, &Callback::opByteList, &Callback::noEx); t->begin_opByteList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2072,11 +2574,30 @@ allTests(const Ice::CommunicatorPtr& communicator) *p = '1' + i++; } +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opMyByteSeqAsync(in, + [&](MyByteSeq ret, MyByteSeq out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opMyByteSeqPtr callback = Test::newCallback_TestIntf_opMyByteSeq(cb, &Callback::opMyByteSeq, &Callback::noEx); t->begin_opMyByteSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2087,11 +2608,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = "short"; in[4] = "strings."; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opStringSeqAsync(in, + [&](deque<string> ret, deque<string> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opStringSeqPtr callback = Test::newCallback_TestIntf_opStringSeq(cb, &Callback::opStringSeq, &Callback::noEx); t->begin_opStringSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2102,11 +2642,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back("short"); in.push_back("strings."); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opStringListAsync(in, + [&](list<string> ret, list<string> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opStringListPtr callback = Test::newCallback_TestIntf_opStringList(cb, &Callback::opStringList, &Callback::noEx); t->begin_opStringList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2117,11 +2676,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3].s = 4; in[4].s = 5; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opFixedSeqAsync(in, + [&](deque<Test::Fixed> ret, deque<Test::Fixed> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opFixedSeqPtr callback = Test::newCallback_TestIntf_opFixedSeq(cb, &Callback::opFixedSeq, &Callback::noEx); t->begin_opFixedSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2132,11 +2710,30 @@ allTests(const Ice::CommunicatorPtr& communicator) (*p).s = num++; } +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opFixedListAsync(in, + [&](list<Test::Fixed> ret, list<Test::Fixed> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opFixedListPtr callback = Test::newCallback_TestIntf_opFixedList(cb, &Callback::opFixedList, &Callback::noEx); t->begin_opFixedList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2147,11 +2744,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3].s = "short"; in[4].s = "strings."; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opVariableSeqAsync(in, + [&](deque<Test::Variable> ret, deque<Test::Variable> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVariableSeqPtr callback = Test::newCallback_TestIntf_opVariableSeq(cb, &Callback::opVariableSeq, &Callback::noEx); t->begin_opVariableSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2168,11 +2784,30 @@ allTests(const Ice::CommunicatorPtr& communicator) v.s = "strings."; in.push_back(v); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opVariableListAsync(in, + [&](list<Test::Variable> ret, list<Test::Variable> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVariableListPtr callback = Test::newCallback_TestIntf_opVariableList(cb, &Callback::opVariableList, &Callback::noEx); t->begin_opVariableList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2183,11 +2818,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3]["D"] = "d"; in[4]["E"] = "e"; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opStringStringDictSeqAsync(in, + [&](deque<Test::StringStringDict> ret, deque<Test::StringStringDict> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opStringStringDictSeqPtr callback = Test::newCallback_TestIntf_opStringStringDictSeq(cb, &Callback::opStringStringDictSeq, &Callback::noEx); t->begin_opStringStringDictSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2204,13 +2858,33 @@ allTests(const Ice::CommunicatorPtr& communicator) ssd["E"] = "e"; in.push_back(ssd); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opStringStringDictListAsync(in, + [&](list<Test::StringStringDict> ret, list<Test::StringStringDict> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opStringStringDictListPtr callback = Test::newCallback_TestIntf_opStringStringDictList(cb, &Callback::opStringStringDictList, &Callback::noEx); t->begin_opStringStringDictList(in, callback, newInParam(in)); cb->check(); +#endif } + { deque<Test::E> in(5); in[0] = Test:: ICE_ENUM(E, E1); @@ -2219,11 +2893,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = Test:: ICE_ENUM(E, E1); in[4] = Test:: ICE_ENUM(E, E3); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opESeqAsync(in, + [&](deque<Test::E> ret, deque<Test::E> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opESeqPtr callback = Test::newCallback_TestIntf_opESeq(cb, &Callback::opESeq, &Callback::noEx); t->begin_opESeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2234,41 +2927,110 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(Test:: ICE_ENUM(E, E1)); in.push_back(Test:: ICE_ENUM(E, E3)); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opEListAsync(in, + [&](list<Test::E> ret, list<Test::E> out) + { + test(ret == out); + test(ret == in); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opEListPtr callback = Test::newCallback_TestIntf_opEList(cb, &Callback::opEList, &Callback::noEx); t->begin_opEList(in, callback, newInParam(in)); cb->check(); +#endif } { - deque<Test::CPrx> in(5); + deque<Test::CPrxPtr> in(5); in[0] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C1:" + endp + " -t 10000")); in[1] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C2:" + endp + " -t 10001")); in[2] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C3:" + endp + " -t 10002")); in[3] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C4:" + endp + " -t 10003")); in[4] = ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C5:" + endp + " -t 10004")); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opCPrxSeqAsync(in, + [&](deque<shared_ptr<Test::CPrx>> ret, deque<shared_ptr<Test::CPrx>> out) + { + test(ret.size() == in.size()); + auto op = out.begin(); + auto rp = ret.begin(); + for(auto i: in) + { + test(Ice::targetEquals(*op++, i)); + test(Ice::targetEquals(*rp++, i)); + } + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opCPrxSeqPtr callback = Test::newCallback_TestIntf_opCPrxSeq(cb, &Callback::opCPrxSeq, &Callback::noEx); t->begin_opCPrxSeq(in, callback, newInParam(in)); cb->check(); +#endif } { - list<Test::CPrx> in; + list<Test::CPrxPtr> in; in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C1:" + endp + " -t 10000"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C2:" + endp + " -t 10001"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C3:" + endp + " -t 10002"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C4:" + endp + " -t 10003"))); in.push_back(ICE_UNCHECKED_CAST(Test::CPrx, communicator->stringToProxy("C5:" + endp + " -t 10004"))); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opCPrxListAsync(in, + [&](list<shared_ptr<Test::CPrx>> ret, list<shared_ptr<Test::CPrx>> out) + { + test(ret.size() == in.size()); + auto op = out.begin(); + auto rp = ret.begin(); + for(auto i: in) + { + test(Ice::targetEquals(*op++, i)); + test(Ice::targetEquals(*rp++, i)); + } + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opCPrxListPtr callback = Test::newCallback_TestIntf_opCPrxList(cb, &Callback::opCPrxList, &Callback::noEx); t->begin_opCPrxList(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2279,10 +3041,29 @@ allTests(const Ice::CommunicatorPtr& communicator) in[3] = in[0]; in[4] = in[0]; +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opCSeqAsync(in, + [&](deque<shared_ptr<Test::C>> ret, deque<shared_ptr<Test::C>> out) + { + test(ret == out); + test(ret.size() == in.size()); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opCSeqPtr callback = Test::newCallback_TestIntf_opCSeq(cb, &Callback::opCSeq, &Callback::noEx); t->begin_opCSeq(in, callback, newInParam(in)); cb->check(); +#endif } { @@ -2293,14 +3074,32 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back(ICE_MAKE_SHARED(Test::C)); in.push_back(ICE_MAKE_SHARED(Test::C)); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opCListAsync(in, + [&](list<shared_ptr<Test::C>> ret, list<shared_ptr<Test::C>> out) + { + test(ret == out); + test(ret.size() == in.size()); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opCListPtr callback = Test::newCallback_TestIntf_opCList(cb, &Callback::opCList, &Callback::noEx); t->begin_opCList(in, callback, newInParam(in)); cb->check(); +#endif } - { Test::ByteSeq in; in.push_back('1'); @@ -2308,14 +3107,34 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('3'); in.push_back('4'); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opOutArrayByteSeqAsync(in, + [&](pair<const Ice::Byte*, const Ice::Byte*> out) + { + test(arrayRangeEquals<Ice::Byte>( + make_pair<const Ice::Byte*>(&in[0], &in[0] + in.size()), out)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opOutArrayByteSeqPtr callback = Test::newCallback_TestIntf_opOutArrayByteSeq(cb, &Callback::opOutArrayByteSeq, &Callback::noEx); t->begin_opOutArrayByteSeq(in, callback, newInParam(in)); cb->check(); +#endif } + { Test::ByteSeq in; in.push_back('1'); @@ -2323,12 +3142,30 @@ allTests(const Ice::CommunicatorPtr& communicator) in.push_back('3'); in.push_back('4'); +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + t->opOutRangeByteSeqAsync(in, + [&](pair<vector<Ice::Byte>::const_iterator, vector<Ice::Byte>::const_iterator> out) + { + test(in == vector<Ice::Byte>(out.first, out.second)); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opOutRangeByteSeqPtr callback = Test::newCallback_TestIntf_opOutRangeByteSeq(cb, &Callback::opOutRangeByteSeq, &Callback::noEx); t->begin_opOutRangeByteSeq(in, callback, newInParam(in)); cb->check(); +#endif } cout << "ok" << endl; @@ -2343,6 +3180,11 @@ allTests(const Ice::CommunicatorPtr& communicator) idict[3] = "three"; idict[-1] = "minus one"; +#ifdef ICE_CPP11_MAPPING + auto r = t->opIntStringDictAsync(idict).get(); + test(r.odict == idict); + test(r.returnValue == idict); +#else Test::IntStringDict out; out[5] = "five"; @@ -2350,6 +3192,7 @@ allTests(const Ice::CommunicatorPtr& communicator) Test::IntStringDict ret = t->end_opIntStringDict(out, r); test(out == idict); test(ret == idict); +#endif } { @@ -2360,6 +3203,15 @@ allTests(const Ice::CommunicatorPtr& communicator) idict["three"] = 3; idict["minus one"] = -1; +#ifdef ICE_CPP11_MAPPING + auto r = t->opVarDictAsync(idict).get(); + test(r.odict == idict); + test(r.returnValue.size() == 1000); + for(auto i: r.returnValue) + { + test(i.second == i.first * i.first); + } +#else Test::CustomMap<std::string, Ice::Int> out; out["five"] = 5; @@ -2372,6 +3224,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(i->second == i->first * i->first); } +#endif } { @@ -2382,6 +3235,17 @@ allTests(const Ice::CommunicatorPtr& communicator) idict[3] = "three"; idict[-1] = "minus one"; +#ifdef ICE_CPP11_MAPPING + auto r = t->opCustomIntStringDictAsync(idict).get(); + test(r.odict.size() == idict.size()); + + test(r.odict == r.returnValue); + + for(auto i: idict) + { + test(r.odict[i.first].size() == i.second.size()); + } +#else Test::IntStringDict out; out[5] = "five"; @@ -2396,7 +3260,9 @@ allTests(const Ice::CommunicatorPtr& communicator) test(out[p->first].size() == p->second.size()); // test(out[p->first] == p->second.to_string()); does not always work due to string converter } +#endif } + } cout << "ok" << endl; @@ -2410,11 +3276,30 @@ allTests(const Ice::CommunicatorPtr& communicator) idict[3] = "three"; idict[-1] = "minus one"; +#ifdef ICE_CPP11_MAPPING + promise<bool> done; + + t->opIntStringDictAsync(idict, + [&](map<int, string> ret, map<int, string> out) + { + test(ret == out); + test(ret == idict); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); + +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opIntStringDictPtr callback = Test::newCallback_TestIntf_opIntStringDict(cb, &Callback::opIntStringDict, &Callback::noEx); t->begin_opIntStringDict(idict, callback, newInParam(idict)); cb->check(); +#endif } { @@ -2425,11 +3310,35 @@ allTests(const Ice::CommunicatorPtr& communicator) idict["three"] = 3; idict["minus one"] = -1; +#ifdef ICE_CPP11_MAPPING + promise<bool> done; + + t->opVarDictAsync(idict, + [&](Test::CustomMap<long long, long long> ret, Test::CustomMap<string, int> out) + { + test(out == idict); + for(auto i: ret) + { + test(i.second == i.first * i.first); + } + + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); + +#else + CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opVarDictPtr callback = Test::newCallback_TestIntf_opVarDict(cb, &Callback::opVarDict, &Callback::noEx); t->begin_opVarDict(idict, callback, newInParam(idict)); cb->check(); +#endif } { @@ -2440,16 +3349,44 @@ allTests(const Ice::CommunicatorPtr& communicator) idict[3] = "three"; idict[-1] = "minus one"; +#ifdef ICE_CPP11_MAPPING + promise<bool> done; + + t->opCustomIntStringDictAsync(idict, + [&](map<int, Util::string_view> ret, map<int, Util::string_view> out) + { + test(ret == out); + for(auto i: idict) + { + // TODO: have to compare size not strings because of string converter + test(ret[i.first].size() == i.second.size()); + } + + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); Test::Callback_TestIntf_opCustomIntStringDictPtr callback = Test::newCallback_TestIntf_opCustomIntStringDict(cb, &Callback::opCustomIntStringDict, &Callback::noEx); t->begin_opCustomIntStringDict(idict, callback, newInParam(idict)); cb->check(); +#endif } } cout << "ok" << endl; + + +#ifndef ICE_CPP11_MAPPING + + cout << "testing class mapped structs ... " << flush; Test::ClassStructPtr cs = new Test::ClassStruct(); cs->y = 10; @@ -2488,6 +3425,8 @@ allTests(const Ice::CommunicatorPtr& communicator) } cout << "ok" << endl; +#endif + cout << "testing wstring... " << flush; Test1::WstringSeq wseq1; @@ -2521,17 +3460,42 @@ allTests(const Ice::CommunicatorPtr& communicator) test(ret == wstr); { +#ifdef ICE_CPP11_MAPPING + auto r = wsc1->opStringAsync(wstr).get(); + test(r.s2 == wstr); + test(r.returnValue == wstr); +#else Ice::AsyncResultPtr r = wsc1->begin_opString(wstr); wstring out; wstring ret = wsc1->end_opString(out, r); test(out == wstr); test(ret == wstr); +#endif } { +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + wsc1->opStringAsync(wstr, + [&](wstring ret, wstring out) + { + test(out == wstr); + test(ret == wstr); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); wsc1->begin_opString(wstr, Test1::newCallback_WstringClass_opString(cb, &Callback::opString, &Callback::noEx), newInParam(wstr)); cb->check(); +#endif } ret = wsc2->opString(wstr, out); @@ -2539,23 +3503,42 @@ allTests(const Ice::CommunicatorPtr& communicator) test(ret == wstr); { +#ifdef ICE_CPP11_MAPPING + auto r = wsc2->opStringAsync(wstr).get(); + test(r.s2 == wstr); + test(r.returnValue == wstr); +#else Ice::AsyncResultPtr r = wsc2->begin_opString(wstr); wstring out; wstring ret = wsc2->end_opString(out, r); test(out == wstr); test(ret == wstr); +#endif } { +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + wsc2->opStringAsync(wstr, + [&](wstring ret, wstring out) + { + test(out == wstr); + test(ret == wstr); + done.set_value(true); + }, + [&](std::exception_ptr) + { + done.set_value(false); + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); wsc2->begin_opString(wstr, Test2::newCallback_WstringClass_opString(cb, &Callback::opString, &Callback::noEx), newInParam(wstr)); cb->check(); - } - { - CallbackPtr cb = new Callback(); - wsc2->begin_opString(wstr, Test2::newCallback_WstringClass_opString(cb, &Callback::opString, - &Callback::noEx), newInParam(wstr)); - cb->check(); +#endif } Test1::WstringStruct wss1; @@ -2582,6 +3565,19 @@ allTests(const Ice::CommunicatorPtr& communicator) } { +#ifdef ICE_CPP11_MAPPING + + auto f = wsc1->throwExceptAsync(wstr); + try + { + f.get(); + test(false); + } + catch(const Test1::WstringException& ex) + { + test(ex.reason == wstr); + } +#else Ice::AsyncResultPtr r = wsc1->begin_throwExcept(wstr); try { @@ -2592,11 +3588,42 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(ex.reason == wstr); } +#endif } { + +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + wsc1->throwExceptAsync(wstr, + [&]() + { + done.set_value(false); + }, + [&](std::exception_ptr eptr) + { + try + { + std::rethrow_exception(eptr); + } + catch(const Test1::WstringException& ex) + { + test(ex.reason == wstr); + done.set_value(true); + } + catch(...) + { + done.set_value(false); + } + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); wsc1->begin_throwExcept(wstr, Ice::newCallback(cb, &Callback::throwExcept1), newInParam(wstr)); cb->check(); +#endif } try @@ -2609,6 +3636,20 @@ allTests(const Ice::CommunicatorPtr& communicator) } { + +#ifdef ICE_CPP11_MAPPING + + auto f = wsc2->throwExceptAsync(wstr); + try + { + f.get(); + test(false); + } + catch(const Test2::WstringException& ex) + { + test(ex.reason == wstr); + } +#else Ice::AsyncResultPtr r = wsc2->begin_throwExcept(wstr); try { @@ -2619,13 +3660,42 @@ allTests(const Ice::CommunicatorPtr& communicator) { test(ex.reason == wstr); } +#endif } { +#ifdef ICE_CPP11_MAPPING + + promise<bool> done; + + wsc2->throwExceptAsync(wstr, + [&]() + { + done.set_value(false); + }, + [&](std::exception_ptr eptr) + { + try + { + std::rethrow_exception(eptr); + } + catch(const Test2::WstringException& ex) + { + test(ex.reason == wstr); + done.set_value(true); + } + catch(...) + { + done.set_value(false); + } + }); + + test(done.get_future().get()); +#else CallbackPtr cb = new Callback(); wsc2->begin_throwExcept(wstr, Ice::newCallback(cb, &Callback::throwExcept2), newInParam(wstr)); cb->check(); - } #endif + } cout << "ok" << endl; diff --git a/cpp/test/Ice/custom/CustomMap.h b/cpp/test/Ice/custom/CustomMap.h index 0dbd70b065b..306aa345ef0 100644 --- a/cpp/test/Ice/custom/CustomMap.h +++ b/cpp/test/Ice/custom/CustomMap.h @@ -11,12 +11,7 @@ #define CUSTOM_MAP_H #include <IceUtil/Config.h> - -#ifdef ICE_CPP11_COMPILER -# include <unordered_map> -#else -# include <map> -#endif +#include <map> namespace Test { diff --git a/cpp/test/Ice/invoke/AllTests.cpp b/cpp/test/Ice/invoke/AllTests.cpp index 40e66f5f77f..244e802ac22 100644 --- a/cpp/test/Ice/invoke/AllTests.cpp +++ b/cpp/test/Ice/invoke/AllTests.cpp @@ -406,10 +406,10 @@ allTests(const Ice::CommunicatorPtr& communicator) // { Ice::ByteSeq inEncaps; - test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().ok); - test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().ok); - test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().ok); - test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().ok); + test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); + test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); + test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); + test(batchOneway->ice_invokeAsync("opOneway", ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); batchOneway->ice_flushBatchRequests(); } @@ -440,7 +440,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { Ice::ByteSeq inEncaps, outEncaps; auto completed = oneway->ice_invokeAsync("opOneway", OperationMode::Normal, inEncaps); - test(completed.get().ok); + test(completed.get().returnValue); } { @@ -485,7 +485,7 @@ allTests(const Ice::CommunicatorPtr& communicator) out.finished(inEncaps); auto result = cl->ice_invokeAsync("opString", OperationMode::Normal, inEncaps).get(); - test(result.ok); + test(result.returnValue); Ice::InputStream in(communicator, result.outParams); in.startEncapsulation(); @@ -508,7 +508,7 @@ allTests(const Ice::CommunicatorPtr& communicator) out.endEncapsulation(); out.finished(inEncaps); - pair<const ::Ice::Byte*, const ::Ice::Byte*> inPair(&inEncaps[0], &inEncaps[0] + inEncaps.size()); + auto inPair = make_pair(inEncaps.data(), inEncaps.data() + inEncaps.size()); cl->ice_invokeAsync("opString", OperationMode::Normal, inPair, [&](bool ok, pair<const Ice::Byte*, const Ice::Byte*> outParams) @@ -539,29 +539,29 @@ allTests(const Ice::CommunicatorPtr& communicator) // // repeat with the future API. // - // TODO: we don't currently support zero-copy with promised based ice_invokeAsync - // { - // Ice::ByteSeq inEncaps, outEncaps; - // Ice::OutputStream out(communicator); - // out.startEncapsulation(); - // out.write(testString); - // out.endEncapsulation(); - // out.finished(inEncaps); - - // pair<const ::Ice::Byte*, const ::Ice::Byte*> inPair(&inEncaps[0], &inEncaps[0] + inEncaps.size()); - - // auto result = cl->ice_invokeAsync("opString", OperationMode::Normal, inPair).get(); - // test(result.ok); - // vector<Ice::Byte>(result.outParams.first, result.outParams.second).swap(outEncaps); - // Ice::InputStream in(communicator, outEncaps); - // in.startEncapsulation(); - // string s; - // in.read(s); - // test(s == testString); - // in.read(s); - // test(s == testString); - // in.endEncapsulation(); - // } + + { + Ice::ByteSeq inEncaps, outEncaps; + Ice::OutputStream out(communicator); + out.startEncapsulation(); + out.write(testString); + out.endEncapsulation(); + out.finished(inEncaps); + + auto inPair = make_pair(inEncaps.data(), inEncaps.data() + inEncaps.size()); + + auto result = cl->ice_invokeAsync("opString", OperationMode::Normal, inPair).get(); + test(result.returnValue); + + Ice::InputStream in(communicator, result.outParams); + in.startEncapsulation(); + string s; + in.read(s); + test(s == testString); + in.read(s); + test(s == testString); + in.endEncapsulation(); + } { promise<bool> completed; @@ -606,7 +606,7 @@ allTests(const Ice::CommunicatorPtr& communicator) { Ice::ByteSeq inEncaps; auto result = cl->ice_invokeAsync("opException", OperationMode::Normal, inEncaps).get(); - test(!result.ok); + test(!result.returnValue); Ice::InputStream in(communicator, result.outParams); in.startEncapsulation(); |